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.
12
"google.golang.org/protobuf/encoding/protowire"
13
"google.golang.org/protobuf/internal/errors"
14
"google.golang.org/protobuf/proto"
15
"google.golang.org/protobuf/reflect/protoreflect"
16
"google.golang.org/protobuf/reflect/protoregistry"
17
"google.golang.org/protobuf/runtime/protoiface"
20
type errInvalidUTF8 struct{}
22
func (errInvalidUTF8) Error() string { return "string field contains invalid UTF-8" }
23
func (errInvalidUTF8) InvalidUTF8() bool { return true }
24
func (errInvalidUTF8) Unwrap() error { return errors.Error }
26
// initOneofFieldCoders initializes the fast-path functions for the fields in a oneof.
28
// For size, marshal, and isInit operations, functions are set only on the first field
29
// in the oneof. The functions are called when the oneof is non-nil, and will dispatch
30
// to the appropriate field-specific function as necessary.
32
// The unmarshal function is set on each field individually as usual.
33
func (mi *MessageInfo) initOneofFieldCoders(od protoreflect.OneofDescriptor, si structInfo) {
34
fs := si.oneofsByName[od.Name()]
36
oneofFields := make(map[reflect.Type]*coderFieldInfo)
39
for i, lim := 0, fields.Len(); i < lim; i++ {
40
fd := od.Fields().Get(i)
42
// Make a copy of the original coderFieldInfo for use in unmarshaling.
44
// oneofFields[oneofType].funcs.marshal is the field-specific marshal function.
46
// mi.coderFields[num].marshal is set on only the first field in the oneof,
47
// and dispatches to the field-specific marshaler in oneofFields.
48
cf := *mi.coderFields[num]
49
ot := si.oneofWrappersByNumber[num]
50
cf.ft = ot.Field(0).Type
51
cf.mi, cf.funcs = fieldCoder(fd, cf.ft)
53
if cf.funcs.isInit != nil {
56
mi.coderFields[num].funcs.unmarshal = func(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (unmarshalOutput, error) {
57
var vw reflect.Value // pointer to wrapper type
58
vi := p.AsValueOf(ft).Elem() // oneof field value of interface kind
59
if !vi.IsNil() && !vi.Elem().IsNil() && vi.Elem().Elem().Type() == ot {
64
out, err := cf.funcs.unmarshal(b, pointerOfValue(vw).Apply(zeroOffset), wtyp, &cf, opts)
72
getInfo := func(p pointer) (pointer, *coderFieldInfo) {
73
v := p.AsValueOf(ft).Elem()
77
v = v.Elem() // interface -> *struct
81
return pointerOfValue(v).Apply(zeroOffset), oneofFields[v.Elem().Type()]
83
first := mi.coderFields[od.Fields().Get(0).Number()]
84
first.funcs.size = func(p pointer, _ *coderFieldInfo, opts marshalOptions) int {
86
if info == nil || info.funcs.size == nil {
89
return info.funcs.size(p, info, opts)
91
first.funcs.marshal = func(b []byte, p pointer, _ *coderFieldInfo, opts marshalOptions) ([]byte, error) {
93
if info == nil || info.funcs.marshal == nil {
96
return info.funcs.marshal(b, p, info, opts)
98
first.funcs.merge = func(dst, src pointer, _ *coderFieldInfo, opts mergeOptions) {
99
srcp, srcinfo := getInfo(src)
100
if srcinfo == nil || srcinfo.funcs.merge == nil {
103
dstp, dstinfo := getInfo(dst)
104
if dstinfo != srcinfo {
105
dst.AsValueOf(ft).Elem().Set(reflect.New(src.AsValueOf(ft).Elem().Elem().Elem().Type()))
106
dstp = pointerOfValue(dst.AsValueOf(ft).Elem().Elem()).Apply(zeroOffset)
108
srcinfo.funcs.merge(dstp, srcp, srcinfo, opts)
111
first.funcs.isInit = func(p pointer, _ *coderFieldInfo) error {
112
p, info := getInfo(p)
113
if info == nil || info.funcs.isInit == nil {
116
return info.funcs.isInit(p, info)
121
func makeWeakMessageFieldCoder(fd protoreflect.FieldDescriptor) pointerCoderFuncs {
123
var messageType protoreflect.MessageType
126
messageName := fd.Message().FullName()
127
messageType, _ = protoregistry.GlobalTypes.FindMessageByName(messageName)
131
return pointerCoderFuncs{
132
size: func(p pointer, f *coderFieldInfo, opts marshalOptions) int {
133
m, ok := p.WeakFields().get(f.num)
138
if messageType == nil {
139
panic(fmt.Sprintf("weak message %v is not linked in", fd.Message().FullName()))
141
return sizeMessage(m, f.tagsize, opts)
143
marshal: func(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
144
m, ok := p.WeakFields().get(f.num)
149
if messageType == nil {
150
panic(fmt.Sprintf("weak message %v is not linked in", fd.Message().FullName()))
152
return appendMessage(b, m, f.wiretag, opts)
154
unmarshal: func(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (unmarshalOutput, error) {
156
m, ok := fs.get(f.num)
159
if messageType == nil {
160
return unmarshalOutput{}, errUnknown
162
m = messageType.New().Interface()
165
return consumeMessage(b, m, wtyp, opts)
167
isInit: func(p pointer, f *coderFieldInfo) error {
168
m, ok := p.WeakFields().get(f.num)
172
return proto.CheckInitialized(m)
174
merge: func(dst, src pointer, f *coderFieldInfo, opts mergeOptions) {
175
sm, ok := src.WeakFields().get(f.num)
179
dm, ok := dst.WeakFields().get(f.num)
182
if messageType == nil {
183
panic(fmt.Sprintf("weak message %v is not linked in", fd.Message().FullName()))
185
dm = messageType.New().Interface()
186
dst.WeakFields().set(f.num, dm)
193
func makeMessageFieldCoder(fd protoreflect.FieldDescriptor, ft reflect.Type) pointerCoderFuncs {
194
if mi := getMessageInfo(ft); mi != nil {
195
funcs := pointerCoderFuncs{
196
size: sizeMessageInfo,
197
marshal: appendMessageInfo,
198
unmarshal: consumeMessageInfo,
201
if needsInitCheck(mi.Desc) {
202
funcs.isInit = isInitMessageInfo
206
return pointerCoderFuncs{
207
size: func(p pointer, f *coderFieldInfo, opts marshalOptions) int {
208
m := asMessage(p.AsValueOf(ft).Elem())
209
return sizeMessage(m, f.tagsize, opts)
211
marshal: func(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
212
m := asMessage(p.AsValueOf(ft).Elem())
213
return appendMessage(b, m, f.wiretag, opts)
215
unmarshal: func(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (unmarshalOutput, error) {
216
mp := p.AsValueOf(ft).Elem()
218
mp.Set(reflect.New(ft.Elem()))
220
return consumeMessage(b, asMessage(mp), wtyp, opts)
222
isInit: func(p pointer, f *coderFieldInfo) error {
223
m := asMessage(p.AsValueOf(ft).Elem())
224
return proto.CheckInitialized(m)
231
func sizeMessageInfo(p pointer, f *coderFieldInfo, opts marshalOptions) int {
232
return protowire.SizeBytes(f.mi.sizePointer(p.Elem(), opts)) + f.tagsize
235
func appendMessageInfo(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
236
b = protowire.AppendVarint(b, f.wiretag)
237
b = protowire.AppendVarint(b, uint64(f.mi.sizePointer(p.Elem(), opts)))
238
return f.mi.marshalAppendPointer(b, p.Elem(), opts)
241
func consumeMessageInfo(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (out unmarshalOutput, err error) {
242
if wtyp != protowire.BytesType {
243
return out, errUnknown
245
v, n := protowire.ConsumeBytes(b)
247
return out, errDecode
249
if p.Elem().IsNil() {
250
p.SetPointer(pointerOfValue(reflect.New(f.mi.GoReflectType.Elem())))
252
o, err := f.mi.unmarshalPointer(v, p.Elem(), 0, opts)
257
out.initialized = o.initialized
261
func isInitMessageInfo(p pointer, f *coderFieldInfo) error {
262
return f.mi.checkInitializedPointer(p.Elem())
265
func sizeMessage(m proto.Message, tagsize int, _ marshalOptions) int {
266
return protowire.SizeBytes(proto.Size(m)) + tagsize
269
func appendMessage(b []byte, m proto.Message, wiretag uint64, opts marshalOptions) ([]byte, error) {
270
b = protowire.AppendVarint(b, wiretag)
271
b = protowire.AppendVarint(b, uint64(proto.Size(m)))
272
return opts.Options().MarshalAppend(b, m)
275
func consumeMessage(b []byte, m proto.Message, wtyp protowire.Type, opts unmarshalOptions) (out unmarshalOutput, err error) {
276
if wtyp != protowire.BytesType {
277
return out, errUnknown
279
v, n := protowire.ConsumeBytes(b)
281
return out, errDecode
283
o, err := opts.Options().UnmarshalState(protoiface.UnmarshalInput{
285
Message: m.ProtoReflect(),
291
out.initialized = o.Flags&protoiface.UnmarshalInitialized != 0
295
func sizeMessageValue(v protoreflect.Value, tagsize int, opts marshalOptions) int {
296
m := v.Message().Interface()
297
return sizeMessage(m, tagsize, opts)
300
func appendMessageValue(b []byte, v protoreflect.Value, wiretag uint64, opts marshalOptions) ([]byte, error) {
301
m := v.Message().Interface()
302
return appendMessage(b, m, wiretag, opts)
305
func consumeMessageValue(b []byte, v protoreflect.Value, _ protowire.Number, wtyp protowire.Type, opts unmarshalOptions) (protoreflect.Value, unmarshalOutput, error) {
306
m := v.Message().Interface()
307
out, err := consumeMessage(b, m, wtyp, opts)
311
func isInitMessageValue(v protoreflect.Value) error {
312
m := v.Message().Interface()
313
return proto.CheckInitialized(m)
316
var coderMessageValue = valueCoderFuncs{
317
size: sizeMessageValue,
318
marshal: appendMessageValue,
319
unmarshal: consumeMessageValue,
320
isInit: isInitMessageValue,
321
merge: mergeMessageValue,
324
func sizeGroupValue(v protoreflect.Value, tagsize int, opts marshalOptions) int {
325
m := v.Message().Interface()
326
return sizeGroup(m, tagsize, opts)
329
func appendGroupValue(b []byte, v protoreflect.Value, wiretag uint64, opts marshalOptions) ([]byte, error) {
330
m := v.Message().Interface()
331
return appendGroup(b, m, wiretag, opts)
334
func consumeGroupValue(b []byte, v protoreflect.Value, num protowire.Number, wtyp protowire.Type, opts unmarshalOptions) (protoreflect.Value, unmarshalOutput, error) {
335
m := v.Message().Interface()
336
out, err := consumeGroup(b, m, num, wtyp, opts)
340
var coderGroupValue = valueCoderFuncs{
341
size: sizeGroupValue,
342
marshal: appendGroupValue,
343
unmarshal: consumeGroupValue,
344
isInit: isInitMessageValue,
345
merge: mergeMessageValue,
348
func makeGroupFieldCoder(fd protoreflect.FieldDescriptor, ft reflect.Type) pointerCoderFuncs {
350
if mi := getMessageInfo(ft); mi != nil {
351
funcs := pointerCoderFuncs{
353
marshal: appendGroupType,
354
unmarshal: consumeGroupType,
357
if needsInitCheck(mi.Desc) {
358
funcs.isInit = isInitMessageInfo
362
return pointerCoderFuncs{
363
size: func(p pointer, f *coderFieldInfo, opts marshalOptions) int {
364
m := asMessage(p.AsValueOf(ft).Elem())
365
return sizeGroup(m, f.tagsize, opts)
367
marshal: func(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
368
m := asMessage(p.AsValueOf(ft).Elem())
369
return appendGroup(b, m, f.wiretag, opts)
371
unmarshal: func(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (unmarshalOutput, error) {
372
mp := p.AsValueOf(ft).Elem()
374
mp.Set(reflect.New(ft.Elem()))
376
return consumeGroup(b, asMessage(mp), num, wtyp, opts)
378
isInit: func(p pointer, f *coderFieldInfo) error {
379
m := asMessage(p.AsValueOf(ft).Elem())
380
return proto.CheckInitialized(m)
387
func sizeGroupType(p pointer, f *coderFieldInfo, opts marshalOptions) int {
388
return 2*f.tagsize + f.mi.sizePointer(p.Elem(), opts)
391
func appendGroupType(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
392
b = protowire.AppendVarint(b, f.wiretag) // start group
393
b, err := f.mi.marshalAppendPointer(b, p.Elem(), opts)
394
b = protowire.AppendVarint(b, f.wiretag+1) // end group
398
func consumeGroupType(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (out unmarshalOutput, err error) {
399
if wtyp != protowire.StartGroupType {
400
return out, errUnknown
402
if p.Elem().IsNil() {
403
p.SetPointer(pointerOfValue(reflect.New(f.mi.GoReflectType.Elem())))
405
return f.mi.unmarshalPointer(b, p.Elem(), f.num, opts)
408
func sizeGroup(m proto.Message, tagsize int, _ marshalOptions) int {
409
return 2*tagsize + proto.Size(m)
412
func appendGroup(b []byte, m proto.Message, wiretag uint64, opts marshalOptions) ([]byte, error) {
413
b = protowire.AppendVarint(b, wiretag) // start group
414
b, err := opts.Options().MarshalAppend(b, m)
415
b = protowire.AppendVarint(b, wiretag+1) // end group
419
func consumeGroup(b []byte, m proto.Message, num protowire.Number, wtyp protowire.Type, opts unmarshalOptions) (out unmarshalOutput, err error) {
420
if wtyp != protowire.StartGroupType {
421
return out, errUnknown
423
b, n := protowire.ConsumeGroup(num, b)
425
return out, errDecode
427
o, err := opts.Options().UnmarshalState(protoiface.UnmarshalInput{
429
Message: m.ProtoReflect(),
435
out.initialized = o.Flags&protoiface.UnmarshalInitialized != 0
439
func makeMessageSliceFieldCoder(fd protoreflect.FieldDescriptor, ft reflect.Type) pointerCoderFuncs {
440
if mi := getMessageInfo(ft); mi != nil {
441
funcs := pointerCoderFuncs{
442
size: sizeMessageSliceInfo,
443
marshal: appendMessageSliceInfo,
444
unmarshal: consumeMessageSliceInfo,
445
merge: mergeMessageSlice,
447
if needsInitCheck(mi.Desc) {
448
funcs.isInit = isInitMessageSliceInfo
452
return pointerCoderFuncs{
453
size: func(p pointer, f *coderFieldInfo, opts marshalOptions) int {
454
return sizeMessageSlice(p, ft, f.tagsize, opts)
456
marshal: func(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
457
return appendMessageSlice(b, p, f.wiretag, ft, opts)
459
unmarshal: func(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (unmarshalOutput, error) {
460
return consumeMessageSlice(b, p, ft, wtyp, opts)
462
isInit: func(p pointer, f *coderFieldInfo) error {
463
return isInitMessageSlice(p, ft)
465
merge: mergeMessageSlice,
469
func sizeMessageSliceInfo(p pointer, f *coderFieldInfo, opts marshalOptions) int {
470
s := p.PointerSlice()
472
for _, v := range s {
473
n += protowire.SizeBytes(f.mi.sizePointer(v, opts)) + f.tagsize
478
func appendMessageSliceInfo(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
479
s := p.PointerSlice()
481
for _, v := range s {
482
b = protowire.AppendVarint(b, f.wiretag)
483
siz := f.mi.sizePointer(v, opts)
484
b = protowire.AppendVarint(b, uint64(siz))
485
b, err = f.mi.marshalAppendPointer(b, v, opts)
493
func consumeMessageSliceInfo(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (out unmarshalOutput, err error) {
494
if wtyp != protowire.BytesType {
495
return out, errUnknown
497
v, n := protowire.ConsumeBytes(b)
499
return out, errDecode
501
m := reflect.New(f.mi.GoReflectType.Elem()).Interface()
502
mp := pointerOfIface(m)
503
o, err := f.mi.unmarshalPointer(v, mp, 0, opts)
507
p.AppendPointerSlice(mp)
509
out.initialized = o.initialized
513
func isInitMessageSliceInfo(p pointer, f *coderFieldInfo) error {
514
s := p.PointerSlice()
515
for _, v := range s {
516
if err := f.mi.checkInitializedPointer(v); err != nil {
523
func sizeMessageSlice(p pointer, goType reflect.Type, tagsize int, _ marshalOptions) int {
524
s := p.PointerSlice()
526
for _, v := range s {
527
m := asMessage(v.AsValueOf(goType.Elem()))
528
n += protowire.SizeBytes(proto.Size(m)) + tagsize
533
func appendMessageSlice(b []byte, p pointer, wiretag uint64, goType reflect.Type, opts marshalOptions) ([]byte, error) {
534
s := p.PointerSlice()
536
for _, v := range s {
537
m := asMessage(v.AsValueOf(goType.Elem()))
538
b = protowire.AppendVarint(b, wiretag)
540
b = protowire.AppendVarint(b, uint64(siz))
541
b, err = opts.Options().MarshalAppend(b, m)
549
func consumeMessageSlice(b []byte, p pointer, goType reflect.Type, wtyp protowire.Type, opts unmarshalOptions) (out unmarshalOutput, err error) {
550
if wtyp != protowire.BytesType {
551
return out, errUnknown
553
v, n := protowire.ConsumeBytes(b)
555
return out, errDecode
557
mp := reflect.New(goType.Elem())
558
o, err := opts.Options().UnmarshalState(protoiface.UnmarshalInput{
560
Message: asMessage(mp).ProtoReflect(),
565
p.AppendPointerSlice(pointerOfValue(mp))
567
out.initialized = o.Flags&protoiface.UnmarshalInitialized != 0
571
func isInitMessageSlice(p pointer, goType reflect.Type) error {
572
s := p.PointerSlice()
573
for _, v := range s {
574
m := asMessage(v.AsValueOf(goType.Elem()))
575
if err := proto.CheckInitialized(m); err != nil {
584
func sizeMessageSliceValue(listv protoreflect.Value, tagsize int, opts marshalOptions) int {
587
for i, llen := 0, list.Len(); i < llen; i++ {
588
m := list.Get(i).Message().Interface()
589
n += protowire.SizeBytes(proto.Size(m)) + tagsize
594
func appendMessageSliceValue(b []byte, listv protoreflect.Value, wiretag uint64, opts marshalOptions) ([]byte, error) {
596
mopts := opts.Options()
597
for i, llen := 0, list.Len(); i < llen; i++ {
598
m := list.Get(i).Message().Interface()
599
b = protowire.AppendVarint(b, wiretag)
601
b = protowire.AppendVarint(b, uint64(siz))
603
b, err = mopts.MarshalAppend(b, m)
611
func consumeMessageSliceValue(b []byte, listv protoreflect.Value, _ protowire.Number, wtyp protowire.Type, opts unmarshalOptions) (_ protoreflect.Value, out unmarshalOutput, err error) {
613
if wtyp != protowire.BytesType {
614
return protoreflect.Value{}, out, errUnknown
616
v, n := protowire.ConsumeBytes(b)
618
return protoreflect.Value{}, out, errDecode
620
m := list.NewElement()
621
o, err := opts.Options().UnmarshalState(protoiface.UnmarshalInput{
623
Message: m.Message(),
626
return protoreflect.Value{}, out, err
630
out.initialized = o.Flags&protoiface.UnmarshalInitialized != 0
631
return listv, out, nil
634
func isInitMessageSliceValue(listv protoreflect.Value) error {
636
for i, llen := 0, list.Len(); i < llen; i++ {
637
m := list.Get(i).Message().Interface()
638
if err := proto.CheckInitialized(m); err != nil {
645
var coderMessageSliceValue = valueCoderFuncs{
646
size: sizeMessageSliceValue,
647
marshal: appendMessageSliceValue,
648
unmarshal: consumeMessageSliceValue,
649
isInit: isInitMessageSliceValue,
650
merge: mergeMessageListValue,
653
func sizeGroupSliceValue(listv protoreflect.Value, tagsize int, opts marshalOptions) int {
656
for i, llen := 0, list.Len(); i < llen; i++ {
657
m := list.Get(i).Message().Interface()
658
n += 2*tagsize + proto.Size(m)
663
func appendGroupSliceValue(b []byte, listv protoreflect.Value, wiretag uint64, opts marshalOptions) ([]byte, error) {
665
mopts := opts.Options()
666
for i, llen := 0, list.Len(); i < llen; i++ {
667
m := list.Get(i).Message().Interface()
668
b = protowire.AppendVarint(b, wiretag) // start group
670
b, err = mopts.MarshalAppend(b, m)
674
b = protowire.AppendVarint(b, wiretag+1) // end group
679
func consumeGroupSliceValue(b []byte, listv protoreflect.Value, num protowire.Number, wtyp protowire.Type, opts unmarshalOptions) (_ protoreflect.Value, out unmarshalOutput, err error) {
681
if wtyp != protowire.StartGroupType {
682
return protoreflect.Value{}, out, errUnknown
684
b, n := protowire.ConsumeGroup(num, b)
686
return protoreflect.Value{}, out, errDecode
688
m := list.NewElement()
689
o, err := opts.Options().UnmarshalState(protoiface.UnmarshalInput{
691
Message: m.Message(),
694
return protoreflect.Value{}, out, err
698
out.initialized = o.Flags&protoiface.UnmarshalInitialized != 0
699
return listv, out, nil
702
var coderGroupSliceValue = valueCoderFuncs{
703
size: sizeGroupSliceValue,
704
marshal: appendGroupSliceValue,
705
unmarshal: consumeGroupSliceValue,
706
isInit: isInitMessageSliceValue,
707
merge: mergeMessageListValue,
710
func makeGroupSliceFieldCoder(fd protoreflect.FieldDescriptor, ft reflect.Type) pointerCoderFuncs {
712
if mi := getMessageInfo(ft); mi != nil {
713
funcs := pointerCoderFuncs{
714
size: sizeGroupSliceInfo,
715
marshal: appendGroupSliceInfo,
716
unmarshal: consumeGroupSliceInfo,
717
merge: mergeMessageSlice,
719
if needsInitCheck(mi.Desc) {
720
funcs.isInit = isInitMessageSliceInfo
724
return pointerCoderFuncs{
725
size: func(p pointer, f *coderFieldInfo, opts marshalOptions) int {
726
return sizeGroupSlice(p, ft, f.tagsize, opts)
728
marshal: func(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
729
return appendGroupSlice(b, p, f.wiretag, ft, opts)
731
unmarshal: func(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (unmarshalOutput, error) {
732
return consumeGroupSlice(b, p, num, wtyp, ft, opts)
734
isInit: func(p pointer, f *coderFieldInfo) error {
735
return isInitMessageSlice(p, ft)
737
merge: mergeMessageSlice,
741
func sizeGroupSlice(p pointer, messageType reflect.Type, tagsize int, _ marshalOptions) int {
742
s := p.PointerSlice()
744
for _, v := range s {
745
m := asMessage(v.AsValueOf(messageType.Elem()))
746
n += 2*tagsize + proto.Size(m)
751
func appendGroupSlice(b []byte, p pointer, wiretag uint64, messageType reflect.Type, opts marshalOptions) ([]byte, error) {
752
s := p.PointerSlice()
754
for _, v := range s {
755
m := asMessage(v.AsValueOf(messageType.Elem()))
756
b = protowire.AppendVarint(b, wiretag) // start group
757
b, err = opts.Options().MarshalAppend(b, m)
761
b = protowire.AppendVarint(b, wiretag+1) // end group
766
func consumeGroupSlice(b []byte, p pointer, num protowire.Number, wtyp protowire.Type, goType reflect.Type, opts unmarshalOptions) (out unmarshalOutput, err error) {
767
if wtyp != protowire.StartGroupType {
768
return out, errUnknown
770
b, n := protowire.ConsumeGroup(num, b)
772
return out, errDecode
774
mp := reflect.New(goType.Elem())
775
o, err := opts.Options().UnmarshalState(protoiface.UnmarshalInput{
777
Message: asMessage(mp).ProtoReflect(),
782
p.AppendPointerSlice(pointerOfValue(mp))
784
out.initialized = o.Flags&protoiface.UnmarshalInitialized != 0
788
func sizeGroupSliceInfo(p pointer, f *coderFieldInfo, opts marshalOptions) int {
789
s := p.PointerSlice()
791
for _, v := range s {
792
n += 2*f.tagsize + f.mi.sizePointer(v, opts)
797
func appendGroupSliceInfo(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
798
s := p.PointerSlice()
800
for _, v := range s {
801
b = protowire.AppendVarint(b, f.wiretag) // start group
802
b, err = f.mi.marshalAppendPointer(b, v, opts)
806
b = protowire.AppendVarint(b, f.wiretag+1) // end group
811
func consumeGroupSliceInfo(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (unmarshalOutput, error) {
812
if wtyp != protowire.StartGroupType {
813
return unmarshalOutput{}, errUnknown
815
m := reflect.New(f.mi.GoReflectType.Elem()).Interface()
816
mp := pointerOfIface(m)
817
out, err := f.mi.unmarshalPointer(b, mp, f.num, opts)
821
p.AppendPointerSlice(mp)
825
func asMessage(v reflect.Value) protoreflect.ProtoMessage {
826
if m, ok := v.Interface().(protoreflect.ProtoMessage); ok {
829
return legacyWrapMessage(v).Interface()