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