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