blob: fc2235c68405542ae3a46c539d94f001845602e4 [file] [log] [blame]
Damien Neil8012b442019-01-18 09:32:24 -08001// Copyright 2018 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 fileinit
6
7import (
8 "bytes"
9 "fmt"
10 "reflect"
11
12 defval "github.com/golang/protobuf/v2/internal/encoding/defval"
13 wire "github.com/golang/protobuf/v2/internal/encoding/wire"
14 pimpl "github.com/golang/protobuf/v2/internal/impl"
15 pvalue "github.com/golang/protobuf/v2/internal/value"
16 pref "github.com/golang/protobuf/v2/reflect/protoreflect"
17 ptype "github.com/golang/protobuf/v2/reflect/prototype"
18)
19
20func (file *fileDesc) lazyInit() *fileLazy {
21 file.once.Do(func() {
22 file.unmarshalFull(file.RawDescriptor)
23 file.resolveImports()
24 file.resolveEnums()
25 file.resolveMessages()
26 file.resolveExtensions()
27 file.resolveServices()
28 file.finishInit()
29 })
30 return file.lazy
31}
32
33func (file *fileDesc) resolveImports() {
34 // TODO: Resolve file dependencies.
35}
36
37func (file *fileDesc) resolveEnums() {
38 enumDecls := file.GoTypes[:len(file.allEnums)]
39 for i := range file.allEnums {
40 ed := &file.allEnums[i]
41
42 // Associate the EnumType with a concrete Go type.
43 enumCache := map[pref.EnumNumber]pref.Enum{}
44 ed.lazy.typ = reflect.TypeOf(enumDecls[i])
45 ed.lazy.new = func(n pref.EnumNumber) pref.Enum {
46 if v, ok := enumCache[n]; ok {
47 return v
48 }
49 v := reflect.New(ed.lazy.typ).Elem()
50 v.SetInt(int64(n))
51 return v.Interface().(pref.Enum)
52 }
53 for i := range ed.lazy.values.list {
54 n := ed.lazy.values.list[i].number
55 enumCache[n] = ed.lazy.new(n)
56 }
57 }
58}
59
60func (file *fileDesc) resolveMessages() {
61 messageDecls := file.GoTypes[len(file.allEnums):]
62 for i := range file.allMessages {
63 md := &file.allMessages[i]
64
65 // Associate the MessageType with a concrete Go type.
66 //
67 // Note that descriptors for map entries, which have no associated
68 // Go type, also implement the protoreflect.MessageType interface,
69 // but have a GoType accessor that reports nil. Calling New results
70 // in a panic, which is sensible behavior.
71 md.lazy.typ = reflect.TypeOf(messageDecls[i])
72 md.lazy.new = func() pref.Message {
73 t := md.lazy.typ.Elem()
74 return reflect.New(t).Interface().(pref.ProtoMessage).ProtoReflect()
75 }
76
77 // Resolve message field dependencies.
78 for j := range md.lazy.fields.list {
79 fd := &md.lazy.fields.list[j]
80 if fd.isWeak {
81 continue
82 }
83
84 switch fd.kind {
85 case pref.EnumKind:
86 fd.enumType = file.popEnumDependency()
87 case pref.MessageKind, pref.GroupKind:
88 fd.messageType = file.popMessageDependency()
89 }
90 fd.isMap = file.isMapEntry(fd.messageType)
91 if !fd.hasPacked && file.lazy.syntax != pref.Proto2 && fd.cardinality == pref.Repeated {
92 switch fd.kind {
93 case pref.StringKind, pref.BytesKind, pref.MessageKind, pref.GroupKind:
94 fd.isPacked = false
95 default:
96 fd.isPacked = true
97 }
98 }
99 fd.defVal.lazyInit(fd.kind, file.enumValuesOf(fd.enumType))
100 }
101 }
102}
103
104func (file *fileDesc) resolveExtensions() {
105 for i := range file.allExtensions {
106 xd := &file.allExtensions[i]
107
108 // Associate the ExtensionType with a concrete Go type.
109 var typ reflect.Type
110 switch xd.lazy.kind {
111 case pref.EnumKind, pref.MessageKind, pref.GroupKind:
112 typ = reflect.TypeOf(file.GoTypes[file.DependencyIndexes[0]])
113 default:
114 typ = goTypeForPBKind[xd.lazy.kind]
115 }
116 switch xd.lazy.cardinality {
117 case pref.Optional:
118 switch xd.lazy.kind {
119 case pref.EnumKind:
120 xd.lazy.typ = typ
121 xd.lazy.new = func() pref.Value {
122 return xd.lazy.defVal.get()
123 }
124 xd.lazy.valueOf = func(v interface{}) pref.Value {
125 ev := v.(pref.Enum)
126 return pref.ValueOf(ev.Number())
127 }
128 xd.lazy.interfaceOf = func(pv pref.Value) interface{} {
129 return xd.lazy.enumType.New(pv.Enum())
130 }
131 case pref.MessageKind, pref.GroupKind:
132 xd.lazy.typ = typ
133 xd.lazy.new = func() pref.Value {
134 return pref.ValueOf(xd.lazy.messageType.New())
135 }
136 xd.lazy.valueOf = func(v interface{}) pref.Value {
137 mv := v.(pref.ProtoMessage).ProtoReflect()
138 return pref.ValueOf(mv)
139 }
140 xd.lazy.interfaceOf = func(pv pref.Value) interface{} {
141 return pv.Message().Interface()
142 }
143 default:
144 xd.lazy.typ = goTypeForPBKind[xd.lazy.kind]
145 xd.lazy.new = func() pref.Value {
146 return xd.lazy.defVal.get()
147 }
148 xd.lazy.valueOf = func(v interface{}) pref.Value {
149 return pref.ValueOf(v)
150 }
151 xd.lazy.interfaceOf = func(pv pref.Value) interface{} {
152 return pv.Interface()
153 }
154 }
155 case pref.Repeated:
156 c := pvalue.NewConverter(typ, xd.lazy.kind)
157 xd.lazy.typ = reflect.PtrTo(reflect.SliceOf(typ))
158 xd.lazy.new = func() pref.Value {
159 v := reflect.New(xd.lazy.typ.Elem()).Interface()
160 return pref.ValueOf(pvalue.ListOf(v, c))
161 }
162 xd.lazy.valueOf = func(v interface{}) pref.Value {
163 return pref.ValueOf(pvalue.ListOf(v, c))
164 }
165 xd.lazy.interfaceOf = func(pv pref.Value) interface{} {
166 return pv.List().(pvalue.Unwrapper).ProtoUnwrap()
167 }
168 default:
169 panic(fmt.Sprintf("invalid cardinality: %v", xd.lazy.cardinality))
170 }
171
172 // Resolve extension field dependency.
173 switch xd.lazy.kind {
174 case pref.EnumKind:
175 xd.lazy.enumType = file.popEnumDependency()
176 case pref.MessageKind, pref.GroupKind:
177 xd.lazy.messageType = file.popMessageDependency()
178 }
179 xd.lazy.defVal.lazyInit(xd.lazy.kind, file.enumValuesOf(xd.lazy.enumType))
180 }
181}
182
183var goTypeForPBKind = map[pref.Kind]reflect.Type{
184 pref.BoolKind: reflect.TypeOf(bool(false)),
185 pref.Int32Kind: reflect.TypeOf(int32(0)),
186 pref.Sint32Kind: reflect.TypeOf(int32(0)),
187 pref.Sfixed32Kind: reflect.TypeOf(int32(0)),
188 pref.Int64Kind: reflect.TypeOf(int64(0)),
189 pref.Sint64Kind: reflect.TypeOf(int64(0)),
190 pref.Sfixed64Kind: reflect.TypeOf(int64(0)),
191 pref.Uint32Kind: reflect.TypeOf(uint32(0)),
192 pref.Fixed32Kind: reflect.TypeOf(uint32(0)),
193 pref.Uint64Kind: reflect.TypeOf(uint64(0)),
194 pref.Fixed64Kind: reflect.TypeOf(uint64(0)),
195 pref.FloatKind: reflect.TypeOf(float32(0)),
196 pref.DoubleKind: reflect.TypeOf(float64(0)),
197 pref.StringKind: reflect.TypeOf(string("")),
198 pref.BytesKind: reflect.TypeOf([]byte(nil)),
199}
200
201func (file *fileDesc) resolveServices() {
202 for i := range file.services.list {
203 sd := &file.services.list[i]
204
205 // Resolve method dependencies.
206 for j := range sd.lazy.methods.list {
207 md := &sd.lazy.methods.list[j]
208 md.inputType = file.popMessageDependency()
209 md.outputType = file.popMessageDependency()
210 }
211 }
212}
213
214// isMapEntry reports whether the message is a map entry, being careful to
215// avoid calling the IsMapEntry method if the message is declared
216// within the same file (which would cause a recursive init deadlock).
217func (fd *fileDesc) isMapEntry(md pref.MessageDescriptor) bool {
218 if md == nil {
219 return false
220 }
221 if md, ok := md.(*messageDesc); ok && md.parentFile == fd {
222 return md.lazy.isMapEntry
223 }
224 return md.IsMapEntry()
225}
226
227// enumValuesOf retrieves the list of enum values for the given enum,
228// being careful to avoid calling the Values method if the enum is declared
229// within the same file (which would cause a recursive init deadlock).
230func (fd *fileDesc) enumValuesOf(ed pref.EnumDescriptor) pref.EnumValueDescriptors {
231 if ed == nil {
232 return nil
233 }
234 if ed, ok := ed.(*enumDesc); ok && ed.parentFile == fd {
235 return &ed.lazy.values
236 }
237 return ed.Values()
238}
239
240func (fd *fileDesc) popEnumDependency() pref.EnumType {
241 depIdx := fd.popDependencyIndex()
242 if depIdx < len(fd.allEnums)+len(fd.allMessages) {
243 return &fd.allEnums[depIdx]
244 } else {
245 return pimpl.Export{}.EnumTypeOf(fd.GoTypes[depIdx])
246 }
247}
248
249func (fd *fileDesc) popMessageDependency() pref.MessageType {
250 depIdx := fd.popDependencyIndex()
251 if depIdx < len(fd.allEnums)+len(fd.allMessages) {
252 return &fd.allMessages[depIdx-len(fd.allEnums)]
253 } else {
254 return pimpl.Export{}.MessageTypeOf(fd.GoTypes[depIdx])
255 }
256}
257
258func (fi *fileInit) popDependencyIndex() int {
259 depIdx := fi.DependencyIndexes[0]
260 fi.DependencyIndexes = fi.DependencyIndexes[1:]
261 return int(depIdx)
262}
263
264func (fi *fileInit) finishInit() {
265 if len(fi.DependencyIndexes) > 0 {
266 panic("unused dependencies")
267 }
268 *fi = fileInit{} // clear fileInit for GC to reclaim resources
269}
270
271type defaultValue struct {
272 has bool
273 val pref.Value
274 enum pref.EnumValueDescriptor
275 check func() // only set for non-empty bytes
276}
277
278func (dv *defaultValue) get() pref.Value {
279 if dv.check != nil {
280 dv.check()
281 }
282 return dv.val
283}
284
285func (dv *defaultValue) lazyInit(k pref.Kind, eds pref.EnumValueDescriptors) {
286 if dv.has {
287 switch k {
288 case pref.EnumKind:
289 // File descriptors always store default enums by name.
290 dv.enum = eds.ByName(pref.Name(dv.val.String()))
291 dv.val = pref.ValueOf(dv.enum.Number())
292 case pref.BytesKind:
293 // Store a copy of the default bytes, so that we can detect
294 // accidental mutations of the original value.
295 b := append([]byte(nil), dv.val.Bytes()...)
296 dv.check = func() {
297 if !bytes.Equal(b, dv.val.Bytes()) {
298 // TODO: Avoid panic if we're running with the race detector
299 // and instead spawn a goroutine that periodically resets
300 // this value back to the original to induce a race.
301 panic("detected mutation on the default bytes")
302 }
303 }
304 }
305 } else {
306 switch k {
307 case pref.BoolKind:
308 dv.val = pref.ValueOf(false)
309 case pref.Int32Kind, pref.Sint32Kind, pref.Sfixed32Kind:
310 dv.val = pref.ValueOf(int32(0))
311 case pref.Int64Kind, pref.Sint64Kind, pref.Sfixed64Kind:
312 dv.val = pref.ValueOf(int64(0))
313 case pref.Uint32Kind, pref.Fixed32Kind:
314 dv.val = pref.ValueOf(uint32(0))
315 case pref.Uint64Kind, pref.Fixed64Kind:
316 dv.val = pref.ValueOf(uint64(0))
317 case pref.FloatKind:
318 dv.val = pref.ValueOf(float32(0))
319 case pref.DoubleKind:
320 dv.val = pref.ValueOf(float64(0))
321 case pref.StringKind:
322 dv.val = pref.ValueOf(string(""))
323 case pref.BytesKind:
324 dv.val = pref.ValueOf([]byte(nil))
325 case pref.EnumKind:
326 dv.enum = eds.Get(0)
327 dv.val = pref.ValueOf(dv.enum.Number())
328 }
329 }
330}
331
332func (fd *fileDesc) unmarshalFull(b []byte) {
333 nb := getNameBuilder()
334 defer putNameBuilder(nb)
335
336 var hasSyntax bool
337 var enumIdx, messageIdx, extensionIdx, serviceIdx int
338 fd.lazy = &fileLazy{byName: make(map[pref.FullName]pref.Descriptor)}
339 for len(b) > 0 {
340 num, typ, n := wire.ConsumeTag(b)
341 b = b[n:]
342 switch typ {
343 case wire.VarintType:
344 v, m := wire.ConsumeVarint(b)
345 b = b[m:]
346 switch num {
347 case fileDesc_PublicImports:
348 fd.lazy.imports[v].IsPublic = true
349 case fileDesc_WeakImports:
350 fd.lazy.imports[v].IsWeak = true
351 }
352 case wire.BytesType:
353 v, m := wire.ConsumeBytes(b)
354 b = b[m:]
355 switch num {
356 case fileDesc_Syntax:
357 hasSyntax = true
358 switch string(v) {
359 case "proto2":
360 fd.lazy.syntax = pref.Proto2
361 case "proto3":
362 fd.lazy.syntax = pref.Proto3
363 default:
364 panic("invalid syntax")
365 }
366 case fileDesc_Imports:
367 fd.lazy.imports = append(fd.lazy.imports, pref.FileImport{
368 FileDescriptor: ptype.PlaceholderFile(nb.MakeString(v), ""),
369 })
370 case fileDesc_Enums:
371 fd.enums.list[enumIdx].unmarshalFull(v, nb)
372 enumIdx++
373 case fileDesc_Messages:
374 fd.messages.list[messageIdx].unmarshalFull(v, nb)
375 messageIdx++
376 case fileDesc_Extensions:
377 fd.extensions.list[extensionIdx].unmarshalFull(v, nb)
378 extensionIdx++
379 case fileDesc_Services:
380 fd.services.list[serviceIdx].unmarshalFull(v, nb)
381 serviceIdx++
382 case fileDesc_Options:
383 fd.lazy.options = append(fd.lazy.options, v...)
384 }
385 default:
386 m := wire.ConsumeFieldValue(num, typ, b)
387 b = b[m:]
388 }
389 }
390
391 // If syntax is missing, it is assumed to be proto2.
392 if !hasSyntax {
393 fd.lazy.syntax = pref.Proto2
394 }
395}
396
397func (ed *enumDesc) unmarshalFull(b []byte, nb *nameBuilder) {
398 var rawValues [][]byte
399 ed.lazy = new(enumLazy)
400 for len(b) > 0 {
401 num, typ, n := wire.ConsumeTag(b)
402 b = b[n:]
403 switch typ {
404 case wire.BytesType:
405 v, m := wire.ConsumeBytes(b)
406 b = b[m:]
407 switch num {
408 case enumDesc_Values:
409 rawValues = append(rawValues, v)
410 case enumDesc_ReservedNames:
411 ed.lazy.resvNames.list = append(ed.lazy.resvNames.list, pref.Name(nb.MakeString(v)))
412 case enumDesc_ReservedRanges:
413 ed.lazy.resvRanges.list = append(ed.lazy.resvRanges.list, unmarshalEnumReservedRange(v))
414 case enumDesc_Options:
415 ed.lazy.options = append(ed.lazy.options, v...)
416 }
417 default:
418 m := wire.ConsumeFieldValue(num, typ, b)
419 b = b[m:]
420 }
421 }
422
423 if len(rawValues) > 0 {
424 ed.lazy.values.list = make([]enumValueDesc, len(rawValues))
425 for i, b := range rawValues {
426 ed.lazy.values.list[i].unmarshalFull(b, nb, ed.parentFile, ed, i)
427 }
428 }
429
430 ed.parentFile.lazy.byName[ed.FullName()] = ed
431}
432
433func unmarshalEnumReservedRange(b []byte) (r [2]pref.EnumNumber) {
434 for len(b) > 0 {
435 num, typ, n := wire.ConsumeTag(b)
436 b = b[n:]
437 switch typ {
438 case wire.VarintType:
439 v, m := wire.ConsumeVarint(b)
440 b = b[m:]
441 switch num {
442 case enumReservedRange_Start:
443 r[0] = pref.EnumNumber(v)
444 case enumReservedRange_End:
445 r[1] = pref.EnumNumber(v)
446 }
447 default:
448 m := wire.ConsumeFieldValue(num, typ, b)
449 b = b[m:]
450 }
451 }
452 return r
453}
454
455func (vd *enumValueDesc) unmarshalFull(b []byte, nb *nameBuilder, pf *fileDesc, pd pref.Descriptor, i int) {
456 vd.parentFile = pf
457 vd.parent = pd
458 vd.index = i
459
460 for len(b) > 0 {
461 num, typ, n := wire.ConsumeTag(b)
462 b = b[n:]
463 switch typ {
464 case wire.VarintType:
465 v, m := wire.ConsumeVarint(b)
466 b = b[m:]
467 switch num {
468 case enumValueDesc_Number:
469 vd.number = pref.EnumNumber(v)
470 }
471 case wire.BytesType:
472 v, m := wire.ConsumeBytes(b)
473 b = b[m:]
474 switch num {
475 case enumValueDesc_Name:
476 vd.fullName = nb.AppendFullName(pd.FullName(), v)
477 case enumValueDesc_Options:
478 vd.options = append(vd.options, v...)
479 }
480 default:
481 m := wire.ConsumeFieldValue(num, typ, b)
482 b = b[m:]
483 }
484 }
485
486 vd.parentFile.lazy.byName[vd.FullName()] = vd
487}
488
489func (md *messageDesc) unmarshalFull(b []byte, nb *nameBuilder) {
490 var rawFields, rawOneofs [][]byte
491 var enumIdx, messageIdx, extensionIdx int
492 md.lazy = new(messageLazy)
493 for len(b) > 0 {
494 num, typ, n := wire.ConsumeTag(b)
495 b = b[n:]
496 switch typ {
497 case wire.BytesType:
498 v, m := wire.ConsumeBytes(b)
499 b = b[m:]
500 switch num {
501 case messageDesc_Fields:
502 rawFields = append(rawFields, v)
503 case messageDesc_Oneofs:
504 rawOneofs = append(rawOneofs, v)
505 case messageDesc_ReservedNames:
506 md.lazy.resvNames.list = append(md.lazy.resvNames.list, pref.Name(nb.MakeString(v)))
507 case messageDesc_ReservedRanges:
508 md.lazy.resvRanges.list = append(md.lazy.resvRanges.list, unmarshalMessageReservedRange(v))
509 case messageDesc_ExtensionRanges:
510 r, opts := unmarshalMessageExtensionRange(v)
511 md.lazy.extRanges.list = append(md.lazy.extRanges.list, r)
512 md.lazy.extRangeOptions = append(md.lazy.extRangeOptions, opts)
513 case messageDesc_Enums:
514 md.enums.list[enumIdx].unmarshalFull(v, nb)
515 enumIdx++
516 case messageDesc_Messages:
517 md.messages.list[messageIdx].unmarshalFull(v, nb)
518 messageIdx++
519 case messageDesc_Extensions:
520 md.extensions.list[extensionIdx].unmarshalFull(v, nb)
521 extensionIdx++
522 case messageDesc_Options:
523 md.unmarshalOptions(v)
524 }
525 default:
526 m := wire.ConsumeFieldValue(num, typ, b)
527 b = b[m:]
528 }
529 }
530
531 if len(rawFields) > 0 || len(rawOneofs) > 0 {
532 md.lazy.fields.list = make([]fieldDesc, len(rawFields))
533 md.lazy.oneofs.list = make([]oneofDesc, len(rawOneofs))
534 for i, b := range rawFields {
535 fd := &md.lazy.fields.list[i]
536 fd.unmarshalFull(b, nb, md.parentFile, md, i)
537 if fd.cardinality == pref.Required {
538 md.lazy.reqNumbers.list = append(md.lazy.reqNumbers.list, fd.number)
539 }
540 }
541 for i, b := range rawOneofs {
542 od := &md.lazy.oneofs.list[i]
543 od.unmarshalFull(b, nb, md.parentFile, md, i)
544 }
545 }
546
547 md.parentFile.lazy.byName[md.FullName()] = md
548}
549
550func (md *messageDesc) unmarshalOptions(b []byte) {
551 md.lazy.options = append(md.lazy.options, b...)
552 for len(b) > 0 {
553 num, typ, n := wire.ConsumeTag(b)
554 b = b[n:]
555 switch typ {
556 case wire.VarintType:
557 v, m := wire.ConsumeVarint(b)
558 b = b[m:]
559 switch num {
560 case messageOptions_IsMapEntry:
561 md.lazy.isMapEntry = wire.DecodeBool(v)
562 }
563 default:
564 m := wire.ConsumeFieldValue(num, typ, b)
565 b = b[m:]
566 }
567 }
568}
569
570func unmarshalMessageReservedRange(b []byte) (r [2]pref.FieldNumber) {
571 for len(b) > 0 {
572 num, typ, n := wire.ConsumeTag(b)
573 b = b[n:]
574 switch typ {
575 case wire.VarintType:
576 v, m := wire.ConsumeVarint(b)
577 b = b[m:]
578 switch num {
579 case messageReservedRange_Start:
580 r[0] = pref.FieldNumber(v)
581 case messageReservedRange_End:
582 r[1] = pref.FieldNumber(v)
583 }
584 default:
585 m := wire.ConsumeFieldValue(num, typ, b)
586 b = b[m:]
587 }
588 }
589 return r
590}
591
592func unmarshalMessageExtensionRange(b []byte) (r [2]pref.FieldNumber, opts []byte) {
593 for len(b) > 0 {
594 num, typ, n := wire.ConsumeTag(b)
595 b = b[n:]
596 switch typ {
597 case wire.VarintType:
598 v, m := wire.ConsumeVarint(b)
599 b = b[m:]
600 switch num {
601 case messageExtensionRange_Start:
602 r[0] = pref.FieldNumber(v)
603 case messageExtensionRange_End:
604 r[1] = pref.FieldNumber(v)
605 }
606 case wire.BytesType:
607 v, m := wire.ConsumeBytes(b)
608 b = b[m:]
609 switch num {
610 case messageExtensionRange_Options:
611 opts = append(opts, v...)
612 }
613 default:
614 m := wire.ConsumeFieldValue(num, typ, b)
615 b = b[m:]
616 }
617 }
618 return r, opts
619}
620
621func (fd *fieldDesc) unmarshalFull(b []byte, nb *nameBuilder, pf *fileDesc, pd pref.Descriptor, i int) {
622 fd.parentFile = pf
623 fd.parent = pd
624 fd.index = i
625
626 var rawDefVal []byte
627 var rawTypeName []byte
628 for len(b) > 0 {
629 num, typ, n := wire.ConsumeTag(b)
630 b = b[n:]
631 switch typ {
632 case wire.VarintType:
633 v, m := wire.ConsumeVarint(b)
634 b = b[m:]
635 switch num {
636 case fieldDesc_Number:
637 fd.number = pref.FieldNumber(v)
638 case fieldDesc_Cardinality:
639 fd.cardinality = pref.Cardinality(v)
640 case fieldDesc_Kind:
641 fd.kind = pref.Kind(v)
642 case fieldDesc_OneofIndex:
643 // In messageDesc.UnmarshalFull, we allocate slices for both
644 // the field and oneof descriptors before unmarshaling either
645 // of them. This ensures pointers to slice elements are stable.
646 od := &pd.(*messageDesc).lazy.oneofs.list[v]
647 od.fields.list = append(od.fields.list, fd)
648 if fd.oneofType != nil {
649 panic("oneof type already set")
650 }
651 fd.oneofType = od
652 }
653 case wire.BytesType:
654 v, m := wire.ConsumeBytes(b)
655 b = b[m:]
656 switch num {
657 case fieldDesc_Name:
658 fd.fullName = nb.AppendFullName(pd.FullName(), v)
659 case fieldDesc_JSONName:
660 fd.hasJSONName = true
661 fd.jsonName = nb.MakeString(v)
662 case fieldDesc_Default:
663 fd.defVal.has = true
664 rawDefVal = v
665 case fieldDesc_TypeName:
666 rawTypeName = v
667 case fieldDesc_Options:
668 fd.unmarshalOptions(v)
669 }
670 default:
671 m := wire.ConsumeFieldValue(num, typ, b)
672 b = b[m:]
673 }
674 }
675
676 if !fd.hasJSONName {
677 fd.jsonName = nb.MakeJSONName(fd.Name())
678 }
679 if rawDefVal != nil {
680 var err error
681 fd.defVal.val, err = defval.Unmarshal(string(rawDefVal), fd.kind, defval.Descriptor)
682 if err != nil {
683 panic(err)
684 }
685 }
686 if fd.isWeak {
687 if len(rawTypeName) == 0 || rawTypeName[0] != '.' {
688 panic("weak target name must be fully qualified")
689 }
690 fd.messageType = ptype.PlaceholderMessage(pref.FullName(rawTypeName[1:]))
691 }
692
693 fd.parentFile.lazy.byName[fd.FullName()] = fd
694}
695
696func (fd *fieldDesc) unmarshalOptions(b []byte) {
697 fd.options = append(fd.options, b...)
698 for len(b) > 0 {
699 num, typ, n := wire.ConsumeTag(b)
700 b = b[n:]
701 switch typ {
702 case wire.VarintType:
703 v, m := wire.ConsumeVarint(b)
704 b = b[m:]
705 switch num {
706 case fieldOptions_IsPacked:
707 fd.hasPacked = true
708 fd.isPacked = wire.DecodeBool(v)
709 case fieldOptions_IsWeak:
710 fd.isWeak = wire.DecodeBool(v)
711 }
712 default:
713 m := wire.ConsumeFieldValue(num, typ, b)
714 b = b[m:]
715 }
716 }
717}
718
719func (od *oneofDesc) unmarshalFull(b []byte, nb *nameBuilder, pf *fileDesc, pd pref.Descriptor, i int) {
720 od.parentFile = pf
721 od.parent = pd
722 od.index = i
723
724 for len(b) > 0 {
725 num, typ, n := wire.ConsumeTag(b)
726 b = b[n:]
727 switch typ {
728 case wire.BytesType:
729 v, m := wire.ConsumeBytes(b)
730 b = b[m:]
731 switch num {
732 case oneofDesc_Name:
733 od.fullName = nb.AppendFullName(pd.FullName(), v)
734 case oneofDesc_Options:
735 od.options = append(od.options, v...)
736 }
737 default:
738 m := wire.ConsumeFieldValue(num, typ, b)
739 b = b[m:]
740 }
741 }
742
743 od.parentFile.lazy.byName[od.FullName()] = od
744}
745
746func (xd *extensionDesc) unmarshalFull(b []byte, nb *nameBuilder) {
747 var rawDefVal []byte
748 xd.lazy = new(extensionLazy)
749 for len(b) > 0 {
750 num, typ, n := wire.ConsumeTag(b)
751 b = b[n:]
752 switch typ {
753 case wire.VarintType:
754 v, m := wire.ConsumeVarint(b)
755 b = b[m:]
756 switch num {
757 case fieldDesc_Cardinality:
758 xd.lazy.cardinality = pref.Cardinality(v)
759 case fieldDesc_Kind:
760 xd.lazy.kind = pref.Kind(v)
761 }
762 case wire.BytesType:
763 v, m := wire.ConsumeBytes(b)
764 b = b[m:]
765 switch num {
766 case fieldDesc_JSONName:
767 xd.lazy.hasJSONName = true
768 xd.lazy.jsonName = nb.MakeString(v)
769 case fieldDesc_Default:
770 xd.lazy.defVal.has = true
771 rawDefVal = v
772 case fieldDesc_Options:
773 xd.unmarshalOptions(v)
774 }
775 default:
776 m := wire.ConsumeFieldValue(num, typ, b)
777 b = b[m:]
778 }
779 }
780
781 if rawDefVal != nil {
782 var err error
783 xd.lazy.defVal.val, err = defval.Unmarshal(string(rawDefVal), xd.lazy.kind, defval.Descriptor)
784 if err != nil {
785 panic(err)
786 }
787 }
788
789 xd.parentFile.lazy.byName[xd.FullName()] = xd
790}
791
792func (xd *extensionDesc) unmarshalOptions(b []byte) {
793 xd.lazy.options = append(xd.lazy.options, b...)
794 for len(b) > 0 {
795 num, typ, n := wire.ConsumeTag(b)
796 b = b[n:]
797 switch typ {
798 case wire.VarintType:
799 v, m := wire.ConsumeVarint(b)
800 b = b[m:]
801 switch num {
802 case fieldOptions_IsPacked:
803 xd.lazy.isPacked = wire.DecodeBool(v)
804 }
805 default:
806 m := wire.ConsumeFieldValue(num, typ, b)
807 b = b[m:]
808 }
809 }
810}
811
812func (sd *serviceDesc) unmarshalFull(b []byte, nb *nameBuilder) {
813 var rawMethods [][]byte
814 sd.lazy = new(serviceLazy)
815 for len(b) > 0 {
816 num, typ, n := wire.ConsumeTag(b)
817 b = b[n:]
818 switch typ {
819 case wire.BytesType:
820 v, m := wire.ConsumeBytes(b)
821 b = b[m:]
822 switch num {
823 case serviceDesc_Methods:
824 rawMethods = append(rawMethods, v)
825 case serviceDesc_Options:
826 sd.lazy.options = append(sd.lazy.options, v...)
827 }
828 default:
829 m := wire.ConsumeFieldValue(num, typ, b)
830 b = b[m:]
831 }
832 }
833
834 if len(rawMethods) > 0 {
835 sd.lazy.methods.list = make([]methodDesc, len(rawMethods))
836 for i, b := range rawMethods {
837 sd.lazy.methods.list[i].unmarshalFull(b, nb, sd.parentFile, sd, i)
838 }
839 }
840
841 sd.parentFile.lazy.byName[sd.FullName()] = sd
842}
843
844func (md *methodDesc) unmarshalFull(b []byte, nb *nameBuilder, pf *fileDesc, pd pref.Descriptor, i int) {
845 md.parentFile = pf
846 md.parent = pd
847 md.index = i
848
849 for len(b) > 0 {
850 num, typ, n := wire.ConsumeTag(b)
851 b = b[n:]
852 switch typ {
853 case wire.VarintType:
854 v, m := wire.ConsumeVarint(b)
855 b = b[m:]
856 switch num {
857 case methodDesc_IsStreamingClient:
858 md.isStreamingClient = wire.DecodeBool(v)
859 case methodDesc_IsStreamingServer:
860 md.isStreamingServer = wire.DecodeBool(v)
861 }
862 case wire.BytesType:
863 v, m := wire.ConsumeBytes(b)
864 b = b[m:]
865 switch num {
866 case methodDesc_Name:
867 md.fullName = nb.AppendFullName(pd.FullName(), v)
868 case methodDesc_Options:
869 md.options = append(md.options, v...)
870 }
871 default:
872 m := wire.ConsumeFieldValue(num, typ, b)
873 b = b[m:]
874 }
875 }
876
877 md.parentFile.lazy.byName[md.FullName()] = md
878}