desc_lazy.go raw
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 "reflect"
9 "sync"
10
11 "google.golang.org/protobuf/encoding/protowire"
12 "google.golang.org/protobuf/internal/descopts"
13 "google.golang.org/protobuf/internal/genid"
14 "google.golang.org/protobuf/internal/strs"
15 "google.golang.org/protobuf/proto"
16 "google.golang.org/protobuf/reflect/protoreflect"
17 )
18
19 func (fd *File) lazyRawInit() {
20 fd.unmarshalFull(fd.builder.RawDescriptor)
21 fd.resolveMessages()
22 fd.resolveExtensions()
23 fd.resolveServices()
24 }
25
26 func (file *File) resolveMessages() {
27 var depIdx int32
28 for i := range file.allMessages {
29 md := &file.allMessages[i]
30
31 // Resolve message field dependencies.
32 for j := range md.L2.Fields.List {
33 fd := &md.L2.Fields.List[j]
34
35 // Resolve message field dependency.
36 switch fd.L1.Kind {
37 case protoreflect.EnumKind:
38 fd.L1.Enum = file.resolveEnumDependency(fd.L1.Enum, listFieldDeps, depIdx)
39 depIdx++
40 case protoreflect.MessageKind, protoreflect.GroupKind:
41 fd.L1.Message = file.resolveMessageDependency(fd.L1.Message, listFieldDeps, depIdx)
42 depIdx++
43 if fd.L1.Kind == protoreflect.GroupKind && (fd.IsMap() || fd.IsMapEntry()) {
44 // A map field might inherit delimited encoding from a file-wide default feature.
45 // But maps never actually use delimited encoding. (At least for now...)
46 fd.L1.Kind = protoreflect.MessageKind
47 }
48 }
49
50 // Default is resolved here since it depends on Enum being resolved.
51 if v := fd.L1.Default.val; v.IsValid() {
52 fd.L1.Default = unmarshalDefault(v.Bytes(), fd.L1.Kind, file, fd.L1.Enum)
53 }
54 }
55 }
56 }
57
58 func (file *File) resolveExtensions() {
59 var depIdx int32
60 for i := range file.allExtensions {
61 xd := &file.allExtensions[i]
62
63 // Resolve extension field dependency.
64 switch xd.L1.Kind {
65 case protoreflect.EnumKind:
66 xd.L2.Enum = file.resolveEnumDependency(xd.L2.Enum, listExtDeps, depIdx)
67 depIdx++
68 case protoreflect.MessageKind, protoreflect.GroupKind:
69 xd.L2.Message = file.resolveMessageDependency(xd.L2.Message, listExtDeps, depIdx)
70 depIdx++
71 }
72
73 // Default is resolved here since it depends on Enum being resolved.
74 if v := xd.L2.Default.val; v.IsValid() {
75 xd.L2.Default = unmarshalDefault(v.Bytes(), xd.L1.Kind, file, xd.L2.Enum)
76 }
77 }
78 }
79
80 func (file *File) resolveServices() {
81 var depIdx int32
82 for i := range file.allServices {
83 sd := &file.allServices[i]
84
85 // Resolve method dependencies.
86 for j := range sd.L2.Methods.List {
87 md := &sd.L2.Methods.List[j]
88 md.L1.Input = file.resolveMessageDependency(md.L1.Input, listMethInDeps, depIdx)
89 md.L1.Output = file.resolveMessageDependency(md.L1.Output, listMethOutDeps, depIdx)
90 depIdx++
91 }
92 }
93 }
94
95 func (file *File) resolveEnumDependency(ed protoreflect.EnumDescriptor, i, j int32) protoreflect.EnumDescriptor {
96 r := file.builder.FileRegistry
97 if r, ok := r.(resolverByIndex); ok {
98 if ed2 := r.FindEnumByIndex(i, j, file.allEnums, file.allMessages); ed2 != nil {
99 return ed2
100 }
101 }
102 for i := range file.allEnums {
103 if ed2 := &file.allEnums[i]; ed2.L0.FullName == ed.FullName() {
104 return ed2
105 }
106 }
107 if d, _ := r.FindDescriptorByName(ed.FullName()); d != nil {
108 return d.(protoreflect.EnumDescriptor)
109 }
110 return ed
111 }
112
113 func (file *File) resolveMessageDependency(md protoreflect.MessageDescriptor, i, j int32) protoreflect.MessageDescriptor {
114 r := file.builder.FileRegistry
115 if r, ok := r.(resolverByIndex); ok {
116 if md2 := r.FindMessageByIndex(i, j, file.allEnums, file.allMessages); md2 != nil {
117 return md2
118 }
119 }
120 for i := range file.allMessages {
121 if md2 := &file.allMessages[i]; md2.L0.FullName == md.FullName() {
122 return md2
123 }
124 }
125 if d, _ := r.FindDescriptorByName(md.FullName()); d != nil {
126 return d.(protoreflect.MessageDescriptor)
127 }
128 return md
129 }
130
131 func (fd *File) unmarshalFull(b []byte) {
132 sb := getBuilder()
133 defer putBuilder(sb)
134
135 var enumIdx, messageIdx, extensionIdx, serviceIdx int
136 var rawOptions []byte
137 var optionImports []string
138 fd.L2 = new(FileL2)
139 for len(b) > 0 {
140 num, typ, n := protowire.ConsumeTag(b)
141 b = b[n:]
142 switch typ {
143 case protowire.VarintType:
144 v, m := protowire.ConsumeVarint(b)
145 b = b[m:]
146 switch num {
147 case genid.FileDescriptorProto_PublicDependency_field_number:
148 fd.L2.Imports[v].IsPublic = true
149 }
150 case protowire.BytesType:
151 v, m := protowire.ConsumeBytes(b)
152 b = b[m:]
153 switch num {
154 case genid.FileDescriptorProto_Dependency_field_number:
155 path := sb.MakeString(v)
156 imp, _ := fd.builder.FileRegistry.FindFileByPath(path)
157 if imp == nil {
158 imp = PlaceholderFile(path)
159 }
160 fd.L2.Imports = append(fd.L2.Imports, protoreflect.FileImport{FileDescriptor: imp})
161 case genid.FileDescriptorProto_OptionDependency_field_number:
162 optionImports = append(optionImports, sb.MakeString(v))
163 case genid.FileDescriptorProto_EnumType_field_number:
164 fd.L1.Enums.List[enumIdx].unmarshalFull(v, sb)
165 enumIdx++
166 case genid.FileDescriptorProto_MessageType_field_number:
167 fd.L1.Messages.List[messageIdx].unmarshalFull(v, sb)
168 messageIdx++
169 case genid.FileDescriptorProto_Extension_field_number:
170 fd.L1.Extensions.List[extensionIdx].unmarshalFull(v, sb)
171 extensionIdx++
172 case genid.FileDescriptorProto_Service_field_number:
173 fd.L1.Services.List[serviceIdx].unmarshalFull(v, sb)
174 serviceIdx++
175 case genid.FileDescriptorProto_Options_field_number:
176 rawOptions = appendOptions(rawOptions, v)
177 }
178 default:
179 m := protowire.ConsumeFieldValue(num, typ, b)
180 b = b[m:]
181 }
182 }
183 fd.L2.Options = fd.builder.optionsUnmarshaler(&descopts.File, rawOptions)
184 if len(optionImports) > 0 {
185 var imps FileImports
186 var once sync.Once
187 fd.L2.OptionImports = func() protoreflect.FileImports {
188 once.Do(func() {
189 imps = make(FileImports, len(optionImports))
190 for i, path := range optionImports {
191 imp, _ := fd.builder.FileRegistry.FindFileByPath(path)
192 if imp == nil {
193 imp = PlaceholderFile(path)
194 }
195 imps[i] = protoreflect.FileImport{FileDescriptor: imp}
196 }
197 })
198 return &imps
199 }
200 }
201 }
202
203 func (ed *Enum) unmarshalFull(b []byte, sb *strs.Builder) {
204 var rawValues [][]byte
205 var rawOptions []byte
206 if !ed.L1.eagerValues {
207 ed.L2 = new(EnumL2)
208 }
209 for len(b) > 0 {
210 num, typ, n := protowire.ConsumeTag(b)
211 b = b[n:]
212 switch typ {
213 case protowire.BytesType:
214 v, m := protowire.ConsumeBytes(b)
215 b = b[m:]
216 switch num {
217 case genid.EnumDescriptorProto_Value_field_number:
218 rawValues = append(rawValues, v)
219 case genid.EnumDescriptorProto_ReservedName_field_number:
220 ed.L2.ReservedNames.List = append(ed.L2.ReservedNames.List, protoreflect.Name(sb.MakeString(v)))
221 case genid.EnumDescriptorProto_ReservedRange_field_number:
222 ed.L2.ReservedRanges.List = append(ed.L2.ReservedRanges.List, unmarshalEnumReservedRange(v))
223 case genid.EnumDescriptorProto_Options_field_number:
224 rawOptions = appendOptions(rawOptions, v)
225 }
226 default:
227 m := protowire.ConsumeFieldValue(num, typ, b)
228 b = b[m:]
229 }
230 }
231 if !ed.L1.eagerValues && len(rawValues) > 0 {
232 ed.L2.Values.List = make([]EnumValue, len(rawValues))
233 for i, b := range rawValues {
234 ed.L2.Values.List[i].unmarshalFull(b, sb, ed.L0.ParentFile, ed, i)
235 }
236 }
237 ed.L2.Options = ed.L0.ParentFile.builder.optionsUnmarshaler(&descopts.Enum, rawOptions)
238 }
239
240 func unmarshalEnumReservedRange(b []byte) (r [2]protoreflect.EnumNumber) {
241 for len(b) > 0 {
242 num, typ, n := protowire.ConsumeTag(b)
243 b = b[n:]
244 switch typ {
245 case protowire.VarintType:
246 v, m := protowire.ConsumeVarint(b)
247 b = b[m:]
248 switch num {
249 case genid.EnumDescriptorProto_EnumReservedRange_Start_field_number:
250 r[0] = protoreflect.EnumNumber(v)
251 case genid.EnumDescriptorProto_EnumReservedRange_End_field_number:
252 r[1] = protoreflect.EnumNumber(v)
253 }
254 default:
255 m := protowire.ConsumeFieldValue(num, typ, b)
256 b = b[m:]
257 }
258 }
259 return r
260 }
261
262 func (vd *EnumValue) unmarshalFull(b []byte, sb *strs.Builder, pf *File, pd protoreflect.Descriptor, i int) {
263 vd.L0.ParentFile = pf
264 vd.L0.Parent = pd
265 vd.L0.Index = i
266
267 var rawOptions []byte
268 for len(b) > 0 {
269 num, typ, n := protowire.ConsumeTag(b)
270 b = b[n:]
271 switch typ {
272 case protowire.VarintType:
273 v, m := protowire.ConsumeVarint(b)
274 b = b[m:]
275 switch num {
276 case genid.EnumValueDescriptorProto_Number_field_number:
277 vd.L1.Number = protoreflect.EnumNumber(v)
278 }
279 case protowire.BytesType:
280 v, m := protowire.ConsumeBytes(b)
281 b = b[m:]
282 switch num {
283 case genid.EnumValueDescriptorProto_Name_field_number:
284 // NOTE: Enum values are in the same scope as the enum parent.
285 vd.L0.FullName = appendFullName(sb, pd.Parent().FullName(), v)
286 case genid.EnumValueDescriptorProto_Options_field_number:
287 rawOptions = appendOptions(rawOptions, v)
288 }
289 default:
290 m := protowire.ConsumeFieldValue(num, typ, b)
291 b = b[m:]
292 }
293 }
294 vd.L1.Options = pf.builder.optionsUnmarshaler(&descopts.EnumValue, rawOptions)
295 }
296
297 func (md *Message) unmarshalFull(b []byte, sb *strs.Builder) {
298 var rawFields, rawOneofs [][]byte
299 var enumIdx, messageIdx, extensionIdx int
300 var rawOptions []byte
301 md.L2 = new(MessageL2)
302 for len(b) > 0 {
303 num, typ, n := protowire.ConsumeTag(b)
304 b = b[n:]
305 switch typ {
306 case protowire.BytesType:
307 v, m := protowire.ConsumeBytes(b)
308 b = b[m:]
309 switch num {
310 case genid.DescriptorProto_Field_field_number:
311 rawFields = append(rawFields, v)
312 case genid.DescriptorProto_OneofDecl_field_number:
313 rawOneofs = append(rawOneofs, v)
314 case genid.DescriptorProto_ReservedName_field_number:
315 md.L2.ReservedNames.List = append(md.L2.ReservedNames.List, protoreflect.Name(sb.MakeString(v)))
316 case genid.DescriptorProto_ReservedRange_field_number:
317 md.L2.ReservedRanges.List = append(md.L2.ReservedRanges.List, unmarshalMessageReservedRange(v))
318 case genid.DescriptorProto_ExtensionRange_field_number:
319 r, rawOptions := unmarshalMessageExtensionRange(v)
320 opts := md.L0.ParentFile.builder.optionsUnmarshaler(&descopts.ExtensionRange, rawOptions)
321 md.L2.ExtensionRanges.List = append(md.L2.ExtensionRanges.List, r)
322 md.L2.ExtensionRangeOptions = append(md.L2.ExtensionRangeOptions, opts)
323 case genid.DescriptorProto_EnumType_field_number:
324 md.L1.Enums.List[enumIdx].unmarshalFull(v, sb)
325 enumIdx++
326 case genid.DescriptorProto_NestedType_field_number:
327 md.L1.Messages.List[messageIdx].unmarshalFull(v, sb)
328 messageIdx++
329 case genid.DescriptorProto_Extension_field_number:
330 md.L1.Extensions.List[extensionIdx].unmarshalFull(v, sb)
331 extensionIdx++
332 case genid.DescriptorProto_Options_field_number:
333 rawOptions = appendOptions(rawOptions, v)
334 }
335 default:
336 m := protowire.ConsumeFieldValue(num, typ, b)
337 b = b[m:]
338 }
339 }
340 if len(rawFields) > 0 || len(rawOneofs) > 0 {
341 md.L2.Fields.List = make([]Field, len(rawFields))
342 md.L2.Oneofs.List = make([]Oneof, len(rawOneofs))
343 for i, b := range rawFields {
344 fd := &md.L2.Fields.List[i]
345 fd.unmarshalFull(b, sb, md.L0.ParentFile, md, i)
346 if fd.L1.Cardinality == protoreflect.Required {
347 md.L2.RequiredNumbers.List = append(md.L2.RequiredNumbers.List, fd.L1.Number)
348 }
349 }
350 for i, b := range rawOneofs {
351 od := &md.L2.Oneofs.List[i]
352 od.unmarshalFull(b, sb, md.L0.ParentFile, md, i)
353 }
354 }
355 md.L2.Options = md.L0.ParentFile.builder.optionsUnmarshaler(&descopts.Message, rawOptions)
356 }
357
358 func unmarshalMessageReservedRange(b []byte) (r [2]protoreflect.FieldNumber) {
359 for len(b) > 0 {
360 num, typ, n := protowire.ConsumeTag(b)
361 b = b[n:]
362 switch typ {
363 case protowire.VarintType:
364 v, m := protowire.ConsumeVarint(b)
365 b = b[m:]
366 switch num {
367 case genid.DescriptorProto_ReservedRange_Start_field_number:
368 r[0] = protoreflect.FieldNumber(v)
369 case genid.DescriptorProto_ReservedRange_End_field_number:
370 r[1] = protoreflect.FieldNumber(v)
371 }
372 default:
373 m := protowire.ConsumeFieldValue(num, typ, b)
374 b = b[m:]
375 }
376 }
377 return r
378 }
379
380 func unmarshalMessageExtensionRange(b []byte) (r [2]protoreflect.FieldNumber, rawOptions []byte) {
381 for len(b) > 0 {
382 num, typ, n := protowire.ConsumeTag(b)
383 b = b[n:]
384 switch typ {
385 case protowire.VarintType:
386 v, m := protowire.ConsumeVarint(b)
387 b = b[m:]
388 switch num {
389 case genid.DescriptorProto_ExtensionRange_Start_field_number:
390 r[0] = protoreflect.FieldNumber(v)
391 case genid.DescriptorProto_ExtensionRange_End_field_number:
392 r[1] = protoreflect.FieldNumber(v)
393 }
394 case protowire.BytesType:
395 v, m := protowire.ConsumeBytes(b)
396 b = b[m:]
397 switch num {
398 case genid.DescriptorProto_ExtensionRange_Options_field_number:
399 rawOptions = appendOptions(rawOptions, v)
400 }
401 default:
402 m := protowire.ConsumeFieldValue(num, typ, b)
403 b = b[m:]
404 }
405 }
406 return r, rawOptions
407 }
408
409 func (fd *Field) unmarshalFull(b []byte, sb *strs.Builder, pf *File, pd protoreflect.Descriptor, i int) {
410 fd.L0.ParentFile = pf
411 fd.L0.Parent = pd
412 fd.L0.Index = i
413 fd.L1.EditionFeatures = featuresFromParentDesc(fd.Parent())
414
415 var rawTypeName []byte
416 var rawOptions []byte
417 for len(b) > 0 {
418 num, typ, n := protowire.ConsumeTag(b)
419 b = b[n:]
420 switch typ {
421 case protowire.VarintType:
422 v, m := protowire.ConsumeVarint(b)
423 b = b[m:]
424 switch num {
425 case genid.FieldDescriptorProto_Number_field_number:
426 fd.L1.Number = protoreflect.FieldNumber(v)
427 case genid.FieldDescriptorProto_Label_field_number:
428 fd.L1.Cardinality = protoreflect.Cardinality(v)
429 case genid.FieldDescriptorProto_Type_field_number:
430 fd.L1.Kind = protoreflect.Kind(v)
431 case genid.FieldDescriptorProto_OneofIndex_field_number:
432 // In Message.unmarshalFull, we allocate slices for both
433 // the field and oneof descriptors before unmarshaling either
434 // of them. This ensures pointers to slice elements are stable.
435 od := &pd.(*Message).L2.Oneofs.List[v]
436 od.L1.Fields.List = append(od.L1.Fields.List, fd)
437 if fd.L1.ContainingOneof != nil {
438 panic("oneof type already set")
439 }
440 fd.L1.ContainingOneof = od
441 case genid.FieldDescriptorProto_Proto3Optional_field_number:
442 fd.L1.IsProto3Optional = protowire.DecodeBool(v)
443 }
444 case protowire.BytesType:
445 v, m := protowire.ConsumeBytes(b)
446 b = b[m:]
447 switch num {
448 case genid.FieldDescriptorProto_Name_field_number:
449 fd.L0.FullName = appendFullName(sb, pd.FullName(), v)
450 case genid.FieldDescriptorProto_JsonName_field_number:
451 fd.L1.StringName.InitJSON(sb.MakeString(v))
452 case genid.FieldDescriptorProto_DefaultValue_field_number:
453 fd.L1.Default.val = protoreflect.ValueOfBytes(v) // temporarily store as bytes; later resolved in resolveMessages
454 case genid.FieldDescriptorProto_TypeName_field_number:
455 rawTypeName = v
456 case genid.FieldDescriptorProto_Options_field_number:
457 fd.unmarshalOptions(v)
458 rawOptions = appendOptions(rawOptions, v)
459 }
460 default:
461 m := protowire.ConsumeFieldValue(num, typ, b)
462 b = b[m:]
463 }
464 }
465 if fd.L1.Kind == protoreflect.MessageKind && fd.L1.EditionFeatures.IsDelimitedEncoded {
466 fd.L1.Kind = protoreflect.GroupKind
467 }
468 if fd.L1.EditionFeatures.IsLegacyRequired {
469 fd.L1.Cardinality = protoreflect.Required
470 }
471 if rawTypeName != nil {
472 name := makeFullName(sb, rawTypeName)
473 switch fd.L1.Kind {
474 case protoreflect.EnumKind:
475 fd.L1.Enum = PlaceholderEnum(name)
476 case protoreflect.MessageKind, protoreflect.GroupKind:
477 fd.L1.Message = PlaceholderMessage(name)
478 }
479 }
480 fd.L1.Options = pf.builder.optionsUnmarshaler(&descopts.Field, rawOptions)
481 }
482
483 func (fd *Field) unmarshalOptions(b []byte) {
484 const FieldOptions_EnforceUTF8 = 13
485
486 for len(b) > 0 {
487 num, typ, n := protowire.ConsumeTag(b)
488 b = b[n:]
489 switch typ {
490 case protowire.VarintType:
491 v, m := protowire.ConsumeVarint(b)
492 b = b[m:]
493 switch num {
494 case genid.FieldOptions_Packed_field_number:
495 fd.L1.EditionFeatures.IsPacked = protowire.DecodeBool(v)
496 case genid.FieldOptions_Lazy_field_number:
497 fd.L1.IsLazy = protowire.DecodeBool(v)
498 case FieldOptions_EnforceUTF8:
499 fd.L1.EditionFeatures.IsUTF8Validated = protowire.DecodeBool(v)
500 }
501 case protowire.BytesType:
502 v, m := protowire.ConsumeBytes(b)
503 b = b[m:]
504 switch num {
505 case genid.FieldOptions_Features_field_number:
506 fd.L1.EditionFeatures = unmarshalFeatureSet(v, fd.L1.EditionFeatures)
507 }
508 default:
509 m := protowire.ConsumeFieldValue(num, typ, b)
510 b = b[m:]
511 }
512 }
513 }
514
515 func (od *Oneof) unmarshalFull(b []byte, sb *strs.Builder, pf *File, pd protoreflect.Descriptor, i int) {
516 od.L0.ParentFile = pf
517 od.L0.Parent = pd
518 od.L0.Index = i
519
520 var rawOptions []byte
521 for len(b) > 0 {
522 num, typ, n := protowire.ConsumeTag(b)
523 b = b[n:]
524 switch typ {
525 case protowire.BytesType:
526 v, m := protowire.ConsumeBytes(b)
527 b = b[m:]
528 switch num {
529 case genid.OneofDescriptorProto_Name_field_number:
530 od.L0.FullName = appendFullName(sb, pd.FullName(), v)
531 case genid.OneofDescriptorProto_Options_field_number:
532 rawOptions = appendOptions(rawOptions, v)
533 }
534 default:
535 m := protowire.ConsumeFieldValue(num, typ, b)
536 b = b[m:]
537 }
538 }
539 od.L1.Options = pf.builder.optionsUnmarshaler(&descopts.Oneof, rawOptions)
540 }
541
542 func (xd *Extension) unmarshalFull(b []byte, sb *strs.Builder) {
543 var rawTypeName []byte
544 var rawOptions []byte
545 xd.L2 = new(ExtensionL2)
546 for len(b) > 0 {
547 num, typ, n := protowire.ConsumeTag(b)
548 b = b[n:]
549 switch typ {
550 case protowire.VarintType:
551 v, m := protowire.ConsumeVarint(b)
552 b = b[m:]
553 switch num {
554 case genid.FieldDescriptorProto_Proto3Optional_field_number:
555 xd.L2.IsProto3Optional = protowire.DecodeBool(v)
556 }
557 case protowire.BytesType:
558 v, m := protowire.ConsumeBytes(b)
559 b = b[m:]
560 switch num {
561 case genid.FieldDescriptorProto_JsonName_field_number:
562 xd.L2.StringName.InitJSON(sb.MakeString(v))
563 case genid.FieldDescriptorProto_DefaultValue_field_number:
564 xd.L2.Default.val = protoreflect.ValueOfBytes(v) // temporarily store as bytes; later resolved in resolveExtensions
565 case genid.FieldDescriptorProto_TypeName_field_number:
566 rawTypeName = v
567 case genid.FieldDescriptorProto_Options_field_number:
568 rawOptions = appendOptions(rawOptions, v)
569 }
570 default:
571 m := protowire.ConsumeFieldValue(num, typ, b)
572 b = b[m:]
573 }
574 }
575 if rawTypeName != nil {
576 name := makeFullName(sb, rawTypeName)
577 switch xd.L1.Kind {
578 case protoreflect.EnumKind:
579 xd.L2.Enum = PlaceholderEnum(name)
580 case protoreflect.MessageKind, protoreflect.GroupKind:
581 xd.L2.Message = PlaceholderMessage(name)
582 }
583 }
584 xd.L2.Options = xd.L0.ParentFile.builder.optionsUnmarshaler(&descopts.Field, rawOptions)
585 }
586
587 func (sd *Service) unmarshalFull(b []byte, sb *strs.Builder) {
588 var rawMethods [][]byte
589 var rawOptions []byte
590 sd.L2 = new(ServiceL2)
591 for len(b) > 0 {
592 num, typ, n := protowire.ConsumeTag(b)
593 b = b[n:]
594 switch typ {
595 case protowire.BytesType:
596 v, m := protowire.ConsumeBytes(b)
597 b = b[m:]
598 switch num {
599 case genid.ServiceDescriptorProto_Method_field_number:
600 rawMethods = append(rawMethods, v)
601 case genid.ServiceDescriptorProto_Options_field_number:
602 rawOptions = appendOptions(rawOptions, v)
603 }
604 default:
605 m := protowire.ConsumeFieldValue(num, typ, b)
606 b = b[m:]
607 }
608 }
609 if len(rawMethods) > 0 {
610 sd.L2.Methods.List = make([]Method, len(rawMethods))
611 for i, b := range rawMethods {
612 sd.L2.Methods.List[i].unmarshalFull(b, sb, sd.L0.ParentFile, sd, i)
613 }
614 }
615 sd.L2.Options = sd.L0.ParentFile.builder.optionsUnmarshaler(&descopts.Service, rawOptions)
616 }
617
618 func (md *Method) unmarshalFull(b []byte, sb *strs.Builder, pf *File, pd protoreflect.Descriptor, i int) {
619 md.L0.ParentFile = pf
620 md.L0.Parent = pd
621 md.L0.Index = i
622
623 var rawOptions []byte
624 for len(b) > 0 {
625 num, typ, n := protowire.ConsumeTag(b)
626 b = b[n:]
627 switch typ {
628 case protowire.VarintType:
629 v, m := protowire.ConsumeVarint(b)
630 b = b[m:]
631 switch num {
632 case genid.MethodDescriptorProto_ClientStreaming_field_number:
633 md.L1.IsStreamingClient = protowire.DecodeBool(v)
634 case genid.MethodDescriptorProto_ServerStreaming_field_number:
635 md.L1.IsStreamingServer = protowire.DecodeBool(v)
636 }
637 case protowire.BytesType:
638 v, m := protowire.ConsumeBytes(b)
639 b = b[m:]
640 switch num {
641 case genid.MethodDescriptorProto_Name_field_number:
642 md.L0.FullName = appendFullName(sb, pd.FullName(), v)
643 case genid.MethodDescriptorProto_InputType_field_number:
644 md.L1.Input = PlaceholderMessage(makeFullName(sb, v))
645 case genid.MethodDescriptorProto_OutputType_field_number:
646 md.L1.Output = PlaceholderMessage(makeFullName(sb, v))
647 case genid.MethodDescriptorProto_Options_field_number:
648 rawOptions = appendOptions(rawOptions, v)
649 }
650 default:
651 m := protowire.ConsumeFieldValue(num, typ, b)
652 b = b[m:]
653 }
654 }
655 md.L1.Options = pf.builder.optionsUnmarshaler(&descopts.Method, rawOptions)
656 }
657
658 // appendOptions appends src to dst, where the returned slice is never nil.
659 // This is necessary to distinguish between empty and unpopulated options.
660 func appendOptions(dst, src []byte) []byte {
661 if dst == nil {
662 dst = []byte{}
663 }
664 return append(dst, src...)
665 }
666
667 // optionsUnmarshaler constructs a lazy unmarshal function for an options message.
668 //
669 // The type of message to unmarshal to is passed as a pointer since the
670 // vars in descopts may not yet be populated at the time this function is called.
671 func (db *Builder) optionsUnmarshaler(p *protoreflect.ProtoMessage, b []byte) func() protoreflect.ProtoMessage {
672 if b == nil {
673 return nil
674 }
675 var opts protoreflect.ProtoMessage
676 var once sync.Once
677 return func() protoreflect.ProtoMessage {
678 once.Do(func() {
679 if *p == nil {
680 panic("Descriptor.Options called without importing the descriptor package")
681 }
682 opts = reflect.New(reflect.TypeOf(*p).Elem()).Interface().(protoreflect.ProtoMessage)
683 if err := (proto.UnmarshalOptions{
684 AllowPartial: true,
685 Resolver: db.TypeResolver,
686 }).Unmarshal(b, opts); err != nil {
687 panic(err)
688 }
689 })
690 return opts
691 }
692 }
693