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