1 | // Copyright 2019 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 |
|
---|
5 | package filedesc
|
---|
6 |
|
---|
7 | import (
|
---|
8 | "bytes"
|
---|
9 | "fmt"
|
---|
10 | "sync"
|
---|
11 | "sync/atomic"
|
---|
12 |
|
---|
13 | "google.golang.org/protobuf/internal/descfmt"
|
---|
14 | "google.golang.org/protobuf/internal/descopts"
|
---|
15 | "google.golang.org/protobuf/internal/encoding/defval"
|
---|
16 | "google.golang.org/protobuf/internal/encoding/messageset"
|
---|
17 | "google.golang.org/protobuf/internal/genid"
|
---|
18 | "google.golang.org/protobuf/internal/pragma"
|
---|
19 | "google.golang.org/protobuf/internal/strs"
|
---|
20 | "google.golang.org/protobuf/reflect/protoreflect"
|
---|
21 | "google.golang.org/protobuf/reflect/protoregistry"
|
---|
22 | )
|
---|
23 |
|
---|
24 | // The types in this file may have a suffix:
|
---|
25 | // • L0: Contains fields common to all descriptors (except File) and
|
---|
26 | // must be initialized up front.
|
---|
27 | // • L1: Contains fields specific to a descriptor and
|
---|
28 | // must be initialized up front.
|
---|
29 | // • L2: Contains fields that are lazily initialized when constructing
|
---|
30 | // from the raw file descriptor. When constructing as a literal, the L2
|
---|
31 | // fields must be initialized up front.
|
---|
32 | //
|
---|
33 | // The types are exported so that packages like reflect/protodesc can
|
---|
34 | // directly construct descriptors.
|
---|
35 |
|
---|
36 | type (
|
---|
37 | File struct {
|
---|
38 | fileRaw
|
---|
39 | L1 FileL1
|
---|
40 |
|
---|
41 | once uint32 // atomically set if L2 is valid
|
---|
42 | mu sync.Mutex // protects L2
|
---|
43 | L2 *FileL2
|
---|
44 | }
|
---|
45 | FileL1 struct {
|
---|
46 | Syntax protoreflect.Syntax
|
---|
47 | Path string
|
---|
48 | Package protoreflect.FullName
|
---|
49 |
|
---|
50 | Enums Enums
|
---|
51 | Messages Messages
|
---|
52 | Extensions Extensions
|
---|
53 | Services Services
|
---|
54 | }
|
---|
55 | FileL2 struct {
|
---|
56 | Options func() protoreflect.ProtoMessage
|
---|
57 | Imports FileImports
|
---|
58 | Locations SourceLocations
|
---|
59 | }
|
---|
60 | )
|
---|
61 |
|
---|
62 | func (fd *File) ParentFile() protoreflect.FileDescriptor { return fd }
|
---|
63 | func (fd *File) Parent() protoreflect.Descriptor { return nil }
|
---|
64 | func (fd *File) Index() int { return 0 }
|
---|
65 | func (fd *File) Syntax() protoreflect.Syntax { return fd.L1.Syntax }
|
---|
66 | func (fd *File) Name() protoreflect.Name { return fd.L1.Package.Name() }
|
---|
67 | func (fd *File) FullName() protoreflect.FullName { return fd.L1.Package }
|
---|
68 | func (fd *File) IsPlaceholder() bool { return false }
|
---|
69 | func (fd *File) Options() protoreflect.ProtoMessage {
|
---|
70 | if f := fd.lazyInit().Options; f != nil {
|
---|
71 | return f()
|
---|
72 | }
|
---|
73 | return descopts.File
|
---|
74 | }
|
---|
75 | func (fd *File) Path() string { return fd.L1.Path }
|
---|
76 | func (fd *File) Package() protoreflect.FullName { return fd.L1.Package }
|
---|
77 | func (fd *File) Imports() protoreflect.FileImports { return &fd.lazyInit().Imports }
|
---|
78 | func (fd *File) Enums() protoreflect.EnumDescriptors { return &fd.L1.Enums }
|
---|
79 | func (fd *File) Messages() protoreflect.MessageDescriptors { return &fd.L1.Messages }
|
---|
80 | func (fd *File) Extensions() protoreflect.ExtensionDescriptors { return &fd.L1.Extensions }
|
---|
81 | func (fd *File) Services() protoreflect.ServiceDescriptors { return &fd.L1.Services }
|
---|
82 | func (fd *File) SourceLocations() protoreflect.SourceLocations { return &fd.lazyInit().Locations }
|
---|
83 | func (fd *File) Format(s fmt.State, r rune) { descfmt.FormatDesc(s, r, fd) }
|
---|
84 | func (fd *File) ProtoType(protoreflect.FileDescriptor) {}
|
---|
85 | func (fd *File) ProtoInternal(pragma.DoNotImplement) {}
|
---|
86 |
|
---|
87 | func (fd *File) lazyInit() *FileL2 {
|
---|
88 | if atomic.LoadUint32(&fd.once) == 0 {
|
---|
89 | fd.lazyInitOnce()
|
---|
90 | }
|
---|
91 | return fd.L2
|
---|
92 | }
|
---|
93 |
|
---|
94 | func (fd *File) lazyInitOnce() {
|
---|
95 | fd.mu.Lock()
|
---|
96 | if fd.L2 == nil {
|
---|
97 | fd.lazyRawInit() // recursively initializes all L2 structures
|
---|
98 | }
|
---|
99 | atomic.StoreUint32(&fd.once, 1)
|
---|
100 | fd.mu.Unlock()
|
---|
101 | }
|
---|
102 |
|
---|
103 | // GoPackagePath is a pseudo-internal API for determining the Go package path
|
---|
104 | // that this file descriptor is declared in.
|
---|
105 | //
|
---|
106 | // WARNING: This method is exempt from the compatibility promise and may be
|
---|
107 | // removed in the future without warning.
|
---|
108 | func (fd *File) GoPackagePath() string {
|
---|
109 | return fd.builder.GoPackagePath
|
---|
110 | }
|
---|
111 |
|
---|
112 | type (
|
---|
113 | Enum struct {
|
---|
114 | Base
|
---|
115 | L1 EnumL1
|
---|
116 | L2 *EnumL2 // protected by fileDesc.once
|
---|
117 | }
|
---|
118 | EnumL1 struct {
|
---|
119 | eagerValues bool // controls whether EnumL2.Values is already populated
|
---|
120 | }
|
---|
121 | EnumL2 struct {
|
---|
122 | Options func() protoreflect.ProtoMessage
|
---|
123 | Values EnumValues
|
---|
124 | ReservedNames Names
|
---|
125 | ReservedRanges EnumRanges
|
---|
126 | }
|
---|
127 |
|
---|
128 | EnumValue struct {
|
---|
129 | Base
|
---|
130 | L1 EnumValueL1
|
---|
131 | }
|
---|
132 | EnumValueL1 struct {
|
---|
133 | Options func() protoreflect.ProtoMessage
|
---|
134 | Number protoreflect.EnumNumber
|
---|
135 | }
|
---|
136 | )
|
---|
137 |
|
---|
138 | func (ed *Enum) Options() protoreflect.ProtoMessage {
|
---|
139 | if f := ed.lazyInit().Options; f != nil {
|
---|
140 | return f()
|
---|
141 | }
|
---|
142 | return descopts.Enum
|
---|
143 | }
|
---|
144 | func (ed *Enum) Values() protoreflect.EnumValueDescriptors {
|
---|
145 | if ed.L1.eagerValues {
|
---|
146 | return &ed.L2.Values
|
---|
147 | }
|
---|
148 | return &ed.lazyInit().Values
|
---|
149 | }
|
---|
150 | func (ed *Enum) ReservedNames() protoreflect.Names { return &ed.lazyInit().ReservedNames }
|
---|
151 | func (ed *Enum) ReservedRanges() protoreflect.EnumRanges { return &ed.lazyInit().ReservedRanges }
|
---|
152 | func (ed *Enum) Format(s fmt.State, r rune) { descfmt.FormatDesc(s, r, ed) }
|
---|
153 | func (ed *Enum) ProtoType(protoreflect.EnumDescriptor) {}
|
---|
154 | func (ed *Enum) lazyInit() *EnumL2 {
|
---|
155 | ed.L0.ParentFile.lazyInit() // implicitly initializes L2
|
---|
156 | return ed.L2
|
---|
157 | }
|
---|
158 |
|
---|
159 | func (ed *EnumValue) Options() protoreflect.ProtoMessage {
|
---|
160 | if f := ed.L1.Options; f != nil {
|
---|
161 | return f()
|
---|
162 | }
|
---|
163 | return descopts.EnumValue
|
---|
164 | }
|
---|
165 | func (ed *EnumValue) Number() protoreflect.EnumNumber { return ed.L1.Number }
|
---|
166 | func (ed *EnumValue) Format(s fmt.State, r rune) { descfmt.FormatDesc(s, r, ed) }
|
---|
167 | func (ed *EnumValue) ProtoType(protoreflect.EnumValueDescriptor) {}
|
---|
168 |
|
---|
169 | type (
|
---|
170 | Message struct {
|
---|
171 | Base
|
---|
172 | L1 MessageL1
|
---|
173 | L2 *MessageL2 // protected by fileDesc.once
|
---|
174 | }
|
---|
175 | MessageL1 struct {
|
---|
176 | Enums Enums
|
---|
177 | Messages Messages
|
---|
178 | Extensions Extensions
|
---|
179 | IsMapEntry bool // promoted from google.protobuf.MessageOptions
|
---|
180 | IsMessageSet bool // promoted from google.protobuf.MessageOptions
|
---|
181 | }
|
---|
182 | MessageL2 struct {
|
---|
183 | Options func() protoreflect.ProtoMessage
|
---|
184 | Fields Fields
|
---|
185 | Oneofs Oneofs
|
---|
186 | ReservedNames Names
|
---|
187 | ReservedRanges FieldRanges
|
---|
188 | RequiredNumbers FieldNumbers // must be consistent with Fields.Cardinality
|
---|
189 | ExtensionRanges FieldRanges
|
---|
190 | ExtensionRangeOptions []func() protoreflect.ProtoMessage // must be same length as ExtensionRanges
|
---|
191 | }
|
---|
192 |
|
---|
193 | Field struct {
|
---|
194 | Base
|
---|
195 | L1 FieldL1
|
---|
196 | }
|
---|
197 | FieldL1 struct {
|
---|
198 | Options func() protoreflect.ProtoMessage
|
---|
199 | Number protoreflect.FieldNumber
|
---|
200 | Cardinality protoreflect.Cardinality // must be consistent with Message.RequiredNumbers
|
---|
201 | Kind protoreflect.Kind
|
---|
202 | StringName stringName
|
---|
203 | IsProto3Optional bool // promoted from google.protobuf.FieldDescriptorProto
|
---|
204 | IsWeak bool // promoted from google.protobuf.FieldOptions
|
---|
205 | HasPacked bool // promoted from google.protobuf.FieldOptions
|
---|
206 | IsPacked bool // promoted from google.protobuf.FieldOptions
|
---|
207 | HasEnforceUTF8 bool // promoted from google.protobuf.FieldOptions
|
---|
208 | EnforceUTF8 bool // promoted from google.protobuf.FieldOptions
|
---|
209 | Default defaultValue
|
---|
210 | ContainingOneof protoreflect.OneofDescriptor // must be consistent with Message.Oneofs.Fields
|
---|
211 | Enum protoreflect.EnumDescriptor
|
---|
212 | Message protoreflect.MessageDescriptor
|
---|
213 | }
|
---|
214 |
|
---|
215 | Oneof struct {
|
---|
216 | Base
|
---|
217 | L1 OneofL1
|
---|
218 | }
|
---|
219 | OneofL1 struct {
|
---|
220 | Options func() protoreflect.ProtoMessage
|
---|
221 | Fields OneofFields // must be consistent with Message.Fields.ContainingOneof
|
---|
222 | }
|
---|
223 | )
|
---|
224 |
|
---|
225 | func (md *Message) Options() protoreflect.ProtoMessage {
|
---|
226 | if f := md.lazyInit().Options; f != nil {
|
---|
227 | return f()
|
---|
228 | }
|
---|
229 | return descopts.Message
|
---|
230 | }
|
---|
231 | func (md *Message) IsMapEntry() bool { return md.L1.IsMapEntry }
|
---|
232 | func (md *Message) Fields() protoreflect.FieldDescriptors { return &md.lazyInit().Fields }
|
---|
233 | func (md *Message) Oneofs() protoreflect.OneofDescriptors { return &md.lazyInit().Oneofs }
|
---|
234 | func (md *Message) ReservedNames() protoreflect.Names { return &md.lazyInit().ReservedNames }
|
---|
235 | func (md *Message) ReservedRanges() protoreflect.FieldRanges { return &md.lazyInit().ReservedRanges }
|
---|
236 | func (md *Message) RequiredNumbers() protoreflect.FieldNumbers { return &md.lazyInit().RequiredNumbers }
|
---|
237 | func (md *Message) ExtensionRanges() protoreflect.FieldRanges { return &md.lazyInit().ExtensionRanges }
|
---|
238 | func (md *Message) ExtensionRangeOptions(i int) protoreflect.ProtoMessage {
|
---|
239 | if f := md.lazyInit().ExtensionRangeOptions[i]; f != nil {
|
---|
240 | return f()
|
---|
241 | }
|
---|
242 | return descopts.ExtensionRange
|
---|
243 | }
|
---|
244 | func (md *Message) Enums() protoreflect.EnumDescriptors { return &md.L1.Enums }
|
---|
245 | func (md *Message) Messages() protoreflect.MessageDescriptors { return &md.L1.Messages }
|
---|
246 | func (md *Message) Extensions() protoreflect.ExtensionDescriptors { return &md.L1.Extensions }
|
---|
247 | func (md *Message) ProtoType(protoreflect.MessageDescriptor) {}
|
---|
248 | func (md *Message) Format(s fmt.State, r rune) { descfmt.FormatDesc(s, r, md) }
|
---|
249 | func (md *Message) lazyInit() *MessageL2 {
|
---|
250 | md.L0.ParentFile.lazyInit() // implicitly initializes L2
|
---|
251 | return md.L2
|
---|
252 | }
|
---|
253 |
|
---|
254 | // IsMessageSet is a pseudo-internal API for checking whether a message
|
---|
255 | // should serialize in the proto1 message format.
|
---|
256 | //
|
---|
257 | // WARNING: This method is exempt from the compatibility promise and may be
|
---|
258 | // removed in the future without warning.
|
---|
259 | func (md *Message) IsMessageSet() bool {
|
---|
260 | return md.L1.IsMessageSet
|
---|
261 | }
|
---|
262 |
|
---|
263 | func (fd *Field) Options() protoreflect.ProtoMessage {
|
---|
264 | if f := fd.L1.Options; f != nil {
|
---|
265 | return f()
|
---|
266 | }
|
---|
267 | return descopts.Field
|
---|
268 | }
|
---|
269 | func (fd *Field) Number() protoreflect.FieldNumber { return fd.L1.Number }
|
---|
270 | func (fd *Field) Cardinality() protoreflect.Cardinality { return fd.L1.Cardinality }
|
---|
271 | func (fd *Field) Kind() protoreflect.Kind { return fd.L1.Kind }
|
---|
272 | func (fd *Field) HasJSONName() bool { return fd.L1.StringName.hasJSON }
|
---|
273 | func (fd *Field) JSONName() string { return fd.L1.StringName.getJSON(fd) }
|
---|
274 | func (fd *Field) TextName() string { return fd.L1.StringName.getText(fd) }
|
---|
275 | func (fd *Field) HasPresence() bool {
|
---|
276 | return fd.L1.Cardinality != protoreflect.Repeated && (fd.L0.ParentFile.L1.Syntax == protoreflect.Proto2 || fd.L1.Message != nil || fd.L1.ContainingOneof != nil)
|
---|
277 | }
|
---|
278 | func (fd *Field) HasOptionalKeyword() bool {
|
---|
279 | return (fd.L0.ParentFile.L1.Syntax == protoreflect.Proto2 && fd.L1.Cardinality == protoreflect.Optional && fd.L1.ContainingOneof == nil) || fd.L1.IsProto3Optional
|
---|
280 | }
|
---|
281 | func (fd *Field) IsPacked() bool {
|
---|
282 | if !fd.L1.HasPacked && fd.L0.ParentFile.L1.Syntax != protoreflect.Proto2 && fd.L1.Cardinality == protoreflect.Repeated {
|
---|
283 | switch fd.L1.Kind {
|
---|
284 | case protoreflect.StringKind, protoreflect.BytesKind, protoreflect.MessageKind, protoreflect.GroupKind:
|
---|
285 | default:
|
---|
286 | return true
|
---|
287 | }
|
---|
288 | }
|
---|
289 | return fd.L1.IsPacked
|
---|
290 | }
|
---|
291 | func (fd *Field) IsExtension() bool { return false }
|
---|
292 | func (fd *Field) IsWeak() bool { return fd.L1.IsWeak }
|
---|
293 | func (fd *Field) IsList() bool { return fd.Cardinality() == protoreflect.Repeated && !fd.IsMap() }
|
---|
294 | func (fd *Field) IsMap() bool { return fd.Message() != nil && fd.Message().IsMapEntry() }
|
---|
295 | func (fd *Field) MapKey() protoreflect.FieldDescriptor {
|
---|
296 | if !fd.IsMap() {
|
---|
297 | return nil
|
---|
298 | }
|
---|
299 | return fd.Message().Fields().ByNumber(genid.MapEntry_Key_field_number)
|
---|
300 | }
|
---|
301 | func (fd *Field) MapValue() protoreflect.FieldDescriptor {
|
---|
302 | if !fd.IsMap() {
|
---|
303 | return nil
|
---|
304 | }
|
---|
305 | return fd.Message().Fields().ByNumber(genid.MapEntry_Value_field_number)
|
---|
306 | }
|
---|
307 | func (fd *Field) HasDefault() bool { return fd.L1.Default.has }
|
---|
308 | func (fd *Field) Default() protoreflect.Value { return fd.L1.Default.get(fd) }
|
---|
309 | func (fd *Field) DefaultEnumValue() protoreflect.EnumValueDescriptor { return fd.L1.Default.enum }
|
---|
310 | func (fd *Field) ContainingOneof() protoreflect.OneofDescriptor { return fd.L1.ContainingOneof }
|
---|
311 | func (fd *Field) ContainingMessage() protoreflect.MessageDescriptor {
|
---|
312 | return fd.L0.Parent.(protoreflect.MessageDescriptor)
|
---|
313 | }
|
---|
314 | func (fd *Field) Enum() protoreflect.EnumDescriptor {
|
---|
315 | return fd.L1.Enum
|
---|
316 | }
|
---|
317 | func (fd *Field) Message() protoreflect.MessageDescriptor {
|
---|
318 | if fd.L1.IsWeak {
|
---|
319 | if d, _ := protoregistry.GlobalFiles.FindDescriptorByName(fd.L1.Message.FullName()); d != nil {
|
---|
320 | return d.(protoreflect.MessageDescriptor)
|
---|
321 | }
|
---|
322 | }
|
---|
323 | return fd.L1.Message
|
---|
324 | }
|
---|
325 | func (fd *Field) Format(s fmt.State, r rune) { descfmt.FormatDesc(s, r, fd) }
|
---|
326 | func (fd *Field) ProtoType(protoreflect.FieldDescriptor) {}
|
---|
327 |
|
---|
328 | // EnforceUTF8 is a pseudo-internal API to determine whether to enforce UTF-8
|
---|
329 | // validation for the string field. This exists for Google-internal use only
|
---|
330 | // since proto3 did not enforce UTF-8 validity prior to the open-source release.
|
---|
331 | // If this method does not exist, the default is to enforce valid UTF-8.
|
---|
332 | //
|
---|
333 | // WARNING: This method is exempt from the compatibility promise and may be
|
---|
334 | // removed in the future without warning.
|
---|
335 | func (fd *Field) EnforceUTF8() bool {
|
---|
336 | if fd.L1.HasEnforceUTF8 {
|
---|
337 | return fd.L1.EnforceUTF8
|
---|
338 | }
|
---|
339 | return fd.L0.ParentFile.L1.Syntax == protoreflect.Proto3
|
---|
340 | }
|
---|
341 |
|
---|
342 | func (od *Oneof) IsSynthetic() bool {
|
---|
343 | return od.L0.ParentFile.L1.Syntax == protoreflect.Proto3 && len(od.L1.Fields.List) == 1 && od.L1.Fields.List[0].HasOptionalKeyword()
|
---|
344 | }
|
---|
345 | func (od *Oneof) Options() protoreflect.ProtoMessage {
|
---|
346 | if f := od.L1.Options; f != nil {
|
---|
347 | return f()
|
---|
348 | }
|
---|
349 | return descopts.Oneof
|
---|
350 | }
|
---|
351 | func (od *Oneof) Fields() protoreflect.FieldDescriptors { return &od.L1.Fields }
|
---|
352 | func (od *Oneof) Format(s fmt.State, r rune) { descfmt.FormatDesc(s, r, od) }
|
---|
353 | func (od *Oneof) ProtoType(protoreflect.OneofDescriptor) {}
|
---|
354 |
|
---|
355 | type (
|
---|
356 | Extension struct {
|
---|
357 | Base
|
---|
358 | L1 ExtensionL1
|
---|
359 | L2 *ExtensionL2 // protected by fileDesc.once
|
---|
360 | }
|
---|
361 | ExtensionL1 struct {
|
---|
362 | Number protoreflect.FieldNumber
|
---|
363 | Extendee protoreflect.MessageDescriptor
|
---|
364 | Cardinality protoreflect.Cardinality
|
---|
365 | Kind protoreflect.Kind
|
---|
366 | }
|
---|
367 | ExtensionL2 struct {
|
---|
368 | Options func() protoreflect.ProtoMessage
|
---|
369 | StringName stringName
|
---|
370 | IsProto3Optional bool // promoted from google.protobuf.FieldDescriptorProto
|
---|
371 | IsPacked bool // promoted from google.protobuf.FieldOptions
|
---|
372 | Default defaultValue
|
---|
373 | Enum protoreflect.EnumDescriptor
|
---|
374 | Message protoreflect.MessageDescriptor
|
---|
375 | }
|
---|
376 | )
|
---|
377 |
|
---|
378 | func (xd *Extension) Options() protoreflect.ProtoMessage {
|
---|
379 | if f := xd.lazyInit().Options; f != nil {
|
---|
380 | return f()
|
---|
381 | }
|
---|
382 | return descopts.Field
|
---|
383 | }
|
---|
384 | func (xd *Extension) Number() protoreflect.FieldNumber { return xd.L1.Number }
|
---|
385 | func (xd *Extension) Cardinality() protoreflect.Cardinality { return xd.L1.Cardinality }
|
---|
386 | func (xd *Extension) Kind() protoreflect.Kind { return xd.L1.Kind }
|
---|
387 | func (xd *Extension) HasJSONName() bool { return xd.lazyInit().StringName.hasJSON }
|
---|
388 | func (xd *Extension) JSONName() string { return xd.lazyInit().StringName.getJSON(xd) }
|
---|
389 | func (xd *Extension) TextName() string { return xd.lazyInit().StringName.getText(xd) }
|
---|
390 | func (xd *Extension) HasPresence() bool { return xd.L1.Cardinality != protoreflect.Repeated }
|
---|
391 | func (xd *Extension) HasOptionalKeyword() bool {
|
---|
392 | return (xd.L0.ParentFile.L1.Syntax == protoreflect.Proto2 && xd.L1.Cardinality == protoreflect.Optional) || xd.lazyInit().IsProto3Optional
|
---|
393 | }
|
---|
394 | func (xd *Extension) IsPacked() bool { return xd.lazyInit().IsPacked }
|
---|
395 | func (xd *Extension) IsExtension() bool { return true }
|
---|
396 | func (xd *Extension) IsWeak() bool { return false }
|
---|
397 | func (xd *Extension) IsList() bool { return xd.Cardinality() == protoreflect.Repeated }
|
---|
398 | func (xd *Extension) IsMap() bool { return false }
|
---|
399 | func (xd *Extension) MapKey() protoreflect.FieldDescriptor { return nil }
|
---|
400 | func (xd *Extension) MapValue() protoreflect.FieldDescriptor { return nil }
|
---|
401 | func (xd *Extension) HasDefault() bool { return xd.lazyInit().Default.has }
|
---|
402 | func (xd *Extension) Default() protoreflect.Value { return xd.lazyInit().Default.get(xd) }
|
---|
403 | func (xd *Extension) DefaultEnumValue() protoreflect.EnumValueDescriptor {
|
---|
404 | return xd.lazyInit().Default.enum
|
---|
405 | }
|
---|
406 | func (xd *Extension) ContainingOneof() protoreflect.OneofDescriptor { return nil }
|
---|
407 | func (xd *Extension) ContainingMessage() protoreflect.MessageDescriptor { return xd.L1.Extendee }
|
---|
408 | func (xd *Extension) Enum() protoreflect.EnumDescriptor { return xd.lazyInit().Enum }
|
---|
409 | func (xd *Extension) Message() protoreflect.MessageDescriptor { return xd.lazyInit().Message }
|
---|
410 | func (xd *Extension) Format(s fmt.State, r rune) { descfmt.FormatDesc(s, r, xd) }
|
---|
411 | func (xd *Extension) ProtoType(protoreflect.FieldDescriptor) {}
|
---|
412 | func (xd *Extension) ProtoInternal(pragma.DoNotImplement) {}
|
---|
413 | func (xd *Extension) lazyInit() *ExtensionL2 {
|
---|
414 | xd.L0.ParentFile.lazyInit() // implicitly initializes L2
|
---|
415 | return xd.L2
|
---|
416 | }
|
---|
417 |
|
---|
418 | type (
|
---|
419 | Service struct {
|
---|
420 | Base
|
---|
421 | L1 ServiceL1
|
---|
422 | L2 *ServiceL2 // protected by fileDesc.once
|
---|
423 | }
|
---|
424 | ServiceL1 struct{}
|
---|
425 | ServiceL2 struct {
|
---|
426 | Options func() protoreflect.ProtoMessage
|
---|
427 | Methods Methods
|
---|
428 | }
|
---|
429 |
|
---|
430 | Method struct {
|
---|
431 | Base
|
---|
432 | L1 MethodL1
|
---|
433 | }
|
---|
434 | MethodL1 struct {
|
---|
435 | Options func() protoreflect.ProtoMessage
|
---|
436 | Input protoreflect.MessageDescriptor
|
---|
437 | Output protoreflect.MessageDescriptor
|
---|
438 | IsStreamingClient bool
|
---|
439 | IsStreamingServer bool
|
---|
440 | }
|
---|
441 | )
|
---|
442 |
|
---|
443 | func (sd *Service) Options() protoreflect.ProtoMessage {
|
---|
444 | if f := sd.lazyInit().Options; f != nil {
|
---|
445 | return f()
|
---|
446 | }
|
---|
447 | return descopts.Service
|
---|
448 | }
|
---|
449 | func (sd *Service) Methods() protoreflect.MethodDescriptors { return &sd.lazyInit().Methods }
|
---|
450 | func (sd *Service) Format(s fmt.State, r rune) { descfmt.FormatDesc(s, r, sd) }
|
---|
451 | func (sd *Service) ProtoType(protoreflect.ServiceDescriptor) {}
|
---|
452 | func (sd *Service) ProtoInternal(pragma.DoNotImplement) {}
|
---|
453 | func (sd *Service) lazyInit() *ServiceL2 {
|
---|
454 | sd.L0.ParentFile.lazyInit() // implicitly initializes L2
|
---|
455 | return sd.L2
|
---|
456 | }
|
---|
457 |
|
---|
458 | func (md *Method) Options() protoreflect.ProtoMessage {
|
---|
459 | if f := md.L1.Options; f != nil {
|
---|
460 | return f()
|
---|
461 | }
|
---|
462 | return descopts.Method
|
---|
463 | }
|
---|
464 | func (md *Method) Input() protoreflect.MessageDescriptor { return md.L1.Input }
|
---|
465 | func (md *Method) Output() protoreflect.MessageDescriptor { return md.L1.Output }
|
---|
466 | func (md *Method) IsStreamingClient() bool { return md.L1.IsStreamingClient }
|
---|
467 | func (md *Method) IsStreamingServer() bool { return md.L1.IsStreamingServer }
|
---|
468 | func (md *Method) Format(s fmt.State, r rune) { descfmt.FormatDesc(s, r, md) }
|
---|
469 | func (md *Method) ProtoType(protoreflect.MethodDescriptor) {}
|
---|
470 | func (md *Method) ProtoInternal(pragma.DoNotImplement) {}
|
---|
471 |
|
---|
472 | // Surrogate files are can be used to create standalone descriptors
|
---|
473 | // where the syntax is only information derived from the parent file.
|
---|
474 | var (
|
---|
475 | SurrogateProto2 = &File{L1: FileL1{Syntax: protoreflect.Proto2}, L2: &FileL2{}}
|
---|
476 | SurrogateProto3 = &File{L1: FileL1{Syntax: protoreflect.Proto3}, L2: &FileL2{}}
|
---|
477 | )
|
---|
478 |
|
---|
479 | type (
|
---|
480 | Base struct {
|
---|
481 | L0 BaseL0
|
---|
482 | }
|
---|
483 | BaseL0 struct {
|
---|
484 | FullName protoreflect.FullName // must be populated
|
---|
485 | ParentFile *File // must be populated
|
---|
486 | Parent protoreflect.Descriptor
|
---|
487 | Index int
|
---|
488 | }
|
---|
489 | )
|
---|
490 |
|
---|
491 | func (d *Base) Name() protoreflect.Name { return d.L0.FullName.Name() }
|
---|
492 | func (d *Base) FullName() protoreflect.FullName { return d.L0.FullName }
|
---|
493 | func (d *Base) ParentFile() protoreflect.FileDescriptor {
|
---|
494 | if d.L0.ParentFile == SurrogateProto2 || d.L0.ParentFile == SurrogateProto3 {
|
---|
495 | return nil // surrogate files are not real parents
|
---|
496 | }
|
---|
497 | return d.L0.ParentFile
|
---|
498 | }
|
---|
499 | func (d *Base) Parent() protoreflect.Descriptor { return d.L0.Parent }
|
---|
500 | func (d *Base) Index() int { return d.L0.Index }
|
---|
501 | func (d *Base) Syntax() protoreflect.Syntax { return d.L0.ParentFile.Syntax() }
|
---|
502 | func (d *Base) IsPlaceholder() bool { return false }
|
---|
503 | func (d *Base) ProtoInternal(pragma.DoNotImplement) {}
|
---|
504 |
|
---|
505 | type stringName struct {
|
---|
506 | hasJSON bool
|
---|
507 | once sync.Once
|
---|
508 | nameJSON string
|
---|
509 | nameText string
|
---|
510 | }
|
---|
511 |
|
---|
512 | // InitJSON initializes the name. It is exported for use by other internal packages.
|
---|
513 | func (s *stringName) InitJSON(name string) {
|
---|
514 | s.hasJSON = true
|
---|
515 | s.nameJSON = name
|
---|
516 | }
|
---|
517 |
|
---|
518 | func (s *stringName) lazyInit(fd protoreflect.FieldDescriptor) *stringName {
|
---|
519 | s.once.Do(func() {
|
---|
520 | if fd.IsExtension() {
|
---|
521 | // For extensions, JSON and text are formatted the same way.
|
---|
522 | var name string
|
---|
523 | if messageset.IsMessageSetExtension(fd) {
|
---|
524 | name = string("[" + fd.FullName().Parent() + "]")
|
---|
525 | } else {
|
---|
526 | name = string("[" + fd.FullName() + "]")
|
---|
527 | }
|
---|
528 | s.nameJSON = name
|
---|
529 | s.nameText = name
|
---|
530 | } else {
|
---|
531 | // Format the JSON name.
|
---|
532 | if !s.hasJSON {
|
---|
533 | s.nameJSON = strs.JSONCamelCase(string(fd.Name()))
|
---|
534 | }
|
---|
535 |
|
---|
536 | // Format the text name.
|
---|
537 | s.nameText = string(fd.Name())
|
---|
538 | if fd.Kind() == protoreflect.GroupKind {
|
---|
539 | s.nameText = string(fd.Message().Name())
|
---|
540 | }
|
---|
541 | }
|
---|
542 | })
|
---|
543 | return s
|
---|
544 | }
|
---|
545 |
|
---|
546 | func (s *stringName) getJSON(fd protoreflect.FieldDescriptor) string { return s.lazyInit(fd).nameJSON }
|
---|
547 | func (s *stringName) getText(fd protoreflect.FieldDescriptor) string { return s.lazyInit(fd).nameText }
|
---|
548 |
|
---|
549 | func DefaultValue(v protoreflect.Value, ev protoreflect.EnumValueDescriptor) defaultValue {
|
---|
550 | dv := defaultValue{has: v.IsValid(), val: v, enum: ev}
|
---|
551 | if b, ok := v.Interface().([]byte); ok {
|
---|
552 | // Store a copy of the default bytes, so that we can detect
|
---|
553 | // accidental mutations of the original value.
|
---|
554 | dv.bytes = append([]byte(nil), b...)
|
---|
555 | }
|
---|
556 | return dv
|
---|
557 | }
|
---|
558 |
|
---|
559 | func unmarshalDefault(b []byte, k protoreflect.Kind, pf *File, ed protoreflect.EnumDescriptor) defaultValue {
|
---|
560 | var evs protoreflect.EnumValueDescriptors
|
---|
561 | if k == protoreflect.EnumKind {
|
---|
562 | // If the enum is declared within the same file, be careful not to
|
---|
563 | // blindly call the Values method, lest we bind ourselves in a deadlock.
|
---|
564 | if e, ok := ed.(*Enum); ok && e.L0.ParentFile == pf {
|
---|
565 | evs = &e.L2.Values
|
---|
566 | } else {
|
---|
567 | evs = ed.Values()
|
---|
568 | }
|
---|
569 |
|
---|
570 | // If we are unable to resolve the enum dependency, use a placeholder
|
---|
571 | // enum value since we will not be able to parse the default value.
|
---|
572 | if ed.IsPlaceholder() && protoreflect.Name(b).IsValid() {
|
---|
573 | v := protoreflect.ValueOfEnum(0)
|
---|
574 | ev := PlaceholderEnumValue(ed.FullName().Parent().Append(protoreflect.Name(b)))
|
---|
575 | return DefaultValue(v, ev)
|
---|
576 | }
|
---|
577 | }
|
---|
578 |
|
---|
579 | v, ev, err := defval.Unmarshal(string(b), k, evs, defval.Descriptor)
|
---|
580 | if err != nil {
|
---|
581 | panic(err)
|
---|
582 | }
|
---|
583 | return DefaultValue(v, ev)
|
---|
584 | }
|
---|
585 |
|
---|
586 | type defaultValue struct {
|
---|
587 | has bool
|
---|
588 | val protoreflect.Value
|
---|
589 | enum protoreflect.EnumValueDescriptor
|
---|
590 | bytes []byte
|
---|
591 | }
|
---|
592 |
|
---|
593 | func (dv *defaultValue) get(fd protoreflect.FieldDescriptor) protoreflect.Value {
|
---|
594 | // Return the zero value as the default if unpopulated.
|
---|
595 | if !dv.has {
|
---|
596 | if fd.Cardinality() == protoreflect.Repeated {
|
---|
597 | return protoreflect.Value{}
|
---|
598 | }
|
---|
599 | switch fd.Kind() {
|
---|
600 | case protoreflect.BoolKind:
|
---|
601 | return protoreflect.ValueOfBool(false)
|
---|
602 | case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind:
|
---|
603 | return protoreflect.ValueOfInt32(0)
|
---|
604 | case protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind:
|
---|
605 | return protoreflect.ValueOfInt64(0)
|
---|
606 | case protoreflect.Uint32Kind, protoreflect.Fixed32Kind:
|
---|
607 | return protoreflect.ValueOfUint32(0)
|
---|
608 | case protoreflect.Uint64Kind, protoreflect.Fixed64Kind:
|
---|
609 | return protoreflect.ValueOfUint64(0)
|
---|
610 | case protoreflect.FloatKind:
|
---|
611 | return protoreflect.ValueOfFloat32(0)
|
---|
612 | case protoreflect.DoubleKind:
|
---|
613 | return protoreflect.ValueOfFloat64(0)
|
---|
614 | case protoreflect.StringKind:
|
---|
615 | return protoreflect.ValueOfString("")
|
---|
616 | case protoreflect.BytesKind:
|
---|
617 | return protoreflect.ValueOfBytes(nil)
|
---|
618 | case protoreflect.EnumKind:
|
---|
619 | if evs := fd.Enum().Values(); evs.Len() > 0 {
|
---|
620 | return protoreflect.ValueOfEnum(evs.Get(0).Number())
|
---|
621 | }
|
---|
622 | return protoreflect.ValueOfEnum(0)
|
---|
623 | }
|
---|
624 | }
|
---|
625 |
|
---|
626 | if len(dv.bytes) > 0 && !bytes.Equal(dv.bytes, dv.val.Bytes()) {
|
---|
627 | // TODO: Avoid panic if we're running with the race detector
|
---|
628 | // and instead spawn a goroutine that periodically resets
|
---|
629 | // this value back to the original to induce a race.
|
---|
630 | panic(fmt.Sprintf("detected mutation on the default bytes for %v", fd.FullName()))
|
---|
631 | }
|
---|
632 | return dv.val
|
---|
633 | }
|
---|