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