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 5package protoreflect 6 7// Descriptor provides a set of accessors that are common to every descriptor. 8// Each descriptor type wraps the equivalent google.protobuf.XXXDescriptorProto, 9// but provides efficient lookup and immutability. 10// 11// Each descriptor is comparable. Equality implies that the two types are 12// exactly identical. However, it is possible for the same semantically 13// identical proto type to be represented by multiple type descriptors. 14// 15// For example, suppose we have t1 and t2 which are both MessageDescriptors. 16// If t1 == t2, then the types are definitely equal and all accessors return 17// the same information. However, if t1 != t2, then it is still possible that 18// they still represent the same proto type (e.g., t1.FullName == t2.FullName). 19// This can occur if a descriptor type is created dynamically, or multiple 20// versions of the same proto type are accidentally linked into the Go binary. 21type Descriptor interface { 22 // ParentFile returns the parent file descriptor that this descriptor 23 // is declared within. The parent file for the file descriptor is itself. 24 // 25 // Support for this functionality is optional and may return nil. 26 ParentFile() FileDescriptor 27 28 // Parent returns the parent containing this descriptor declaration. 29 // The following shows the mapping from child type to possible parent types: 30 // 31 // ╔═════════════════════╤═══════════════════════════════════╗ 32 // ║ Child type │ Possible parent types ║ 33 // ╠═════════════════════╪═══════════════════════════════════╣ 34 // ║ FileDescriptor │ nil ║ 35 // ║ MessageDescriptor │ FileDescriptor, MessageDescriptor ║ 36 // ║ FieldDescriptor │ FileDescriptor, MessageDescriptor ║ 37 // ║ OneofDescriptor │ MessageDescriptor ║ 38 // ║ EnumDescriptor │ FileDescriptor, MessageDescriptor ║ 39 // ║ EnumValueDescriptor │ EnumDescriptor ║ 40 // ║ ServiceDescriptor │ FileDescriptor ║ 41 // ║ MethodDescriptor │ ServiceDescriptor ║ 42 // ╚═════════════════════╧═══════════════════════════════════╝ 43 // 44 // Support for this functionality is optional and may return nil. 45 Parent() Descriptor 46 47 // Index returns the index of this descriptor within its parent. 48 // It returns 0 if the descriptor does not have a parent or if the parent 49 // is unknown. 50 Index() int 51 52 // Syntax is the protobuf syntax. 53 Syntax() Syntax // e.g., Proto2 or Proto3 54 55 // Name is the short name of the declaration (i.e., FullName.Name). 56 Name() Name // e.g., "Any" 57 58 // FullName is the fully-qualified name of the declaration. 59 // 60 // The FullName is a concatenation of the full name of the type that this 61 // type is declared within and the declaration name. For example, 62 // field "foo_field" in message "proto.package.MyMessage" is 63 // uniquely identified as "proto.package.MyMessage.foo_field". 64 // Enum values are an exception to the rule (see EnumValueDescriptor). 65 FullName() FullName // e.g., "google.protobuf.Any" 66 67 // IsPlaceholder reports whether type information is missing since a 68 // dependency is not resolved, in which case only name information is known. 69 // 70 // Placeholder types may only be returned by the following accessors 71 // as a result of unresolved dependencies or weak imports: 72 // 73 // ╔═══════════════════════════════════╤═════════════════════╗ 74 // ║ Accessor │ Descriptor ║ 75 // ╠═══════════════════════════════════╪═════════════════════╣ 76 // ║ FileImports.FileDescriptor │ FileDescriptor ║ 77 // ║ FieldDescriptor.Enum │ EnumDescriptor ║ 78 // ║ FieldDescriptor.Message │ MessageDescriptor ║ 79 // ║ FieldDescriptor.DefaultEnumValue │ EnumValueDescriptor ║ 80 // ║ FieldDescriptor.ContainingMessage │ MessageDescriptor ║ 81 // ║ MethodDescriptor.Input │ MessageDescriptor ║ 82 // ║ MethodDescriptor.Output │ MessageDescriptor ║ 83 // ╚═══════════════════════════════════╧═════════════════════╝ 84 // 85 // If true, only Name and FullName are valid. 86 // For FileDescriptor, the Path is also valid. 87 IsPlaceholder() bool 88 89 // Options returns the descriptor options. The caller must not modify 90 // the returned value. 91 // 92 // To avoid a dependency cycle, this function returns a proto.Message value. 93 // The proto message type returned for each descriptor type is as follows: 94 // ╔═════════════════════╤══════════════════════════════════════════╗ 95 // ║ Go type │ Protobuf message type ║ 96 // ╠═════════════════════╪══════════════════════════════════════════╣ 97 // ║ FileDescriptor │ google.protobuf.FileOptions ║ 98 // ║ EnumDescriptor │ google.protobuf.EnumOptions ║ 99 // ║ EnumValueDescriptor │ google.protobuf.EnumValueOptions ║ 100 // ║ MessageDescriptor │ google.protobuf.MessageOptions ║ 101 // ║ FieldDescriptor │ google.protobuf.FieldOptions ║ 102 // ║ OneofDescriptor │ google.protobuf.OneofOptions ║ 103 // ║ ServiceDescriptor │ google.protobuf.ServiceOptions ║ 104 // ║ MethodDescriptor │ google.protobuf.MethodOptions ║ 105 // ╚═════════════════════╧══════════════════════════════════════════╝ 106 // 107 // This method returns a typed nil-pointer if no options are present. 108 // The caller must import the descriptorpb package to use this. 109 Options() ProtoMessage 110 111 doNotImplement 112} 113 114// FileDescriptor describes the types in a complete proto file and 115// corresponds with the google.protobuf.FileDescriptorProto message. 116// 117// Top-level declarations: 118// EnumDescriptor, MessageDescriptor, FieldDescriptor, and/or ServiceDescriptor. 119type FileDescriptor interface { 120 Descriptor // Descriptor.FullName is identical to Package 121 122 // Path returns the file name, relative to the source tree root. 123 Path() string // e.g., "path/to/file.proto" 124 // Package returns the protobuf package namespace. 125 Package() FullName // e.g., "google.protobuf" 126 127 // Imports is a list of imported proto files. 128 Imports() FileImports 129 130 // Enums is a list of the top-level enum declarations. 131 Enums() EnumDescriptors 132 // Messages is a list of the top-level message declarations. 133 Messages() MessageDescriptors 134 // Extensions is a list of the top-level extension declarations. 135 Extensions() ExtensionDescriptors 136 // Services is a list of the top-level service declarations. 137 Services() ServiceDescriptors 138 139 // SourceLocations is a list of source locations. 140 SourceLocations() SourceLocations 141 142 isFileDescriptor 143} 144type isFileDescriptor interface{ ProtoType(FileDescriptor) } 145 146// FileImports is a list of file imports. 147type FileImports interface { 148 // Len reports the number of files imported by this proto file. 149 Len() int 150 // Get returns the ith FileImport. It panics if out of bounds. 151 Get(i int) FileImport 152 153 doNotImplement 154} 155 156// FileImport is the declaration for a proto file import. 157type FileImport struct { 158 // FileDescriptor is the file type for the given import. 159 // It is a placeholder descriptor if IsWeak is set or if a dependency has 160 // not been regenerated to implement the new reflection APIs. 161 FileDescriptor 162 163 // IsPublic reports whether this is a public import, which causes this file 164 // to alias declarations within the imported file. The intended use cases 165 // for this feature is the ability to move proto files without breaking 166 // existing dependencies. 167 // 168 // The current file and the imported file must be within proto package. 169 IsPublic bool 170 171 // IsWeak reports whether this is a weak import, which does not impose 172 // a direct dependency on the target file. 173 // 174 // Weak imports are a legacy proto1 feature. Equivalent behavior is 175 // achieved using proto2 extension fields or proto3 Any messages. 176 IsWeak bool 177} 178 179// MessageDescriptor describes a message and 180// corresponds with the google.protobuf.DescriptorProto message. 181// 182// Nested declarations: 183// FieldDescriptor, OneofDescriptor, FieldDescriptor, EnumDescriptor, 184// and/or MessageDescriptor. 185type MessageDescriptor interface { 186 Descriptor 187 188 // IsMapEntry indicates that this is an auto-generated message type to 189 // represent the entry type for a map field. 190 // 191 // Map entry messages have only two fields: 192 // • a "key" field with a field number of 1 193 // • a "value" field with a field number of 2 194 // The key and value types are determined by these two fields. 195 // 196 // If IsMapEntry is true, it implies that FieldDescriptor.IsMap is true 197 // for some field with this message type. 198 IsMapEntry() bool 199 200 // Fields is a list of nested field declarations. 201 Fields() FieldDescriptors 202 // Oneofs is a list of nested oneof declarations. 203 Oneofs() OneofDescriptors 204 205 // ReservedNames is a list of reserved field names. 206 ReservedNames() Names 207 // ReservedRanges is a list of reserved ranges of field numbers. 208 ReservedRanges() FieldRanges 209 // RequiredNumbers is a list of required field numbers. 210 // In Proto3, it is always an empty list. 211 RequiredNumbers() FieldNumbers 212 // ExtensionRanges is the field ranges used for extension fields. 213 // In Proto3, it is always an empty ranges. 214 ExtensionRanges() FieldRanges 215 // ExtensionRangeOptions returns the ith extension range options. 216 // 217 // To avoid a dependency cycle, this method returns a proto.Message value, 218 // which always contains a google.protobuf.ExtensionRangeOptions message. 219 // This method returns a typed nil-pointer if no options are present. 220 // The caller must import the descriptorpb package to use this. 221 ExtensionRangeOptions(i int) ProtoMessage 222 223 // Enums is a list of nested enum declarations. 224 Enums() EnumDescriptors 225 // Messages is a list of nested message declarations. 226 Messages() MessageDescriptors 227 // Extensions is a list of nested extension declarations. 228 Extensions() ExtensionDescriptors 229 230 isMessageDescriptor 231} 232type isMessageDescriptor interface{ ProtoType(MessageDescriptor) } 233 234// MessageType encapsulates a MessageDescriptor with a concrete Go implementation. 235type MessageType interface { 236 // New returns a newly allocated empty message. 237 New() Message 238 239 // Zero returns an empty, read-only message. 240 Zero() Message 241 242 // Descriptor returns the message descriptor. 243 // 244 // Invariant: t.Descriptor() == t.New().Descriptor() 245 Descriptor() MessageDescriptor 246} 247 248// MessageDescriptors is a list of message declarations. 249type MessageDescriptors interface { 250 // Len reports the number of messages. 251 Len() int 252 // Get returns the ith MessageDescriptor. It panics if out of bounds. 253 Get(i int) MessageDescriptor 254 // ByName returns the MessageDescriptor for a message named s. 255 // It returns nil if not found. 256 ByName(s Name) MessageDescriptor 257 258 doNotImplement 259} 260 261// FieldDescriptor describes a field within a message and 262// corresponds with the google.protobuf.FieldDescriptorProto message. 263// 264// It is used for both normal fields defined within the parent message 265// (e.g., MessageDescriptor.Fields) and fields that extend some remote message 266// (e.g., FileDescriptor.Extensions or MessageDescriptor.Extensions). 267type FieldDescriptor interface { 268 Descriptor 269 270 // Number reports the unique number for this field. 271 Number() FieldNumber 272 // Cardinality reports the cardinality for this field. 273 Cardinality() Cardinality 274 // Kind reports the basic kind for this field. 275 Kind() Kind 276 277 // HasJSONName reports whether this field has an explicitly set JSON name. 278 HasJSONName() bool 279 280 // JSONName reports the name used for JSON serialization. 281 // It is usually the camel-cased form of the field name. 282 JSONName() string 283 284 // HasPresence reports whether the field distinguishes between unpopulated 285 // and default values. 286 HasPresence() bool 287 288 // IsExtension reports whether this is an extension field. If false, 289 // then Parent and ContainingMessage refer to the same message. 290 // Otherwise, ContainingMessage and Parent likely differ. 291 IsExtension() bool 292 293 // HasOptionalKeyword reports whether the "optional" keyword was explicitly 294 // specified in the source .proto file. 295 HasOptionalKeyword() bool 296 297 // IsWeak reports whether this is a weak field, which does not impose a 298 // direct dependency on the target type. 299 // If true, then Message returns a placeholder type. 300 IsWeak() bool 301 302 // IsPacked reports whether repeated primitive numeric kinds should be 303 // serialized using a packed encoding. 304 // If true, then it implies Cardinality is Repeated. 305 IsPacked() bool 306 307 // IsList reports whether this field represents a list, 308 // where the value type for the associated field is a List. 309 // It is equivalent to checking whether Cardinality is Repeated and 310 // that IsMap reports false. 311 IsList() bool 312 313 // IsMap reports whether this field represents a map, 314 // where the value type for the associated field is a Map. 315 // It is equivalent to checking whether Cardinality is Repeated, 316 // that the Kind is MessageKind, and that Message.IsMapEntry reports true. 317 IsMap() bool 318 319 // MapKey returns the field descriptor for the key in the map entry. 320 // It returns nil if IsMap reports false. 321 MapKey() FieldDescriptor 322 323 // MapValue returns the field descriptor for the value in the map entry. 324 // It returns nil if IsMap reports false. 325 MapValue() FieldDescriptor 326 327 // HasDefault reports whether this field has a default value. 328 HasDefault() bool 329 330 // Default returns the default value for scalar fields. 331 // For proto2, it is the default value as specified in the proto file, 332 // or the zero value if unspecified. 333 // For proto3, it is always the zero value of the scalar. 334 // The Value type is determined by the Kind. 335 Default() Value 336 337 // DefaultEnumValue returns the enum value descriptor for the default value 338 // of an enum field, and is nil for any other kind of field. 339 DefaultEnumValue() EnumValueDescriptor 340 341 // ContainingOneof is the containing oneof that this field belongs to, 342 // and is nil if this field is not part of a oneof. 343 ContainingOneof() OneofDescriptor 344 345 // ContainingMessage is the containing message that this field belongs to. 346 // For extension fields, this may not necessarily be the parent message 347 // that the field is declared within. 348 ContainingMessage() MessageDescriptor 349 350 // Enum is the enum descriptor if Kind is EnumKind. 351 // It returns nil for any other Kind. 352 Enum() EnumDescriptor 353 354 // Message is the message descriptor if Kind is 355 // MessageKind or GroupKind. It returns nil for any other Kind. 356 Message() MessageDescriptor 357 358 isFieldDescriptor 359} 360type isFieldDescriptor interface{ ProtoType(FieldDescriptor) } 361 362// FieldDescriptors is a list of field declarations. 363type FieldDescriptors interface { 364 // Len reports the number of fields. 365 Len() int 366 // Get returns the ith FieldDescriptor. It panics if out of bounds. 367 Get(i int) FieldDescriptor 368 // ByName returns the FieldDescriptor for a field named s. 369 // It returns nil if not found. 370 ByName(s Name) FieldDescriptor 371 // ByJSONName returns the FieldDescriptor for a field with s as the JSON name. 372 // It returns nil if not found. 373 ByJSONName(s string) FieldDescriptor 374 // ByNumber returns the FieldDescriptor for a field numbered n. 375 // It returns nil if not found. 376 ByNumber(n FieldNumber) FieldDescriptor 377 378 doNotImplement 379} 380 381// OneofDescriptor describes a oneof field set within a given message and 382// corresponds with the google.protobuf.OneofDescriptorProto message. 383type OneofDescriptor interface { 384 Descriptor 385 386 // IsSynthetic reports whether this is a synthetic oneof created to support 387 // proto3 optional semantics. If true, Fields contains exactly one field 388 // with HasOptionalKeyword specified. 389 IsSynthetic() bool 390 391 // Fields is a list of fields belonging to this oneof. 392 Fields() FieldDescriptors 393 394 isOneofDescriptor 395} 396type isOneofDescriptor interface{ ProtoType(OneofDescriptor) } 397 398// OneofDescriptors is a list of oneof declarations. 399type OneofDescriptors interface { 400 // Len reports the number of oneof fields. 401 Len() int 402 // Get returns the ith OneofDescriptor. It panics if out of bounds. 403 Get(i int) OneofDescriptor 404 // ByName returns the OneofDescriptor for a oneof named s. 405 // It returns nil if not found. 406 ByName(s Name) OneofDescriptor 407 408 doNotImplement 409} 410 411// ExtensionDescriptor is an alias of FieldDescriptor for documentation. 412type ExtensionDescriptor = FieldDescriptor 413 414// ExtensionTypeDescriptor is an ExtensionDescriptor with an associated ExtensionType. 415type ExtensionTypeDescriptor interface { 416 ExtensionDescriptor 417 418 // Type returns the associated ExtensionType. 419 Type() ExtensionType 420 421 // Descriptor returns the plain ExtensionDescriptor without the 422 // associated ExtensionType. 423 Descriptor() ExtensionDescriptor 424} 425 426// ExtensionDescriptors is a list of field declarations. 427type ExtensionDescriptors interface { 428 // Len reports the number of fields. 429 Len() int 430 // Get returns the ith ExtensionDescriptor. It panics if out of bounds. 431 Get(i int) ExtensionDescriptor 432 // ByName returns the ExtensionDescriptor for a field named s. 433 // It returns nil if not found. 434 ByName(s Name) ExtensionDescriptor 435 436 doNotImplement 437} 438 439// ExtensionType encapsulates an ExtensionDescriptor with a concrete 440// Go implementation. The nested field descriptor must be for a extension field. 441// 442// While a normal field is a member of the parent message that it is declared 443// within (see Descriptor.Parent), an extension field is a member of some other 444// target message (see ExtensionDescriptor.Extendee) and may have no 445// relationship with the parent. However, the full name of an extension field is 446// relative to the parent that it is declared within. 447// 448// For example: 449// syntax = "proto2"; 450// package example; 451// message FooMessage { 452// extensions 100 to max; 453// } 454// message BarMessage { 455// extends FooMessage { optional BarMessage bar_field = 100; } 456// } 457// 458// Field "bar_field" is an extension of FooMessage, but its full name is 459// "example.BarMessage.bar_field" instead of "example.FooMessage.bar_field". 460type ExtensionType interface { 461 // New returns a new value for the field. 462 // For scalars, this returns the default value in native Go form. 463 New() Value 464 465 // Zero returns a new value for the field. 466 // For scalars, this returns the default value in native Go form. 467 // For composite types, this returns an empty, read-only message, list, or map. 468 Zero() Value 469 470 // TypeDescriptor returns the extension type descriptor. 471 TypeDescriptor() ExtensionTypeDescriptor 472 473 // ValueOf wraps the input and returns it as a Value. 474 // ValueOf panics if the input value is invalid or not the appropriate type. 475 // 476 // ValueOf is more extensive than protoreflect.ValueOf for a given field's 477 // value as it has more type information available. 478 ValueOf(interface{}) Value 479 480 // InterfaceOf completely unwraps the Value to the underlying Go type. 481 // InterfaceOf panics if the input is nil or does not represent the 482 // appropriate underlying Go type. For composite types, it panics if the 483 // value is not mutable. 484 // 485 // InterfaceOf is able to unwrap the Value further than Value.Interface 486 // as it has more type information available. 487 InterfaceOf(Value) interface{} 488 489 // IsValidValue reports whether the Value is valid to assign to the field. 490 IsValidValue(Value) bool 491 492 // IsValidInterface reports whether the input is valid to assign to the field. 493 IsValidInterface(interface{}) bool 494} 495 496// EnumDescriptor describes an enum and 497// corresponds with the google.protobuf.EnumDescriptorProto message. 498// 499// Nested declarations: 500// EnumValueDescriptor. 501type EnumDescriptor interface { 502 Descriptor 503 504 // Values is a list of nested enum value declarations. 505 Values() EnumValueDescriptors 506 507 // ReservedNames is a list of reserved enum names. 508 ReservedNames() Names 509 // ReservedRanges is a list of reserved ranges of enum numbers. 510 ReservedRanges() EnumRanges 511 512 isEnumDescriptor 513} 514type isEnumDescriptor interface{ ProtoType(EnumDescriptor) } 515 516// EnumType encapsulates an EnumDescriptor with a concrete Go implementation. 517type EnumType interface { 518 // New returns an instance of this enum type with its value set to n. 519 New(n EnumNumber) Enum 520 521 // Descriptor returns the enum descriptor. 522 // 523 // Invariant: t.Descriptor() == t.New(0).Descriptor() 524 Descriptor() EnumDescriptor 525} 526 527// EnumDescriptors is a list of enum declarations. 528type EnumDescriptors interface { 529 // Len reports the number of enum types. 530 Len() int 531 // Get returns the ith EnumDescriptor. It panics if out of bounds. 532 Get(i int) EnumDescriptor 533 // ByName returns the EnumDescriptor for an enum named s. 534 // It returns nil if not found. 535 ByName(s Name) EnumDescriptor 536 537 doNotImplement 538} 539 540// EnumValueDescriptor describes an enum value and 541// corresponds with the google.protobuf.EnumValueDescriptorProto message. 542// 543// All other proto declarations are in the namespace of the parent. 544// However, enum values do not follow this rule and are within the namespace 545// of the parent's parent (i.e., they are a sibling of the containing enum). 546// Thus, a value named "FOO_VALUE" declared within an enum uniquely identified 547// as "proto.package.MyEnum" has a full name of "proto.package.FOO_VALUE". 548type EnumValueDescriptor interface { 549 Descriptor 550 551 // Number returns the enum value as an integer. 552 Number() EnumNumber 553 554 isEnumValueDescriptor 555} 556type isEnumValueDescriptor interface{ ProtoType(EnumValueDescriptor) } 557 558// EnumValueDescriptors is a list of enum value declarations. 559type EnumValueDescriptors interface { 560 // Len reports the number of enum values. 561 Len() int 562 // Get returns the ith EnumValueDescriptor. It panics if out of bounds. 563 Get(i int) EnumValueDescriptor 564 // ByName returns the EnumValueDescriptor for the enum value named s. 565 // It returns nil if not found. 566 ByName(s Name) EnumValueDescriptor 567 // ByNumber returns the EnumValueDescriptor for the enum value numbered n. 568 // If multiple have the same number, the first one defined is returned 569 // It returns nil if not found. 570 ByNumber(n EnumNumber) EnumValueDescriptor 571 572 doNotImplement 573} 574 575// ServiceDescriptor describes a service and 576// corresponds with the google.protobuf.ServiceDescriptorProto message. 577// 578// Nested declarations: MethodDescriptor. 579type ServiceDescriptor interface { 580 Descriptor 581 582 // Methods is a list of nested message declarations. 583 Methods() MethodDescriptors 584 585 isServiceDescriptor 586} 587type isServiceDescriptor interface{ ProtoType(ServiceDescriptor) } 588 589// ServiceDescriptors is a list of service declarations. 590type ServiceDescriptors interface { 591 // Len reports the number of services. 592 Len() int 593 // Get returns the ith ServiceDescriptor. It panics if out of bounds. 594 Get(i int) ServiceDescriptor 595 // ByName returns the ServiceDescriptor for a service named s. 596 // It returns nil if not found. 597 ByName(s Name) ServiceDescriptor 598 599 doNotImplement 600} 601 602// MethodDescriptor describes a method and 603// corresponds with the google.protobuf.MethodDescriptorProto message. 604type MethodDescriptor interface { 605 Descriptor 606 607 // Input is the input message descriptor. 608 Input() MessageDescriptor 609 // Output is the output message descriptor. 610 Output() MessageDescriptor 611 // IsStreamingClient reports whether the client streams multiple messages. 612 IsStreamingClient() bool 613 // IsStreamingServer reports whether the server streams multiple messages. 614 IsStreamingServer() bool 615 616 isMethodDescriptor 617} 618type isMethodDescriptor interface{ ProtoType(MethodDescriptor) } 619 620// MethodDescriptors is a list of method declarations. 621type MethodDescriptors interface { 622 // Len reports the number of methods. 623 Len() int 624 // Get returns the ith MethodDescriptor. It panics if out of bounds. 625 Get(i int) MethodDescriptor 626 // ByName returns the MethodDescriptor for a service method named s. 627 // It returns nil if not found. 628 ByName(s Name) MethodDescriptor 629 630 doNotImplement 631} 632