podman

Форк
0
830 строк · 24.6 Кб
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 impl
6

7
import (
8
	"fmt"
9
	"reflect"
10
	"sync"
11

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"
18
)
19

20
type errInvalidUTF8 struct{}
21

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 }
25

26
// initOneofFieldCoders initializes the fast-path functions for the fields in a oneof.
27
//
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.
31
//
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()]
35
	ft := fs.Type
36
	oneofFields := make(map[reflect.Type]*coderFieldInfo)
37
	needIsInit := false
38
	fields := od.Fields()
39
	for i, lim := 0, fields.Len(); i < lim; i++ {
40
		fd := od.Fields().Get(i)
41
		num := fd.Number()
42
		// Make a copy of the original coderFieldInfo for use in unmarshaling.
43
		//
44
		// oneofFields[oneofType].funcs.marshal is the field-specific marshal function.
45
		//
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)
52
		oneofFields[ot] = &cf
53
		if cf.funcs.isInit != nil {
54
			needIsInit = true
55
		}
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 {
60
				vw = vi.Elem()
61
			} else {
62
				vw = reflect.New(ot)
63
			}
64
			out, err := cf.funcs.unmarshal(b, pointerOfValue(vw).Apply(zeroOffset), wtyp, &cf, opts)
65
			if err != nil {
66
				return out, err
67
			}
68
			vi.Set(vw)
69
			return out, nil
70
		}
71
	}
72
	getInfo := func(p pointer) (pointer, *coderFieldInfo) {
73
		v := p.AsValueOf(ft).Elem()
74
		if v.IsNil() {
75
			return pointer{}, nil
76
		}
77
		v = v.Elem() // interface -> *struct
78
		if v.IsNil() {
79
			return pointer{}, nil
80
		}
81
		return pointerOfValue(v).Apply(zeroOffset), oneofFields[v.Elem().Type()]
82
	}
83
	first := mi.coderFields[od.Fields().Get(0).Number()]
84
	first.funcs.size = func(p pointer, _ *coderFieldInfo, opts marshalOptions) int {
85
		p, info := getInfo(p)
86
		if info == nil || info.funcs.size == nil {
87
			return 0
88
		}
89
		return info.funcs.size(p, info, opts)
90
	}
91
	first.funcs.marshal = func(b []byte, p pointer, _ *coderFieldInfo, opts marshalOptions) ([]byte, error) {
92
		p, info := getInfo(p)
93
		if info == nil || info.funcs.marshal == nil {
94
			return b, nil
95
		}
96
		return info.funcs.marshal(b, p, info, opts)
97
	}
98
	first.funcs.merge = func(dst, src pointer, _ *coderFieldInfo, opts mergeOptions) {
99
		srcp, srcinfo := getInfo(src)
100
		if srcinfo == nil || srcinfo.funcs.merge == nil {
101
			return
102
		}
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)
107
		}
108
		srcinfo.funcs.merge(dstp, srcp, srcinfo, opts)
109
	}
110
	if needIsInit {
111
		first.funcs.isInit = func(p pointer, _ *coderFieldInfo) error {
112
			p, info := getInfo(p)
113
			if info == nil || info.funcs.isInit == nil {
114
				return nil
115
			}
116
			return info.funcs.isInit(p, info)
117
		}
118
	}
119
}
120

121
func makeWeakMessageFieldCoder(fd protoreflect.FieldDescriptor) pointerCoderFuncs {
122
	var once sync.Once
123
	var messageType protoreflect.MessageType
124
	lazyInit := func() {
125
		once.Do(func() {
126
			messageName := fd.Message().FullName()
127
			messageType, _ = protoregistry.GlobalTypes.FindMessageByName(messageName)
128
		})
129
	}
130

131
	return pointerCoderFuncs{
132
		size: func(p pointer, f *coderFieldInfo, opts marshalOptions) int {
133
			m, ok := p.WeakFields().get(f.num)
134
			if !ok {
135
				return 0
136
			}
137
			lazyInit()
138
			if messageType == nil {
139
				panic(fmt.Sprintf("weak message %v is not linked in", fd.Message().FullName()))
140
			}
141
			return sizeMessage(m, f.tagsize, opts)
142
		},
143
		marshal: func(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
144
			m, ok := p.WeakFields().get(f.num)
145
			if !ok {
146
				return b, nil
147
			}
148
			lazyInit()
149
			if messageType == nil {
150
				panic(fmt.Sprintf("weak message %v is not linked in", fd.Message().FullName()))
151
			}
152
			return appendMessage(b, m, f.wiretag, opts)
153
		},
154
		unmarshal: func(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (unmarshalOutput, error) {
155
			fs := p.WeakFields()
156
			m, ok := fs.get(f.num)
157
			if !ok {
158
				lazyInit()
159
				if messageType == nil {
160
					return unmarshalOutput{}, errUnknown
161
				}
162
				m = messageType.New().Interface()
163
				fs.set(f.num, m)
164
			}
165
			return consumeMessage(b, m, wtyp, opts)
166
		},
167
		isInit: func(p pointer, f *coderFieldInfo) error {
168
			m, ok := p.WeakFields().get(f.num)
169
			if !ok {
170
				return nil
171
			}
172
			return proto.CheckInitialized(m)
173
		},
174
		merge: func(dst, src pointer, f *coderFieldInfo, opts mergeOptions) {
175
			sm, ok := src.WeakFields().get(f.num)
176
			if !ok {
177
				return
178
			}
179
			dm, ok := dst.WeakFields().get(f.num)
180
			if !ok {
181
				lazyInit()
182
				if messageType == nil {
183
					panic(fmt.Sprintf("weak message %v is not linked in", fd.Message().FullName()))
184
				}
185
				dm = messageType.New().Interface()
186
				dst.WeakFields().set(f.num, dm)
187
			}
188
			opts.Merge(dm, sm)
189
		},
190
	}
191
}
192

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,
199
			merge:     mergeMessage,
200
		}
201
		if needsInitCheck(mi.Desc) {
202
			funcs.isInit = isInitMessageInfo
203
		}
204
		return funcs
205
	} else {
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)
210
			},
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)
214
			},
215
			unmarshal: func(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (unmarshalOutput, error) {
216
				mp := p.AsValueOf(ft).Elem()
217
				if mp.IsNil() {
218
					mp.Set(reflect.New(ft.Elem()))
219
				}
220
				return consumeMessage(b, asMessage(mp), wtyp, opts)
221
			},
222
			isInit: func(p pointer, f *coderFieldInfo) error {
223
				m := asMessage(p.AsValueOf(ft).Elem())
224
				return proto.CheckInitialized(m)
225
			},
226
			merge: mergeMessage,
227
		}
228
	}
229
}
230

231
func sizeMessageInfo(p pointer, f *coderFieldInfo, opts marshalOptions) int {
232
	return protowire.SizeBytes(f.mi.sizePointer(p.Elem(), opts)) + f.tagsize
233
}
234

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)
239
}
240

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
244
	}
245
	v, n := protowire.ConsumeBytes(b)
246
	if n < 0 {
247
		return out, errDecode
248
	}
249
	if p.Elem().IsNil() {
250
		p.SetPointer(pointerOfValue(reflect.New(f.mi.GoReflectType.Elem())))
251
	}
252
	o, err := f.mi.unmarshalPointer(v, p.Elem(), 0, opts)
253
	if err != nil {
254
		return out, err
255
	}
256
	out.n = n
257
	out.initialized = o.initialized
258
	return out, nil
259
}
260

261
func isInitMessageInfo(p pointer, f *coderFieldInfo) error {
262
	return f.mi.checkInitializedPointer(p.Elem())
263
}
264

265
func sizeMessage(m proto.Message, tagsize int, _ marshalOptions) int {
266
	return protowire.SizeBytes(proto.Size(m)) + tagsize
267
}
268

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)
273
}
274

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
278
	}
279
	v, n := protowire.ConsumeBytes(b)
280
	if n < 0 {
281
		return out, errDecode
282
	}
283
	o, err := opts.Options().UnmarshalState(protoiface.UnmarshalInput{
284
		Buf:     v,
285
		Message: m.ProtoReflect(),
286
	})
287
	if err != nil {
288
		return out, err
289
	}
290
	out.n = n
291
	out.initialized = o.Flags&protoiface.UnmarshalInitialized != 0
292
	return out, nil
293
}
294

295
func sizeMessageValue(v protoreflect.Value, tagsize int, opts marshalOptions) int {
296
	m := v.Message().Interface()
297
	return sizeMessage(m, tagsize, opts)
298
}
299

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)
303
}
304

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)
308
	return v, out, err
309
}
310

311
func isInitMessageValue(v protoreflect.Value) error {
312
	m := v.Message().Interface()
313
	return proto.CheckInitialized(m)
314
}
315

316
var coderMessageValue = valueCoderFuncs{
317
	size:      sizeMessageValue,
318
	marshal:   appendMessageValue,
319
	unmarshal: consumeMessageValue,
320
	isInit:    isInitMessageValue,
321
	merge:     mergeMessageValue,
322
}
323

324
func sizeGroupValue(v protoreflect.Value, tagsize int, opts marshalOptions) int {
325
	m := v.Message().Interface()
326
	return sizeGroup(m, tagsize, opts)
327
}
328

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)
332
}
333

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)
337
	return v, out, err
338
}
339

340
var coderGroupValue = valueCoderFuncs{
341
	size:      sizeGroupValue,
342
	marshal:   appendGroupValue,
343
	unmarshal: consumeGroupValue,
344
	isInit:    isInitMessageValue,
345
	merge:     mergeMessageValue,
346
}
347

348
func makeGroupFieldCoder(fd protoreflect.FieldDescriptor, ft reflect.Type) pointerCoderFuncs {
349
	num := fd.Number()
350
	if mi := getMessageInfo(ft); mi != nil {
351
		funcs := pointerCoderFuncs{
352
			size:      sizeGroupType,
353
			marshal:   appendGroupType,
354
			unmarshal: consumeGroupType,
355
			merge:     mergeMessage,
356
		}
357
		if needsInitCheck(mi.Desc) {
358
			funcs.isInit = isInitMessageInfo
359
		}
360
		return funcs
361
	} else {
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)
366
			},
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)
370
			},
371
			unmarshal: func(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (unmarshalOutput, error) {
372
				mp := p.AsValueOf(ft).Elem()
373
				if mp.IsNil() {
374
					mp.Set(reflect.New(ft.Elem()))
375
				}
376
				return consumeGroup(b, asMessage(mp), num, wtyp, opts)
377
			},
378
			isInit: func(p pointer, f *coderFieldInfo) error {
379
				m := asMessage(p.AsValueOf(ft).Elem())
380
				return proto.CheckInitialized(m)
381
			},
382
			merge: mergeMessage,
383
		}
384
	}
385
}
386

387
func sizeGroupType(p pointer, f *coderFieldInfo, opts marshalOptions) int {
388
	return 2*f.tagsize + f.mi.sizePointer(p.Elem(), opts)
389
}
390

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
395
	return b, err
396
}
397

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
401
	}
402
	if p.Elem().IsNil() {
403
		p.SetPointer(pointerOfValue(reflect.New(f.mi.GoReflectType.Elem())))
404
	}
405
	return f.mi.unmarshalPointer(b, p.Elem(), f.num, opts)
406
}
407

408
func sizeGroup(m proto.Message, tagsize int, _ marshalOptions) int {
409
	return 2*tagsize + proto.Size(m)
410
}
411

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
416
	return b, err
417
}
418

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
422
	}
423
	b, n := protowire.ConsumeGroup(num, b)
424
	if n < 0 {
425
		return out, errDecode
426
	}
427
	o, err := opts.Options().UnmarshalState(protoiface.UnmarshalInput{
428
		Buf:     b,
429
		Message: m.ProtoReflect(),
430
	})
431
	if err != nil {
432
		return out, err
433
	}
434
	out.n = n
435
	out.initialized = o.Flags&protoiface.UnmarshalInitialized != 0
436
	return out, nil
437
}
438

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,
446
		}
447
		if needsInitCheck(mi.Desc) {
448
			funcs.isInit = isInitMessageSliceInfo
449
		}
450
		return funcs
451
	}
452
	return pointerCoderFuncs{
453
		size: func(p pointer, f *coderFieldInfo, opts marshalOptions) int {
454
			return sizeMessageSlice(p, ft, f.tagsize, opts)
455
		},
456
		marshal: func(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
457
			return appendMessageSlice(b, p, f.wiretag, ft, opts)
458
		},
459
		unmarshal: func(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (unmarshalOutput, error) {
460
			return consumeMessageSlice(b, p, ft, wtyp, opts)
461
		},
462
		isInit: func(p pointer, f *coderFieldInfo) error {
463
			return isInitMessageSlice(p, ft)
464
		},
465
		merge: mergeMessageSlice,
466
	}
467
}
468

469
func sizeMessageSliceInfo(p pointer, f *coderFieldInfo, opts marshalOptions) int {
470
	s := p.PointerSlice()
471
	n := 0
472
	for _, v := range s {
473
		n += protowire.SizeBytes(f.mi.sizePointer(v, opts)) + f.tagsize
474
	}
475
	return n
476
}
477

478
func appendMessageSliceInfo(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
479
	s := p.PointerSlice()
480
	var err error
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)
486
		if err != nil {
487
			return b, err
488
		}
489
	}
490
	return b, nil
491
}
492

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
496
	}
497
	v, n := protowire.ConsumeBytes(b)
498
	if n < 0 {
499
		return out, errDecode
500
	}
501
	m := reflect.New(f.mi.GoReflectType.Elem()).Interface()
502
	mp := pointerOfIface(m)
503
	o, err := f.mi.unmarshalPointer(v, mp, 0, opts)
504
	if err != nil {
505
		return out, err
506
	}
507
	p.AppendPointerSlice(mp)
508
	out.n = n
509
	out.initialized = o.initialized
510
	return out, nil
511
}
512

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 {
517
			return err
518
		}
519
	}
520
	return nil
521
}
522

523
func sizeMessageSlice(p pointer, goType reflect.Type, tagsize int, _ marshalOptions) int {
524
	s := p.PointerSlice()
525
	n := 0
526
	for _, v := range s {
527
		m := asMessage(v.AsValueOf(goType.Elem()))
528
		n += protowire.SizeBytes(proto.Size(m)) + tagsize
529
	}
530
	return n
531
}
532

533
func appendMessageSlice(b []byte, p pointer, wiretag uint64, goType reflect.Type, opts marshalOptions) ([]byte, error) {
534
	s := p.PointerSlice()
535
	var err error
536
	for _, v := range s {
537
		m := asMessage(v.AsValueOf(goType.Elem()))
538
		b = protowire.AppendVarint(b, wiretag)
539
		siz := proto.Size(m)
540
		b = protowire.AppendVarint(b, uint64(siz))
541
		b, err = opts.Options().MarshalAppend(b, m)
542
		if err != nil {
543
			return b, err
544
		}
545
	}
546
	return b, nil
547
}
548

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
552
	}
553
	v, n := protowire.ConsumeBytes(b)
554
	if n < 0 {
555
		return out, errDecode
556
	}
557
	mp := reflect.New(goType.Elem())
558
	o, err := opts.Options().UnmarshalState(protoiface.UnmarshalInput{
559
		Buf:     v,
560
		Message: asMessage(mp).ProtoReflect(),
561
	})
562
	if err != nil {
563
		return out, err
564
	}
565
	p.AppendPointerSlice(pointerOfValue(mp))
566
	out.n = n
567
	out.initialized = o.Flags&protoiface.UnmarshalInitialized != 0
568
	return out, nil
569
}
570

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 {
576
			return err
577
		}
578
	}
579
	return nil
580
}
581

582
// Slices of messages
583

584
func sizeMessageSliceValue(listv protoreflect.Value, tagsize int, opts marshalOptions) int {
585
	list := listv.List()
586
	n := 0
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
590
	}
591
	return n
592
}
593

594
func appendMessageSliceValue(b []byte, listv protoreflect.Value, wiretag uint64, opts marshalOptions) ([]byte, error) {
595
	list := listv.List()
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)
600
		siz := proto.Size(m)
601
		b = protowire.AppendVarint(b, uint64(siz))
602
		var err error
603
		b, err = mopts.MarshalAppend(b, m)
604
		if err != nil {
605
			return b, err
606
		}
607
	}
608
	return b, nil
609
}
610

611
func consumeMessageSliceValue(b []byte, listv protoreflect.Value, _ protowire.Number, wtyp protowire.Type, opts unmarshalOptions) (_ protoreflect.Value, out unmarshalOutput, err error) {
612
	list := listv.List()
613
	if wtyp != protowire.BytesType {
614
		return protoreflect.Value{}, out, errUnknown
615
	}
616
	v, n := protowire.ConsumeBytes(b)
617
	if n < 0 {
618
		return protoreflect.Value{}, out, errDecode
619
	}
620
	m := list.NewElement()
621
	o, err := opts.Options().UnmarshalState(protoiface.UnmarshalInput{
622
		Buf:     v,
623
		Message: m.Message(),
624
	})
625
	if err != nil {
626
		return protoreflect.Value{}, out, err
627
	}
628
	list.Append(m)
629
	out.n = n
630
	out.initialized = o.Flags&protoiface.UnmarshalInitialized != 0
631
	return listv, out, nil
632
}
633

634
func isInitMessageSliceValue(listv protoreflect.Value) error {
635
	list := listv.List()
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 {
639
			return err
640
		}
641
	}
642
	return nil
643
}
644

645
var coderMessageSliceValue = valueCoderFuncs{
646
	size:      sizeMessageSliceValue,
647
	marshal:   appendMessageSliceValue,
648
	unmarshal: consumeMessageSliceValue,
649
	isInit:    isInitMessageSliceValue,
650
	merge:     mergeMessageListValue,
651
}
652

653
func sizeGroupSliceValue(listv protoreflect.Value, tagsize int, opts marshalOptions) int {
654
	list := listv.List()
655
	n := 0
656
	for i, llen := 0, list.Len(); i < llen; i++ {
657
		m := list.Get(i).Message().Interface()
658
		n += 2*tagsize + proto.Size(m)
659
	}
660
	return n
661
}
662

663
func appendGroupSliceValue(b []byte, listv protoreflect.Value, wiretag uint64, opts marshalOptions) ([]byte, error) {
664
	list := listv.List()
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
669
		var err error
670
		b, err = mopts.MarshalAppend(b, m)
671
		if err != nil {
672
			return b, err
673
		}
674
		b = protowire.AppendVarint(b, wiretag+1) // end group
675
	}
676
	return b, nil
677
}
678

679
func consumeGroupSliceValue(b []byte, listv protoreflect.Value, num protowire.Number, wtyp protowire.Type, opts unmarshalOptions) (_ protoreflect.Value, out unmarshalOutput, err error) {
680
	list := listv.List()
681
	if wtyp != protowire.StartGroupType {
682
		return protoreflect.Value{}, out, errUnknown
683
	}
684
	b, n := protowire.ConsumeGroup(num, b)
685
	if n < 0 {
686
		return protoreflect.Value{}, out, errDecode
687
	}
688
	m := list.NewElement()
689
	o, err := opts.Options().UnmarshalState(protoiface.UnmarshalInput{
690
		Buf:     b,
691
		Message: m.Message(),
692
	})
693
	if err != nil {
694
		return protoreflect.Value{}, out, err
695
	}
696
	list.Append(m)
697
	out.n = n
698
	out.initialized = o.Flags&protoiface.UnmarshalInitialized != 0
699
	return listv, out, nil
700
}
701

702
var coderGroupSliceValue = valueCoderFuncs{
703
	size:      sizeGroupSliceValue,
704
	marshal:   appendGroupSliceValue,
705
	unmarshal: consumeGroupSliceValue,
706
	isInit:    isInitMessageSliceValue,
707
	merge:     mergeMessageListValue,
708
}
709

710
func makeGroupSliceFieldCoder(fd protoreflect.FieldDescriptor, ft reflect.Type) pointerCoderFuncs {
711
	num := fd.Number()
712
	if mi := getMessageInfo(ft); mi != nil {
713
		funcs := pointerCoderFuncs{
714
			size:      sizeGroupSliceInfo,
715
			marshal:   appendGroupSliceInfo,
716
			unmarshal: consumeGroupSliceInfo,
717
			merge:     mergeMessageSlice,
718
		}
719
		if needsInitCheck(mi.Desc) {
720
			funcs.isInit = isInitMessageSliceInfo
721
		}
722
		return funcs
723
	}
724
	return pointerCoderFuncs{
725
		size: func(p pointer, f *coderFieldInfo, opts marshalOptions) int {
726
			return sizeGroupSlice(p, ft, f.tagsize, opts)
727
		},
728
		marshal: func(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
729
			return appendGroupSlice(b, p, f.wiretag, ft, opts)
730
		},
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)
733
		},
734
		isInit: func(p pointer, f *coderFieldInfo) error {
735
			return isInitMessageSlice(p, ft)
736
		},
737
		merge: mergeMessageSlice,
738
	}
739
}
740

741
func sizeGroupSlice(p pointer, messageType reflect.Type, tagsize int, _ marshalOptions) int {
742
	s := p.PointerSlice()
743
	n := 0
744
	for _, v := range s {
745
		m := asMessage(v.AsValueOf(messageType.Elem()))
746
		n += 2*tagsize + proto.Size(m)
747
	}
748
	return n
749
}
750

751
func appendGroupSlice(b []byte, p pointer, wiretag uint64, messageType reflect.Type, opts marshalOptions) ([]byte, error) {
752
	s := p.PointerSlice()
753
	var err error
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)
758
		if err != nil {
759
			return b, err
760
		}
761
		b = protowire.AppendVarint(b, wiretag+1) // end group
762
	}
763
	return b, nil
764
}
765

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
769
	}
770
	b, n := protowire.ConsumeGroup(num, b)
771
	if n < 0 {
772
		return out, errDecode
773
	}
774
	mp := reflect.New(goType.Elem())
775
	o, err := opts.Options().UnmarshalState(protoiface.UnmarshalInput{
776
		Buf:     b,
777
		Message: asMessage(mp).ProtoReflect(),
778
	})
779
	if err != nil {
780
		return out, err
781
	}
782
	p.AppendPointerSlice(pointerOfValue(mp))
783
	out.n = n
784
	out.initialized = o.Flags&protoiface.UnmarshalInitialized != 0
785
	return out, nil
786
}
787

788
func sizeGroupSliceInfo(p pointer, f *coderFieldInfo, opts marshalOptions) int {
789
	s := p.PointerSlice()
790
	n := 0
791
	for _, v := range s {
792
		n += 2*f.tagsize + f.mi.sizePointer(v, opts)
793
	}
794
	return n
795
}
796

797
func appendGroupSliceInfo(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
798
	s := p.PointerSlice()
799
	var err error
800
	for _, v := range s {
801
		b = protowire.AppendVarint(b, f.wiretag) // start group
802
		b, err = f.mi.marshalAppendPointer(b, v, opts)
803
		if err != nil {
804
			return b, err
805
		}
806
		b = protowire.AppendVarint(b, f.wiretag+1) // end group
807
	}
808
	return b, nil
809
}
810

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
814
	}
815
	m := reflect.New(f.mi.GoReflectType.Elem()).Interface()
816
	mp := pointerOfIface(m)
817
	out, err := f.mi.unmarshalPointer(b, mp, f.num, opts)
818
	if err != nil {
819
		return out, err
820
	}
821
	p.AppendPointerSlice(mp)
822
	return out, nil
823
}
824

825
func asMessage(v reflect.Value) protoreflect.ProtoMessage {
826
	if m, ok := v.Interface().(protoreflect.ProtoMessage); ok {
827
		return m
828
	}
829
	return legacyWrapMessage(v).Interface()
830
}
831

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.