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