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