blob: 9b54e6d10bdaeac71a63b0bc97a8531830afcddb [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"
Joe Tsai97a87392019-07-07 01:49:59 -070014 "google.golang.org/protobuf/internal/strs"
Joe Tsaid8881392019-06-06 13:01:53 -070015 "google.golang.org/protobuf/proto"
16 pref "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 // Weak fields are only resolved by name.
36 if fd.L1.IsWeak {
37 r := file.builder.FileRegistry
Joe Tsaie407ee12019-06-24 16:19:06 -070038 if d, _ := r.FindDescriptorByName(fd.L1.Message.FullName()); d != nil {
39 fd.L1.Message = d.(pref.MessageDescriptor)
Joe Tsaid8881392019-06-06 13:01:53 -070040 }
41 continue
42 }
43
44 // Resolve message field dependency.
45 switch fd.L1.Kind {
46 case pref.EnumKind:
47 fd.L1.Enum = file.resolveEnumDependency(fd.L1.Enum, listFieldDeps, depIdx)
48 depIdx++
49 case pref.MessageKind, pref.GroupKind:
50 fd.L1.Message = file.resolveMessageDependency(fd.L1.Message, listFieldDeps, depIdx)
51 depIdx++
52 }
53
54 // Default is resolved here since it depends on Enum being resolved.
55 if v := fd.L1.Default.val; v.IsValid() {
56 fd.L1.Default = unmarshalDefault(v.Bytes(), fd.L1.Kind, file, fd.L1.Enum)
57 }
58 }
59 }
60}
61
62func (file *File) resolveExtensions() {
63 var depIdx int32
64 for i := range file.allExtensions {
65 xd := &file.allExtensions[i]
66
67 // Resolve extension field dependency.
68 switch xd.L1.Kind {
69 case pref.EnumKind:
70 xd.L2.Enum = file.resolveEnumDependency(xd.L2.Enum, listExtDeps, depIdx)
71 depIdx++
72 case pref.MessageKind, pref.GroupKind:
73 xd.L2.Message = file.resolveMessageDependency(xd.L2.Message, listExtDeps, depIdx)
74 depIdx++
75 }
76
77 // Default is resolved here since it depends on Enum being resolved.
78 if v := xd.L2.Default.val; v.IsValid() {
79 xd.L2.Default = unmarshalDefault(v.Bytes(), xd.L1.Kind, file, xd.L2.Enum)
80 }
81 }
82}
83
84func (file *File) resolveServices() {
85 var depIdx int32
86 for i := range file.allServices {
87 sd := &file.allServices[i]
88
89 // Resolve method dependencies.
90 for j := range sd.L2.Methods.List {
91 md := &sd.L2.Methods.List[j]
92 md.L1.Input = file.resolveMessageDependency(md.L1.Input, listMethInDeps, depIdx)
93 md.L1.Output = file.resolveMessageDependency(md.L1.Output, listMethOutDeps, depIdx)
94 depIdx++
95 }
96 }
97}
98
99func (file *File) resolveEnumDependency(ed pref.EnumDescriptor, i, j int32) pref.EnumDescriptor {
100 r := file.builder.FileRegistry
101 if r, ok := r.(resolverByIndex); ok {
102 if ed2 := r.FindEnumByIndex(i, j, file.allEnums, file.allMessages); ed2 != nil {
103 return ed2
104 }
105 }
106 for i := range file.allEnums {
107 if ed2 := &file.allEnums[i]; ed2.L0.FullName == ed.FullName() {
108 return ed2
109 }
110 }
Joe Tsaie407ee12019-06-24 16:19:06 -0700111 if d, _ := r.FindDescriptorByName(ed.FullName()); d != nil {
112 return d.(pref.EnumDescriptor)
Joe Tsaid8881392019-06-06 13:01:53 -0700113 }
114 return ed
115}
116
117func (file *File) resolveMessageDependency(md pref.MessageDescriptor, i, j int32) pref.MessageDescriptor {
118 r := file.builder.FileRegistry
119 if r, ok := r.(resolverByIndex); ok {
120 if md2 := r.FindMessageByIndex(i, j, file.allEnums, file.allMessages); md2 != nil {
121 return md2
122 }
123 }
124 for i := range file.allMessages {
125 if md2 := &file.allMessages[i]; md2.L0.FullName == md.FullName() {
126 return md2
127 }
128 }
Joe Tsaie407ee12019-06-24 16:19:06 -0700129 if d, _ := r.FindDescriptorByName(md.FullName()); d != nil {
130 return d.(pref.MessageDescriptor)
Joe Tsaid8881392019-06-06 13:01:53 -0700131 }
132 return md
133}
134
135func (fd *File) unmarshalFull(b []byte) {
Joe Tsai97a87392019-07-07 01:49:59 -0700136 sb := getBuilder()
137 defer putBuilder(sb)
Joe Tsaid8881392019-06-06 13:01:53 -0700138
139 var enumIdx, messageIdx, extensionIdx, serviceIdx int
140 var rawOptions []byte
141 fd.L2 = new(FileL2)
142 for len(b) > 0 {
143 num, typ, n := wire.ConsumeTag(b)
144 b = b[n:]
145 switch typ {
146 case wire.VarintType:
147 v, m := wire.ConsumeVarint(b)
148 b = b[m:]
149 switch num {
150 case fieldnum.FileDescriptorProto_PublicDependency:
151 fd.L2.Imports[v].IsPublic = true
152 case fieldnum.FileDescriptorProto_WeakDependency:
153 fd.L2.Imports[v].IsWeak = true
154 }
155 case wire.BytesType:
156 v, m := wire.ConsumeBytes(b)
157 b = b[m:]
158 switch num {
159 case fieldnum.FileDescriptorProto_Dependency:
Joe Tsai97a87392019-07-07 01:49:59 -0700160 path := sb.MakeString(v)
Joe Tsaid8881392019-06-06 13:01:53 -0700161 imp, _ := fd.builder.FileRegistry.FindFileByPath(path)
162 if imp == nil {
163 imp = PlaceholderFile(path)
164 }
165 fd.L2.Imports = append(fd.L2.Imports, pref.FileImport{FileDescriptor: imp})
166 case fieldnum.FileDescriptorProto_EnumType:
Joe Tsai97a87392019-07-07 01:49:59 -0700167 fd.L1.Enums.List[enumIdx].unmarshalFull(v, sb)
Joe Tsaid8881392019-06-06 13:01:53 -0700168 enumIdx++
169 case fieldnum.FileDescriptorProto_MessageType:
Joe Tsai97a87392019-07-07 01:49:59 -0700170 fd.L1.Messages.List[messageIdx].unmarshalFull(v, sb)
Joe Tsaid8881392019-06-06 13:01:53 -0700171 messageIdx++
172 case fieldnum.FileDescriptorProto_Extension:
Joe Tsai97a87392019-07-07 01:49:59 -0700173 fd.L1.Extensions.List[extensionIdx].unmarshalFull(v, sb)
Joe Tsaid8881392019-06-06 13:01:53 -0700174 extensionIdx++
175 case fieldnum.FileDescriptorProto_Service:
Joe Tsai97a87392019-07-07 01:49:59 -0700176 fd.L1.Services.List[serviceIdx].unmarshalFull(v, sb)
Joe Tsaid8881392019-06-06 13:01:53 -0700177 serviceIdx++
178 case fieldnum.FileDescriptorProto_Options:
179 rawOptions = appendOptions(rawOptions, v)
180 }
181 default:
182 m := wire.ConsumeFieldValue(num, typ, b)
183 b = b[m:]
184 }
185 }
186 fd.L2.Options = fd.builder.optionsUnmarshaler(descopts.File, rawOptions)
187}
188
Joe Tsai97a87392019-07-07 01:49:59 -0700189func (ed *Enum) unmarshalFull(b []byte, sb *strs.Builder) {
Joe Tsaid8881392019-06-06 13:01:53 -0700190 var rawValues [][]byte
191 var rawOptions []byte
Joe Tsai42413972019-06-21 14:25:16 -0700192 if !ed.L1.eagerValues {
193 ed.L2 = new(EnumL2)
194 }
Joe Tsaid8881392019-06-06 13:01:53 -0700195 for len(b) > 0 {
196 num, typ, n := wire.ConsumeTag(b)
197 b = b[n:]
198 switch typ {
199 case wire.BytesType:
200 v, m := wire.ConsumeBytes(b)
201 b = b[m:]
202 switch num {
203 case fieldnum.EnumDescriptorProto_Value:
204 rawValues = append(rawValues, v)
205 case fieldnum.EnumDescriptorProto_ReservedName:
Joe Tsai97a87392019-07-07 01:49:59 -0700206 ed.L2.ReservedNames.List = append(ed.L2.ReservedNames.List, pref.Name(sb.MakeString(v)))
Joe Tsaid8881392019-06-06 13:01:53 -0700207 case fieldnum.EnumDescriptorProto_ReservedRange:
208 ed.L2.ReservedRanges.List = append(ed.L2.ReservedRanges.List, unmarshalEnumReservedRange(v))
209 case fieldnum.EnumDescriptorProto_Options:
210 rawOptions = appendOptions(rawOptions, v)
211 }
212 default:
213 m := wire.ConsumeFieldValue(num, typ, b)
214 b = b[m:]
215 }
216 }
Joe Tsai42413972019-06-21 14:25:16 -0700217 if !ed.L1.eagerValues && len(rawValues) > 0 {
Joe Tsaid8881392019-06-06 13:01:53 -0700218 ed.L2.Values.List = make([]EnumValue, len(rawValues))
219 for i, b := range rawValues {
Joe Tsai97a87392019-07-07 01:49:59 -0700220 ed.L2.Values.List[i].unmarshalFull(b, sb, ed.L0.ParentFile, ed, i)
Joe Tsaid8881392019-06-06 13:01:53 -0700221 }
222 }
223 ed.L2.Options = ed.L0.ParentFile.builder.optionsUnmarshaler(descopts.Enum, rawOptions)
224}
225
226func unmarshalEnumReservedRange(b []byte) (r [2]pref.EnumNumber) {
227 for len(b) > 0 {
228 num, typ, n := wire.ConsumeTag(b)
229 b = b[n:]
230 switch typ {
231 case wire.VarintType:
232 v, m := wire.ConsumeVarint(b)
233 b = b[m:]
234 switch num {
235 case fieldnum.EnumDescriptorProto_EnumReservedRange_Start:
236 r[0] = pref.EnumNumber(v)
237 case fieldnum.EnumDescriptorProto_EnumReservedRange_End:
238 r[1] = pref.EnumNumber(v)
239 }
240 default:
241 m := wire.ConsumeFieldValue(num, typ, b)
242 b = b[m:]
243 }
244 }
245 return r
246}
247
Joe Tsai97a87392019-07-07 01:49:59 -0700248func (vd *EnumValue) unmarshalFull(b []byte, sb *strs.Builder, pf *File, pd pref.Descriptor, i int) {
Joe Tsaid8881392019-06-06 13:01:53 -0700249 vd.L0.ParentFile = pf
250 vd.L0.Parent = pd
251 vd.L0.Index = i
252
253 var rawOptions []byte
254 for len(b) > 0 {
255 num, typ, n := wire.ConsumeTag(b)
256 b = b[n:]
257 switch typ {
258 case wire.VarintType:
259 v, m := wire.ConsumeVarint(b)
260 b = b[m:]
261 switch num {
262 case fieldnum.EnumValueDescriptorProto_Number:
263 vd.L1.Number = pref.EnumNumber(v)
264 }
265 case wire.BytesType:
266 v, m := wire.ConsumeBytes(b)
267 b = b[m:]
268 switch num {
269 case fieldnum.EnumValueDescriptorProto_Name:
270 // NOTE: Enum values are in the same scope as the enum parent.
Joe Tsai97a87392019-07-07 01:49:59 -0700271 vd.L0.FullName = appendFullName(sb, pd.Parent().FullName(), v)
Joe Tsaid8881392019-06-06 13:01:53 -0700272 case fieldnum.EnumValueDescriptorProto_Options:
273 rawOptions = appendOptions(rawOptions, v)
274 }
275 default:
276 m := wire.ConsumeFieldValue(num, typ, b)
277 b = b[m:]
278 }
279 }
280 vd.L1.Options = pf.builder.optionsUnmarshaler(descopts.EnumValue, rawOptions)
281}
282
Joe Tsai97a87392019-07-07 01:49:59 -0700283func (md *Message) unmarshalFull(b []byte, sb *strs.Builder) {
Joe Tsaid8881392019-06-06 13:01:53 -0700284 var rawFields, rawOneofs [][]byte
285 var enumIdx, messageIdx, extensionIdx int
286 var rawOptions []byte
287 md.L2 = new(MessageL2)
288 for len(b) > 0 {
289 num, typ, n := wire.ConsumeTag(b)
290 b = b[n:]
291 switch typ {
292 case wire.BytesType:
293 v, m := wire.ConsumeBytes(b)
294 b = b[m:]
295 switch num {
296 case fieldnum.DescriptorProto_Field:
297 rawFields = append(rawFields, v)
298 case fieldnum.DescriptorProto_OneofDecl:
299 rawOneofs = append(rawOneofs, v)
300 case fieldnum.DescriptorProto_ReservedName:
Joe Tsai97a87392019-07-07 01:49:59 -0700301 md.L2.ReservedNames.List = append(md.L2.ReservedNames.List, pref.Name(sb.MakeString(v)))
Joe Tsaid8881392019-06-06 13:01:53 -0700302 case fieldnum.DescriptorProto_ReservedRange:
303 md.L2.ReservedRanges.List = append(md.L2.ReservedRanges.List, unmarshalMessageReservedRange(v))
304 case fieldnum.DescriptorProto_ExtensionRange:
305 r, rawOptions := unmarshalMessageExtensionRange(v)
306 opts := md.L0.ParentFile.builder.optionsUnmarshaler(descopts.ExtensionRange, rawOptions)
307 md.L2.ExtensionRanges.List = append(md.L2.ExtensionRanges.List, r)
308 md.L2.ExtensionRangeOptions = append(md.L2.ExtensionRangeOptions, opts)
309 case fieldnum.DescriptorProto_EnumType:
Joe Tsai97a87392019-07-07 01:49:59 -0700310 md.L1.Enums.List[enumIdx].unmarshalFull(v, sb)
Joe Tsaid8881392019-06-06 13:01:53 -0700311 enumIdx++
312 case fieldnum.DescriptorProto_NestedType:
Joe Tsai97a87392019-07-07 01:49:59 -0700313 md.L1.Messages.List[messageIdx].unmarshalFull(v, sb)
Joe Tsaid8881392019-06-06 13:01:53 -0700314 messageIdx++
315 case fieldnum.DescriptorProto_Extension:
Joe Tsai97a87392019-07-07 01:49:59 -0700316 md.L1.Extensions.List[extensionIdx].unmarshalFull(v, sb)
Joe Tsaid8881392019-06-06 13:01:53 -0700317 extensionIdx++
318 case fieldnum.DescriptorProto_Options:
319 md.unmarshalOptions(v)
320 rawOptions = appendOptions(rawOptions, v)
321 }
322 default:
323 m := wire.ConsumeFieldValue(num, typ, b)
324 b = b[m:]
325 }
326 }
327 if len(rawFields) > 0 || len(rawOneofs) > 0 {
328 md.L2.Fields.List = make([]Field, len(rawFields))
329 md.L2.Oneofs.List = make([]Oneof, len(rawOneofs))
330 for i, b := range rawFields {
331 fd := &md.L2.Fields.List[i]
Joe Tsai97a87392019-07-07 01:49:59 -0700332 fd.unmarshalFull(b, sb, md.L0.ParentFile, md, i)
Joe Tsaid8881392019-06-06 13:01:53 -0700333 if fd.L1.Cardinality == pref.Required {
334 md.L2.RequiredNumbers.List = append(md.L2.RequiredNumbers.List, fd.L1.Number)
335 }
336 }
337 for i, b := range rawOneofs {
338 od := &md.L2.Oneofs.List[i]
Joe Tsai97a87392019-07-07 01:49:59 -0700339 od.unmarshalFull(b, sb, md.L0.ParentFile, md, i)
Joe Tsaid8881392019-06-06 13:01:53 -0700340 }
341 }
342 md.L2.Options = md.L0.ParentFile.builder.optionsUnmarshaler(descopts.Message, rawOptions)
343}
344
345func (md *Message) unmarshalOptions(b []byte) {
346 for len(b) > 0 {
347 num, typ, n := wire.ConsumeTag(b)
348 b = b[n:]
349 switch typ {
350 case wire.VarintType:
351 v, m := wire.ConsumeVarint(b)
352 b = b[m:]
353 switch num {
354 case fieldnum.MessageOptions_MapEntry:
355 md.L2.IsMapEntry = wire.DecodeBool(v)
356 case fieldnum.MessageOptions_MessageSetWireFormat:
357 md.L2.IsMessageSet = wire.DecodeBool(v)
358 }
359 default:
360 m := wire.ConsumeFieldValue(num, typ, b)
361 b = b[m:]
362 }
363 }
364}
365
366func unmarshalMessageReservedRange(b []byte) (r [2]pref.FieldNumber) {
367 for len(b) > 0 {
368 num, typ, n := wire.ConsumeTag(b)
369 b = b[n:]
370 switch typ {
371 case wire.VarintType:
372 v, m := wire.ConsumeVarint(b)
373 b = b[m:]
374 switch num {
375 case fieldnum.DescriptorProto_ReservedRange_Start:
376 r[0] = pref.FieldNumber(v)
377 case fieldnum.DescriptorProto_ReservedRange_End:
378 r[1] = pref.FieldNumber(v)
379 }
380 default:
381 m := wire.ConsumeFieldValue(num, typ, b)
382 b = b[m:]
383 }
384 }
385 return r
386}
387
388func unmarshalMessageExtensionRange(b []byte) (r [2]pref.FieldNumber, rawOptions []byte) {
389 for len(b) > 0 {
390 num, typ, n := wire.ConsumeTag(b)
391 b = b[n:]
392 switch typ {
393 case wire.VarintType:
394 v, m := wire.ConsumeVarint(b)
395 b = b[m:]
396 switch num {
397 case fieldnum.DescriptorProto_ExtensionRange_Start:
398 r[0] = pref.FieldNumber(v)
399 case fieldnum.DescriptorProto_ExtensionRange_End:
400 r[1] = pref.FieldNumber(v)
401 }
402 case wire.BytesType:
403 v, m := wire.ConsumeBytes(b)
404 b = b[m:]
405 switch num {
406 case fieldnum.DescriptorProto_ExtensionRange_Options:
407 rawOptions = appendOptions(rawOptions, v)
408 }
409 default:
410 m := wire.ConsumeFieldValue(num, typ, b)
411 b = b[m:]
412 }
413 }
414 return r, rawOptions
415}
416
Joe Tsai97a87392019-07-07 01:49:59 -0700417func (fd *Field) unmarshalFull(b []byte, sb *strs.Builder, pf *File, pd pref.Descriptor, i int) {
Joe Tsaid8881392019-06-06 13:01:53 -0700418 fd.L0.ParentFile = pf
419 fd.L0.Parent = pd
420 fd.L0.Index = i
421
422 var rawTypeName []byte
423 var rawOptions []byte
424 for len(b) > 0 {
425 num, typ, n := wire.ConsumeTag(b)
426 b = b[n:]
427 switch typ {
428 case wire.VarintType:
429 v, m := wire.ConsumeVarint(b)
430 b = b[m:]
431 switch num {
432 case fieldnum.FieldDescriptorProto_Number:
433 fd.L1.Number = pref.FieldNumber(v)
434 case fieldnum.FieldDescriptorProto_Label:
435 fd.L1.Cardinality = pref.Cardinality(v)
436 case fieldnum.FieldDescriptorProto_Type:
437 fd.L1.Kind = pref.Kind(v)
438 case fieldnum.FieldDescriptorProto_OneofIndex:
439 // In Message.unmarshalFull, we allocate slices for both
440 // the field and oneof descriptors before unmarshaling either
441 // of them. This ensures pointers to slice elements are stable.
442 od := &pd.(*Message).L2.Oneofs.List[v]
443 od.L1.Fields.List = append(od.L1.Fields.List, fd)
444 if fd.L1.ContainingOneof != nil {
445 panic("oneof type already set")
446 }
447 fd.L1.ContainingOneof = od
448 }
449 case wire.BytesType:
450 v, m := wire.ConsumeBytes(b)
451 b = b[m:]
452 switch num {
453 case fieldnum.FieldDescriptorProto_Name:
Joe Tsai97a87392019-07-07 01:49:59 -0700454 fd.L0.FullName = appendFullName(sb, pd.FullName(), v)
Joe Tsaid8881392019-06-06 13:01:53 -0700455 case fieldnum.FieldDescriptorProto_JsonName:
Joe Tsai97a87392019-07-07 01:49:59 -0700456 fd.L1.JSONName = JSONName(sb.MakeString(v))
Joe Tsaid8881392019-06-06 13:01:53 -0700457 case fieldnum.FieldDescriptorProto_DefaultValue:
458 fd.L1.Default.val = pref.ValueOf(v) // temporarily store as bytes; later resolved in resolveMessages
459 case fieldnum.FieldDescriptorProto_TypeName:
460 rawTypeName = v
461 case fieldnum.FieldDescriptorProto_Options:
462 fd.unmarshalOptions(v)
463 rawOptions = appendOptions(rawOptions, v)
464 }
465 default:
466 m := wire.ConsumeFieldValue(num, typ, b)
467 b = b[m:]
468 }
469 }
470 if rawTypeName != nil {
Joe Tsai97a87392019-07-07 01:49:59 -0700471 name := makeFullName(sb, rawTypeName)
Joe Tsaid8881392019-06-06 13:01:53 -0700472 switch fd.L1.Kind {
473 case pref.EnumKind:
474 fd.L1.Enum = PlaceholderEnum(name)
475 case pref.MessageKind, pref.GroupKind:
476 fd.L1.Message = PlaceholderMessage(name)
477 }
478 }
479 fd.L1.Options = pf.builder.optionsUnmarshaler(descopts.Field, rawOptions)
480}
481
482func (fd *Field) unmarshalOptions(b []byte) {
Joe Tsaic51e2e02019-07-13 00:44:41 -0700483 const FieldOptions_EnforceUTF8 = 13
484
Joe Tsaid8881392019-06-06 13:01:53 -0700485 for len(b) > 0 {
486 num, typ, n := wire.ConsumeTag(b)
487 b = b[n:]
488 switch typ {
489 case wire.VarintType:
490 v, m := wire.ConsumeVarint(b)
491 b = b[m:]
492 switch num {
493 case fieldnum.FieldOptions_Packed:
494 fd.L1.HasPacked = true
495 fd.L1.IsPacked = wire.DecodeBool(v)
496 case fieldnum.FieldOptions_Weak:
497 fd.L1.IsWeak = wire.DecodeBool(v)
Joe Tsaic51e2e02019-07-13 00:44:41 -0700498 case FieldOptions_EnforceUTF8:
499 fd.L1.HasEnforceUTF8 = true
500 fd.L1.EnforceUTF8 = !wire.DecodeBool(v)
Joe Tsaid8881392019-06-06 13:01:53 -0700501 }
502 default:
503 m := wire.ConsumeFieldValue(num, typ, b)
504 b = b[m:]
505 }
506 }
507}
508
Joe Tsai97a87392019-07-07 01:49:59 -0700509func (od *Oneof) unmarshalFull(b []byte, sb *strs.Builder, pf *File, pd pref.Descriptor, i int) {
Joe Tsaid8881392019-06-06 13:01:53 -0700510 od.L0.ParentFile = pf
511 od.L0.Parent = pd
512 od.L0.Index = i
513
514 var rawOptions []byte
515 for len(b) > 0 {
516 num, typ, n := wire.ConsumeTag(b)
517 b = b[n:]
518 switch typ {
519 case wire.BytesType:
520 v, m := wire.ConsumeBytes(b)
521 b = b[m:]
522 switch num {
523 case fieldnum.OneofDescriptorProto_Name:
Joe Tsai97a87392019-07-07 01:49:59 -0700524 od.L0.FullName = appendFullName(sb, pd.FullName(), v)
Joe Tsaid8881392019-06-06 13:01:53 -0700525 case fieldnum.OneofDescriptorProto_Options:
526 rawOptions = appendOptions(rawOptions, v)
527 }
528 default:
529 m := wire.ConsumeFieldValue(num, typ, b)
530 b = b[m:]
531 }
532 }
533 od.L1.Options = pf.builder.optionsUnmarshaler(descopts.Oneof, rawOptions)
534}
535
Joe Tsai97a87392019-07-07 01:49:59 -0700536func (xd *Extension) unmarshalFull(b []byte, sb *strs.Builder) {
Joe Tsaid8881392019-06-06 13:01:53 -0700537 var rawTypeName []byte
538 var rawOptions []byte
539 xd.L2 = new(ExtensionL2)
540 for len(b) > 0 {
541 num, typ, n := wire.ConsumeTag(b)
542 b = b[n:]
543 switch typ {
544 case wire.VarintType:
545 v, m := wire.ConsumeVarint(b)
546 b = b[m:]
547 switch num {
548 case fieldnum.FieldDescriptorProto_Label:
549 xd.L2.Cardinality = pref.Cardinality(v)
550 }
551 case wire.BytesType:
552 v, m := wire.ConsumeBytes(b)
553 b = b[m:]
554 switch num {
555 case fieldnum.FieldDescriptorProto_JsonName:
Joe Tsai97a87392019-07-07 01:49:59 -0700556 xd.L2.JSONName = JSONName(sb.MakeString(v))
Joe Tsaid8881392019-06-06 13:01:53 -0700557 case fieldnum.FieldDescriptorProto_DefaultValue:
558 xd.L2.Default.val = pref.ValueOf(v) // temporarily store as bytes; later resolved in resolveExtensions
559 case fieldnum.FieldDescriptorProto_TypeName:
560 rawTypeName = v
561 case fieldnum.FieldDescriptorProto_Options:
562 xd.unmarshalOptions(v)
563 rawOptions = appendOptions(rawOptions, v)
564 }
565 default:
566 m := wire.ConsumeFieldValue(num, typ, b)
567 b = b[m:]
568 }
569 }
570 if rawTypeName != nil {
Joe Tsai97a87392019-07-07 01:49:59 -0700571 name := makeFullName(sb, rawTypeName)
Joe Tsaid8881392019-06-06 13:01:53 -0700572 switch xd.L1.Kind {
573 case pref.EnumKind:
574 xd.L2.Enum = PlaceholderEnum(name)
575 case pref.MessageKind, pref.GroupKind:
576 xd.L2.Message = PlaceholderMessage(name)
577 }
578 }
579 xd.L2.Options = xd.L0.ParentFile.builder.optionsUnmarshaler(descopts.Field, rawOptions)
580}
581
582func (xd *Extension) unmarshalOptions(b []byte) {
583 for len(b) > 0 {
584 num, typ, n := wire.ConsumeTag(b)
585 b = b[n:]
586 switch typ {
587 case wire.VarintType:
588 v, m := wire.ConsumeVarint(b)
589 b = b[m:]
590 switch num {
591 case fieldnum.FieldOptions_Packed:
592 xd.L2.IsPacked = wire.DecodeBool(v)
593 }
594 default:
595 m := wire.ConsumeFieldValue(num, typ, b)
596 b = b[m:]
597 }
598 }
599}
600
Joe Tsai97a87392019-07-07 01:49:59 -0700601func (sd *Service) unmarshalFull(b []byte, sb *strs.Builder) {
Joe Tsaid8881392019-06-06 13:01:53 -0700602 var rawMethods [][]byte
603 var rawOptions []byte
604 sd.L2 = new(ServiceL2)
605 for len(b) > 0 {
606 num, typ, n := wire.ConsumeTag(b)
607 b = b[n:]
608 switch typ {
609 case wire.BytesType:
610 v, m := wire.ConsumeBytes(b)
611 b = b[m:]
612 switch num {
613 case fieldnum.ServiceDescriptorProto_Method:
614 rawMethods = append(rawMethods, v)
615 case fieldnum.ServiceDescriptorProto_Options:
616 rawOptions = appendOptions(rawOptions, v)
617 }
618 default:
619 m := wire.ConsumeFieldValue(num, typ, b)
620 b = b[m:]
621 }
622 }
623 if len(rawMethods) > 0 {
624 sd.L2.Methods.List = make([]Method, len(rawMethods))
625 for i, b := range rawMethods {
Joe Tsai97a87392019-07-07 01:49:59 -0700626 sd.L2.Methods.List[i].unmarshalFull(b, sb, sd.L0.ParentFile, sd, i)
Joe Tsaid8881392019-06-06 13:01:53 -0700627 }
628 }
629 sd.L2.Options = sd.L0.ParentFile.builder.optionsUnmarshaler(descopts.Service, rawOptions)
630}
631
Joe Tsai97a87392019-07-07 01:49:59 -0700632func (md *Method) unmarshalFull(b []byte, sb *strs.Builder, pf *File, pd pref.Descriptor, i int) {
Joe Tsaid8881392019-06-06 13:01:53 -0700633 md.L0.ParentFile = pf
634 md.L0.Parent = pd
635 md.L0.Index = i
636
637 var rawOptions []byte
638 for len(b) > 0 {
639 num, typ, n := wire.ConsumeTag(b)
640 b = b[n:]
641 switch typ {
642 case wire.VarintType:
643 v, m := wire.ConsumeVarint(b)
644 b = b[m:]
645 switch num {
646 case fieldnum.MethodDescriptorProto_ClientStreaming:
647 md.L1.IsStreamingClient = wire.DecodeBool(v)
648 case fieldnum.MethodDescriptorProto_ServerStreaming:
649 md.L1.IsStreamingServer = wire.DecodeBool(v)
650 }
651 case wire.BytesType:
652 v, m := wire.ConsumeBytes(b)
653 b = b[m:]
654 switch num {
655 case fieldnum.MethodDescriptorProto_Name:
Joe Tsai97a87392019-07-07 01:49:59 -0700656 md.L0.FullName = appendFullName(sb, pd.FullName(), v)
Joe Tsaid8881392019-06-06 13:01:53 -0700657 case fieldnum.MethodDescriptorProto_InputType:
Joe Tsai97a87392019-07-07 01:49:59 -0700658 md.L1.Input = PlaceholderMessage(makeFullName(sb, v))
Joe Tsaid8881392019-06-06 13:01:53 -0700659 case fieldnum.MethodDescriptorProto_OutputType:
Joe Tsai97a87392019-07-07 01:49:59 -0700660 md.L1.Output = PlaceholderMessage(makeFullName(sb, v))
Joe Tsaid8881392019-06-06 13:01:53 -0700661 case fieldnum.MethodDescriptorProto_Options:
662 rawOptions = appendOptions(rawOptions, v)
663 }
664 default:
665 m := wire.ConsumeFieldValue(num, typ, b)
666 b = b[m:]
667 }
668 }
669 md.L1.Options = pf.builder.optionsUnmarshaler(descopts.Method, rawOptions)
670}
671
672// appendOptions appends src to dst, where the returned slice is never nil.
673// This is necessary to distinguish between empty and unpopulated options.
674func appendOptions(dst, src []byte) []byte {
675 if dst == nil {
676 dst = []byte{}
677 }
678 return append(dst, src...)
679}
680
681func (db *DescBuilder) optionsUnmarshaler(p pref.ProtoMessage, b []byte) func() pref.ProtoMessage {
682 if b == nil {
683 return nil
684 }
Joe Tsai8a4c3d12019-07-06 18:08:55 -0700685 var opts pref.ProtoMessage
686 var once sync.Once
Joe Tsaid8881392019-06-06 13:01:53 -0700687 return func() pref.ProtoMessage {
Joe Tsai8a4c3d12019-07-06 18:08:55 -0700688 once.Do(func() {
689 opts = reflect.New(reflect.TypeOf(p).Elem()).Interface().(pref.ProtoMessage)
690 if err := (proto.UnmarshalOptions{
691 AllowPartial: true,
692 Resolver: db.TypeResolver,
693 }).Unmarshal(b, opts); err != nil {
694 panic(err)
695 }
696 })
697 return opts
Joe Tsaid8881392019-06-06 13:01:53 -0700698 }
699}