gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

proto.go (17016B)


      1 // Copyright 2018 The Go Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style
      3 // license that can be found in the LICENSE file.
      4 
      5 // Package protoreflect provides interfaces to dynamically manipulate messages.
      6 //
      7 // This package includes type descriptors which describe the structure of types
      8 // defined in proto source files and value interfaces which provide the
      9 // ability to examine and manipulate the contents of messages.
     10 //
     11 // # Protocol Buffer Descriptors
     12 //
     13 // Protobuf descriptors (e.g., EnumDescriptor or MessageDescriptor)
     14 // are immutable objects that represent protobuf type information.
     15 // They are wrappers around the messages declared in descriptor.proto.
     16 // Protobuf descriptors alone lack any information regarding Go types.
     17 //
     18 // Enums and messages generated by this module implement Enum and ProtoMessage,
     19 // where the Descriptor and ProtoReflect.Descriptor accessors respectively
     20 // return the protobuf descriptor for the values.
     21 //
     22 // The protobuf descriptor interfaces are not meant to be implemented by
     23 // user code since they might need to be extended in the future to support
     24 // additions to the protobuf language.
     25 // The "google.golang.org/protobuf/reflect/protodesc" package converts between
     26 // google.protobuf.DescriptorProto messages and protobuf descriptors.
     27 //
     28 // # Go Type Descriptors
     29 //
     30 // A type descriptor (e.g., EnumType or MessageType) is a constructor for
     31 // a concrete Go type that represents the associated protobuf descriptor.
     32 // There is commonly a one-to-one relationship between protobuf descriptors and
     33 // Go type descriptors, but it can potentially be a one-to-many relationship.
     34 //
     35 // Enums and messages generated by this module implement Enum and ProtoMessage,
     36 // where the Type and ProtoReflect.Type accessors respectively
     37 // return the protobuf descriptor for the values.
     38 //
     39 // The "google.golang.org/protobuf/types/dynamicpb" package can be used to
     40 // create Go type descriptors from protobuf descriptors.
     41 //
     42 // # Value Interfaces
     43 //
     44 // The Enum and Message interfaces provide a reflective view over an
     45 // enum or message instance. For enums, it provides the ability to retrieve
     46 // the enum value number for any concrete enum type. For messages, it provides
     47 // the ability to access or manipulate fields of the message.
     48 //
     49 // To convert a proto.Message to a protoreflect.Message, use the
     50 // former's ProtoReflect method. Since the ProtoReflect method is new to the
     51 // v2 message interface, it may not be present on older message implementations.
     52 // The "github.com/golang/protobuf/proto".MessageReflect function can be used
     53 // to obtain a reflective view on older messages.
     54 //
     55 // # Relationships
     56 //
     57 // The following diagrams demonstrate the relationships between
     58 // various types declared in this package.
     59 //
     60 //	                       ┌───────────────────────────────────┐
     61 //	                       V                                   │
     62 //	   ┌────────────── New(n) ─────────────┐                   │
     63 //	   │                                   │                   │
     64 //	   │      ┌──── Descriptor() ──┐       │  ┌── Number() ──┐ │
     65 //	   │      │                    V       V  │              V │
     66 //	╔════════════╗  ╔════════════════╗  ╔════════╗  ╔════════════╗
     67 //	║  EnumType  ║  ║ EnumDescriptor ║  ║  Enum  ║  ║ EnumNumber ║
     68 //	╚════════════╝  ╚════════════════╝  ╚════════╝  ╚════════════╝
     69 //	      Λ           Λ                   │ │
     70 //	      │           └─── Descriptor() ──┘ │
     71 //	      │                                 │
     72 //	      └────────────────── Type() ───────┘
     73 //
     74 // • An EnumType describes a concrete Go enum type.
     75 // It has an EnumDescriptor and can construct an Enum instance.
     76 //
     77 // • An EnumDescriptor describes an abstract protobuf enum type.
     78 //
     79 // • An Enum is a concrete enum instance. Generated enums implement Enum.
     80 //
     81 //	  ┌──────────────── New() ─────────────────┐
     82 //	  │                                        │
     83 //	  │         ┌─── Descriptor() ─────┐       │   ┌── Interface() ───┐
     84 //	  │         │                      V       V   │                  V
     85 //	╔═════════════╗  ╔═══════════════════╗  ╔═════════╗  ╔══════════════╗
     86 //	║ MessageType ║  ║ MessageDescriptor ║  ║ Message ║  ║ ProtoMessage ║
     87 //	╚═════════════╝  ╚═══════════════════╝  ╚═════════╝  ╚══════════════╝
     88 //	       Λ           Λ                      │ │  Λ                  │
     89 //	       │           └──── Descriptor() ────┘ │  └─ ProtoReflect() ─┘
     90 //	       │                                    │
     91 //	       └─────────────────── Type() ─────────┘
     92 //
     93 // • A MessageType describes a concrete Go message type.
     94 // It has a MessageDescriptor and can construct a Message instance.
     95 // Just as how Go's reflect.Type is a reflective description of a Go type,
     96 // a MessageType is a reflective description of a Go type for a protobuf message.
     97 //
     98 // • A MessageDescriptor describes an abstract protobuf message type.
     99 // It has no understanding of Go types. In order to construct a MessageType
    100 // from just a MessageDescriptor, you can consider looking up the message type
    101 // in the global registry using protoregistry.GlobalTypes.FindMessageByName
    102 // or constructing a dynamic MessageType using dynamicpb.NewMessageType.
    103 //
    104 // • A Message is a reflective view over a concrete message instance.
    105 // Generated messages implement ProtoMessage, which can convert to a Message.
    106 // Just as how Go's reflect.Value is a reflective view over a Go value,
    107 // a Message is a reflective view over a concrete protobuf message instance.
    108 // Using Go reflection as an analogy, the ProtoReflect method is similar to
    109 // calling reflect.ValueOf, and the Message.Interface method is similar to
    110 // calling reflect.Value.Interface.
    111 //
    112 //	      ┌── TypeDescriptor() ──┐    ┌───── Descriptor() ─────┐
    113 //	      │                      V    │                        V
    114 //	╔═══════════════╗  ╔═════════════════════════╗  ╔═════════════════════╗
    115 //	║ ExtensionType ║  ║ ExtensionTypeDescriptor ║  ║ ExtensionDescriptor ║
    116 //	╚═══════════════╝  ╚═════════════════════════╝  ╚═════════════════════╝
    117 //	      Λ                      │   │ Λ                      │ Λ
    118 //	      └─────── Type() ───────┘   │ └─── may implement ────┘ │
    119 //	                                 │                          │
    120 //	                                 └────── implements ────────┘
    121 //
    122 // • An ExtensionType describes a concrete Go implementation of an extension.
    123 // It has an ExtensionTypeDescriptor and can convert to/from
    124 // abstract Values and Go values.
    125 //
    126 // • An ExtensionTypeDescriptor is an ExtensionDescriptor
    127 // which also has an ExtensionType.
    128 //
    129 // • An ExtensionDescriptor describes an abstract protobuf extension field and
    130 // may not always be an ExtensionTypeDescriptor.
    131 package protoreflect
    132 
    133 import (
    134 	"fmt"
    135 	"strings"
    136 
    137 	"google.golang.org/protobuf/encoding/protowire"
    138 	"google.golang.org/protobuf/internal/pragma"
    139 )
    140 
    141 type doNotImplement pragma.DoNotImplement
    142 
    143 // ProtoMessage is the top-level interface that all proto messages implement.
    144 // This is declared in the protoreflect package to avoid a cyclic dependency;
    145 // use the proto.Message type instead, which aliases this type.
    146 type ProtoMessage interface{ ProtoReflect() Message }
    147 
    148 // Syntax is the language version of the proto file.
    149 type Syntax syntax
    150 
    151 type syntax int8 // keep exact type opaque as the int type may change
    152 
    153 const (
    154 	Proto2 Syntax = 2
    155 	Proto3 Syntax = 3
    156 )
    157 
    158 // IsValid reports whether the syntax is valid.
    159 func (s Syntax) IsValid() bool {
    160 	switch s {
    161 	case Proto2, Proto3:
    162 		return true
    163 	default:
    164 		return false
    165 	}
    166 }
    167 
    168 // String returns s as a proto source identifier (e.g., "proto2").
    169 func (s Syntax) String() string {
    170 	switch s {
    171 	case Proto2:
    172 		return "proto2"
    173 	case Proto3:
    174 		return "proto3"
    175 	default:
    176 		return fmt.Sprintf("<unknown:%d>", s)
    177 	}
    178 }
    179 
    180 // GoString returns s as a Go source identifier (e.g., "Proto2").
    181 func (s Syntax) GoString() string {
    182 	switch s {
    183 	case Proto2:
    184 		return "Proto2"
    185 	case Proto3:
    186 		return "Proto3"
    187 	default:
    188 		return fmt.Sprintf("Syntax(%d)", s)
    189 	}
    190 }
    191 
    192 // Cardinality determines whether a field is optional, required, or repeated.
    193 type Cardinality cardinality
    194 
    195 type cardinality int8 // keep exact type opaque as the int type may change
    196 
    197 // Constants as defined by the google.protobuf.Cardinality enumeration.
    198 const (
    199 	Optional Cardinality = 1 // appears zero or one times
    200 	Required Cardinality = 2 // appears exactly one time; invalid with Proto3
    201 	Repeated Cardinality = 3 // appears zero or more times
    202 )
    203 
    204 // IsValid reports whether the cardinality is valid.
    205 func (c Cardinality) IsValid() bool {
    206 	switch c {
    207 	case Optional, Required, Repeated:
    208 		return true
    209 	default:
    210 		return false
    211 	}
    212 }
    213 
    214 // String returns c as a proto source identifier (e.g., "optional").
    215 func (c Cardinality) String() string {
    216 	switch c {
    217 	case Optional:
    218 		return "optional"
    219 	case Required:
    220 		return "required"
    221 	case Repeated:
    222 		return "repeated"
    223 	default:
    224 		return fmt.Sprintf("<unknown:%d>", c)
    225 	}
    226 }
    227 
    228 // GoString returns c as a Go source identifier (e.g., "Optional").
    229 func (c Cardinality) GoString() string {
    230 	switch c {
    231 	case Optional:
    232 		return "Optional"
    233 	case Required:
    234 		return "Required"
    235 	case Repeated:
    236 		return "Repeated"
    237 	default:
    238 		return fmt.Sprintf("Cardinality(%d)", c)
    239 	}
    240 }
    241 
    242 // Kind indicates the basic proto kind of a field.
    243 type Kind kind
    244 
    245 type kind int8 // keep exact type opaque as the int type may change
    246 
    247 // Constants as defined by the google.protobuf.Field.Kind enumeration.
    248 const (
    249 	BoolKind     Kind = 8
    250 	EnumKind     Kind = 14
    251 	Int32Kind    Kind = 5
    252 	Sint32Kind   Kind = 17
    253 	Uint32Kind   Kind = 13
    254 	Int64Kind    Kind = 3
    255 	Sint64Kind   Kind = 18
    256 	Uint64Kind   Kind = 4
    257 	Sfixed32Kind Kind = 15
    258 	Fixed32Kind  Kind = 7
    259 	FloatKind    Kind = 2
    260 	Sfixed64Kind Kind = 16
    261 	Fixed64Kind  Kind = 6
    262 	DoubleKind   Kind = 1
    263 	StringKind   Kind = 9
    264 	BytesKind    Kind = 12
    265 	MessageKind  Kind = 11
    266 	GroupKind    Kind = 10
    267 )
    268 
    269 // IsValid reports whether the kind is valid.
    270 func (k Kind) IsValid() bool {
    271 	switch k {
    272 	case BoolKind, EnumKind,
    273 		Int32Kind, Sint32Kind, Uint32Kind,
    274 		Int64Kind, Sint64Kind, Uint64Kind,
    275 		Sfixed32Kind, Fixed32Kind, FloatKind,
    276 		Sfixed64Kind, Fixed64Kind, DoubleKind,
    277 		StringKind, BytesKind, MessageKind, GroupKind:
    278 		return true
    279 	default:
    280 		return false
    281 	}
    282 }
    283 
    284 // String returns k as a proto source identifier (e.g., "bool").
    285 func (k Kind) String() string {
    286 	switch k {
    287 	case BoolKind:
    288 		return "bool"
    289 	case EnumKind:
    290 		return "enum"
    291 	case Int32Kind:
    292 		return "int32"
    293 	case Sint32Kind:
    294 		return "sint32"
    295 	case Uint32Kind:
    296 		return "uint32"
    297 	case Int64Kind:
    298 		return "int64"
    299 	case Sint64Kind:
    300 		return "sint64"
    301 	case Uint64Kind:
    302 		return "uint64"
    303 	case Sfixed32Kind:
    304 		return "sfixed32"
    305 	case Fixed32Kind:
    306 		return "fixed32"
    307 	case FloatKind:
    308 		return "float"
    309 	case Sfixed64Kind:
    310 		return "sfixed64"
    311 	case Fixed64Kind:
    312 		return "fixed64"
    313 	case DoubleKind:
    314 		return "double"
    315 	case StringKind:
    316 		return "string"
    317 	case BytesKind:
    318 		return "bytes"
    319 	case MessageKind:
    320 		return "message"
    321 	case GroupKind:
    322 		return "group"
    323 	default:
    324 		return fmt.Sprintf("<unknown:%d>", k)
    325 	}
    326 }
    327 
    328 // GoString returns k as a Go source identifier (e.g., "BoolKind").
    329 func (k Kind) GoString() string {
    330 	switch k {
    331 	case BoolKind:
    332 		return "BoolKind"
    333 	case EnumKind:
    334 		return "EnumKind"
    335 	case Int32Kind:
    336 		return "Int32Kind"
    337 	case Sint32Kind:
    338 		return "Sint32Kind"
    339 	case Uint32Kind:
    340 		return "Uint32Kind"
    341 	case Int64Kind:
    342 		return "Int64Kind"
    343 	case Sint64Kind:
    344 		return "Sint64Kind"
    345 	case Uint64Kind:
    346 		return "Uint64Kind"
    347 	case Sfixed32Kind:
    348 		return "Sfixed32Kind"
    349 	case Fixed32Kind:
    350 		return "Fixed32Kind"
    351 	case FloatKind:
    352 		return "FloatKind"
    353 	case Sfixed64Kind:
    354 		return "Sfixed64Kind"
    355 	case Fixed64Kind:
    356 		return "Fixed64Kind"
    357 	case DoubleKind:
    358 		return "DoubleKind"
    359 	case StringKind:
    360 		return "StringKind"
    361 	case BytesKind:
    362 		return "BytesKind"
    363 	case MessageKind:
    364 		return "MessageKind"
    365 	case GroupKind:
    366 		return "GroupKind"
    367 	default:
    368 		return fmt.Sprintf("Kind(%d)", k)
    369 	}
    370 }
    371 
    372 // FieldNumber is the field number in a message.
    373 type FieldNumber = protowire.Number
    374 
    375 // FieldNumbers represent a list of field numbers.
    376 type FieldNumbers interface {
    377 	// Len reports the number of fields in the list.
    378 	Len() int
    379 	// Get returns the ith field number. It panics if out of bounds.
    380 	Get(i int) FieldNumber
    381 	// Has reports whether n is within the list of fields.
    382 	Has(n FieldNumber) bool
    383 
    384 	doNotImplement
    385 }
    386 
    387 // FieldRanges represent a list of field number ranges.
    388 type FieldRanges interface {
    389 	// Len reports the number of ranges in the list.
    390 	Len() int
    391 	// Get returns the ith range. It panics if out of bounds.
    392 	Get(i int) [2]FieldNumber // start inclusive; end exclusive
    393 	// Has reports whether n is within any of the ranges.
    394 	Has(n FieldNumber) bool
    395 
    396 	doNotImplement
    397 }
    398 
    399 // EnumNumber is the numeric value for an enum.
    400 type EnumNumber int32
    401 
    402 // EnumRanges represent a list of enum number ranges.
    403 type EnumRanges interface {
    404 	// Len reports the number of ranges in the list.
    405 	Len() int
    406 	// Get returns the ith range. It panics if out of bounds.
    407 	Get(i int) [2]EnumNumber // start inclusive; end inclusive
    408 	// Has reports whether n is within any of the ranges.
    409 	Has(n EnumNumber) bool
    410 
    411 	doNotImplement
    412 }
    413 
    414 // Name is the short name for a proto declaration. This is not the name
    415 // as used in Go source code, which might not be identical to the proto name.
    416 type Name string // e.g., "Kind"
    417 
    418 // IsValid reports whether s is a syntactically valid name.
    419 // An empty name is invalid.
    420 func (s Name) IsValid() bool {
    421 	return consumeIdent(string(s)) == len(s)
    422 }
    423 
    424 // Names represent a list of names.
    425 type Names interface {
    426 	// Len reports the number of names in the list.
    427 	Len() int
    428 	// Get returns the ith name. It panics if out of bounds.
    429 	Get(i int) Name
    430 	// Has reports whether s matches any names in the list.
    431 	Has(s Name) bool
    432 
    433 	doNotImplement
    434 }
    435 
    436 // FullName is a qualified name that uniquely identifies a proto declaration.
    437 // A qualified name is the concatenation of the proto package along with the
    438 // fully-declared name (i.e., name of parent preceding the name of the child),
    439 // with a '.' delimiter placed between each Name.
    440 //
    441 // This should not have any leading or trailing dots.
    442 type FullName string // e.g., "google.protobuf.Field.Kind"
    443 
    444 // IsValid reports whether s is a syntactically valid full name.
    445 // An empty full name is invalid.
    446 func (s FullName) IsValid() bool {
    447 	i := consumeIdent(string(s))
    448 	if i < 0 {
    449 		return false
    450 	}
    451 	for len(s) > i {
    452 		if s[i] != '.' {
    453 			return false
    454 		}
    455 		i++
    456 		n := consumeIdent(string(s[i:]))
    457 		if n < 0 {
    458 			return false
    459 		}
    460 		i += n
    461 	}
    462 	return true
    463 }
    464 
    465 func consumeIdent(s string) (i int) {
    466 	if len(s) == 0 || !isLetter(s[i]) {
    467 		return -1
    468 	}
    469 	i++
    470 	for len(s) > i && isLetterDigit(s[i]) {
    471 		i++
    472 	}
    473 	return i
    474 }
    475 func isLetter(c byte) bool {
    476 	return c == '_' || ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z')
    477 }
    478 func isLetterDigit(c byte) bool {
    479 	return isLetter(c) || ('0' <= c && c <= '9')
    480 }
    481 
    482 // Name returns the short name, which is the last identifier segment.
    483 // A single segment FullName is the Name itself.
    484 func (n FullName) Name() Name {
    485 	if i := strings.LastIndexByte(string(n), '.'); i >= 0 {
    486 		return Name(n[i+1:])
    487 	}
    488 	return Name(n)
    489 }
    490 
    491 // Parent returns the full name with the trailing identifier removed.
    492 // A single segment FullName has no parent.
    493 func (n FullName) Parent() FullName {
    494 	if i := strings.LastIndexByte(string(n), '.'); i >= 0 {
    495 		return n[:i]
    496 	}
    497 	return ""
    498 }
    499 
    500 // Append returns the qualified name appended with the provided short name.
    501 //
    502 // Invariant: n == n.Parent().Append(n.Name()) // assuming n is valid
    503 func (n FullName) Append(s Name) FullName {
    504 	if n == "" {
    505 		return FullName(s)
    506 	}
    507 	return n + "." + FullName(s)
    508 }