github.com/Big-big-orange/protoreflect@v0.0.0-20240408141420-285cedfdf6a4/desc/descriptor.go (about) 1 package desc 2 3 import ( 4 "bytes" 5 "fmt" 6 "sort" 7 "strconv" 8 "unicode" 9 "unicode/utf8" 10 11 "github.com/golang/protobuf/proto" 12 "google.golang.org/protobuf/reflect/protoreflect" 13 "google.golang.org/protobuf/types/descriptorpb" 14 15 "github.com/Big-big-orange/protoreflect/desc/internal" 16 ) 17 18 // Descriptor is the common interface implemented by all descriptor objects. 19 type Descriptor interface { 20 // GetName returns the name of the object described by the descriptor. This will 21 // be a base name that does not include enclosing message names or the package name. 22 // For file descriptors, this indicates the path and name to the described file. 23 GetName() string 24 // GetFullyQualifiedName returns the fully-qualified name of the object described by 25 // the descriptor. This will include the package name and any enclosing message names. 26 // For file descriptors, this returns the path and name to the described file (same as 27 // GetName). 28 GetFullyQualifiedName() string 29 // GetParent returns the enclosing element in a proto source file. If the described 30 // object is a top-level object, this returns the file descriptor. Otherwise, it returns 31 // the element in which the described object was declared. File descriptors have no 32 // parent and return nil. 33 GetParent() Descriptor 34 // GetFile returns the file descriptor in which this element was declared. File 35 // descriptors return themselves. 36 GetFile() *FileDescriptor 37 // GetOptions returns the options proto containing options for the described element. 38 GetOptions() proto.Message 39 // GetSourceInfo returns any source code information that was present in the file 40 // descriptor. Source code info is optional. If no source code info is available for 41 // the element (including if there is none at all in the file descriptor) then this 42 // returns nil 43 GetSourceInfo() *descriptorpb.SourceCodeInfo_Location 44 // AsProto returns the underlying descriptor proto for this descriptor. 45 AsProto() proto.Message 46 } 47 48 type sourceInfoRecomputeFunc = internal.SourceInfoComputeFunc 49 50 // FileDescriptor describes a proto source file. 51 type FileDescriptor struct { 52 wrapped protoreflect.FileDescriptor 53 proto *descriptorpb.FileDescriptorProto 54 symbols map[string]Descriptor 55 deps []*FileDescriptor 56 publicDeps []*FileDescriptor 57 weakDeps []*FileDescriptor 58 messages []*MessageDescriptor 59 enums []*EnumDescriptor 60 extensions []*FieldDescriptor 61 services []*ServiceDescriptor 62 fieldIndex map[string]map[int32]*FieldDescriptor 63 sourceInfo internal.SourceInfoMap 64 sourceInfoRecomputeFunc 65 } 66 67 // Unwrap returns the underlying protoreflect.Descriptor. Most usages will be more 68 // interested in UnwrapFile, which has a more specific return type. This generic 69 // version is present to satisfy the DescriptorWrapper interface. 70 func (fd *FileDescriptor) Unwrap() protoreflect.Descriptor { 71 return fd.wrapped 72 } 73 74 // UnwrapFile returns the underlying protoreflect.FileDescriptor. 75 func (fd *FileDescriptor) UnwrapFile() protoreflect.FileDescriptor { 76 return fd.wrapped 77 } 78 79 func (fd *FileDescriptor) recomputeSourceInfo() { 80 internal.PopulateSourceInfoMap(fd.proto, fd.sourceInfo) 81 } 82 83 func (fd *FileDescriptor) registerField(field *FieldDescriptor) { 84 fields := fd.fieldIndex[field.owner.GetFullyQualifiedName()] 85 if fields == nil { 86 fields = map[int32]*FieldDescriptor{} 87 fd.fieldIndex[field.owner.GetFullyQualifiedName()] = fields 88 } 89 fields[field.GetNumber()] = field 90 } 91 92 // GetName returns the name of the file, as it was given to the protoc invocation 93 // to compile it, possibly including path (relative to a directory in the proto 94 // import path). 95 func (fd *FileDescriptor) GetName() string { 96 return fd.wrapped.Path() 97 } 98 99 // GetFullyQualifiedName returns the name of the file, same as GetName. It is 100 // present to satisfy the Descriptor interface. 101 func (fd *FileDescriptor) GetFullyQualifiedName() string { 102 return fd.wrapped.Path() 103 } 104 105 // GetPackage returns the name of the package declared in the file. 106 func (fd *FileDescriptor) GetPackage() string { 107 return string(fd.wrapped.Package()) 108 } 109 110 // GetParent always returns nil: files are the root of descriptor hierarchies. 111 // Is it present to satisfy the Descriptor interface. 112 func (fd *FileDescriptor) GetParent() Descriptor { 113 return nil 114 } 115 116 // GetFile returns the receiver, which is a file descriptor. This is present 117 // to satisfy the Descriptor interface. 118 func (fd *FileDescriptor) GetFile() *FileDescriptor { 119 return fd 120 } 121 122 // GetOptions returns the file's options. Most usages will be more interested 123 // in GetFileOptions, which has a concrete return type. This generic version 124 // is present to satisfy the Descriptor interface. 125 func (fd *FileDescriptor) GetOptions() proto.Message { 126 return fd.proto.GetOptions() 127 } 128 129 // GetFileOptions returns the file's options. 130 func (fd *FileDescriptor) GetFileOptions() *descriptorpb.FileOptions { 131 return fd.proto.GetOptions() 132 } 133 134 // GetSourceInfo returns nil for files. It is present to satisfy the Descriptor 135 // interface. 136 func (fd *FileDescriptor) GetSourceInfo() *descriptorpb.SourceCodeInfo_Location { 137 return nil 138 } 139 140 // AsProto returns the underlying descriptor proto. Most usages will be more 141 // interested in AsFileDescriptorProto, which has a concrete return type. This 142 // generic version is present to satisfy the Descriptor interface. 143 func (fd *FileDescriptor) AsProto() proto.Message { 144 return fd.proto 145 } 146 147 // AsFileDescriptorProto returns the underlying descriptor proto. 148 func (fd *FileDescriptor) AsFileDescriptorProto() *descriptorpb.FileDescriptorProto { 149 return fd.proto 150 } 151 152 // String returns the underlying descriptor proto, in compact text format. 153 func (fd *FileDescriptor) String() string { 154 return fd.proto.String() 155 } 156 157 // IsProto3 returns true if the file declares a syntax of "proto3". 158 func (fd *FileDescriptor) IsProto3() bool { 159 return fd.wrapped.Syntax() == protoreflect.Proto3 160 } 161 162 // GetDependencies returns all of this file's dependencies. These correspond to 163 // import statements in the file. 164 func (fd *FileDescriptor) GetDependencies() []*FileDescriptor { 165 return fd.deps 166 } 167 168 // GetPublicDependencies returns all of this file's public dependencies. These 169 // correspond to public import statements in the file. 170 func (fd *FileDescriptor) GetPublicDependencies() []*FileDescriptor { 171 return fd.publicDeps 172 } 173 174 // GetWeakDependencies returns all of this file's weak dependencies. These 175 // correspond to weak import statements in the file. 176 func (fd *FileDescriptor) GetWeakDependencies() []*FileDescriptor { 177 return fd.weakDeps 178 } 179 180 // GetMessageTypes returns all top-level messages declared in this file. 181 func (fd *FileDescriptor) GetMessageTypes() []*MessageDescriptor { 182 return fd.messages 183 } 184 185 // GetEnumTypes returns all top-level enums declared in this file. 186 func (fd *FileDescriptor) GetEnumTypes() []*EnumDescriptor { 187 return fd.enums 188 } 189 190 // GetExtensions returns all top-level extensions declared in this file. 191 func (fd *FileDescriptor) GetExtensions() []*FieldDescriptor { 192 return fd.extensions 193 } 194 195 // GetServices returns all services declared in this file. 196 func (fd *FileDescriptor) GetServices() []*ServiceDescriptor { 197 return fd.services 198 } 199 200 // FindSymbol returns the descriptor contained within this file for the 201 // element with the given fully-qualified symbol name. If no such element 202 // exists then this method returns nil. 203 func (fd *FileDescriptor) FindSymbol(symbol string) Descriptor { 204 if len(symbol) == 0 { 205 return nil 206 } 207 if symbol[0] == '.' { 208 symbol = symbol[1:] 209 } 210 if ret := fd.symbols[symbol]; ret != nil { 211 return ret 212 } 213 214 // allow accessing symbols through public imports, too 215 for _, dep := range fd.GetPublicDependencies() { 216 if ret := dep.FindSymbol(symbol); ret != nil { 217 return ret 218 } 219 } 220 221 // not found 222 return nil 223 } 224 225 // FindMessage finds the message with the given fully-qualified name. If no 226 // such element exists in this file then nil is returned. 227 func (fd *FileDescriptor) FindMessage(msgName string) *MessageDescriptor { 228 if md, ok := fd.symbols[msgName].(*MessageDescriptor); ok { 229 return md 230 } else { 231 return nil 232 } 233 } 234 235 // FindEnum finds the enum with the given fully-qualified name. If no such 236 // element exists in this file then nil is returned. 237 func (fd *FileDescriptor) FindEnum(enumName string) *EnumDescriptor { 238 if ed, ok := fd.symbols[enumName].(*EnumDescriptor); ok { 239 return ed 240 } else { 241 return nil 242 } 243 } 244 245 // FindService finds the service with the given fully-qualified name. If no 246 // such element exists in this file then nil is returned. 247 func (fd *FileDescriptor) FindService(serviceName string) *ServiceDescriptor { 248 if sd, ok := fd.symbols[serviceName].(*ServiceDescriptor); ok { 249 return sd 250 } else { 251 return nil 252 } 253 } 254 255 // FindExtension finds the extension field for the given extended type name and 256 // tag number. If no such element exists in this file then nil is returned. 257 func (fd *FileDescriptor) FindExtension(extendeeName string, tagNumber int32) *FieldDescriptor { 258 if exd, ok := fd.fieldIndex[extendeeName][tagNumber]; ok && exd.IsExtension() { 259 return exd 260 } else { 261 return nil 262 } 263 } 264 265 // FindExtensionByName finds the extension field with the given fully-qualified 266 // name. If no such element exists in this file then nil is returned. 267 func (fd *FileDescriptor) FindExtensionByName(extName string) *FieldDescriptor { 268 if exd, ok := fd.symbols[extName].(*FieldDescriptor); ok && exd.IsExtension() { 269 return exd 270 } else { 271 return nil 272 } 273 } 274 275 // MessageDescriptor describes a protocol buffer message. 276 type MessageDescriptor struct { 277 wrapped protoreflect.MessageDescriptor 278 proto *descriptorpb.DescriptorProto 279 parent Descriptor 280 file *FileDescriptor 281 fields []*FieldDescriptor 282 nested []*MessageDescriptor 283 enums []*EnumDescriptor 284 extensions []*FieldDescriptor 285 oneOfs []*OneOfDescriptor 286 extRanges extRanges 287 sourceInfoPath []int32 288 jsonNames jsonNameMap 289 } 290 291 // Unwrap returns the underlying protoreflect.Descriptor. Most usages will be more 292 // interested in UnwrapMessage, which has a more specific return type. This generic 293 // version is present to satisfy the DescriptorWrapper interface. 294 func (md *MessageDescriptor) Unwrap() protoreflect.Descriptor { 295 return md.wrapped 296 } 297 298 // UnwrapMessage returns the underlying protoreflect.MessageDescriptor. 299 func (md *MessageDescriptor) UnwrapMessage() protoreflect.MessageDescriptor { 300 return md.wrapped 301 } 302 303 func createMessageDescriptor(fd *FileDescriptor, parent Descriptor, md protoreflect.MessageDescriptor, mdp *descriptorpb.DescriptorProto, symbols map[string]Descriptor, cache descriptorCache, path []int32) *MessageDescriptor { 304 ret := &MessageDescriptor{ 305 wrapped: md, 306 proto: mdp, 307 parent: parent, 308 file: fd, 309 sourceInfoPath: append([]int32(nil), path...), // defensive copy 310 } 311 cache.put(md, ret) 312 path = append(path, internal.Message_nestedMessagesTag) 313 for i := 0; i < md.Messages().Len(); i++ { 314 src := md.Messages().Get(i) 315 srcProto := mdp.GetNestedType()[src.Index()] 316 nmd := createMessageDescriptor(fd, ret, src, srcProto, symbols, cache, append(path, int32(i))) 317 symbols[string(src.FullName())] = nmd 318 ret.nested = append(ret.nested, nmd) 319 } 320 path[len(path)-1] = internal.Message_enumsTag 321 for i := 0; i < md.Enums().Len(); i++ { 322 src := md.Enums().Get(i) 323 srcProto := mdp.GetEnumType()[src.Index()] 324 ed := createEnumDescriptor(fd, ret, src, srcProto, symbols, cache, append(path, int32(i))) 325 symbols[string(src.FullName())] = ed 326 ret.enums = append(ret.enums, ed) 327 } 328 path[len(path)-1] = internal.Message_fieldsTag 329 for i := 0; i < md.Fields().Len(); i++ { 330 src := md.Fields().Get(i) 331 srcProto := mdp.GetField()[src.Index()] 332 fld := createFieldDescriptor(fd, ret, src, srcProto, cache, append(path, int32(i))) 333 symbols[string(src.FullName())] = fld 334 ret.fields = append(ret.fields, fld) 335 } 336 path[len(path)-1] = internal.Message_extensionsTag 337 for i := 0; i < md.Extensions().Len(); i++ { 338 src := md.Extensions().Get(i) 339 srcProto := mdp.GetExtension()[src.Index()] 340 exd := createFieldDescriptor(fd, ret, src, srcProto, cache, append(path, int32(i))) 341 symbols[string(src.FullName())] = exd 342 ret.extensions = append(ret.extensions, exd) 343 } 344 path[len(path)-1] = internal.Message_oneOfsTag 345 for i := 0; i < md.Oneofs().Len(); i++ { 346 src := md.Oneofs().Get(i) 347 srcProto := mdp.GetOneofDecl()[src.Index()] 348 od := createOneOfDescriptor(fd, ret, i, src, srcProto, append(path, int32(i))) 349 symbols[string(src.FullName())] = od 350 ret.oneOfs = append(ret.oneOfs, od) 351 } 352 for _, r := range mdp.GetExtensionRange() { 353 // proto.ExtensionRange is inclusive (and that's how extension ranges are defined in code). 354 // but protoc converts range to exclusive end in descriptor, so we must convert back 355 end := r.GetEnd() - 1 356 ret.extRanges = append(ret.extRanges, proto.ExtensionRange{ 357 Start: r.GetStart(), 358 End: end}) 359 } 360 sort.Sort(ret.extRanges) 361 362 return ret 363 } 364 365 func (md *MessageDescriptor) resolve(cache descriptorCache) error { 366 for _, nmd := range md.nested { 367 if err := nmd.resolve(cache); err != nil { 368 return err 369 } 370 } 371 for _, fld := range md.fields { 372 if err := fld.resolve(cache); err != nil { 373 return err 374 } 375 } 376 for _, exd := range md.extensions { 377 if err := exd.resolve(cache); err != nil { 378 return err 379 } 380 } 381 return nil 382 } 383 384 // GetName returns the simple (unqualified) name of the message. 385 func (md *MessageDescriptor) GetName() string { 386 return string(md.wrapped.Name()) 387 } 388 389 // GetFullyQualifiedName returns the fully qualified name of the message. This 390 // includes the package name (if there is one) as well as the names of any 391 // enclosing messages. 392 func (md *MessageDescriptor) GetFullyQualifiedName() string { 393 return string(md.wrapped.FullName()) 394 } 395 396 // GetParent returns the message's enclosing descriptor. For top-level messages, 397 // this will be a file descriptor. Otherwise it will be the descriptor for the 398 // enclosing message. 399 func (md *MessageDescriptor) GetParent() Descriptor { 400 return md.parent 401 } 402 403 // GetFile returns the descriptor for the file in which this message is defined. 404 func (md *MessageDescriptor) GetFile() *FileDescriptor { 405 return md.file 406 } 407 408 // GetOptions returns the message's options. Most usages will be more interested 409 // in GetMessageOptions, which has a concrete return type. This generic version 410 // is present to satisfy the Descriptor interface. 411 func (md *MessageDescriptor) GetOptions() proto.Message { 412 return md.proto.GetOptions() 413 } 414 415 // GetMessageOptions returns the message's options. 416 func (md *MessageDescriptor) GetMessageOptions() *descriptorpb.MessageOptions { 417 return md.proto.GetOptions() 418 } 419 420 // GetSourceInfo returns source info for the message, if present in the 421 // descriptor. Not all descriptors will contain source info. If non-nil, the 422 // returned info contains information about the location in the file where the 423 // message was defined and also contains comments associated with the message 424 // definition. 425 func (md *MessageDescriptor) GetSourceInfo() *descriptorpb.SourceCodeInfo_Location { 426 return md.file.sourceInfo.Get(md.sourceInfoPath) 427 } 428 429 // AsProto returns the underlying descriptor proto. Most usages will be more 430 // interested in AsDescriptorProto, which has a concrete return type. This 431 // generic version is present to satisfy the Descriptor interface. 432 func (md *MessageDescriptor) AsProto() proto.Message { 433 return md.proto 434 } 435 436 // AsDescriptorProto returns the underlying descriptor proto. 437 func (md *MessageDescriptor) AsDescriptorProto() *descriptorpb.DescriptorProto { 438 return md.proto 439 } 440 441 // String returns the underlying descriptor proto, in compact text format. 442 func (md *MessageDescriptor) String() string { 443 return md.proto.String() 444 } 445 446 // IsMapEntry returns true if this is a synthetic message type that represents an entry 447 // in a map field. 448 func (md *MessageDescriptor) IsMapEntry() bool { 449 return md.wrapped.IsMapEntry() 450 } 451 452 // GetFields returns all of the fields for this message. 453 func (md *MessageDescriptor) GetFields() []*FieldDescriptor { 454 return md.fields 455 } 456 457 // GetNestedMessageTypes returns all of the message types declared inside this message. 458 func (md *MessageDescriptor) GetNestedMessageTypes() []*MessageDescriptor { 459 return md.nested 460 } 461 462 // GetNestedEnumTypes returns all of the enums declared inside this message. 463 func (md *MessageDescriptor) GetNestedEnumTypes() []*EnumDescriptor { 464 return md.enums 465 } 466 467 // GetNestedExtensions returns all of the extensions declared inside this message. 468 func (md *MessageDescriptor) GetNestedExtensions() []*FieldDescriptor { 469 return md.extensions 470 } 471 472 // GetOneOfs returns all of the one-of field sets declared inside this message. 473 func (md *MessageDescriptor) GetOneOfs() []*OneOfDescriptor { 474 return md.oneOfs 475 } 476 477 // IsProto3 returns true if the file in which this message is defined declares a syntax of "proto3". 478 func (md *MessageDescriptor) IsProto3() bool { 479 return md.file.IsProto3() 480 } 481 482 // GetExtensionRanges returns the ranges of extension field numbers for this message. 483 func (md *MessageDescriptor) GetExtensionRanges() []proto.ExtensionRange { 484 return md.extRanges 485 } 486 487 // IsExtendable returns true if this message has any extension ranges. 488 func (md *MessageDescriptor) IsExtendable() bool { 489 return len(md.extRanges) > 0 490 } 491 492 // IsExtension returns true if the given tag number is within any of this message's 493 // extension ranges. 494 func (md *MessageDescriptor) IsExtension(tagNumber int32) bool { 495 return md.extRanges.IsExtension(tagNumber) 496 } 497 498 type extRanges []proto.ExtensionRange 499 500 func (er extRanges) String() string { 501 var buf bytes.Buffer 502 first := true 503 for _, r := range er { 504 if first { 505 first = false 506 } else { 507 buf.WriteString(",") 508 } 509 fmt.Fprintf(&buf, "%d..%d", r.Start, r.End) 510 } 511 return buf.String() 512 } 513 514 func (er extRanges) IsExtension(tagNumber int32) bool { 515 i := sort.Search(len(er), func(i int) bool { return er[i].End >= tagNumber }) 516 return i < len(er) && tagNumber >= er[i].Start 517 } 518 519 func (er extRanges) Len() int { 520 return len(er) 521 } 522 523 func (er extRanges) Less(i, j int) bool { 524 return er[i].Start < er[j].Start 525 } 526 527 func (er extRanges) Swap(i, j int) { 528 er[i], er[j] = er[j], er[i] 529 } 530 531 // FindFieldByName finds the field with the given name. If no such field exists 532 // then nil is returned. Only regular fields are returned, not extensions. 533 func (md *MessageDescriptor) FindFieldByName(fieldName string) *FieldDescriptor { 534 fqn := fmt.Sprintf("%s.%s", md.GetFullyQualifiedName(), fieldName) 535 if fd, ok := md.file.symbols[fqn].(*FieldDescriptor); ok && !fd.IsExtension() { 536 return fd 537 } else { 538 return nil 539 } 540 } 541 542 // FindFieldByNumber finds the field with the given tag number. If no such field 543 // exists then nil is returned. Only regular fields are returned, not extensions. 544 func (md *MessageDescriptor) FindFieldByNumber(tagNumber int32) *FieldDescriptor { 545 if fd, ok := md.file.fieldIndex[md.GetFullyQualifiedName()][tagNumber]; ok && !fd.IsExtension() { 546 return fd 547 } else { 548 return nil 549 } 550 } 551 552 // FieldDescriptor describes a field of a protocol buffer message. 553 type FieldDescriptor struct { 554 wrapped protoreflect.FieldDescriptor 555 proto *descriptorpb.FieldDescriptorProto 556 parent Descriptor 557 owner *MessageDescriptor 558 file *FileDescriptor 559 oneOf *OneOfDescriptor 560 msgType *MessageDescriptor 561 enumType *EnumDescriptor 562 sourceInfoPath []int32 563 def memoizedDefault 564 } 565 566 // Unwrap returns the underlying protoreflect.Descriptor. Most usages will be more 567 // interested in UnwrapField, which has a more specific return type. This generic 568 // version is present to satisfy the DescriptorWrapper interface. 569 func (fd *FieldDescriptor) Unwrap() protoreflect.Descriptor { 570 return fd.wrapped 571 } 572 573 // UnwrapField returns the underlying protoreflect.FieldDescriptor. 574 func (fd *FieldDescriptor) UnwrapField() protoreflect.FieldDescriptor { 575 return fd.wrapped 576 } 577 578 func createFieldDescriptor(fd *FileDescriptor, parent Descriptor, fld protoreflect.FieldDescriptor, fldp *descriptorpb.FieldDescriptorProto, cache descriptorCache, path []int32) *FieldDescriptor { 579 ret := &FieldDescriptor{ 580 wrapped: fld, 581 proto: fldp, 582 parent: parent, 583 file: fd, 584 sourceInfoPath: append([]int32(nil), path...), // defensive copy 585 } 586 cache.put(fld, ret) 587 if !fld.IsExtension() { 588 ret.owner = parent.(*MessageDescriptor) 589 } 590 // owner for extensions, field type (be it message or enum), and one-ofs get resolved later 591 return ret 592 } 593 594 func descriptorType(d Descriptor) string { 595 switch d := d.(type) { 596 case *FileDescriptor: 597 return "a file" 598 case *MessageDescriptor: 599 return "a message" 600 case *FieldDescriptor: 601 if d.IsExtension() { 602 return "an extension" 603 } 604 return "a field" 605 case *OneOfDescriptor: 606 return "a oneof" 607 case *EnumDescriptor: 608 return "an enum" 609 case *EnumValueDescriptor: 610 return "an enum value" 611 case *ServiceDescriptor: 612 return "a service" 613 case *MethodDescriptor: 614 return "a method" 615 default: 616 return fmt.Sprintf("a %T", d) 617 } 618 } 619 620 func (fd *FieldDescriptor) resolve(cache descriptorCache) error { 621 if fd.proto.OneofIndex != nil && fd.oneOf == nil { 622 return fmt.Errorf("could not link field %s to one-of index %d", fd.GetFullyQualifiedName(), *fd.proto.OneofIndex) 623 } 624 if fd.proto.GetType() == descriptorpb.FieldDescriptorProto_TYPE_ENUM { 625 desc, err := resolve(fd.file, fd.wrapped.Enum(), cache) 626 if err != nil { 627 return err 628 } 629 enumType, ok := desc.(*EnumDescriptor) 630 if !ok { 631 return fmt.Errorf("field %v indicates a type of enum, but references %q which is %s", fd.GetFullyQualifiedName(), fd.proto.GetTypeName(), descriptorType(desc)) 632 } 633 fd.enumType = enumType 634 } 635 if fd.proto.GetType() == descriptorpb.FieldDescriptorProto_TYPE_MESSAGE || fd.proto.GetType() == descriptorpb.FieldDescriptorProto_TYPE_GROUP { 636 desc, err := resolve(fd.file, fd.wrapped.Message(), cache) 637 if err != nil { 638 return err 639 } 640 msgType, ok := desc.(*MessageDescriptor) 641 if !ok { 642 return fmt.Errorf("field %v indicates a type of message, but references %q which is %s", fd.GetFullyQualifiedName(), fd.proto.GetTypeName(), descriptorType(desc)) 643 } 644 fd.msgType = msgType 645 } 646 if fd.IsExtension() { 647 desc, err := resolve(fd.file, fd.wrapped.ContainingMessage(), cache) 648 if err != nil { 649 return err 650 } 651 msgType, ok := desc.(*MessageDescriptor) 652 if !ok { 653 return fmt.Errorf("field %v extends %q which should be a message but is %s", fd.GetFullyQualifiedName(), fd.proto.GetExtendee(), descriptorType(desc)) 654 } 655 fd.owner = msgType 656 } 657 fd.file.registerField(fd) 658 return nil 659 } 660 661 func (fd *FieldDescriptor) determineDefault() interface{} { 662 if fd.IsMap() { 663 return map[interface{}]interface{}(nil) 664 } else if fd.IsRepeated() { 665 return []interface{}(nil) 666 } else if fd.msgType != nil { 667 return nil 668 } 669 670 proto3 := fd.file.IsProto3() 671 if !proto3 { 672 def := fd.AsFieldDescriptorProto().GetDefaultValue() 673 if def != "" { 674 ret := parseDefaultValue(fd, def) 675 if ret != nil { 676 return ret 677 } 678 // if we can't parse default value, fall-through to return normal default... 679 } 680 } 681 682 switch fd.GetType() { 683 case descriptorpb.FieldDescriptorProto_TYPE_FIXED32, 684 descriptorpb.FieldDescriptorProto_TYPE_UINT32: 685 return uint32(0) 686 case descriptorpb.FieldDescriptorProto_TYPE_SFIXED32, 687 descriptorpb.FieldDescriptorProto_TYPE_INT32, 688 descriptorpb.FieldDescriptorProto_TYPE_SINT32: 689 return int32(0) 690 case descriptorpb.FieldDescriptorProto_TYPE_FIXED64, 691 descriptorpb.FieldDescriptorProto_TYPE_UINT64: 692 return uint64(0) 693 case descriptorpb.FieldDescriptorProto_TYPE_SFIXED64, 694 descriptorpb.FieldDescriptorProto_TYPE_INT64, 695 descriptorpb.FieldDescriptorProto_TYPE_SINT64: 696 return int64(0) 697 case descriptorpb.FieldDescriptorProto_TYPE_FLOAT: 698 return float32(0.0) 699 case descriptorpb.FieldDescriptorProto_TYPE_DOUBLE: 700 return float64(0.0) 701 case descriptorpb.FieldDescriptorProto_TYPE_BOOL: 702 return false 703 case descriptorpb.FieldDescriptorProto_TYPE_BYTES: 704 return []byte(nil) 705 case descriptorpb.FieldDescriptorProto_TYPE_STRING: 706 return "" 707 case descriptorpb.FieldDescriptorProto_TYPE_ENUM: 708 if proto3 { 709 return int32(0) 710 } 711 enumVals := fd.GetEnumType().GetValues() 712 if len(enumVals) > 0 { 713 return enumVals[0].GetNumber() 714 } else { 715 return int32(0) // WTF? 716 } 717 default: 718 panic(fmt.Sprintf("Unknown field type: %v", fd.GetType())) 719 } 720 } 721 722 func parseDefaultValue(fd *FieldDescriptor, val string) interface{} { 723 switch fd.GetType() { 724 case descriptorpb.FieldDescriptorProto_TYPE_ENUM: 725 vd := fd.GetEnumType().FindValueByName(val) 726 if vd != nil { 727 return vd.GetNumber() 728 } 729 return nil 730 case descriptorpb.FieldDescriptorProto_TYPE_BOOL: 731 if val == "true" { 732 return true 733 } else if val == "false" { 734 return false 735 } 736 return nil 737 case descriptorpb.FieldDescriptorProto_TYPE_BYTES: 738 return []byte(unescape(val)) 739 case descriptorpb.FieldDescriptorProto_TYPE_STRING: 740 return val 741 case descriptorpb.FieldDescriptorProto_TYPE_FLOAT: 742 if f, err := strconv.ParseFloat(val, 32); err == nil { 743 return float32(f) 744 } else { 745 return float32(0) 746 } 747 case descriptorpb.FieldDescriptorProto_TYPE_DOUBLE: 748 if f, err := strconv.ParseFloat(val, 64); err == nil { 749 return f 750 } else { 751 return float64(0) 752 } 753 case descriptorpb.FieldDescriptorProto_TYPE_INT32, 754 descriptorpb.FieldDescriptorProto_TYPE_SINT32, 755 descriptorpb.FieldDescriptorProto_TYPE_SFIXED32: 756 if i, err := strconv.ParseInt(val, 10, 32); err == nil { 757 return int32(i) 758 } else { 759 return int32(0) 760 } 761 case descriptorpb.FieldDescriptorProto_TYPE_UINT32, 762 descriptorpb.FieldDescriptorProto_TYPE_FIXED32: 763 if i, err := strconv.ParseUint(val, 10, 32); err == nil { 764 return uint32(i) 765 } else { 766 return uint32(0) 767 } 768 case descriptorpb.FieldDescriptorProto_TYPE_INT64, 769 descriptorpb.FieldDescriptorProto_TYPE_SINT64, 770 descriptorpb.FieldDescriptorProto_TYPE_SFIXED64: 771 if i, err := strconv.ParseInt(val, 10, 64); err == nil { 772 return i 773 } else { 774 return int64(0) 775 } 776 case descriptorpb.FieldDescriptorProto_TYPE_UINT64, 777 descriptorpb.FieldDescriptorProto_TYPE_FIXED64: 778 if i, err := strconv.ParseUint(val, 10, 64); err == nil { 779 return i 780 } else { 781 return uint64(0) 782 } 783 default: 784 return nil 785 } 786 } 787 788 func unescape(s string) string { 789 // protoc encodes default values for 'bytes' fields using C escaping, 790 // so this function reverses that escaping 791 out := make([]byte, 0, len(s)) 792 var buf [4]byte 793 for len(s) > 0 { 794 if s[0] != '\\' || len(s) < 2 { 795 // not escape sequence, or too short to be well-formed escape 796 out = append(out, s[0]) 797 s = s[1:] 798 } else if s[1] == 'x' || s[1] == 'X' { 799 n := matchPrefix(s[2:], 2, isHex) 800 if n == 0 { 801 // bad escape 802 out = append(out, s[:2]...) 803 s = s[2:] 804 } else { 805 c, err := strconv.ParseUint(s[2:2+n], 16, 8) 806 if err != nil { 807 // shouldn't really happen... 808 out = append(out, s[:2+n]...) 809 } else { 810 out = append(out, byte(c)) 811 } 812 s = s[2+n:] 813 } 814 } else if s[1] >= '0' && s[1] <= '7' { 815 n := 1 + matchPrefix(s[2:], 2, isOctal) 816 c, err := strconv.ParseUint(s[1:1+n], 8, 8) 817 if err != nil || c > 0xff { 818 out = append(out, s[:1+n]...) 819 } else { 820 out = append(out, byte(c)) 821 } 822 s = s[1+n:] 823 } else if s[1] == 'u' { 824 if len(s) < 6 { 825 // bad escape 826 out = append(out, s...) 827 s = s[len(s):] 828 } else { 829 c, err := strconv.ParseUint(s[2:6], 16, 16) 830 if err != nil { 831 // bad escape 832 out = append(out, s[:6]...) 833 } else { 834 w := utf8.EncodeRune(buf[:], rune(c)) 835 out = append(out, buf[:w]...) 836 } 837 s = s[6:] 838 } 839 } else if s[1] == 'U' { 840 if len(s) < 10 { 841 // bad escape 842 out = append(out, s...) 843 s = s[len(s):] 844 } else { 845 c, err := strconv.ParseUint(s[2:10], 16, 32) 846 if err != nil || c > 0x10ffff { 847 // bad escape 848 out = append(out, s[:10]...) 849 } else { 850 w := utf8.EncodeRune(buf[:], rune(c)) 851 out = append(out, buf[:w]...) 852 } 853 s = s[10:] 854 } 855 } else { 856 switch s[1] { 857 case 'a': 858 out = append(out, '\a') 859 case 'b': 860 out = append(out, '\b') 861 case 'f': 862 out = append(out, '\f') 863 case 'n': 864 out = append(out, '\n') 865 case 'r': 866 out = append(out, '\r') 867 case 't': 868 out = append(out, '\t') 869 case 'v': 870 out = append(out, '\v') 871 case '\\': 872 out = append(out, '\\') 873 case '\'': 874 out = append(out, '\'') 875 case '"': 876 out = append(out, '"') 877 case '?': 878 out = append(out, '?') 879 default: 880 // invalid escape, just copy it as-is 881 out = append(out, s[:2]...) 882 } 883 s = s[2:] 884 } 885 } 886 return string(out) 887 } 888 889 func isOctal(b byte) bool { return b >= '0' && b <= '7' } 890 func isHex(b byte) bool { 891 return (b >= '0' && b <= '9') || (b >= 'a' && b <= 'f') || (b >= 'A' && b <= 'F') 892 } 893 func matchPrefix(s string, limit int, fn func(byte) bool) int { 894 l := len(s) 895 if l > limit { 896 l = limit 897 } 898 i := 0 899 for ; i < l; i++ { 900 if !fn(s[i]) { 901 return i 902 } 903 } 904 return i 905 } 906 907 // GetName returns the name of the field. 908 func (fd *FieldDescriptor) GetName() string { 909 return string(fd.wrapped.Name()) 910 } 911 912 // GetNumber returns the tag number of this field. 913 func (fd *FieldDescriptor) GetNumber() int32 { 914 return int32(fd.wrapped.Number()) 915 } 916 917 // GetFullyQualifiedName returns the fully qualified name of the field. Unlike 918 // GetName, this includes fully qualified name of the enclosing message for 919 // regular fields. 920 // 921 // For extension fields, this includes the package (if there is one) as well as 922 // any enclosing messages. The package and/or enclosing messages are for where 923 // the extension is defined, not the message it extends. 924 // 925 // If this field is part of a one-of, the fully qualified name does *not* 926 // include the name of the one-of, only of the enclosing message. 927 func (fd *FieldDescriptor) GetFullyQualifiedName() string { 928 return string(fd.wrapped.FullName()) 929 } 930 931 // GetParent returns the fields's enclosing descriptor. For normal 932 // (non-extension) fields, this is the enclosing message. For extensions, this 933 // is the descriptor in which the extension is defined, not the message that is 934 // extended. The parent for an extension may be a file descriptor or a message, 935 // depending on where the extension is defined. 936 func (fd *FieldDescriptor) GetParent() Descriptor { 937 return fd.parent 938 } 939 940 // GetFile returns the descriptor for the file in which this field is defined. 941 func (fd *FieldDescriptor) GetFile() *FileDescriptor { 942 return fd.file 943 } 944 945 // GetOptions returns the field's options. Most usages will be more interested 946 // in GetFieldOptions, which has a concrete return type. This generic version 947 // is present to satisfy the Descriptor interface. 948 func (fd *FieldDescriptor) GetOptions() proto.Message { 949 return fd.proto.GetOptions() 950 } 951 952 // GetFieldOptions returns the field's options. 953 func (fd *FieldDescriptor) GetFieldOptions() *descriptorpb.FieldOptions { 954 return fd.proto.GetOptions() 955 } 956 957 // GetSourceInfo returns source info for the field, if present in the 958 // descriptor. Not all descriptors will contain source info. If non-nil, the 959 // returned info contains information about the location in the file where the 960 // field was defined and also contains comments associated with the field 961 // definition. 962 func (fd *FieldDescriptor) GetSourceInfo() *descriptorpb.SourceCodeInfo_Location { 963 return fd.file.sourceInfo.Get(fd.sourceInfoPath) 964 } 965 966 // AsProto returns the underlying descriptor proto. Most usages will be more 967 // interested in AsFieldDescriptorProto, which has a concrete return type. This 968 // generic version is present to satisfy the Descriptor interface. 969 func (fd *FieldDescriptor) AsProto() proto.Message { 970 return fd.proto 971 } 972 973 // AsFieldDescriptorProto returns the underlying descriptor proto. 974 func (fd *FieldDescriptor) AsFieldDescriptorProto() *descriptorpb.FieldDescriptorProto { 975 return fd.proto 976 } 977 978 // String returns the underlying descriptor proto, in compact text format. 979 func (fd *FieldDescriptor) String() string { 980 return fd.proto.String() 981 } 982 983 // GetJSONName returns the name of the field as referenced in the message's JSON 984 // format. 985 func (fd *FieldDescriptor) GetJSONName() string { 986 if jsonName := fd.proto.JsonName; jsonName != nil { 987 // if json name is present, use its value 988 return *jsonName 989 } 990 // otherwise, compute the proper JSON name from the field name 991 return jsonCamelCase(fd.proto.GetName()) 992 } 993 994 func jsonCamelCase(s string) string { 995 // This mirrors the implementation in protoc/C++ runtime and in the Java runtime: 996 // https://github.com/protocolbuffers/protobuf/blob/a104dffcb6b1958a424f5fa6f9e6bdc0ab9b6f9e/src/google/protobuf/descriptor.cc#L276 997 // https://github.com/protocolbuffers/protobuf/blob/a1c886834425abb64a966231dd2c9dd84fb289b3/java/core/src/main/java/com/google/protobuf/Descriptors.java#L1286 998 var buf bytes.Buffer 999 prevWasUnderscore := false 1000 for _, r := range s { 1001 if r == '_' { 1002 prevWasUnderscore = true 1003 continue 1004 } 1005 if prevWasUnderscore { 1006 r = unicode.ToUpper(r) 1007 prevWasUnderscore = false 1008 } 1009 buf.WriteRune(r) 1010 } 1011 return buf.String() 1012 } 1013 1014 // GetFullyQualifiedJSONName returns the JSON format name (same as GetJSONName), 1015 // but includes the fully qualified name of the enclosing message. 1016 // 1017 // If the field is an extension, it will return the package name (if there is 1018 // one) as well as the names of any enclosing messages. The package and/or 1019 // enclosing messages are for where the extension is defined, not the message it 1020 // extends. 1021 func (fd *FieldDescriptor) GetFullyQualifiedJSONName() string { 1022 parent := fd.GetParent() 1023 switch parent := parent.(type) { 1024 case *FileDescriptor: 1025 pkg := parent.GetPackage() 1026 if pkg == "" { 1027 return fd.GetJSONName() 1028 } 1029 return fmt.Sprintf("%s.%s", pkg, fd.GetJSONName()) 1030 default: 1031 return fmt.Sprintf("%s.%s", parent.GetFullyQualifiedName(), fd.GetJSONName()) 1032 } 1033 } 1034 1035 // GetOwner returns the message type that this field belongs to. If this is a normal 1036 // field then this is the same as GetParent. But for extensions, this will be the 1037 // extendee message whereas GetParent refers to where the extension was declared. 1038 func (fd *FieldDescriptor) GetOwner() *MessageDescriptor { 1039 return fd.owner 1040 } 1041 1042 // IsExtension returns true if this is an extension field. 1043 func (fd *FieldDescriptor) IsExtension() bool { 1044 return fd.wrapped.IsExtension() 1045 } 1046 1047 // GetOneOf returns the one-of field set to which this field belongs. If this field 1048 // is not part of a one-of then this method returns nil. 1049 func (fd *FieldDescriptor) GetOneOf() *OneOfDescriptor { 1050 return fd.oneOf 1051 } 1052 1053 // GetType returns the type of this field. If the type indicates an enum, the 1054 // enum type can be queried via GetEnumType. If the type indicates a message, the 1055 // message type can be queried via GetMessageType. 1056 func (fd *FieldDescriptor) GetType() descriptorpb.FieldDescriptorProto_Type { 1057 return fd.proto.GetType() 1058 } 1059 1060 // GetLabel returns the label for this field. The label can be required (proto2-only), 1061 // optional (default for proto3), or required. 1062 func (fd *FieldDescriptor) GetLabel() descriptorpb.FieldDescriptorProto_Label { 1063 return fd.proto.GetLabel() 1064 } 1065 1066 // IsRequired returns true if this field has the "required" label. 1067 func (fd *FieldDescriptor) IsRequired() bool { 1068 return fd.wrapped.Cardinality() == protoreflect.Required 1069 } 1070 1071 // IsRepeated returns true if this field has the "repeated" label. 1072 func (fd *FieldDescriptor) IsRepeated() bool { 1073 return fd.wrapped.Cardinality() == protoreflect.Repeated 1074 } 1075 1076 // IsProto3Optional returns true if this field has an explicit "optional" label 1077 // and is in a "proto3" syntax file. Such fields, if they are normal fields (not 1078 // extensions), will be nested in synthetic oneofs that contain only the single 1079 // field. 1080 func (fd *FieldDescriptor) IsProto3Optional() bool { 1081 return fd.proto.GetProto3Optional() 1082 } 1083 1084 // HasPresence returns true if this field can distinguish when a value is 1085 // present or not. Scalar fields in "proto3" syntax files, for example, return 1086 // false since absent values are indistinguishable from zero values. 1087 func (fd *FieldDescriptor) HasPresence() bool { 1088 return fd.wrapped.HasPresence() 1089 } 1090 1091 // IsMap returns true if this is a map field. If so, it will have the "repeated" 1092 // label its type will be a message that represents a map entry. The map entry 1093 // message will have exactly two fields: tag #1 is the key and tag #2 is the value. 1094 func (fd *FieldDescriptor) IsMap() bool { 1095 return fd.wrapped.IsMap() 1096 } 1097 1098 // GetMapKeyType returns the type of the key field if this is a map field. If it is 1099 // not a map field, nil is returned. 1100 func (fd *FieldDescriptor) GetMapKeyType() *FieldDescriptor { 1101 if fd.IsMap() { 1102 return fd.msgType.FindFieldByNumber(int32(1)) 1103 } 1104 return nil 1105 } 1106 1107 // GetMapValueType returns the type of the value field if this is a map field. If it 1108 // is not a map field, nil is returned. 1109 func (fd *FieldDescriptor) GetMapValueType() *FieldDescriptor { 1110 if fd.IsMap() { 1111 return fd.msgType.FindFieldByNumber(int32(2)) 1112 } 1113 return nil 1114 } 1115 1116 // GetMessageType returns the type of this field if it is a message type. If 1117 // this field is not a message type, it returns nil. 1118 func (fd *FieldDescriptor) GetMessageType() *MessageDescriptor { 1119 return fd.msgType 1120 } 1121 1122 // GetEnumType returns the type of this field if it is an enum type. If this 1123 // field is not an enum type, it returns nil. 1124 func (fd *FieldDescriptor) GetEnumType() *EnumDescriptor { 1125 return fd.enumType 1126 } 1127 1128 // GetDefaultValue returns the default value for this field. 1129 // 1130 // If this field represents a message type, this method always returns nil (even though 1131 // for proto2 files, the default value should be a default instance of the message type). 1132 // If the field represents an enum type, this method returns an int32 corresponding to the 1133 // enum value. If this field is a map, it returns a nil map[interface{}]interface{}. If 1134 // this field is repeated (and not a map), it returns a nil []interface{}. 1135 // 1136 // Otherwise, it returns the declared default value for the field or a zero value, if no 1137 // default is declared or if the file is proto3. The type of said return value corresponds 1138 // to the type of the field: 1139 // 1140 // +-------------------------+-----------+ 1141 // | Declared Type | Go Type | 1142 // +-------------------------+-----------+ 1143 // | int32, sint32, sfixed32 | int32 | 1144 // | int64, sint64, sfixed64 | int64 | 1145 // | uint32, fixed32 | uint32 | 1146 // | uint64, fixed64 | uint64 | 1147 // | float | float32 | 1148 // | double | double32 | 1149 // | bool | bool | 1150 // | string | string | 1151 // | bytes | []byte | 1152 // +-------------------------+-----------+ 1153 func (fd *FieldDescriptor) GetDefaultValue() interface{} { 1154 return fd.getDefaultValue() 1155 } 1156 1157 // EnumDescriptor describes an enum declared in a proto file. 1158 type EnumDescriptor struct { 1159 wrapped protoreflect.EnumDescriptor 1160 proto *descriptorpb.EnumDescriptorProto 1161 parent Descriptor 1162 file *FileDescriptor 1163 values []*EnumValueDescriptor 1164 valuesByNum sortedValues 1165 sourceInfoPath []int32 1166 } 1167 1168 // Unwrap returns the underlying protoreflect.Descriptor. Most usages will be more 1169 // interested in UnwrapEnum, which has a more specific return type. This generic 1170 // version is present to satisfy the DescriptorWrapper interface. 1171 func (ed *EnumDescriptor) Unwrap() protoreflect.Descriptor { 1172 return ed.wrapped 1173 } 1174 1175 // UnwrapEnum returns the underlying protoreflect.EnumDescriptor. 1176 func (ed *EnumDescriptor) UnwrapEnum() protoreflect.EnumDescriptor { 1177 return ed.wrapped 1178 } 1179 1180 func createEnumDescriptor(fd *FileDescriptor, parent Descriptor, ed protoreflect.EnumDescriptor, edp *descriptorpb.EnumDescriptorProto, symbols map[string]Descriptor, cache descriptorCache, path []int32) *EnumDescriptor { 1181 ret := &EnumDescriptor{ 1182 wrapped: ed, 1183 proto: edp, 1184 parent: parent, 1185 file: fd, 1186 sourceInfoPath: append([]int32(nil), path...), // defensive copy 1187 } 1188 path = append(path, internal.Enum_valuesTag) 1189 for i := 0; i < ed.Values().Len(); i++ { 1190 src := ed.Values().Get(i) 1191 srcProto := edp.GetValue()[src.Index()] 1192 evd := createEnumValueDescriptor(fd, ret, src, srcProto, append(path, int32(i))) 1193 symbols[string(src.FullName())] = evd 1194 // NB: for backwards compatibility, also register the enum value as if 1195 // scoped within the enum (counter-intuitively, enum value full names are 1196 // scoped in the enum's parent element). EnumValueDescripto.GetFullyQualifiedName 1197 // returns that alternate full name. 1198 symbols[evd.GetFullyQualifiedName()] = evd 1199 ret.values = append(ret.values, evd) 1200 } 1201 if len(ret.values) > 0 { 1202 ret.valuesByNum = make(sortedValues, len(ret.values)) 1203 copy(ret.valuesByNum, ret.values) 1204 sort.Stable(ret.valuesByNum) 1205 } 1206 return ret 1207 } 1208 1209 type sortedValues []*EnumValueDescriptor 1210 1211 func (sv sortedValues) Len() int { 1212 return len(sv) 1213 } 1214 1215 func (sv sortedValues) Less(i, j int) bool { 1216 return sv[i].GetNumber() < sv[j].GetNumber() 1217 } 1218 1219 func (sv sortedValues) Swap(i, j int) { 1220 sv[i], sv[j] = sv[j], sv[i] 1221 1222 } 1223 1224 // GetName returns the simple (unqualified) name of the enum type. 1225 func (ed *EnumDescriptor) GetName() string { 1226 return string(ed.wrapped.Name()) 1227 } 1228 1229 // GetFullyQualifiedName returns the fully qualified name of the enum type. 1230 // This includes the package name (if there is one) as well as the names of any 1231 // enclosing messages. 1232 func (ed *EnumDescriptor) GetFullyQualifiedName() string { 1233 return string(ed.wrapped.FullName()) 1234 } 1235 1236 // GetParent returns the enum type's enclosing descriptor. For top-level enums, 1237 // this will be a file descriptor. Otherwise it will be the descriptor for the 1238 // enclosing message. 1239 func (ed *EnumDescriptor) GetParent() Descriptor { 1240 return ed.parent 1241 } 1242 1243 // GetFile returns the descriptor for the file in which this enum is defined. 1244 func (ed *EnumDescriptor) GetFile() *FileDescriptor { 1245 return ed.file 1246 } 1247 1248 // GetOptions returns the enum type's options. Most usages will be more 1249 // interested in GetEnumOptions, which has a concrete return type. This generic 1250 // version is present to satisfy the Descriptor interface. 1251 func (ed *EnumDescriptor) GetOptions() proto.Message { 1252 return ed.proto.GetOptions() 1253 } 1254 1255 // GetEnumOptions returns the enum type's options. 1256 func (ed *EnumDescriptor) GetEnumOptions() *descriptorpb.EnumOptions { 1257 return ed.proto.GetOptions() 1258 } 1259 1260 // GetSourceInfo returns source info for the enum type, if present in the 1261 // descriptor. Not all descriptors will contain source info. If non-nil, the 1262 // returned info contains information about the location in the file where the 1263 // enum type was defined and also contains comments associated with the enum 1264 // definition. 1265 func (ed *EnumDescriptor) GetSourceInfo() *descriptorpb.SourceCodeInfo_Location { 1266 return ed.file.sourceInfo.Get(ed.sourceInfoPath) 1267 } 1268 1269 // AsProto returns the underlying descriptor proto. Most usages will be more 1270 // interested in AsEnumDescriptorProto, which has a concrete return type. This 1271 // generic version is present to satisfy the Descriptor interface. 1272 func (ed *EnumDescriptor) AsProto() proto.Message { 1273 return ed.proto 1274 } 1275 1276 // AsEnumDescriptorProto returns the underlying descriptor proto. 1277 func (ed *EnumDescriptor) AsEnumDescriptorProto() *descriptorpb.EnumDescriptorProto { 1278 return ed.proto 1279 } 1280 1281 // String returns the underlying descriptor proto, in compact text format. 1282 func (ed *EnumDescriptor) String() string { 1283 return ed.proto.String() 1284 } 1285 1286 // GetValues returns all of the allowed values defined for this enum. 1287 func (ed *EnumDescriptor) GetValues() []*EnumValueDescriptor { 1288 return ed.values 1289 } 1290 1291 // FindValueByName finds the enum value with the given name. If no such value exists 1292 // then nil is returned. 1293 func (ed *EnumDescriptor) FindValueByName(name string) *EnumValueDescriptor { 1294 fqn := fmt.Sprintf("%s.%s", ed.GetFullyQualifiedName(), name) 1295 if vd, ok := ed.file.symbols[fqn].(*EnumValueDescriptor); ok { 1296 return vd 1297 } else { 1298 return nil 1299 } 1300 } 1301 1302 // FindValueByNumber finds the value with the given numeric value. If no such value 1303 // exists then nil is returned. If aliases are allowed and multiple values have the 1304 // given number, the first declared value is returned. 1305 func (ed *EnumDescriptor) FindValueByNumber(num int32) *EnumValueDescriptor { 1306 index := sort.Search(len(ed.valuesByNum), func(i int) bool { return ed.valuesByNum[i].GetNumber() >= num }) 1307 if index < len(ed.valuesByNum) { 1308 vd := ed.valuesByNum[index] 1309 if vd.GetNumber() == num { 1310 return vd 1311 } 1312 } 1313 return nil 1314 } 1315 1316 // EnumValueDescriptor describes an allowed value of an enum declared in a proto file. 1317 type EnumValueDescriptor struct { 1318 wrapped protoreflect.EnumValueDescriptor 1319 proto *descriptorpb.EnumValueDescriptorProto 1320 parent *EnumDescriptor 1321 file *FileDescriptor 1322 sourceInfoPath []int32 1323 } 1324 1325 // Unwrap returns the underlying protoreflect.Descriptor. Most usages will be more 1326 // interested in UnwrapEnumValue, which has a more specific return type. This generic 1327 // version is present to satisfy the DescriptorWrapper interface. 1328 func (vd *EnumValueDescriptor) Unwrap() protoreflect.Descriptor { 1329 return vd.wrapped 1330 } 1331 1332 // UnwrapEnumValue returns the underlying protoreflect.EnumValueDescriptor. 1333 func (vd *EnumValueDescriptor) UnwrapEnumValue() protoreflect.EnumValueDescriptor { 1334 return vd.wrapped 1335 } 1336 1337 func createEnumValueDescriptor(fd *FileDescriptor, parent *EnumDescriptor, evd protoreflect.EnumValueDescriptor, evdp *descriptorpb.EnumValueDescriptorProto, path []int32) *EnumValueDescriptor { 1338 return &EnumValueDescriptor{ 1339 wrapped: evd, 1340 proto: evdp, 1341 parent: parent, 1342 file: fd, 1343 sourceInfoPath: append([]int32(nil), path...), // defensive copy 1344 } 1345 } 1346 1347 func (vd *EnumValueDescriptor) resolve(path []int32) { 1348 vd.sourceInfoPath = append([]int32(nil), path...) // defensive copy 1349 } 1350 1351 // GetName returns the name of the enum value. 1352 func (vd *EnumValueDescriptor) GetName() string { 1353 return string(vd.wrapped.Name()) 1354 } 1355 1356 // GetNumber returns the numeric value associated with this enum value. 1357 func (vd *EnumValueDescriptor) GetNumber() int32 { 1358 return int32(vd.wrapped.Number()) 1359 } 1360 1361 // GetFullyQualifiedName returns the fully qualified name of the enum value. 1362 // Unlike GetName, this includes fully qualified name of the enclosing enum. 1363 func (vd *EnumValueDescriptor) GetFullyQualifiedName() string { 1364 // NB: Technically, we do not return the correct value. Enum values are 1365 // scoped within the enclosing element, not within the enum itself (which 1366 // is very non-intuitive, but it follows C++ scoping rules). The value 1367 // returned from vd.wrapped.FullName() is correct. However, we return 1368 // something different, just for backwards compatibility, as this package 1369 // has always instead returned the name scoped inside the enum. 1370 return fmt.Sprintf("%s.%s", vd.parent.GetFullyQualifiedName(), vd.wrapped.Name()) 1371 } 1372 1373 // GetParent returns the descriptor for the enum in which this enum value is 1374 // defined. Most usages will prefer to use GetEnum, which has a concrete return 1375 // type. This more generic method is present to satisfy the Descriptor interface. 1376 func (vd *EnumValueDescriptor) GetParent() Descriptor { 1377 return vd.parent 1378 } 1379 1380 // GetEnum returns the enum in which this enum value is defined. 1381 func (vd *EnumValueDescriptor) GetEnum() *EnumDescriptor { 1382 return vd.parent 1383 } 1384 1385 // GetFile returns the descriptor for the file in which this enum value is 1386 // defined. 1387 func (vd *EnumValueDescriptor) GetFile() *FileDescriptor { 1388 return vd.file 1389 } 1390 1391 // GetOptions returns the enum value's options. Most usages will be more 1392 // interested in GetEnumValueOptions, which has a concrete return type. This 1393 // generic version is present to satisfy the Descriptor interface. 1394 func (vd *EnumValueDescriptor) GetOptions() proto.Message { 1395 return vd.proto.GetOptions() 1396 } 1397 1398 // GetEnumValueOptions returns the enum value's options. 1399 func (vd *EnumValueDescriptor) GetEnumValueOptions() *descriptorpb.EnumValueOptions { 1400 return vd.proto.GetOptions() 1401 } 1402 1403 // GetSourceInfo returns source info for the enum value, if present in the 1404 // descriptor. Not all descriptors will contain source info. If non-nil, the 1405 // returned info contains information about the location in the file where the 1406 // enum value was defined and also contains comments associated with the enum 1407 // value definition. 1408 func (vd *EnumValueDescriptor) GetSourceInfo() *descriptorpb.SourceCodeInfo_Location { 1409 return vd.file.sourceInfo.Get(vd.sourceInfoPath) 1410 } 1411 1412 // AsProto returns the underlying descriptor proto. Most usages will be more 1413 // interested in AsEnumValueDescriptorProto, which has a concrete return type. 1414 // This generic version is present to satisfy the Descriptor interface. 1415 func (vd *EnumValueDescriptor) AsProto() proto.Message { 1416 return vd.proto 1417 } 1418 1419 // AsEnumValueDescriptorProto returns the underlying descriptor proto. 1420 func (vd *EnumValueDescriptor) AsEnumValueDescriptorProto() *descriptorpb.EnumValueDescriptorProto { 1421 return vd.proto 1422 } 1423 1424 // String returns the underlying descriptor proto, in compact text format. 1425 func (vd *EnumValueDescriptor) String() string { 1426 return vd.proto.String() 1427 } 1428 1429 // ServiceDescriptor describes an RPC service declared in a proto file. 1430 type ServiceDescriptor struct { 1431 wrapped protoreflect.ServiceDescriptor 1432 proto *descriptorpb.ServiceDescriptorProto 1433 file *FileDescriptor 1434 methods []*MethodDescriptor 1435 sourceInfoPath []int32 1436 } 1437 1438 // Unwrap returns the underlying protoreflect.Descriptor. Most usages will be more 1439 // interested in UnwrapService, which has a more specific return type. This generic 1440 // version is present to satisfy the DescriptorWrapper interface. 1441 func (sd *ServiceDescriptor) Unwrap() protoreflect.Descriptor { 1442 return sd.wrapped 1443 } 1444 1445 // UnwrapService returns the underlying protoreflect.ServiceDescriptor. 1446 func (sd *ServiceDescriptor) UnwrapService() protoreflect.ServiceDescriptor { 1447 return sd.wrapped 1448 } 1449 1450 func createServiceDescriptor(fd *FileDescriptor, sd protoreflect.ServiceDescriptor, sdp *descriptorpb.ServiceDescriptorProto, symbols map[string]Descriptor, path []int32) *ServiceDescriptor { 1451 ret := &ServiceDescriptor{ 1452 wrapped: sd, 1453 proto: sdp, 1454 file: fd, 1455 sourceInfoPath: append([]int32(nil), path...), // defensive copy 1456 } 1457 path = append(path, internal.Service_methodsTag) 1458 for i := 0; i < sd.Methods().Len(); i++ { 1459 src := sd.Methods().Get(i) 1460 srcProto := sdp.GetMethod()[src.Index()] 1461 md := createMethodDescriptor(fd, ret, src, srcProto, append(path, int32(i))) 1462 symbols[string(src.FullName())] = md 1463 ret.methods = append(ret.methods, md) 1464 } 1465 return ret 1466 } 1467 1468 func (sd *ServiceDescriptor) resolve(cache descriptorCache) error { 1469 for _, md := range sd.methods { 1470 if err := md.resolve(cache); err != nil { 1471 return err 1472 } 1473 } 1474 return nil 1475 } 1476 1477 // GetName returns the simple (unqualified) name of the service. 1478 func (sd *ServiceDescriptor) GetName() string { 1479 return string(sd.wrapped.Name()) 1480 } 1481 1482 // GetFullyQualifiedName returns the fully qualified name of the service. This 1483 // includes the package name (if there is one). 1484 func (sd *ServiceDescriptor) GetFullyQualifiedName() string { 1485 return string(sd.wrapped.FullName()) 1486 } 1487 1488 // GetParent returns the descriptor for the file in which this service is 1489 // defined. Most usages will prefer to use GetFile, which has a concrete return 1490 // type. This more generic method is present to satisfy the Descriptor interface. 1491 func (sd *ServiceDescriptor) GetParent() Descriptor { 1492 return sd.file 1493 } 1494 1495 // GetFile returns the descriptor for the file in which this service is defined. 1496 func (sd *ServiceDescriptor) GetFile() *FileDescriptor { 1497 return sd.file 1498 } 1499 1500 // GetOptions returns the service's options. Most usages will be more interested 1501 // in GetServiceOptions, which has a concrete return type. This generic version 1502 // is present to satisfy the Descriptor interface. 1503 func (sd *ServiceDescriptor) GetOptions() proto.Message { 1504 return sd.proto.GetOptions() 1505 } 1506 1507 // GetServiceOptions returns the service's options. 1508 func (sd *ServiceDescriptor) GetServiceOptions() *descriptorpb.ServiceOptions { 1509 return sd.proto.GetOptions() 1510 } 1511 1512 // GetSourceInfo returns source info for the service, if present in the 1513 // descriptor. Not all descriptors will contain source info. If non-nil, the 1514 // returned info contains information about the location in the file where the 1515 // service was defined and also contains comments associated with the service 1516 // definition. 1517 func (sd *ServiceDescriptor) GetSourceInfo() *descriptorpb.SourceCodeInfo_Location { 1518 return sd.file.sourceInfo.Get(sd.sourceInfoPath) 1519 } 1520 1521 // AsProto returns the underlying descriptor proto. Most usages will be more 1522 // interested in AsServiceDescriptorProto, which has a concrete return type. 1523 // This generic version is present to satisfy the Descriptor interface. 1524 func (sd *ServiceDescriptor) AsProto() proto.Message { 1525 return sd.proto 1526 } 1527 1528 // AsServiceDescriptorProto returns the underlying descriptor proto. 1529 func (sd *ServiceDescriptor) AsServiceDescriptorProto() *descriptorpb.ServiceDescriptorProto { 1530 return sd.proto 1531 } 1532 1533 // String returns the underlying descriptor proto, in compact text format. 1534 func (sd *ServiceDescriptor) String() string { 1535 return sd.proto.String() 1536 } 1537 1538 // GetMethods returns all of the RPC methods for this service. 1539 func (sd *ServiceDescriptor) GetMethods() []*MethodDescriptor { 1540 return sd.methods 1541 } 1542 1543 // FindMethodByName finds the method with the given name. If no such method exists 1544 // then nil is returned. 1545 func (sd *ServiceDescriptor) FindMethodByName(name string) *MethodDescriptor { 1546 fqn := fmt.Sprintf("%s.%s", sd.GetFullyQualifiedName(), name) 1547 if md, ok := sd.file.symbols[fqn].(*MethodDescriptor); ok { 1548 return md 1549 } else { 1550 return nil 1551 } 1552 } 1553 1554 // MethodDescriptor describes an RPC method declared in a proto file. 1555 type MethodDescriptor struct { 1556 wrapped protoreflect.MethodDescriptor 1557 proto *descriptorpb.MethodDescriptorProto 1558 parent *ServiceDescriptor 1559 file *FileDescriptor 1560 inType *MessageDescriptor 1561 outType *MessageDescriptor 1562 sourceInfoPath []int32 1563 } 1564 1565 // Unwrap returns the underlying protoreflect.Descriptor. Most usages will be more 1566 // interested in UnwrapMethod, which has a more specific return type. This generic 1567 // version is present to satisfy the DescriptorWrapper interface. 1568 func (md *MethodDescriptor) Unwrap() protoreflect.Descriptor { 1569 return md.wrapped 1570 } 1571 1572 // UnwrapMethod returns the underlying protoreflect.MethodDescriptor. 1573 func (md *MethodDescriptor) UnwrapMethod() protoreflect.MethodDescriptor { 1574 return md.wrapped 1575 } 1576 1577 func createMethodDescriptor(fd *FileDescriptor, parent *ServiceDescriptor, md protoreflect.MethodDescriptor, mdp *descriptorpb.MethodDescriptorProto, path []int32) *MethodDescriptor { 1578 // request and response types get resolved later 1579 return &MethodDescriptor{ 1580 wrapped: md, 1581 proto: mdp, 1582 parent: parent, 1583 file: fd, 1584 sourceInfoPath: append([]int32(nil), path...), // defensive copy 1585 } 1586 } 1587 1588 func (md *MethodDescriptor) resolve(cache descriptorCache) error { 1589 if desc, err := resolve(md.file, md.wrapped.Input(), cache); err != nil { 1590 return err 1591 } else { 1592 msgType, ok := desc.(*MessageDescriptor) 1593 if !ok { 1594 return fmt.Errorf("method %v has request type %q which should be a message but is %s", md.GetFullyQualifiedName(), md.proto.GetInputType(), descriptorType(desc)) 1595 } 1596 md.inType = msgType 1597 } 1598 if desc, err := resolve(md.file, md.wrapped.Output(), cache); err != nil { 1599 return err 1600 } else { 1601 msgType, ok := desc.(*MessageDescriptor) 1602 if !ok { 1603 return fmt.Errorf("method %v has response type %q which should be a message but is %s", md.GetFullyQualifiedName(), md.proto.GetOutputType(), descriptorType(desc)) 1604 } 1605 md.outType = msgType 1606 } 1607 return nil 1608 } 1609 1610 // GetName returns the name of the method. 1611 func (md *MethodDescriptor) GetName() string { 1612 return string(md.wrapped.Name()) 1613 } 1614 1615 // GetFullyQualifiedName returns the fully qualified name of the method. Unlike 1616 // GetName, this includes fully qualified name of the enclosing service. 1617 func (md *MethodDescriptor) GetFullyQualifiedName() string { 1618 return string(md.wrapped.FullName()) 1619 } 1620 1621 // GetParent returns the descriptor for the service in which this method is 1622 // defined. Most usages will prefer to use GetService, which has a concrete 1623 // return type. This more generic method is present to satisfy the Descriptor 1624 // interface. 1625 func (md *MethodDescriptor) GetParent() Descriptor { 1626 return md.parent 1627 } 1628 1629 // GetService returns the RPC service in which this method is declared. 1630 func (md *MethodDescriptor) GetService() *ServiceDescriptor { 1631 return md.parent 1632 } 1633 1634 // GetFile returns the descriptor for the file in which this method is defined. 1635 func (md *MethodDescriptor) GetFile() *FileDescriptor { 1636 return md.file 1637 } 1638 1639 // GetOptions returns the method's options. Most usages will be more interested 1640 // in GetMethodOptions, which has a concrete return type. This generic version 1641 // is present to satisfy the Descriptor interface. 1642 func (md *MethodDescriptor) GetOptions() proto.Message { 1643 return md.proto.GetOptions() 1644 } 1645 1646 // GetMethodOptions returns the method's options. 1647 func (md *MethodDescriptor) GetMethodOptions() *descriptorpb.MethodOptions { 1648 return md.proto.GetOptions() 1649 } 1650 1651 // GetSourceInfo returns source info for the method, if present in the 1652 // descriptor. Not all descriptors will contain source info. If non-nil, the 1653 // returned info contains information about the location in the file where the 1654 // method was defined and also contains comments associated with the method 1655 // definition. 1656 func (md *MethodDescriptor) GetSourceInfo() *descriptorpb.SourceCodeInfo_Location { 1657 return md.file.sourceInfo.Get(md.sourceInfoPath) 1658 } 1659 1660 // AsProto returns the underlying descriptor proto. Most usages will be more 1661 // interested in AsMethodDescriptorProto, which has a concrete return type. This 1662 // generic version is present to satisfy the Descriptor interface. 1663 func (md *MethodDescriptor) AsProto() proto.Message { 1664 return md.proto 1665 } 1666 1667 // AsMethodDescriptorProto returns the underlying descriptor proto. 1668 func (md *MethodDescriptor) AsMethodDescriptorProto() *descriptorpb.MethodDescriptorProto { 1669 return md.proto 1670 } 1671 1672 // String returns the underlying descriptor proto, in compact text format. 1673 func (md *MethodDescriptor) String() string { 1674 return md.proto.String() 1675 } 1676 1677 // IsServerStreaming returns true if this is a server-streaming method. 1678 func (md *MethodDescriptor) IsServerStreaming() bool { 1679 return md.wrapped.IsStreamingServer() 1680 } 1681 1682 // IsClientStreaming returns true if this is a client-streaming method. 1683 func (md *MethodDescriptor) IsClientStreaming() bool { 1684 return md.wrapped.IsStreamingClient() 1685 } 1686 1687 // GetInputType returns the input type, or request type, of the RPC method. 1688 func (md *MethodDescriptor) GetInputType() *MessageDescriptor { 1689 return md.inType 1690 } 1691 1692 // GetOutputType returns the output type, or response type, of the RPC method. 1693 func (md *MethodDescriptor) GetOutputType() *MessageDescriptor { 1694 return md.outType 1695 } 1696 1697 // OneOfDescriptor describes a one-of field set declared in a protocol buffer message. 1698 type OneOfDescriptor struct { 1699 wrapped protoreflect.OneofDescriptor 1700 proto *descriptorpb.OneofDescriptorProto 1701 parent *MessageDescriptor 1702 file *FileDescriptor 1703 choices []*FieldDescriptor 1704 sourceInfoPath []int32 1705 } 1706 1707 // Unwrap returns the underlying protoreflect.Descriptor. Most usages will be more 1708 // interested in UnwrapOneOf, which has a more specific return type. This generic 1709 // version is present to satisfy the DescriptorWrapper interface. 1710 func (od *OneOfDescriptor) Unwrap() protoreflect.Descriptor { 1711 return od.wrapped 1712 } 1713 1714 // UnwrapOneOf returns the underlying protoreflect.OneofDescriptor. 1715 func (od *OneOfDescriptor) UnwrapOneOf() protoreflect.OneofDescriptor { 1716 return od.wrapped 1717 } 1718 1719 func createOneOfDescriptor(fd *FileDescriptor, parent *MessageDescriptor, index int, od protoreflect.OneofDescriptor, odp *descriptorpb.OneofDescriptorProto, path []int32) *OneOfDescriptor { 1720 ret := &OneOfDescriptor{ 1721 wrapped: od, 1722 proto: odp, 1723 parent: parent, 1724 file: fd, 1725 sourceInfoPath: append([]int32(nil), path...), // defensive copy 1726 } 1727 for _, f := range parent.fields { 1728 oi := f.proto.OneofIndex 1729 if oi != nil && *oi == int32(index) { 1730 f.oneOf = ret 1731 ret.choices = append(ret.choices, f) 1732 } 1733 } 1734 return ret 1735 } 1736 1737 // GetName returns the name of the one-of. 1738 func (od *OneOfDescriptor) GetName() string { 1739 return string(od.wrapped.Name()) 1740 } 1741 1742 // GetFullyQualifiedName returns the fully qualified name of the one-of. Unlike 1743 // GetName, this includes fully qualified name of the enclosing message. 1744 func (od *OneOfDescriptor) GetFullyQualifiedName() string { 1745 return string(od.wrapped.FullName()) 1746 } 1747 1748 // GetParent returns the descriptor for the message in which this one-of is 1749 // defined. Most usages will prefer to use GetOwner, which has a concrete 1750 // return type. This more generic method is present to satisfy the Descriptor 1751 // interface. 1752 func (od *OneOfDescriptor) GetParent() Descriptor { 1753 return od.parent 1754 } 1755 1756 // GetOwner returns the message to which this one-of field set belongs. 1757 func (od *OneOfDescriptor) GetOwner() *MessageDescriptor { 1758 return od.parent 1759 } 1760 1761 // GetFile returns the descriptor for the file in which this one-fof is defined. 1762 func (od *OneOfDescriptor) GetFile() *FileDescriptor { 1763 return od.file 1764 } 1765 1766 // GetOptions returns the one-of's options. Most usages will be more interested 1767 // in GetOneOfOptions, which has a concrete return type. This generic version 1768 // is present to satisfy the Descriptor interface. 1769 func (od *OneOfDescriptor) GetOptions() proto.Message { 1770 return od.proto.GetOptions() 1771 } 1772 1773 // GetOneOfOptions returns the one-of's options. 1774 func (od *OneOfDescriptor) GetOneOfOptions() *descriptorpb.OneofOptions { 1775 return od.proto.GetOptions() 1776 } 1777 1778 // GetSourceInfo returns source info for the one-of, if present in the 1779 // descriptor. Not all descriptors will contain source info. If non-nil, the 1780 // returned info contains information about the location in the file where the 1781 // one-of was defined and also contains comments associated with the one-of 1782 // definition. 1783 func (od *OneOfDescriptor) GetSourceInfo() *descriptorpb.SourceCodeInfo_Location { 1784 return od.file.sourceInfo.Get(od.sourceInfoPath) 1785 } 1786 1787 // AsProto returns the underlying descriptor proto. Most usages will be more 1788 // interested in AsOneofDescriptorProto, which has a concrete return type. This 1789 // generic version is present to satisfy the Descriptor interface. 1790 func (od *OneOfDescriptor) AsProto() proto.Message { 1791 return od.proto 1792 } 1793 1794 // AsOneofDescriptorProto returns the underlying descriptor proto. 1795 func (od *OneOfDescriptor) AsOneofDescriptorProto() *descriptorpb.OneofDescriptorProto { 1796 return od.proto 1797 } 1798 1799 // String returns the underlying descriptor proto, in compact text format. 1800 func (od *OneOfDescriptor) String() string { 1801 return od.proto.String() 1802 } 1803 1804 // GetChoices returns the fields that are part of the one-of field set. At most one of 1805 // these fields may be set for a given message. 1806 func (od *OneOfDescriptor) GetChoices() []*FieldDescriptor { 1807 return od.choices 1808 } 1809 1810 func (od *OneOfDescriptor) IsSynthetic() bool { 1811 return od.wrapped.IsSynthetic() 1812 } 1813 1814 func resolve(fd *FileDescriptor, src protoreflect.Descriptor, cache descriptorCache) (Descriptor, error) { 1815 d := cache.get(src) 1816 if d != nil { 1817 return d, nil 1818 } 1819 1820 fqn := string(src.FullName()) 1821 1822 d = fd.FindSymbol(fqn) 1823 if d != nil { 1824 return d, nil 1825 } 1826 1827 for _, dep := range fd.deps { 1828 d := dep.FindSymbol(fqn) 1829 if d != nil { 1830 return d, nil 1831 } 1832 } 1833 1834 return nil, fmt.Errorf("file %q included an unresolvable reference to %q", fd.proto.GetName(), fqn) 1835 }