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// IsProto3Optional returns true if this field has an explicit "optional" label
998// and is in a "proto3" syntax file. Such fields, if they are normal fields (not
999// extensions), will be nested in synthetic oneofs that contain only the single
1000// field.
1001func (fd *FieldDescriptor) IsProto3Optional() bool {
1002	return internal.GetProto3Optional(fd.proto)
1003}
1004
1005// HasPresence returns true if this field can distinguish when a value is
1006// present or not. Scalar fields in "proto3" syntax files, for example, return
1007// false since absent values are indistinguishable from zero values.
1008func (fd *FieldDescriptor) HasPresence() bool {
1009	if !fd.file.isProto3 {
1010		return true
1011	}
1012	return fd.msgType != nil || fd.oneOf != nil
1013}
1014
1015// IsMap returns true if this is a map field. If so, it will have the "repeated"
1016// label its type will be a message that represents a map entry. The map entry
1017// message will have exactly two fields: tag #1 is the key and tag #2 is the value.
1018func (fd *FieldDescriptor) IsMap() bool {
1019	return fd.isMap
1020}
1021
1022// GetMapKeyType returns the type of the key field if this is a map field. If it is
1023// not a map field, nil is returned.
1024func (fd *FieldDescriptor) GetMapKeyType() *FieldDescriptor {
1025	if fd.isMap {
1026		return fd.msgType.FindFieldByNumber(int32(1))
1027	}
1028	return nil
1029}
1030
1031// GetMapValueType returns the type of the value field if this is a map field. If it
1032// is not a map field, nil is returned.
1033func (fd *FieldDescriptor) GetMapValueType() *FieldDescriptor {
1034	if fd.isMap {
1035		return fd.msgType.FindFieldByNumber(int32(2))
1036	}
1037	return nil
1038}
1039
1040// GetMessageType returns the type of this field if it is a message type. If
1041// this field is not a message type, it returns nil.
1042func (fd *FieldDescriptor) GetMessageType() *MessageDescriptor {
1043	return fd.msgType
1044}
1045
1046// GetEnumType returns the type of this field if it is an enum type. If this
1047// field is not an enum type, it returns nil.
1048func (fd *FieldDescriptor) GetEnumType() *EnumDescriptor {
1049	return fd.enumType
1050}
1051
1052// GetDefaultValue returns the default value for this field.
1053//
1054// If this field represents a message type, this method always returns nil (even though
1055// for proto2 files, the default value should be a default instance of the message type).
1056// If the field represents an enum type, this method returns an int32 corresponding to the
1057// enum value. If this field is a map, it returns a nil map[interface{}]interface{}. If
1058// this field is repeated (and not a map), it returns a nil []interface{}.
1059//
1060// Otherwise, it returns the declared default value for the field or a zero value, if no
1061// default is declared or if the file is proto3. The type of said return value corresponds
1062// to the type of the field:
1063//  +-------------------------+-----------+
1064//  |       Declared Type     |  Go Type  |
1065//  +-------------------------+-----------+
1066//  | int32, sint32, sfixed32 | int32     |
1067//  | int64, sint64, sfixed64 | int64     |
1068//  | uint32, fixed32         | uint32    |
1069//  | uint64, fixed64         | uint64    |
1070//  | float                   | float32   |
1071//  | double                  | double32  |
1072//  | bool                    | bool      |
1073//  | string                  | string    |
1074//  | bytes                   | []byte    |
1075//  +-------------------------+-----------+
1076func (fd *FieldDescriptor) GetDefaultValue() interface{} {
1077	return fd.getDefaultValue()
1078}
1079
1080// EnumDescriptor describes an enum declared in a proto file.
1081type EnumDescriptor struct {
1082	proto          *dpb.EnumDescriptorProto
1083	parent         Descriptor
1084	file           *FileDescriptor
1085	values         []*EnumValueDescriptor
1086	valuesByNum    sortedValues
1087	fqn            string
1088	sourceInfoPath []int32
1089}
1090
1091func createEnumDescriptor(fd *FileDescriptor, parent Descriptor, enclosing string, ed *dpb.EnumDescriptorProto, symbols map[string]Descriptor) (*EnumDescriptor, string) {
1092	enumName := merge(enclosing, ed.GetName())
1093	ret := &EnumDescriptor{proto: ed, parent: parent, file: fd, fqn: enumName}
1094	for _, ev := range ed.GetValue() {
1095		evd, n := createEnumValueDescriptor(fd, ret, enumName, ev)
1096		symbols[n] = evd
1097		ret.values = append(ret.values, evd)
1098	}
1099	if len(ret.values) > 0 {
1100		ret.valuesByNum = make(sortedValues, len(ret.values))
1101		copy(ret.valuesByNum, ret.values)
1102		sort.Stable(ret.valuesByNum)
1103	}
1104	return ret, enumName
1105}
1106
1107type sortedValues []*EnumValueDescriptor
1108
1109func (sv sortedValues) Len() int {
1110	return len(sv)
1111}
1112
1113func (sv sortedValues) Less(i, j int) bool {
1114	return sv[i].GetNumber() < sv[j].GetNumber()
1115}
1116
1117func (sv sortedValues) Swap(i, j int) {
1118	sv[i], sv[j] = sv[j], sv[i]
1119}
1120
1121func (ed *EnumDescriptor) resolve(path []int32) {
1122	ed.sourceInfoPath = append([]int32(nil), path...) // defensive copy
1123	path = append(path, internal.Enum_valuesTag)
1124	for i, evd := range ed.values {
1125		evd.resolve(append(path, int32(i)))
1126	}
1127}
1128
1129// GetName returns the simple (unqualified) name of the enum type.
1130func (ed *EnumDescriptor) GetName() string {
1131	return ed.proto.GetName()
1132}
1133
1134// GetFullyQualifiedName returns the fully qualified name of the enum type.
1135// This includes the package name (if there is one) as well as the names of any
1136// enclosing messages.
1137func (ed *EnumDescriptor) GetFullyQualifiedName() string {
1138	return ed.fqn
1139}
1140
1141// GetParent returns the enum type's enclosing descriptor. For top-level enums,
1142// this will be a file descriptor. Otherwise it will be the descriptor for the
1143// enclosing message.
1144func (ed *EnumDescriptor) GetParent() Descriptor {
1145	return ed.parent
1146}
1147
1148// GetFile returns the descriptor for the file in which this enum is defined.
1149func (ed *EnumDescriptor) GetFile() *FileDescriptor {
1150	return ed.file
1151}
1152
1153// GetOptions returns the enum type's options. Most usages will be more
1154// interested in GetEnumOptions, which has a concrete return type. This generic
1155// version is present to satisfy the Descriptor interface.
1156func (ed *EnumDescriptor) GetOptions() proto.Message {
1157	return ed.proto.GetOptions()
1158}
1159
1160// GetEnumOptions returns the enum type's options.
1161func (ed *EnumDescriptor) GetEnumOptions() *dpb.EnumOptions {
1162	return ed.proto.GetOptions()
1163}
1164
1165// GetSourceInfo returns source info for the enum type, if present in the
1166// descriptor. Not all descriptors will contain source info. If non-nil, the
1167// returned info contains information about the location in the file where the
1168// enum type was defined and also contains comments associated with the enum
1169// definition.
1170func (ed *EnumDescriptor) GetSourceInfo() *dpb.SourceCodeInfo_Location {
1171	return ed.file.sourceInfo.Get(ed.sourceInfoPath)
1172}
1173
1174// AsProto returns the underlying descriptor proto. Most usages will be more
1175// interested in AsEnumDescriptorProto, which has a concrete return type. This
1176// generic version is present to satisfy the Descriptor interface.
1177func (ed *EnumDescriptor) AsProto() proto.Message {
1178	return ed.proto
1179}
1180
1181// AsEnumDescriptorProto returns the underlying descriptor proto.
1182func (ed *EnumDescriptor) AsEnumDescriptorProto() *dpb.EnumDescriptorProto {
1183	return ed.proto
1184}
1185
1186// String returns the underlying descriptor proto, in compact text format.
1187func (ed *EnumDescriptor) String() string {
1188	return ed.proto.String()
1189}
1190
1191// GetValues returns all of the allowed values defined for this enum.
1192func (ed *EnumDescriptor) GetValues() []*EnumValueDescriptor {
1193	return ed.values
1194}
1195
1196// FindValueByName finds the enum value with the given name. If no such value exists
1197// then nil is returned.
1198func (ed *EnumDescriptor) FindValueByName(name string) *EnumValueDescriptor {
1199	fqn := fmt.Sprintf("%s.%s", ed.fqn, name)
1200	if vd, ok := ed.file.symbols[fqn].(*EnumValueDescriptor); ok {
1201		return vd
1202	} else {
1203		return nil
1204	}
1205}
1206
1207// FindValueByNumber finds the value with the given numeric value. If no such value
1208// exists then nil is returned. If aliases are allowed and multiple values have the
1209// given number, the first declared value is returned.
1210func (ed *EnumDescriptor) FindValueByNumber(num int32) *EnumValueDescriptor {
1211	index := sort.Search(len(ed.valuesByNum), func(i int) bool { return ed.valuesByNum[i].GetNumber() >= num })
1212	if index < len(ed.valuesByNum) {
1213		vd := ed.valuesByNum[index]
1214		if vd.GetNumber() == num {
1215			return vd
1216		}
1217	}
1218	return nil
1219}
1220
1221// EnumValueDescriptor describes an allowed value of an enum declared in a proto file.
1222type EnumValueDescriptor struct {
1223	proto          *dpb.EnumValueDescriptorProto
1224	parent         *EnumDescriptor
1225	file           *FileDescriptor
1226	fqn            string
1227	sourceInfoPath []int32
1228}
1229
1230func createEnumValueDescriptor(fd *FileDescriptor, parent *EnumDescriptor, enclosing string, evd *dpb.EnumValueDescriptorProto) (*EnumValueDescriptor, string) {
1231	valName := merge(enclosing, evd.GetName())
1232	return &EnumValueDescriptor{proto: evd, parent: parent, file: fd, fqn: valName}, valName
1233}
1234
1235func (vd *EnumValueDescriptor) resolve(path []int32) {
1236	vd.sourceInfoPath = append([]int32(nil), path...) // defensive copy
1237}
1238
1239// GetName returns the name of the enum value.
1240func (vd *EnumValueDescriptor) GetName() string {
1241	return vd.proto.GetName()
1242}
1243
1244// GetNumber returns the numeric value associated with this enum value.
1245func (vd *EnumValueDescriptor) GetNumber() int32 {
1246	return vd.proto.GetNumber()
1247}
1248
1249// GetFullyQualifiedName returns the fully qualified name of the enum value.
1250// Unlike GetName, this includes fully qualified name of the enclosing enum.
1251func (vd *EnumValueDescriptor) GetFullyQualifiedName() string {
1252	return vd.fqn
1253}
1254
1255// GetParent returns the descriptor for the enum in which this enum value is
1256// defined. Most usages will prefer to use GetEnum, which has a concrete return
1257// type. This more generic method is present to satisfy the Descriptor interface.
1258func (vd *EnumValueDescriptor) GetParent() Descriptor {
1259	return vd.parent
1260}
1261
1262// GetEnum returns the enum in which this enum value is defined.
1263func (vd *EnumValueDescriptor) GetEnum() *EnumDescriptor {
1264	return vd.parent
1265}
1266
1267// GetFile returns the descriptor for the file in which this enum value is
1268// defined.
1269func (vd *EnumValueDescriptor) GetFile() *FileDescriptor {
1270	return vd.file
1271}
1272
1273// GetOptions returns the enum value's options. Most usages will be more
1274// interested in GetEnumValueOptions, which has a concrete return type. This
1275// generic version is present to satisfy the Descriptor interface.
1276func (vd *EnumValueDescriptor) GetOptions() proto.Message {
1277	return vd.proto.GetOptions()
1278}
1279
1280// GetEnumValueOptions returns the enum value's options.
1281func (vd *EnumValueDescriptor) GetEnumValueOptions() *dpb.EnumValueOptions {
1282	return vd.proto.GetOptions()
1283}
1284
1285// GetSourceInfo returns source info for the enum value, if present in the
1286// descriptor. Not all descriptors will contain source info. If non-nil, the
1287// returned info contains information about the location in the file where the
1288// enum value was defined and also contains comments associated with the enum
1289// value definition.
1290func (vd *EnumValueDescriptor) GetSourceInfo() *dpb.SourceCodeInfo_Location {
1291	return vd.file.sourceInfo.Get(vd.sourceInfoPath)
1292}
1293
1294// AsProto returns the underlying descriptor proto. Most usages will be more
1295// interested in AsEnumValueDescriptorProto, which has a concrete return type.
1296// This generic version is present to satisfy the Descriptor interface.
1297func (vd *EnumValueDescriptor) AsProto() proto.Message {
1298	return vd.proto
1299}
1300
1301// AsEnumValueDescriptorProto returns the underlying descriptor proto.
1302func (vd *EnumValueDescriptor) AsEnumValueDescriptorProto() *dpb.EnumValueDescriptorProto {
1303	return vd.proto
1304}
1305
1306// String returns the underlying descriptor proto, in compact text format.
1307func (vd *EnumValueDescriptor) String() string {
1308	return vd.proto.String()
1309}
1310
1311// ServiceDescriptor describes an RPC service declared in a proto file.
1312type ServiceDescriptor struct {
1313	proto          *dpb.ServiceDescriptorProto
1314	file           *FileDescriptor
1315	methods        []*MethodDescriptor
1316	fqn            string
1317	sourceInfoPath []int32
1318}
1319
1320func createServiceDescriptor(fd *FileDescriptor, enclosing string, sd *dpb.ServiceDescriptorProto, symbols map[string]Descriptor) (*ServiceDescriptor, string) {
1321	serviceName := merge(enclosing, sd.GetName())
1322	ret := &ServiceDescriptor{proto: sd, file: fd, fqn: serviceName}
1323	for _, m := range sd.GetMethod() {
1324		md, n := createMethodDescriptor(fd, ret, serviceName, m)
1325		symbols[n] = md
1326		ret.methods = append(ret.methods, md)
1327	}
1328	return ret, serviceName
1329}
1330
1331func (sd *ServiceDescriptor) resolve(path []int32, scopes []scope) error {
1332	sd.sourceInfoPath = append([]int32(nil), path...) // defensive copy
1333	path = append(path, internal.Service_methodsTag)
1334	for i, md := range sd.methods {
1335		if err := md.resolve(append(path, int32(i)), scopes); err != nil {
1336			return err
1337		}
1338	}
1339	return nil
1340}
1341
1342// GetName returns the simple (unqualified) name of the service.
1343func (sd *ServiceDescriptor) GetName() string {
1344	return sd.proto.GetName()
1345}
1346
1347// GetFullyQualifiedName returns the fully qualified name of the service. This
1348// includes the package name (if there is one).
1349func (sd *ServiceDescriptor) GetFullyQualifiedName() string {
1350	return sd.fqn
1351}
1352
1353// GetParent returns the descriptor for the file in which this service is
1354// defined. Most usages will prefer to use GetFile, which has a concrete return
1355// type. This more generic method is present to satisfy the Descriptor interface.
1356func (sd *ServiceDescriptor) GetParent() Descriptor {
1357	return sd.file
1358}
1359
1360// GetFile returns the descriptor for the file in which this service is defined.
1361func (sd *ServiceDescriptor) GetFile() *FileDescriptor {
1362	return sd.file
1363}
1364
1365// GetOptions returns the service's options. Most usages will be more interested
1366// in GetServiceOptions, which has a concrete return type. This generic version
1367// is present to satisfy the Descriptor interface.
1368func (sd *ServiceDescriptor) GetOptions() proto.Message {
1369	return sd.proto.GetOptions()
1370}
1371
1372// GetServiceOptions returns the service's options.
1373func (sd *ServiceDescriptor) GetServiceOptions() *dpb.ServiceOptions {
1374	return sd.proto.GetOptions()
1375}
1376
1377// GetSourceInfo returns source info for the service, if present in the
1378// descriptor. Not all descriptors will contain source info. If non-nil, the
1379// returned info contains information about the location in the file where the
1380// service was defined and also contains comments associated with the service
1381// definition.
1382func (sd *ServiceDescriptor) GetSourceInfo() *dpb.SourceCodeInfo_Location {
1383	return sd.file.sourceInfo.Get(sd.sourceInfoPath)
1384}
1385
1386// AsProto returns the underlying descriptor proto. Most usages will be more
1387// interested in AsServiceDescriptorProto, which has a concrete return type.
1388// This generic version is present to satisfy the Descriptor interface.
1389func (sd *ServiceDescriptor) AsProto() proto.Message {
1390	return sd.proto
1391}
1392
1393// AsServiceDescriptorProto returns the underlying descriptor proto.
1394func (sd *ServiceDescriptor) AsServiceDescriptorProto() *dpb.ServiceDescriptorProto {
1395	return sd.proto
1396}
1397
1398// String returns the underlying descriptor proto, in compact text format.
1399func (sd *ServiceDescriptor) String() string {
1400	return sd.proto.String()
1401}
1402
1403// GetMethods returns all of the RPC methods for this service.
1404func (sd *ServiceDescriptor) GetMethods() []*MethodDescriptor {
1405	return sd.methods
1406}
1407
1408// FindMethodByName finds the method with the given name. If no such method exists
1409// then nil is returned.
1410func (sd *ServiceDescriptor) FindMethodByName(name string) *MethodDescriptor {
1411	fqn := fmt.Sprintf("%s.%s", sd.fqn, name)
1412	if md, ok := sd.file.symbols[fqn].(*MethodDescriptor); ok {
1413		return md
1414	} else {
1415		return nil
1416	}
1417}
1418
1419// MethodDescriptor describes an RPC method declared in a proto file.
1420type MethodDescriptor struct {
1421	proto          *dpb.MethodDescriptorProto
1422	parent         *ServiceDescriptor
1423	file           *FileDescriptor
1424	inType         *MessageDescriptor
1425	outType        *MessageDescriptor
1426	fqn            string
1427	sourceInfoPath []int32
1428}
1429
1430func createMethodDescriptor(fd *FileDescriptor, parent *ServiceDescriptor, enclosing string, md *dpb.MethodDescriptorProto) (*MethodDescriptor, string) {
1431	// request and response types get resolved later
1432	methodName := merge(enclosing, md.GetName())
1433	return &MethodDescriptor{proto: md, parent: parent, file: fd, fqn: methodName}, methodName
1434}
1435
1436func (md *MethodDescriptor) resolve(path []int32, scopes []scope) error {
1437	md.sourceInfoPath = append([]int32(nil), path...) // defensive copy
1438	if desc, err := resolve(md.file, md.proto.GetInputType(), scopes); err != nil {
1439		return err
1440	} else {
1441		md.inType = desc.(*MessageDescriptor)
1442	}
1443	if desc, err := resolve(md.file, md.proto.GetOutputType(), scopes); err != nil {
1444		return err
1445	} else {
1446		md.outType = desc.(*MessageDescriptor)
1447	}
1448	return nil
1449}
1450
1451// GetName returns the name of the method.
1452func (md *MethodDescriptor) GetName() string {
1453	return md.proto.GetName()
1454}
1455
1456// GetFullyQualifiedName returns the fully qualified name of the method. Unlike
1457// GetName, this includes fully qualified name of the enclosing service.
1458func (md *MethodDescriptor) GetFullyQualifiedName() string {
1459	return md.fqn
1460}
1461
1462// GetParent returns the descriptor for the service in which this method is
1463// defined. Most usages will prefer to use GetService, which has a concrete
1464// return type. This more generic method is present to satisfy the Descriptor
1465// interface.
1466func (md *MethodDescriptor) GetParent() Descriptor {
1467	return md.parent
1468}
1469
1470// GetService returns the RPC service in which this method is declared.
1471func (md *MethodDescriptor) GetService() *ServiceDescriptor {
1472	return md.parent
1473}
1474
1475// GetFile returns the descriptor for the file in which this method is defined.
1476func (md *MethodDescriptor) GetFile() *FileDescriptor {
1477	return md.file
1478}
1479
1480// GetOptions returns the method's options. Most usages will be more interested
1481// in GetMethodOptions, which has a concrete return type. This generic version
1482// is present to satisfy the Descriptor interface.
1483func (md *MethodDescriptor) GetOptions() proto.Message {
1484	return md.proto.GetOptions()
1485}
1486
1487// GetMethodOptions returns the method's options.
1488func (md *MethodDescriptor) GetMethodOptions() *dpb.MethodOptions {
1489	return md.proto.GetOptions()
1490}
1491
1492// GetSourceInfo returns source info for the method, if present in the
1493// descriptor. Not all descriptors will contain source info. If non-nil, the
1494// returned info contains information about the location in the file where the
1495// method was defined and also contains comments associated with the method
1496// definition.
1497func (md *MethodDescriptor) GetSourceInfo() *dpb.SourceCodeInfo_Location {
1498	return md.file.sourceInfo.Get(md.sourceInfoPath)
1499}
1500
1501// AsProto returns the underlying descriptor proto. Most usages will be more
1502// interested in AsMethodDescriptorProto, which has a concrete return type. This
1503// generic version is present to satisfy the Descriptor interface.
1504func (md *MethodDescriptor) AsProto() proto.Message {
1505	return md.proto
1506}
1507
1508// AsMethodDescriptorProto returns the underlying descriptor proto.
1509func (md *MethodDescriptor) AsMethodDescriptorProto() *dpb.MethodDescriptorProto {
1510	return md.proto
1511}
1512
1513// String returns the underlying descriptor proto, in compact text format.
1514func (md *MethodDescriptor) String() string {
1515	return md.proto.String()
1516}
1517
1518// IsServerStreaming returns true if this is a server-streaming method.
1519func (md *MethodDescriptor) IsServerStreaming() bool {
1520	return md.proto.GetServerStreaming()
1521}
1522
1523// IsClientStreaming returns true if this is a client-streaming method.
1524func (md *MethodDescriptor) IsClientStreaming() bool {
1525	return md.proto.GetClientStreaming()
1526}
1527
1528// GetInputType returns the input type, or request type, of the RPC method.
1529func (md *MethodDescriptor) GetInputType() *MessageDescriptor {
1530	return md.inType
1531}
1532
1533// GetOutputType returns the output type, or response type, of the RPC method.
1534func (md *MethodDescriptor) GetOutputType() *MessageDescriptor {
1535	return md.outType
1536}
1537
1538// OneOfDescriptor describes a one-of field set declared in a protocol buffer message.
1539type OneOfDescriptor struct {
1540	proto          *dpb.OneofDescriptorProto
1541	parent         *MessageDescriptor
1542	file           *FileDescriptor
1543	choices        []*FieldDescriptor
1544	fqn            string
1545	sourceInfoPath []int32
1546}
1547
1548func createOneOfDescriptor(fd *FileDescriptor, parent *MessageDescriptor, index int, enclosing string, od *dpb.OneofDescriptorProto) (*OneOfDescriptor, string) {
1549	oneOfName := merge(enclosing, od.GetName())
1550	ret := &OneOfDescriptor{proto: od, parent: parent, file: fd, fqn: oneOfName}
1551	for _, f := range parent.fields {
1552		oi := f.proto.OneofIndex
1553		if oi != nil && *oi == int32(index) {
1554			f.oneOf = ret
1555			ret.choices = append(ret.choices, f)
1556		}
1557	}
1558	return ret, oneOfName
1559}
1560
1561func (od *OneOfDescriptor) resolve(path []int32) {
1562	od.sourceInfoPath = append([]int32(nil), path...) // defensive copy
1563}
1564
1565// GetName returns the name of the one-of.
1566func (od *OneOfDescriptor) GetName() string {
1567	return od.proto.GetName()
1568}
1569
1570// GetFullyQualifiedName returns the fully qualified name of the one-of. Unlike
1571// GetName, this includes fully qualified name of the enclosing message.
1572func (od *OneOfDescriptor) GetFullyQualifiedName() string {
1573	return od.fqn
1574}
1575
1576// GetParent returns the descriptor for the message in which this one-of is
1577// defined. Most usages will prefer to use GetOwner, which has a concrete
1578// return type. This more generic method is present to satisfy the Descriptor
1579// interface.
1580func (od *OneOfDescriptor) GetParent() Descriptor {
1581	return od.parent
1582}
1583
1584// GetOwner returns the message to which this one-of field set belongs.
1585func (od *OneOfDescriptor) GetOwner() *MessageDescriptor {
1586	return od.parent
1587}
1588
1589// GetFile returns the descriptor for the file in which this one-fof is defined.
1590func (od *OneOfDescriptor) GetFile() *FileDescriptor {
1591	return od.file
1592}
1593
1594// GetOptions returns the one-of's options. Most usages will be more interested
1595// in GetOneOfOptions, which has a concrete return type. This generic version
1596// is present to satisfy the Descriptor interface.
1597func (od *OneOfDescriptor) GetOptions() proto.Message {
1598	return od.proto.GetOptions()
1599}
1600
1601// GetOneOfOptions returns the one-of's options.
1602func (od *OneOfDescriptor) GetOneOfOptions() *dpb.OneofOptions {
1603	return od.proto.GetOptions()
1604}
1605
1606// GetSourceInfo returns source info for the one-of, if present in the
1607// descriptor. Not all descriptors will contain source info. If non-nil, the
1608// returned info contains information about the location in the file where the
1609// one-of was defined and also contains comments associated with the one-of
1610// definition.
1611func (od *OneOfDescriptor) GetSourceInfo() *dpb.SourceCodeInfo_Location {
1612	return od.file.sourceInfo.Get(od.sourceInfoPath)
1613}
1614
1615// AsProto returns the underlying descriptor proto. Most usages will be more
1616// interested in AsOneofDescriptorProto, which has a concrete return type. This
1617// generic version is present to satisfy the Descriptor interface.
1618func (od *OneOfDescriptor) AsProto() proto.Message {
1619	return od.proto
1620}
1621
1622// AsOneofDescriptorProto returns the underlying descriptor proto.
1623func (od *OneOfDescriptor) AsOneofDescriptorProto() *dpb.OneofDescriptorProto {
1624	return od.proto
1625}
1626
1627// String returns the underlying descriptor proto, in compact text format.
1628func (od *OneOfDescriptor) String() string {
1629	return od.proto.String()
1630}
1631
1632// GetChoices returns the fields that are part of the one-of field set. At most one of
1633// these fields may be set for a given message.
1634func (od *OneOfDescriptor) GetChoices() []*FieldDescriptor {
1635	return od.choices
1636}
1637
1638func (od *OneOfDescriptor) IsSynthetic() bool {
1639	return len(od.choices) == 1 && od.choices[0].IsProto3Optional()
1640}
1641
1642// scope represents a lexical scope in a proto file in which messages and enums
1643// can be declared.
1644type scope func(string) Descriptor
1645
1646func fileScope(fd *FileDescriptor) scope {
1647	// we search symbols in this file, but also symbols in other files that have
1648	// the same package as this file or a "parent" package (in protobuf,
1649	// packages are a hierarchy like C++ namespaces)
1650	prefixes := internal.CreatePrefixList(fd.proto.GetPackage())
1651	return func(name string) Descriptor {
1652		for _, prefix := range prefixes {
1653			n := merge(prefix, name)
1654			d := findSymbol(fd, n, false)
1655			if d != nil {
1656				return d
1657			}
1658		}
1659		return nil
1660	}
1661}
1662
1663func messageScope(md *MessageDescriptor) scope {
1664	return func(name string) Descriptor {
1665		n := merge(md.fqn, name)
1666		if d, ok := md.file.symbols[n]; ok {
1667			return d
1668		}
1669		return nil
1670	}
1671}
1672
1673func resolve(fd *FileDescriptor, name string, scopes []scope) (Descriptor, error) {
1674	if strings.HasPrefix(name, ".") {
1675		// already fully-qualified
1676		d := findSymbol(fd, name[1:], false)
1677		if d != nil {
1678			return d, nil
1679		}
1680	} else {
1681		// unqualified, so we look in the enclosing (last) scope first and move
1682		// towards outermost (first) scope, trying to resolve the symbol
1683		for i := len(scopes) - 1; i >= 0; i-- {
1684			d := scopes[i](name)
1685			if d != nil {
1686				return d, nil
1687			}
1688		}
1689	}
1690	return nil, fmt.Errorf("file %q included an unresolvable reference to %q", fd.proto.GetName(), name)
1691}
1692
1693func findSymbol(fd *FileDescriptor, name string, public bool) Descriptor {
1694	d := fd.symbols[name]
1695	if d != nil {
1696		return d
1697	}
1698
1699	// When public = false, we are searching only directly imported symbols. But we
1700	// also need to search transitive public imports due to semantics of public imports.
1701	var deps []*FileDescriptor
1702	if public {
1703		deps = fd.publicDeps
1704	} else {
1705		deps = fd.deps
1706	}
1707	for _, dep := range deps {
1708		d = findSymbol(dep, name, true)
1709		if d != nil {
1710			return d
1711		}
1712	}
1713
1714	return nil
1715}
1716
1717func merge(a, b string) string {
1718	if a == "" {
1719		return b
1720	} else {
1721		return a + "." + b
1722	}
1723}
1724