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