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