blob: 9fc5b1bbb0f12d167787831349161e37c1db6dde [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
Joe Tsaie407ee12019-06-24 16:19:06 -070036 if d, _ := r.FindDescriptorByName(fd.L1.Message.FullName()); d != nil {
37 fd.L1.Message = d.(pref.MessageDescriptor)
Joe Tsaid8881392019-06-06 13:01:53 -070038 }
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 }
Joe Tsaie407ee12019-06-24 16:19:06 -0700109 if d, _ := r.FindDescriptorByName(ed.FullName()); d != nil {
110 return d.(pref.EnumDescriptor)
Joe Tsaid8881392019-06-06 13:01:53 -0700111 }
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 }
Joe Tsaie407ee12019-06-24 16:19:06 -0700127 if d, _ := r.FindDescriptorByName(md.FullName()); d != nil {
128 return d.(pref.MessageDescriptor)
Joe Tsaid8881392019-06-06 13:01:53 -0700129 }
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
Joe Tsai42413972019-06-21 14:25:16 -0700190 if !ed.L1.eagerValues {
191 ed.L2 = new(EnumL2)
192 }
Joe Tsaid8881392019-06-06 13:01:53 -0700193 for len(b) > 0 {
194 num, typ, n := wire.ConsumeTag(b)
195 b = b[n:]
196 switch typ {
197 case wire.BytesType:
198 v, m := wire.ConsumeBytes(b)
199 b = b[m:]
200 switch num {
201 case fieldnum.EnumDescriptorProto_Value:
202 rawValues = append(rawValues, v)
203 case fieldnum.EnumDescriptorProto_ReservedName:
204 ed.L2.ReservedNames.List = append(ed.L2.ReservedNames.List, pref.Name(nb.MakeString(v)))
205 case fieldnum.EnumDescriptorProto_ReservedRange:
206 ed.L2.ReservedRanges.List = append(ed.L2.ReservedRanges.List, unmarshalEnumReservedRange(v))
207 case fieldnum.EnumDescriptorProto_Options:
208 rawOptions = appendOptions(rawOptions, v)
209 }
210 default:
211 m := wire.ConsumeFieldValue(num, typ, b)
212 b = b[m:]
213 }
214 }
Joe Tsai42413972019-06-21 14:25:16 -0700215 if !ed.L1.eagerValues && len(rawValues) > 0 {
Joe Tsaid8881392019-06-06 13:01:53 -0700216 ed.L2.Values.List = make([]EnumValue, len(rawValues))
217 for i, b := range rawValues {
218 ed.L2.Values.List[i].unmarshalFull(b, nb, ed.L0.ParentFile, ed, i)
219 }
220 }
221 ed.L2.Options = ed.L0.ParentFile.builder.optionsUnmarshaler(descopts.Enum, rawOptions)
222}
223
224func unmarshalEnumReservedRange(b []byte) (r [2]pref.EnumNumber) {
225 for len(b) > 0 {
226 num, typ, n := wire.ConsumeTag(b)
227 b = b[n:]
228 switch typ {
229 case wire.VarintType:
230 v, m := wire.ConsumeVarint(b)
231 b = b[m:]
232 switch num {
233 case fieldnum.EnumDescriptorProto_EnumReservedRange_Start:
234 r[0] = pref.EnumNumber(v)
235 case fieldnum.EnumDescriptorProto_EnumReservedRange_End:
236 r[1] = pref.EnumNumber(v)
237 }
238 default:
239 m := wire.ConsumeFieldValue(num, typ, b)
240 b = b[m:]
241 }
242 }
243 return r
244}
245
246func (vd *EnumValue) unmarshalFull(b []byte, nb *nameBuilder, pf *File, pd pref.Descriptor, i int) {
247 vd.L0.ParentFile = pf
248 vd.L0.Parent = pd
249 vd.L0.Index = i
250
251 var rawOptions []byte
252 for len(b) > 0 {
253 num, typ, n := wire.ConsumeTag(b)
254 b = b[n:]
255 switch typ {
256 case wire.VarintType:
257 v, m := wire.ConsumeVarint(b)
258 b = b[m:]
259 switch num {
260 case fieldnum.EnumValueDescriptorProto_Number:
261 vd.L1.Number = pref.EnumNumber(v)
262 }
263 case wire.BytesType:
264 v, m := wire.ConsumeBytes(b)
265 b = b[m:]
266 switch num {
267 case fieldnum.EnumValueDescriptorProto_Name:
268 // NOTE: Enum values are in the same scope as the enum parent.
269 vd.L0.FullName = nb.AppendFullName(pd.Parent().FullName(), v)
270 case fieldnum.EnumValueDescriptorProto_Options:
271 rawOptions = appendOptions(rawOptions, v)
272 }
273 default:
274 m := wire.ConsumeFieldValue(num, typ, b)
275 b = b[m:]
276 }
277 }
278 vd.L1.Options = pf.builder.optionsUnmarshaler(descopts.EnumValue, rawOptions)
279}
280
281func (md *Message) unmarshalFull(b []byte, nb *nameBuilder) {
282 var rawFields, rawOneofs [][]byte
283 var enumIdx, messageIdx, extensionIdx int
284 var rawOptions []byte
285 md.L2 = new(MessageL2)
286 for len(b) > 0 {
287 num, typ, n := wire.ConsumeTag(b)
288 b = b[n:]
289 switch typ {
290 case wire.BytesType:
291 v, m := wire.ConsumeBytes(b)
292 b = b[m:]
293 switch num {
294 case fieldnum.DescriptorProto_Field:
295 rawFields = append(rawFields, v)
296 case fieldnum.DescriptorProto_OneofDecl:
297 rawOneofs = append(rawOneofs, v)
298 case fieldnum.DescriptorProto_ReservedName:
299 md.L2.ReservedNames.List = append(md.L2.ReservedNames.List, pref.Name(nb.MakeString(v)))
300 case fieldnum.DescriptorProto_ReservedRange:
301 md.L2.ReservedRanges.List = append(md.L2.ReservedRanges.List, unmarshalMessageReservedRange(v))
302 case fieldnum.DescriptorProto_ExtensionRange:
303 r, rawOptions := unmarshalMessageExtensionRange(v)
304 opts := md.L0.ParentFile.builder.optionsUnmarshaler(descopts.ExtensionRange, rawOptions)
305 md.L2.ExtensionRanges.List = append(md.L2.ExtensionRanges.List, r)
306 md.L2.ExtensionRangeOptions = append(md.L2.ExtensionRangeOptions, opts)
307 case fieldnum.DescriptorProto_EnumType:
308 md.L1.Enums.List[enumIdx].unmarshalFull(v, nb)
309 enumIdx++
310 case fieldnum.DescriptorProto_NestedType:
311 md.L1.Messages.List[messageIdx].unmarshalFull(v, nb)
312 messageIdx++
313 case fieldnum.DescriptorProto_Extension:
314 md.L1.Extensions.List[extensionIdx].unmarshalFull(v, nb)
315 extensionIdx++
316 case fieldnum.DescriptorProto_Options:
317 md.unmarshalOptions(v)
318 rawOptions = appendOptions(rawOptions, v)
319 }
320 default:
321 m := wire.ConsumeFieldValue(num, typ, b)
322 b = b[m:]
323 }
324 }
325 if len(rawFields) > 0 || len(rawOneofs) > 0 {
326 md.L2.Fields.List = make([]Field, len(rawFields))
327 md.L2.Oneofs.List = make([]Oneof, len(rawOneofs))
328 for i, b := range rawFields {
329 fd := &md.L2.Fields.List[i]
330 fd.unmarshalFull(b, nb, md.L0.ParentFile, md, i)
331 if fd.L1.Cardinality == pref.Required {
332 md.L2.RequiredNumbers.List = append(md.L2.RequiredNumbers.List, fd.L1.Number)
333 }
334 }
335 for i, b := range rawOneofs {
336 od := &md.L2.Oneofs.List[i]
337 od.unmarshalFull(b, nb, md.L0.ParentFile, md, i)
338 }
339 }
340 md.L2.Options = md.L0.ParentFile.builder.optionsUnmarshaler(descopts.Message, rawOptions)
341}
342
343func (md *Message) unmarshalOptions(b []byte) {
344 for len(b) > 0 {
345 num, typ, n := wire.ConsumeTag(b)
346 b = b[n:]
347 switch typ {
348 case wire.VarintType:
349 v, m := wire.ConsumeVarint(b)
350 b = b[m:]
351 switch num {
352 case fieldnum.MessageOptions_MapEntry:
353 md.L2.IsMapEntry = wire.DecodeBool(v)
354 case fieldnum.MessageOptions_MessageSetWireFormat:
355 md.L2.IsMessageSet = wire.DecodeBool(v)
356 }
357 default:
358 m := wire.ConsumeFieldValue(num, typ, b)
359 b = b[m:]
360 }
361 }
362}
363
364func unmarshalMessageReservedRange(b []byte) (r [2]pref.FieldNumber) {
365 for len(b) > 0 {
366 num, typ, n := wire.ConsumeTag(b)
367 b = b[n:]
368 switch typ {
369 case wire.VarintType:
370 v, m := wire.ConsumeVarint(b)
371 b = b[m:]
372 switch num {
373 case fieldnum.DescriptorProto_ReservedRange_Start:
374 r[0] = pref.FieldNumber(v)
375 case fieldnum.DescriptorProto_ReservedRange_End:
376 r[1] = pref.FieldNumber(v)
377 }
378 default:
379 m := wire.ConsumeFieldValue(num, typ, b)
380 b = b[m:]
381 }
382 }
383 return r
384}
385
386func unmarshalMessageExtensionRange(b []byte) (r [2]pref.FieldNumber, rawOptions []byte) {
387 for len(b) > 0 {
388 num, typ, n := wire.ConsumeTag(b)
389 b = b[n:]
390 switch typ {
391 case wire.VarintType:
392 v, m := wire.ConsumeVarint(b)
393 b = b[m:]
394 switch num {
395 case fieldnum.DescriptorProto_ExtensionRange_Start:
396 r[0] = pref.FieldNumber(v)
397 case fieldnum.DescriptorProto_ExtensionRange_End:
398 r[1] = pref.FieldNumber(v)
399 }
400 case wire.BytesType:
401 v, m := wire.ConsumeBytes(b)
402 b = b[m:]
403 switch num {
404 case fieldnum.DescriptorProto_ExtensionRange_Options:
405 rawOptions = appendOptions(rawOptions, v)
406 }
407 default:
408 m := wire.ConsumeFieldValue(num, typ, b)
409 b = b[m:]
410 }
411 }
412 return r, rawOptions
413}
414
415func (fd *Field) unmarshalFull(b []byte, nb *nameBuilder, pf *File, pd pref.Descriptor, i int) {
416 fd.L0.ParentFile = pf
417 fd.L0.Parent = pd
418 fd.L0.Index = i
419
420 var rawTypeName []byte
421 var rawOptions []byte
422 for len(b) > 0 {
423 num, typ, n := wire.ConsumeTag(b)
424 b = b[n:]
425 switch typ {
426 case wire.VarintType:
427 v, m := wire.ConsumeVarint(b)
428 b = b[m:]
429 switch num {
430 case fieldnum.FieldDescriptorProto_Number:
431 fd.L1.Number = pref.FieldNumber(v)
432 case fieldnum.FieldDescriptorProto_Label:
433 fd.L1.Cardinality = pref.Cardinality(v)
434 case fieldnum.FieldDescriptorProto_Type:
435 fd.L1.Kind = pref.Kind(v)
436 case fieldnum.FieldDescriptorProto_OneofIndex:
437 // In Message.unmarshalFull, we allocate slices for both
438 // the field and oneof descriptors before unmarshaling either
439 // of them. This ensures pointers to slice elements are stable.
440 od := &pd.(*Message).L2.Oneofs.List[v]
441 od.L1.Fields.List = append(od.L1.Fields.List, fd)
442 if fd.L1.ContainingOneof != nil {
443 panic("oneof type already set")
444 }
445 fd.L1.ContainingOneof = od
446 }
447 case wire.BytesType:
448 v, m := wire.ConsumeBytes(b)
449 b = b[m:]
450 switch num {
451 case fieldnum.FieldDescriptorProto_Name:
452 fd.L0.FullName = nb.AppendFullName(pd.FullName(), v)
453 case fieldnum.FieldDescriptorProto_JsonName:
454 fd.L1.JSONName = JSONName(nb.MakeString(v))
455 case fieldnum.FieldDescriptorProto_DefaultValue:
456 fd.L1.Default.val = pref.ValueOf(v) // temporarily store as bytes; later resolved in resolveMessages
457 case fieldnum.FieldDescriptorProto_TypeName:
458 rawTypeName = v
459 case fieldnum.FieldDescriptorProto_Options:
460 fd.unmarshalOptions(v)
461 rawOptions = appendOptions(rawOptions, v)
462 }
463 default:
464 m := wire.ConsumeFieldValue(num, typ, b)
465 b = b[m:]
466 }
467 }
468 if rawTypeName != nil {
469 name := nb.MakeFullName(rawTypeName)
470 switch fd.L1.Kind {
471 case pref.EnumKind:
472 fd.L1.Enum = PlaceholderEnum(name)
473 case pref.MessageKind, pref.GroupKind:
474 fd.L1.Message = PlaceholderMessage(name)
475 }
476 }
477 fd.L1.Options = pf.builder.optionsUnmarshaler(descopts.Field, rawOptions)
478}
479
480func (fd *Field) unmarshalOptions(b []byte) {
481 for len(b) > 0 {
482 num, typ, n := wire.ConsumeTag(b)
483 b = b[n:]
484 switch typ {
485 case wire.VarintType:
486 v, m := wire.ConsumeVarint(b)
487 b = b[m:]
488 switch num {
489 case fieldnum.FieldOptions_Packed:
490 fd.L1.HasPacked = true
491 fd.L1.IsPacked = wire.DecodeBool(v)
492 case fieldnum.FieldOptions_Weak:
493 fd.L1.IsWeak = wire.DecodeBool(v)
494 }
495 default:
496 m := wire.ConsumeFieldValue(num, typ, b)
497 b = b[m:]
498 }
499 }
500}
501
502func (od *Oneof) unmarshalFull(b []byte, nb *nameBuilder, pf *File, pd pref.Descriptor, i int) {
503 od.L0.ParentFile = pf
504 od.L0.Parent = pd
505 od.L0.Index = i
506
507 var rawOptions []byte
508 for len(b) > 0 {
509 num, typ, n := wire.ConsumeTag(b)
510 b = b[n:]
511 switch typ {
512 case wire.BytesType:
513 v, m := wire.ConsumeBytes(b)
514 b = b[m:]
515 switch num {
516 case fieldnum.OneofDescriptorProto_Name:
517 od.L0.FullName = nb.AppendFullName(pd.FullName(), v)
518 case fieldnum.OneofDescriptorProto_Options:
519 rawOptions = appendOptions(rawOptions, v)
520 }
521 default:
522 m := wire.ConsumeFieldValue(num, typ, b)
523 b = b[m:]
524 }
525 }
526 od.L1.Options = pf.builder.optionsUnmarshaler(descopts.Oneof, rawOptions)
527}
528
529func (xd *Extension) unmarshalFull(b []byte, nb *nameBuilder) {
530 var rawTypeName []byte
531 var rawOptions []byte
532 xd.L2 = new(ExtensionL2)
533 for len(b) > 0 {
534 num, typ, n := wire.ConsumeTag(b)
535 b = b[n:]
536 switch typ {
537 case wire.VarintType:
538 v, m := wire.ConsumeVarint(b)
539 b = b[m:]
540 switch num {
541 case fieldnum.FieldDescriptorProto_Label:
542 xd.L2.Cardinality = pref.Cardinality(v)
543 }
544 case wire.BytesType:
545 v, m := wire.ConsumeBytes(b)
546 b = b[m:]
547 switch num {
548 case fieldnum.FieldDescriptorProto_JsonName:
549 xd.L2.JSONName = JSONName(nb.MakeString(v))
550 case fieldnum.FieldDescriptorProto_DefaultValue:
551 xd.L2.Default.val = pref.ValueOf(v) // temporarily store as bytes; later resolved in resolveExtensions
552 case fieldnum.FieldDescriptorProto_TypeName:
553 rawTypeName = v
554 case fieldnum.FieldDescriptorProto_Options:
555 xd.unmarshalOptions(v)
556 rawOptions = appendOptions(rawOptions, v)
557 }
558 default:
559 m := wire.ConsumeFieldValue(num, typ, b)
560 b = b[m:]
561 }
562 }
563 if rawTypeName != nil {
564 name := nb.MakeFullName(rawTypeName)
565 switch xd.L1.Kind {
566 case pref.EnumKind:
567 xd.L2.Enum = PlaceholderEnum(name)
568 case pref.MessageKind, pref.GroupKind:
569 xd.L2.Message = PlaceholderMessage(name)
570 }
571 }
572 xd.L2.Options = xd.L0.ParentFile.builder.optionsUnmarshaler(descopts.Field, rawOptions)
573}
574
575func (xd *Extension) unmarshalOptions(b []byte) {
576 for len(b) > 0 {
577 num, typ, n := wire.ConsumeTag(b)
578 b = b[n:]
579 switch typ {
580 case wire.VarintType:
581 v, m := wire.ConsumeVarint(b)
582 b = b[m:]
583 switch num {
584 case fieldnum.FieldOptions_Packed:
585 xd.L2.IsPacked = wire.DecodeBool(v)
586 }
587 default:
588 m := wire.ConsumeFieldValue(num, typ, b)
589 b = b[m:]
590 }
591 }
592}
593
594func (sd *Service) unmarshalFull(b []byte, nb *nameBuilder) {
595 var rawMethods [][]byte
596 var rawOptions []byte
597 sd.L2 = new(ServiceL2)
598 for len(b) > 0 {
599 num, typ, n := wire.ConsumeTag(b)
600 b = b[n:]
601 switch typ {
602 case wire.BytesType:
603 v, m := wire.ConsumeBytes(b)
604 b = b[m:]
605 switch num {
606 case fieldnum.ServiceDescriptorProto_Method:
607 rawMethods = append(rawMethods, v)
608 case fieldnum.ServiceDescriptorProto_Options:
609 rawOptions = appendOptions(rawOptions, v)
610 }
611 default:
612 m := wire.ConsumeFieldValue(num, typ, b)
613 b = b[m:]
614 }
615 }
616 if len(rawMethods) > 0 {
617 sd.L2.Methods.List = make([]Method, len(rawMethods))
618 for i, b := range rawMethods {
619 sd.L2.Methods.List[i].unmarshalFull(b, nb, sd.L0.ParentFile, sd, i)
620 }
621 }
622 sd.L2.Options = sd.L0.ParentFile.builder.optionsUnmarshaler(descopts.Service, rawOptions)
623}
624
625func (md *Method) unmarshalFull(b []byte, nb *nameBuilder, pf *File, pd pref.Descriptor, i int) {
626 md.L0.ParentFile = pf
627 md.L0.Parent = pd
628 md.L0.Index = i
629
630 var rawOptions []byte
631 for len(b) > 0 {
632 num, typ, n := wire.ConsumeTag(b)
633 b = b[n:]
634 switch typ {
635 case wire.VarintType:
636 v, m := wire.ConsumeVarint(b)
637 b = b[m:]
638 switch num {
639 case fieldnum.MethodDescriptorProto_ClientStreaming:
640 md.L1.IsStreamingClient = wire.DecodeBool(v)
641 case fieldnum.MethodDescriptorProto_ServerStreaming:
642 md.L1.IsStreamingServer = wire.DecodeBool(v)
643 }
644 case wire.BytesType:
645 v, m := wire.ConsumeBytes(b)
646 b = b[m:]
647 switch num {
648 case fieldnum.MethodDescriptorProto_Name:
649 md.L0.FullName = nb.AppendFullName(pd.FullName(), v)
650 case fieldnum.MethodDescriptorProto_InputType:
651 md.L1.Input = PlaceholderMessage(nb.MakeFullName(v))
652 case fieldnum.MethodDescriptorProto_OutputType:
653 md.L1.Output = PlaceholderMessage(nb.MakeFullName(v))
654 case fieldnum.MethodDescriptorProto_Options:
655 rawOptions = appendOptions(rawOptions, v)
656 }
657 default:
658 m := wire.ConsumeFieldValue(num, typ, b)
659 b = b[m:]
660 }
661 }
662 md.L1.Options = pf.builder.optionsUnmarshaler(descopts.Method, rawOptions)
663}
664
665// appendOptions appends src to dst, where the returned slice is never nil.
666// This is necessary to distinguish between empty and unpopulated options.
667func appendOptions(dst, src []byte) []byte {
668 if dst == nil {
669 dst = []byte{}
670 }
671 return append(dst, src...)
672}
673
674func (db *DescBuilder) optionsUnmarshaler(p pref.ProtoMessage, b []byte) func() pref.ProtoMessage {
675 if b == nil {
676 return nil
677 }
678 return func() pref.ProtoMessage {
679 p := reflect.New(reflect.TypeOf(p).Elem()).Interface().(pref.ProtoMessage)
680 if err := (proto.UnmarshalOptions{
681 AllowPartial: true,
682 Resolver: db.TypeResolver,
683 }).Unmarshal(b, p); err != nil {
684 panic(err)
685 }
686 return p
687 }
688}