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