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 }