1// Copyright 2018 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package protoreflect
6
7// Descriptor provides a set of accessors that are common to every descriptor.
8// Each descriptor type wraps the equivalent google.protobuf.XXXDescriptorProto,
9// but provides efficient lookup and immutability.
10//
11// Each descriptor is comparable. Equality implies that the two types are
12// exactly identical. However, it is possible for the same semantically
13// identical proto type to be represented by multiple type descriptors.
14//
15// For example, suppose we have t1 and t2 which are both MessageDescriptors.
16// If t1 == t2, then the types are definitely equal and all accessors return
17// the same information. However, if t1 != t2, then it is still possible that
18// they still represent the same proto type (e.g., t1.FullName == t2.FullName).
19// This can occur if a descriptor type is created dynamically, or multiple
20// versions of the same proto type are accidentally linked into the Go binary.
21type Descriptor interface {
22	// ParentFile returns the parent file descriptor that this descriptor
23	// is declared within. The parent file for the file descriptor is itself.
24	//
25	// Support for this functionality is optional and may return nil.
26	ParentFile() FileDescriptor
27
28	// Parent returns the parent containing this descriptor declaration.
29	// The following shows the mapping from child type to possible parent types:
30	//
31	//	╔═════════════════════╤═══════════════════════════════════╗
32	//	║ Child type          │ Possible parent types             ║
33	//	╠═════════════════════╪═══════════════════════════════════╣
34	//	║ FileDescriptor      │ nil                               ║
35	//	║ MessageDescriptor   │ FileDescriptor, MessageDescriptor ║
36	//	║ FieldDescriptor     │ FileDescriptor, MessageDescriptor ║
37	//	║ OneofDescriptor     │ MessageDescriptor                 ║
38	//	║ EnumDescriptor      │ FileDescriptor, MessageDescriptor ║
39	//	║ EnumValueDescriptor │ EnumDescriptor                    ║
40	//	║ ServiceDescriptor   │ FileDescriptor                    ║
41	//	║ MethodDescriptor    │ ServiceDescriptor                 ║
42	//	╚═════════════════════╧═══════════════════════════════════╝
43	//
44	// Support for this functionality is optional and may return nil.
45	Parent() Descriptor
46
47	// Index returns the index of this descriptor within its parent.
48	// It returns 0 if the descriptor does not have a parent or if the parent
49	// is unknown.
50	Index() int
51
52	// Syntax is the protobuf syntax.
53	Syntax() Syntax // e.g., Proto2 or Proto3
54
55	// Name is the short name of the declaration (i.e., FullName.Name).
56	Name() Name // e.g., "Any"
57
58	// FullName is the fully-qualified name of the declaration.
59	//
60	// The FullName is a concatenation of the full name of the type that this
61	// type is declared within and the declaration name. For example,
62	// field "foo_field" in message "proto.package.MyMessage" is
63	// uniquely identified as "proto.package.MyMessage.foo_field".
64	// Enum values are an exception to the rule (see EnumValueDescriptor).
65	FullName() FullName // e.g., "google.protobuf.Any"
66
67	// IsPlaceholder reports whether type information is missing since a
68	// dependency is not resolved, in which case only name information is known.
69	//
70	// Placeholder types may only be returned by the following accessors
71	// as a result of unresolved dependencies or weak imports:
72	//
73	//	╔═══════════════════════════════════╤═════════════════════╗
74	//	║ Accessor                          │ Descriptor          ║
75	//	╠═══════════════════════════════════╪═════════════════════╣
76	//	║ FileImports.FileDescriptor        │ FileDescriptor      ║
77	//	║ FieldDescriptor.Enum              │ EnumDescriptor      ║
78	//	║ FieldDescriptor.Message           │ MessageDescriptor   ║
79	//	║ FieldDescriptor.DefaultEnumValue  │ EnumValueDescriptor ║
80	//	║ FieldDescriptor.ContainingMessage │ MessageDescriptor   ║
81	//	║ MethodDescriptor.Input            │ MessageDescriptor   ║
82	//	║ MethodDescriptor.Output           │ MessageDescriptor   ║
83	//	╚═══════════════════════════════════╧═════════════════════╝
84	//
85	// If true, only Name and FullName are valid.
86	// For FileDescriptor, the Path is also valid.
87	IsPlaceholder() bool
88
89	// Options returns the descriptor options. The caller must not modify
90	// the returned value.
91	//
92	// To avoid a dependency cycle, this function returns a proto.Message value.
93	// The proto message type returned for each descriptor type is as follows:
94	//	╔═════════════════════╤══════════════════════════════════════════╗
95	//	║ Go type             │ Protobuf message type                    ║
96	//	╠═════════════════════╪══════════════════════════════════════════╣
97	//	║ FileDescriptor      │ google.protobuf.FileOptions              ║
98	//	║ EnumDescriptor      │ google.protobuf.EnumOptions              ║
99	//	║ EnumValueDescriptor │ google.protobuf.EnumValueOptions         ║
100	//	║ MessageDescriptor   │ google.protobuf.MessageOptions           ║
101	//	║ FieldDescriptor     │ google.protobuf.FieldOptions             ║
102	//	║ OneofDescriptor     │ google.protobuf.OneofOptions             ║
103	//	║ ServiceDescriptor   │ google.protobuf.ServiceOptions           ║
104	//	║ MethodDescriptor    │ google.protobuf.MethodOptions            ║
105	//	╚═════════════════════╧══════════════════════════════════════════╝
106	//
107	// This method returns a typed nil-pointer if no options are present.
108	// The caller must import the descriptorpb package to use this.
109	Options() ProtoMessage
110
111	doNotImplement
112}
113
114// FileDescriptor describes the types in a complete proto file and
115// corresponds with the google.protobuf.FileDescriptorProto message.
116//
117// Top-level declarations:
118// EnumDescriptor, MessageDescriptor, FieldDescriptor, and/or ServiceDescriptor.
119type FileDescriptor interface {
120	Descriptor // Descriptor.FullName is identical to Package
121
122	// Path returns the file name, relative to the source tree root.
123	Path() string // e.g., "path/to/file.proto"
124	// Package returns the protobuf package namespace.
125	Package() FullName // e.g., "google.protobuf"
126
127	// Imports is a list of imported proto files.
128	Imports() FileImports
129
130	// Enums is a list of the top-level enum declarations.
131	Enums() EnumDescriptors
132	// Messages is a list of the top-level message declarations.
133	Messages() MessageDescriptors
134	// Extensions is a list of the top-level extension declarations.
135	Extensions() ExtensionDescriptors
136	// Services is a list of the top-level service declarations.
137	Services() ServiceDescriptors
138
139	// SourceLocations is a list of source locations.
140	SourceLocations() SourceLocations
141
142	isFileDescriptor
143}
144type isFileDescriptor interface{ ProtoType(FileDescriptor) }
145
146// FileImports is a list of file imports.
147type FileImports interface {
148	// Len reports the number of files imported by this proto file.
149	Len() int
150	// Get returns the ith FileImport. It panics if out of bounds.
151	Get(i int) FileImport
152
153	doNotImplement
154}
155
156// FileImport is the declaration for a proto file import.
157type FileImport struct {
158	// FileDescriptor is the file type for the given import.
159	// It is a placeholder descriptor if IsWeak is set or if a dependency has
160	// not been regenerated to implement the new reflection APIs.
161	FileDescriptor
162
163	// IsPublic reports whether this is a public import, which causes this file
164	// to alias declarations within the imported file. The intended use cases
165	// for this feature is the ability to move proto files without breaking
166	// existing dependencies.
167	//
168	// The current file and the imported file must be within proto package.
169	IsPublic bool
170
171	// IsWeak reports whether this is a weak import, which does not impose
172	// a direct dependency on the target file.
173	//
174	// Weak imports are a legacy proto1 feature. Equivalent behavior is
175	// achieved using proto2 extension fields or proto3 Any messages.
176	IsWeak bool
177}
178
179// MessageDescriptor describes a message and
180// corresponds with the google.protobuf.DescriptorProto message.
181//
182// Nested declarations:
183// FieldDescriptor, OneofDescriptor, FieldDescriptor, EnumDescriptor,
184// and/or MessageDescriptor.
185type MessageDescriptor interface {
186	Descriptor
187
188	// IsMapEntry indicates that this is an auto-generated message type to
189	// represent the entry type for a map field.
190	//
191	// Map entry messages have only two fields:
192	//	• a "key" field with a field number of 1
193	//	• a "value" field with a field number of 2
194	// The key and value types are determined by these two fields.
195	//
196	// If IsMapEntry is true, it implies that FieldDescriptor.IsMap is true
197	// for some field with this message type.
198	IsMapEntry() bool
199
200	// Fields is a list of nested field declarations.
201	Fields() FieldDescriptors
202	// Oneofs is a list of nested oneof declarations.
203	Oneofs() OneofDescriptors
204
205	// ReservedNames is a list of reserved field names.
206	ReservedNames() Names
207	// ReservedRanges is a list of reserved ranges of field numbers.
208	ReservedRanges() FieldRanges
209	// RequiredNumbers is a list of required field numbers.
210	// In Proto3, it is always an empty list.
211	RequiredNumbers() FieldNumbers
212	// ExtensionRanges is the field ranges used for extension fields.
213	// In Proto3, it is always an empty ranges.
214	ExtensionRanges() FieldRanges
215	// ExtensionRangeOptions returns the ith extension range options.
216	//
217	// To avoid a dependency cycle, this method returns a proto.Message value,
218	// which always contains a google.protobuf.ExtensionRangeOptions message.
219	// This method returns a typed nil-pointer if no options are present.
220	// The caller must import the descriptorpb package to use this.
221	ExtensionRangeOptions(i int) ProtoMessage
222
223	// Enums is a list of nested enum declarations.
224	Enums() EnumDescriptors
225	// Messages is a list of nested message declarations.
226	Messages() MessageDescriptors
227	// Extensions is a list of nested extension declarations.
228	Extensions() ExtensionDescriptors
229
230	isMessageDescriptor
231}
232type isMessageDescriptor interface{ ProtoType(MessageDescriptor) }
233
234// MessageType encapsulates a MessageDescriptor with a concrete Go implementation.
235type MessageType interface {
236	// New returns a newly allocated empty message.
237	New() Message
238
239	// Zero returns an empty, read-only message.
240	Zero() Message
241
242	// Descriptor returns the message descriptor.
243	//
244	// Invariant: t.Descriptor() == t.New().Descriptor()
245	Descriptor() MessageDescriptor
246}
247
248// MessageDescriptors is a list of message declarations.
249type MessageDescriptors interface {
250	// Len reports the number of messages.
251	Len() int
252	// Get returns the ith MessageDescriptor. It panics if out of bounds.
253	Get(i int) MessageDescriptor
254	// ByName returns the MessageDescriptor for a message named s.
255	// It returns nil if not found.
256	ByName(s Name) MessageDescriptor
257
258	doNotImplement
259}
260
261// FieldDescriptor describes a field within a message and
262// corresponds with the google.protobuf.FieldDescriptorProto message.
263//
264// It is used for both normal fields defined within the parent message
265// (e.g., MessageDescriptor.Fields) and fields that extend some remote message
266// (e.g., FileDescriptor.Extensions or MessageDescriptor.Extensions).
267type FieldDescriptor interface {
268	Descriptor
269
270	// Number reports the unique number for this field.
271	Number() FieldNumber
272	// Cardinality reports the cardinality for this field.
273	Cardinality() Cardinality
274	// Kind reports the basic kind for this field.
275	Kind() Kind
276
277	// HasJSONName reports whether this field has an explicitly set JSON name.
278	HasJSONName() bool
279
280	// JSONName reports the name used for JSON serialization.
281	// It is usually the camel-cased form of the field name.
282	JSONName() string
283
284	// HasPresence reports whether the field distinguishes between unpopulated
285	// and default values.
286	HasPresence() bool
287
288	// IsExtension reports whether this is an extension field. If false,
289	// then Parent and ContainingMessage refer to the same message.
290	// Otherwise, ContainingMessage and Parent likely differ.
291	IsExtension() bool
292
293	// HasOptionalKeyword reports whether the "optional" keyword was explicitly
294	// specified in the source .proto file.
295	HasOptionalKeyword() bool
296
297	// IsWeak reports whether this is a weak field, which does not impose a
298	// direct dependency on the target type.
299	// If true, then Message returns a placeholder type.
300	IsWeak() bool
301
302	// IsPacked reports whether repeated primitive numeric kinds should be
303	// serialized using a packed encoding.
304	// If true, then it implies Cardinality is Repeated.
305	IsPacked() bool
306
307	// IsList reports whether this field represents a list,
308	// where the value type for the associated field is a List.
309	// It is equivalent to checking whether Cardinality is Repeated and
310	// that IsMap reports false.
311	IsList() bool
312
313	// IsMap reports whether this field represents a map,
314	// where the value type for the associated field is a Map.
315	// It is equivalent to checking whether Cardinality is Repeated,
316	// that the Kind is MessageKind, and that Message.IsMapEntry reports true.
317	IsMap() bool
318
319	// MapKey returns the field descriptor for the key in the map entry.
320	// It returns nil if IsMap reports false.
321	MapKey() FieldDescriptor
322
323	// MapValue returns the field descriptor for the value in the map entry.
324	// It returns nil if IsMap reports false.
325	MapValue() FieldDescriptor
326
327	// HasDefault reports whether this field has a default value.
328	HasDefault() bool
329
330	// Default returns the default value for scalar fields.
331	// For proto2, it is the default value as specified in the proto file,
332	// or the zero value if unspecified.
333	// For proto3, it is always the zero value of the scalar.
334	// The Value type is determined by the Kind.
335	Default() Value
336
337	// DefaultEnumValue returns the enum value descriptor for the default value
338	// of an enum field, and is nil for any other kind of field.
339	DefaultEnumValue() EnumValueDescriptor
340
341	// ContainingOneof is the containing oneof that this field belongs to,
342	// and is nil if this field is not part of a oneof.
343	ContainingOneof() OneofDescriptor
344
345	// ContainingMessage is the containing message that this field belongs to.
346	// For extension fields, this may not necessarily be the parent message
347	// that the field is declared within.
348	ContainingMessage() MessageDescriptor
349
350	// Enum is the enum descriptor if Kind is EnumKind.
351	// It returns nil for any other Kind.
352	Enum() EnumDescriptor
353
354	// Message is the message descriptor if Kind is
355	// MessageKind or GroupKind. It returns nil for any other Kind.
356	Message() MessageDescriptor
357
358	isFieldDescriptor
359}
360type isFieldDescriptor interface{ ProtoType(FieldDescriptor) }
361
362// FieldDescriptors is a list of field declarations.
363type FieldDescriptors interface {
364	// Len reports the number of fields.
365	Len() int
366	// Get returns the ith FieldDescriptor. It panics if out of bounds.
367	Get(i int) FieldDescriptor
368	// ByName returns the FieldDescriptor for a field named s.
369	// It returns nil if not found.
370	ByName(s Name) FieldDescriptor
371	// ByJSONName returns the FieldDescriptor for a field with s as the JSON name.
372	// It returns nil if not found.
373	ByJSONName(s string) FieldDescriptor
374	// ByNumber returns the FieldDescriptor for a field numbered n.
375	// It returns nil if not found.
376	ByNumber(n FieldNumber) FieldDescriptor
377
378	doNotImplement
379}
380
381// OneofDescriptor describes a oneof field set within a given message and
382// corresponds with the google.protobuf.OneofDescriptorProto message.
383type OneofDescriptor interface {
384	Descriptor
385
386	// IsSynthetic reports whether this is a synthetic oneof created to support
387	// proto3 optional semantics. If true, Fields contains exactly one field
388	// with HasOptionalKeyword specified.
389	IsSynthetic() bool
390
391	// Fields is a list of fields belonging to this oneof.
392	Fields() FieldDescriptors
393
394	isOneofDescriptor
395}
396type isOneofDescriptor interface{ ProtoType(OneofDescriptor) }
397
398// OneofDescriptors is a list of oneof declarations.
399type OneofDescriptors interface {
400	// Len reports the number of oneof fields.
401	Len() int
402	// Get returns the ith OneofDescriptor. It panics if out of bounds.
403	Get(i int) OneofDescriptor
404	// ByName returns the OneofDescriptor for a oneof named s.
405	// It returns nil if not found.
406	ByName(s Name) OneofDescriptor
407
408	doNotImplement
409}
410
411// ExtensionDescriptor is an alias of FieldDescriptor for documentation.
412type ExtensionDescriptor = FieldDescriptor
413
414// ExtensionTypeDescriptor is an ExtensionDescriptor with an associated ExtensionType.
415type ExtensionTypeDescriptor interface {
416	ExtensionDescriptor
417
418	// Type returns the associated ExtensionType.
419	Type() ExtensionType
420
421	// Descriptor returns the plain ExtensionDescriptor without the
422	// associated ExtensionType.
423	Descriptor() ExtensionDescriptor
424}
425
426// ExtensionDescriptors is a list of field declarations.
427type ExtensionDescriptors interface {
428	// Len reports the number of fields.
429	Len() int
430	// Get returns the ith ExtensionDescriptor. It panics if out of bounds.
431	Get(i int) ExtensionDescriptor
432	// ByName returns the ExtensionDescriptor for a field named s.
433	// It returns nil if not found.
434	ByName(s Name) ExtensionDescriptor
435
436	doNotImplement
437}
438
439// ExtensionType encapsulates an ExtensionDescriptor with a concrete
440// Go implementation. The nested field descriptor must be for a extension field.
441//
442// While a normal field is a member of the parent message that it is declared
443// within (see Descriptor.Parent), an extension field is a member of some other
444// target message (see ExtensionDescriptor.Extendee) and may have no
445// relationship with the parent. However, the full name of an extension field is
446// relative to the parent that it is declared within.
447//
448// For example:
449//	syntax = "proto2";
450//	package example;
451//	message FooMessage {
452//		extensions 100 to max;
453//	}
454//	message BarMessage {
455//		extends FooMessage { optional BarMessage bar_field = 100; }
456//	}
457//
458// Field "bar_field" is an extension of FooMessage, but its full name is
459// "example.BarMessage.bar_field" instead of "example.FooMessage.bar_field".
460type ExtensionType interface {
461	// New returns a new value for the field.
462	// For scalars, this returns the default value in native Go form.
463	New() Value
464
465	// Zero returns a new value for the field.
466	// For scalars, this returns the default value in native Go form.
467	// For composite types, this returns an empty, read-only message, list, or map.
468	Zero() Value
469
470	// TypeDescriptor returns the extension type descriptor.
471	TypeDescriptor() ExtensionTypeDescriptor
472
473	// ValueOf wraps the input and returns it as a Value.
474	// ValueOf panics if the input value is invalid or not the appropriate type.
475	//
476	// ValueOf is more extensive than protoreflect.ValueOf for a given field's
477	// value as it has more type information available.
478	ValueOf(interface{}) Value
479
480	// InterfaceOf completely unwraps the Value to the underlying Go type.
481	// InterfaceOf panics if the input is nil or does not represent the
482	// appropriate underlying Go type. For composite types, it panics if the
483	// value is not mutable.
484	//
485	// InterfaceOf is able to unwrap the Value further than Value.Interface
486	// as it has more type information available.
487	InterfaceOf(Value) interface{}
488
489	// IsValidValue reports whether the Value is valid to assign to the field.
490	IsValidValue(Value) bool
491
492	// IsValidInterface reports whether the input is valid to assign to the field.
493	IsValidInterface(interface{}) bool
494}
495
496// EnumDescriptor describes an enum and
497// corresponds with the google.protobuf.EnumDescriptorProto message.
498//
499// Nested declarations:
500// EnumValueDescriptor.
501type EnumDescriptor interface {
502	Descriptor
503
504	// Values is a list of nested enum value declarations.
505	Values() EnumValueDescriptors
506
507	// ReservedNames is a list of reserved enum names.
508	ReservedNames() Names
509	// ReservedRanges is a list of reserved ranges of enum numbers.
510	ReservedRanges() EnumRanges
511
512	isEnumDescriptor
513}
514type isEnumDescriptor interface{ ProtoType(EnumDescriptor) }
515
516// EnumType encapsulates an EnumDescriptor with a concrete Go implementation.
517type EnumType interface {
518	// New returns an instance of this enum type with its value set to n.
519	New(n EnumNumber) Enum
520
521	// Descriptor returns the enum descriptor.
522	//
523	// Invariant: t.Descriptor() == t.New(0).Descriptor()
524	Descriptor() EnumDescriptor
525}
526
527// EnumDescriptors is a list of enum declarations.
528type EnumDescriptors interface {
529	// Len reports the number of enum types.
530	Len() int
531	// Get returns the ith EnumDescriptor. It panics if out of bounds.
532	Get(i int) EnumDescriptor
533	// ByName returns the EnumDescriptor for an enum named s.
534	// It returns nil if not found.
535	ByName(s Name) EnumDescriptor
536
537	doNotImplement
538}
539
540// EnumValueDescriptor describes an enum value and
541// corresponds with the google.protobuf.EnumValueDescriptorProto message.
542//
543// All other proto declarations are in the namespace of the parent.
544// However, enum values do not follow this rule and are within the namespace
545// of the parent's parent (i.e., they are a sibling of the containing enum).
546// Thus, a value named "FOO_VALUE" declared within an enum uniquely identified
547// as "proto.package.MyEnum" has a full name of "proto.package.FOO_VALUE".
548type EnumValueDescriptor interface {
549	Descriptor
550
551	// Number returns the enum value as an integer.
552	Number() EnumNumber
553
554	isEnumValueDescriptor
555}
556type isEnumValueDescriptor interface{ ProtoType(EnumValueDescriptor) }
557
558// EnumValueDescriptors is a list of enum value declarations.
559type EnumValueDescriptors interface {
560	// Len reports the number of enum values.
561	Len() int
562	// Get returns the ith EnumValueDescriptor. It panics if out of bounds.
563	Get(i int) EnumValueDescriptor
564	// ByName returns the EnumValueDescriptor for the enum value named s.
565	// It returns nil if not found.
566	ByName(s Name) EnumValueDescriptor
567	// ByNumber returns the EnumValueDescriptor for the enum value numbered n.
568	// If multiple have the same number, the first one defined is returned
569	// It returns nil if not found.
570	ByNumber(n EnumNumber) EnumValueDescriptor
571
572	doNotImplement
573}
574
575// ServiceDescriptor describes a service and
576// corresponds with the google.protobuf.ServiceDescriptorProto message.
577//
578// Nested declarations: MethodDescriptor.
579type ServiceDescriptor interface {
580	Descriptor
581
582	// Methods is a list of nested message declarations.
583	Methods() MethodDescriptors
584
585	isServiceDescriptor
586}
587type isServiceDescriptor interface{ ProtoType(ServiceDescriptor) }
588
589// ServiceDescriptors is a list of service declarations.
590type ServiceDescriptors interface {
591	// Len reports the number of services.
592	Len() int
593	// Get returns the ith ServiceDescriptor. It panics if out of bounds.
594	Get(i int) ServiceDescriptor
595	// ByName returns the ServiceDescriptor for a service named s.
596	// It returns nil if not found.
597	ByName(s Name) ServiceDescriptor
598
599	doNotImplement
600}
601
602// MethodDescriptor describes a method and
603// corresponds with the google.protobuf.MethodDescriptorProto message.
604type MethodDescriptor interface {
605	Descriptor
606
607	// Input is the input message descriptor.
608	Input() MessageDescriptor
609	// Output is the output message descriptor.
610	Output() MessageDescriptor
611	// IsStreamingClient reports whether the client streams multiple messages.
612	IsStreamingClient() bool
613	// IsStreamingServer reports whether the server streams multiple messages.
614	IsStreamingServer() bool
615
616	isMethodDescriptor
617}
618type isMethodDescriptor interface{ ProtoType(MethodDescriptor) }
619
620// MethodDescriptors is a list of method declarations.
621type MethodDescriptors interface {
622	// Len reports the number of methods.
623	Len() int
624	// Get returns the ith MethodDescriptor. It panics if out of bounds.
625	Get(i int) MethodDescriptor
626	// ByName returns the MethodDescriptor for a service method named s.
627	// It returns nil if not found.
628	ByName(s Name) MethodDescriptor
629
630	doNotImplement
631}
632