1
2
3
4
5 package filedesc
6
7 import (
8 "fmt"
9 "sync"
10
11 "google.golang.org/protobuf/encoding/protowire"
12 "google.golang.org/protobuf/internal/genid"
13 "google.golang.org/protobuf/internal/strs"
14 "google.golang.org/protobuf/reflect/protoreflect"
15 )
16
17
18
19 type fileRaw struct {
20 builder Builder
21 allEnums []Enum
22 allMessages []Message
23 allExtensions []Extension
24 allServices []Service
25 }
26
27 func newRawFile(db Builder) *File {
28 fd := &File{fileRaw: fileRaw{builder: db}}
29 fd.initDecls(db.NumEnums, db.NumMessages, db.NumExtensions, db.NumServices)
30 fd.unmarshalSeed(db.RawDescriptor)
31
32
33
34 for i := range fd.allExtensions {
35 xd := &fd.allExtensions[i]
36 xd.L1.Extendee = fd.resolveMessageDependency(xd.L1.Extendee, listExtTargets, int32(i))
37 }
38
39 fd.checkDecls()
40 return fd
41 }
42
43
44
45
46
47
48
49 func (fd *File) initDecls(numEnums, numMessages, numExtensions, numServices int32) {
50 fd.allEnums = make([]Enum, 0, numEnums)
51 fd.allMessages = make([]Message, 0, numMessages)
52 fd.allExtensions = make([]Extension, 0, numExtensions)
53 fd.allServices = make([]Service, 0, numServices)
54 }
55
56 func (fd *File) allocEnums(n int) []Enum {
57 total := len(fd.allEnums)
58 es := fd.allEnums[total : total+n]
59 fd.allEnums = fd.allEnums[:total+n]
60 return es
61 }
62 func (fd *File) allocMessages(n int) []Message {
63 total := len(fd.allMessages)
64 ms := fd.allMessages[total : total+n]
65 fd.allMessages = fd.allMessages[:total+n]
66 return ms
67 }
68 func (fd *File) allocExtensions(n int) []Extension {
69 total := len(fd.allExtensions)
70 xs := fd.allExtensions[total : total+n]
71 fd.allExtensions = fd.allExtensions[:total+n]
72 return xs
73 }
74 func (fd *File) allocServices(n int) []Service {
75 total := len(fd.allServices)
76 xs := fd.allServices[total : total+n]
77 fd.allServices = fd.allServices[:total+n]
78 return xs
79 }
80
81
82
83 func (fd *File) checkDecls() {
84 switch {
85 case len(fd.allEnums) != cap(fd.allEnums):
86 case len(fd.allMessages) != cap(fd.allMessages):
87 case len(fd.allExtensions) != cap(fd.allExtensions):
88 case len(fd.allServices) != cap(fd.allServices):
89 default:
90 return
91 }
92 panic("mismatching cardinality")
93 }
94
95 func (fd *File) unmarshalSeed(b []byte) {
96 sb := getBuilder()
97 defer putBuilder(sb)
98
99 var prevField protoreflect.FieldNumber
100 var numEnums, numMessages, numExtensions, numServices int
101 var posEnums, posMessages, posExtensions, posServices int
102 var options []byte
103 b0 := b
104 for len(b) > 0 {
105 num, typ, n := protowire.ConsumeTag(b)
106 b = b[n:]
107 switch typ {
108 case protowire.BytesType:
109 v, m := protowire.ConsumeBytes(b)
110 b = b[m:]
111 switch num {
112 case genid.FileDescriptorProto_Syntax_field_number:
113 switch string(v) {
114 case "proto2":
115 fd.L1.Syntax = protoreflect.Proto2
116 fd.L1.Edition = EditionProto2
117 case "proto3":
118 fd.L1.Syntax = protoreflect.Proto3
119 fd.L1.Edition = EditionProto3
120 case "editions":
121 fd.L1.Syntax = protoreflect.Editions
122 default:
123 panic("invalid syntax")
124 }
125 case genid.FileDescriptorProto_Name_field_number:
126 fd.L1.Path = sb.MakeString(v)
127 case genid.FileDescriptorProto_Package_field_number:
128 fd.L1.Package = protoreflect.FullName(sb.MakeString(v))
129 case genid.FileDescriptorProto_Options_field_number:
130 options = v
131 case genid.FileDescriptorProto_EnumType_field_number:
132 if prevField != genid.FileDescriptorProto_EnumType_field_number {
133 if numEnums > 0 {
134 panic("non-contiguous repeated field")
135 }
136 posEnums = len(b0) - len(b) - n - m
137 }
138 numEnums++
139 case genid.FileDescriptorProto_MessageType_field_number:
140 if prevField != genid.FileDescriptorProto_MessageType_field_number {
141 if numMessages > 0 {
142 panic("non-contiguous repeated field")
143 }
144 posMessages = len(b0) - len(b) - n - m
145 }
146 numMessages++
147 case genid.FileDescriptorProto_Extension_field_number:
148 if prevField != genid.FileDescriptorProto_Extension_field_number {
149 if numExtensions > 0 {
150 panic("non-contiguous repeated field")
151 }
152 posExtensions = len(b0) - len(b) - n - m
153 }
154 numExtensions++
155 case genid.FileDescriptorProto_Service_field_number:
156 if prevField != genid.FileDescriptorProto_Service_field_number {
157 if numServices > 0 {
158 panic("non-contiguous repeated field")
159 }
160 posServices = len(b0) - len(b) - n - m
161 }
162 numServices++
163 }
164 prevField = num
165 case protowire.VarintType:
166 v, m := protowire.ConsumeVarint(b)
167 b = b[m:]
168 switch num {
169 case genid.FileDescriptorProto_Edition_field_number:
170 fd.L1.Edition = Edition(v)
171 }
172 default:
173 m := protowire.ConsumeFieldValue(num, typ, b)
174 b = b[m:]
175 prevField = -1
176 }
177 }
178
179
180 if fd.L1.Syntax == 0 {
181 fd.L1.Syntax = protoreflect.Proto2
182 fd.L1.Edition = EditionProto2
183 }
184
185 fd.L1.EditionFeatures = getFeaturesFor(fd.L1.Edition)
186
187
188 if options != nil {
189 fd.unmarshalSeedOptions(options)
190 }
191
192
193
194 if numEnums > 0 {
195 fd.L1.Enums.List = fd.allocEnums(numEnums)
196 }
197 if numMessages > 0 {
198 fd.L1.Messages.List = fd.allocMessages(numMessages)
199 }
200 if numExtensions > 0 {
201 fd.L1.Extensions.List = fd.allocExtensions(numExtensions)
202 }
203 if numServices > 0 {
204 fd.L1.Services.List = fd.allocServices(numServices)
205 }
206
207 if numEnums > 0 {
208 b := b0[posEnums:]
209 for i := range fd.L1.Enums.List {
210 _, n := protowire.ConsumeVarint(b)
211 v, m := protowire.ConsumeBytes(b[n:])
212 fd.L1.Enums.List[i].unmarshalSeed(v, sb, fd, fd, i)
213 b = b[n+m:]
214 }
215 }
216 if numMessages > 0 {
217 b := b0[posMessages:]
218 for i := range fd.L1.Messages.List {
219 _, n := protowire.ConsumeVarint(b)
220 v, m := protowire.ConsumeBytes(b[n:])
221 fd.L1.Messages.List[i].unmarshalSeed(v, sb, fd, fd, i)
222 b = b[n+m:]
223 }
224 }
225 if numExtensions > 0 {
226 b := b0[posExtensions:]
227 for i := range fd.L1.Extensions.List {
228 _, n := protowire.ConsumeVarint(b)
229 v, m := protowire.ConsumeBytes(b[n:])
230 fd.L1.Extensions.List[i].unmarshalSeed(v, sb, fd, fd, i)
231 b = b[n+m:]
232 }
233 }
234 if numServices > 0 {
235 b := b0[posServices:]
236 for i := range fd.L1.Services.List {
237 _, n := protowire.ConsumeVarint(b)
238 v, m := protowire.ConsumeBytes(b[n:])
239 fd.L1.Services.List[i].unmarshalSeed(v, sb, fd, fd, i)
240 b = b[n+m:]
241 }
242 }
243 }
244
245 func (fd *File) unmarshalSeedOptions(b []byte) {
246 for b := b; len(b) > 0; {
247 num, typ, n := protowire.ConsumeTag(b)
248 b = b[n:]
249 switch typ {
250 case protowire.BytesType:
251 v, m := protowire.ConsumeBytes(b)
252 b = b[m:]
253 switch num {
254 case genid.FileOptions_Features_field_number:
255 if fd.Syntax() != protoreflect.Editions {
256 panic(fmt.Sprintf("invalid descriptor: using edition features in a proto with syntax %s", fd.Syntax()))
257 }
258 fd.L1.EditionFeatures = unmarshalFeatureSet(v, fd.L1.EditionFeatures)
259 }
260 default:
261 m := protowire.ConsumeFieldValue(num, typ, b)
262 b = b[m:]
263 }
264 }
265 }
266
267 func (ed *Enum) unmarshalSeed(b []byte, sb *strs.Builder, pf *File, pd protoreflect.Descriptor, i int) {
268 ed.L0.ParentFile = pf
269 ed.L0.Parent = pd
270 ed.L0.Index = i
271 ed.L1.EditionFeatures = featuresFromParentDesc(ed.Parent())
272
273 var numValues int
274 for b := b; len(b) > 0; {
275 num, typ, n := protowire.ConsumeTag(b)
276 b = b[n:]
277 switch typ {
278 case protowire.BytesType:
279 v, m := protowire.ConsumeBytes(b)
280 b = b[m:]
281 switch num {
282 case genid.EnumDescriptorProto_Name_field_number:
283 ed.L0.FullName = appendFullName(sb, pd.FullName(), v)
284 case genid.EnumDescriptorProto_Value_field_number:
285 numValues++
286 }
287 default:
288 m := protowire.ConsumeFieldValue(num, typ, b)
289 b = b[m:]
290 }
291 }
292
293
294
295 if pd != pf {
296 return
297 }
298 ed.L1.eagerValues = true
299 ed.L2 = new(EnumL2)
300 ed.L2.Values.List = make([]EnumValue, numValues)
301 for i := 0; len(b) > 0; {
302 num, typ, n := protowire.ConsumeTag(b)
303 b = b[n:]
304 switch typ {
305 case protowire.BytesType:
306 v, m := protowire.ConsumeBytes(b)
307 b = b[m:]
308 switch num {
309 case genid.EnumDescriptorProto_Value_field_number:
310 ed.L2.Values.List[i].unmarshalFull(v, sb, pf, ed, i)
311 i++
312 }
313 default:
314 m := protowire.ConsumeFieldValue(num, typ, b)
315 b = b[m:]
316 }
317 }
318 }
319
320 func (md *Message) unmarshalSeed(b []byte, sb *strs.Builder, pf *File, pd protoreflect.Descriptor, i int) {
321 md.L0.ParentFile = pf
322 md.L0.Parent = pd
323 md.L0.Index = i
324 md.L1.EditionFeatures = featuresFromParentDesc(md.Parent())
325
326 var prevField protoreflect.FieldNumber
327 var numEnums, numMessages, numExtensions int
328 var posEnums, posMessages, posExtensions int
329 b0 := b
330 for len(b) > 0 {
331 num, typ, n := protowire.ConsumeTag(b)
332 b = b[n:]
333 switch typ {
334 case protowire.BytesType:
335 v, m := protowire.ConsumeBytes(b)
336 b = b[m:]
337 switch num {
338 case genid.DescriptorProto_Name_field_number:
339 md.L0.FullName = appendFullName(sb, pd.FullName(), v)
340 case genid.DescriptorProto_EnumType_field_number:
341 if prevField != genid.DescriptorProto_EnumType_field_number {
342 if numEnums > 0 {
343 panic("non-contiguous repeated field")
344 }
345 posEnums = len(b0) - len(b) - n - m
346 }
347 numEnums++
348 case genid.DescriptorProto_NestedType_field_number:
349 if prevField != genid.DescriptorProto_NestedType_field_number {
350 if numMessages > 0 {
351 panic("non-contiguous repeated field")
352 }
353 posMessages = len(b0) - len(b) - n - m
354 }
355 numMessages++
356 case genid.DescriptorProto_Extension_field_number:
357 if prevField != genid.DescriptorProto_Extension_field_number {
358 if numExtensions > 0 {
359 panic("non-contiguous repeated field")
360 }
361 posExtensions = len(b0) - len(b) - n - m
362 }
363 numExtensions++
364 case genid.DescriptorProto_Options_field_number:
365 md.unmarshalSeedOptions(v)
366 }
367 prevField = num
368 default:
369 m := protowire.ConsumeFieldValue(num, typ, b)
370 b = b[m:]
371 prevField = -1
372 }
373 }
374
375
376
377 if numEnums > 0 {
378 md.L1.Enums.List = pf.allocEnums(numEnums)
379 }
380 if numMessages > 0 {
381 md.L1.Messages.List = pf.allocMessages(numMessages)
382 }
383 if numExtensions > 0 {
384 md.L1.Extensions.List = pf.allocExtensions(numExtensions)
385 }
386
387 if numEnums > 0 {
388 b := b0[posEnums:]
389 for i := range md.L1.Enums.List {
390 _, n := protowire.ConsumeVarint(b)
391 v, m := protowire.ConsumeBytes(b[n:])
392 md.L1.Enums.List[i].unmarshalSeed(v, sb, pf, md, i)
393 b = b[n+m:]
394 }
395 }
396 if numMessages > 0 {
397 b := b0[posMessages:]
398 for i := range md.L1.Messages.List {
399 _, n := protowire.ConsumeVarint(b)
400 v, m := protowire.ConsumeBytes(b[n:])
401 md.L1.Messages.List[i].unmarshalSeed(v, sb, pf, md, i)
402 b = b[n+m:]
403 }
404 }
405 if numExtensions > 0 {
406 b := b0[posExtensions:]
407 for i := range md.L1.Extensions.List {
408 _, n := protowire.ConsumeVarint(b)
409 v, m := protowire.ConsumeBytes(b[n:])
410 md.L1.Extensions.List[i].unmarshalSeed(v, sb, pf, md, i)
411 b = b[n+m:]
412 }
413 }
414 }
415
416 func (md *Message) unmarshalSeedOptions(b []byte) {
417 for len(b) > 0 {
418 num, typ, n := protowire.ConsumeTag(b)
419 b = b[n:]
420 switch typ {
421 case protowire.VarintType:
422 v, m := protowire.ConsumeVarint(b)
423 b = b[m:]
424 switch num {
425 case genid.MessageOptions_MapEntry_field_number:
426 md.L1.IsMapEntry = protowire.DecodeBool(v)
427 case genid.MessageOptions_MessageSetWireFormat_field_number:
428 md.L1.IsMessageSet = protowire.DecodeBool(v)
429 }
430 case protowire.BytesType:
431 v, m := protowire.ConsumeBytes(b)
432 b = b[m:]
433 switch num {
434 case genid.MessageOptions_Features_field_number:
435 md.L1.EditionFeatures = unmarshalFeatureSet(v, md.L1.EditionFeatures)
436 }
437 default:
438 m := protowire.ConsumeFieldValue(num, typ, b)
439 b = b[m:]
440 }
441 }
442 }
443
444 func (xd *Extension) unmarshalSeed(b []byte, sb *strs.Builder, pf *File, pd protoreflect.Descriptor, i int) {
445 xd.L0.ParentFile = pf
446 xd.L0.Parent = pd
447 xd.L0.Index = i
448 xd.L1.EditionFeatures = featuresFromParentDesc(pd)
449
450 for len(b) > 0 {
451 num, typ, n := protowire.ConsumeTag(b)
452 b = b[n:]
453 switch typ {
454 case protowire.VarintType:
455 v, m := protowire.ConsumeVarint(b)
456 b = b[m:]
457 switch num {
458 case genid.FieldDescriptorProto_Number_field_number:
459 xd.L1.Number = protoreflect.FieldNumber(v)
460 case genid.FieldDescriptorProto_Label_field_number:
461 xd.L1.Cardinality = protoreflect.Cardinality(v)
462 case genid.FieldDescriptorProto_Type_field_number:
463 xd.L1.Kind = protoreflect.Kind(v)
464 }
465 case protowire.BytesType:
466 v, m := protowire.ConsumeBytes(b)
467 b = b[m:]
468 switch num {
469 case genid.FieldDescriptorProto_Name_field_number:
470 xd.L0.FullName = appendFullName(sb, pd.FullName(), v)
471 case genid.FieldDescriptorProto_Extendee_field_number:
472 xd.L1.Extendee = PlaceholderMessage(makeFullName(sb, v))
473 case genid.FieldDescriptorProto_Options_field_number:
474 xd.unmarshalOptions(v)
475 }
476 default:
477 m := protowire.ConsumeFieldValue(num, typ, b)
478 b = b[m:]
479 }
480 }
481
482 if xd.L1.Kind == protoreflect.MessageKind && xd.L1.EditionFeatures.IsDelimitedEncoded {
483 xd.L1.Kind = protoreflect.GroupKind
484 }
485 }
486
487 func (xd *Extension) unmarshalOptions(b []byte) {
488 for len(b) > 0 {
489 num, typ, n := protowire.ConsumeTag(b)
490 b = b[n:]
491 switch typ {
492 case protowire.VarintType:
493 v, m := protowire.ConsumeVarint(b)
494 b = b[m:]
495 switch num {
496 case genid.FieldOptions_Packed_field_number:
497 xd.L1.EditionFeatures.IsPacked = protowire.DecodeBool(v)
498 }
499 case protowire.BytesType:
500 v, m := protowire.ConsumeBytes(b)
501 b = b[m:]
502 switch num {
503 case genid.FieldOptions_Features_field_number:
504 xd.L1.EditionFeatures = unmarshalFeatureSet(v, xd.L1.EditionFeatures)
505 }
506 default:
507 m := protowire.ConsumeFieldValue(num, typ, b)
508 b = b[m:]
509 }
510 }
511 }
512
513 func (sd *Service) unmarshalSeed(b []byte, sb *strs.Builder, pf *File, pd protoreflect.Descriptor, i int) {
514 sd.L0.ParentFile = pf
515 sd.L0.Parent = pd
516 sd.L0.Index = i
517
518 for len(b) > 0 {
519 num, typ, n := protowire.ConsumeTag(b)
520 b = b[n:]
521 switch typ {
522 case protowire.BytesType:
523 v, m := protowire.ConsumeBytes(b)
524 b = b[m:]
525 switch num {
526 case genid.ServiceDescriptorProto_Name_field_number:
527 sd.L0.FullName = appendFullName(sb, pd.FullName(), v)
528 }
529 default:
530 m := protowire.ConsumeFieldValue(num, typ, b)
531 b = b[m:]
532 }
533 }
534 }
535
536 var nameBuilderPool = sync.Pool{
537 New: func() interface{} { return new(strs.Builder) },
538 }
539
540 func getBuilder() *strs.Builder {
541 return nameBuilderPool.Get().(*strs.Builder)
542 }
543 func putBuilder(b *strs.Builder) {
544 nameBuilderPool.Put(b)
545 }
546
547
548
549 func makeFullName(sb *strs.Builder, b []byte) protoreflect.FullName {
550 if len(b) == 0 || b[0] != '.' {
551 panic("name reference must be fully qualified")
552 }
553 return protoreflect.FullName(sb.MakeString(b[1:]))
554 }
555
556 func appendFullName(sb *strs.Builder, prefix protoreflect.FullName, suffix []byte) protoreflect.FullName {
557 return sb.AppendFullName(prefix, protoreflect.Name(strs.UnsafeString(suffix)))
558 }
559
View as plain text