codec_field.go raw

   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  	"reflect"
   9  
  10  	"google.golang.org/protobuf/encoding/protowire"
  11  	"google.golang.org/protobuf/internal/errors"
  12  	"google.golang.org/protobuf/proto"
  13  	"google.golang.org/protobuf/reflect/protoreflect"
  14  	"google.golang.org/protobuf/runtime/protoiface"
  15  )
  16  
  17  type errInvalidUTF8 struct{}
  18  
  19  func (errInvalidUTF8) Error() string     { return "string field contains invalid UTF-8" }
  20  func (errInvalidUTF8) InvalidUTF8() bool { return true }
  21  func (errInvalidUTF8) Unwrap() error     { return errors.Error }
  22  
  23  // initOneofFieldCoders initializes the fast-path functions for the fields in a oneof.
  24  //
  25  // For size, marshal, and isInit operations, functions are set only on the first field
  26  // in the oneof. The functions are called when the oneof is non-nil, and will dispatch
  27  // to the appropriate field-specific function as necessary.
  28  //
  29  // The unmarshal function is set on each field individually as usual.
  30  func (mi *MessageInfo) initOneofFieldCoders(od protoreflect.OneofDescriptor, si structInfo) {
  31  	fs := si.oneofsByName[od.Name()]
  32  	ft := fs.Type
  33  	oneofFields := make(map[reflect.Type]*coderFieldInfo)
  34  	needIsInit := false
  35  	fields := od.Fields()
  36  	for i, lim := 0, fields.Len(); i < lim; i++ {
  37  		fd := od.Fields().Get(i)
  38  		num := fd.Number()
  39  		// Make a copy of the original coderFieldInfo for use in unmarshaling.
  40  		//
  41  		// oneofFields[oneofType].funcs.marshal is the field-specific marshal function.
  42  		//
  43  		// mi.coderFields[num].marshal is set on only the first field in the oneof,
  44  		// and dispatches to the field-specific marshaler in oneofFields.
  45  		cf := *mi.coderFields[num]
  46  		ot := si.oneofWrappersByNumber[num]
  47  		cf.ft = ot.Field(0).Type
  48  		cf.mi, cf.funcs = fieldCoder(fd, cf.ft)
  49  		oneofFields[ot] = &cf
  50  		if cf.funcs.isInit != nil {
  51  			needIsInit = true
  52  		}
  53  		mi.coderFields[num].funcs.unmarshal = func(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (unmarshalOutput, error) {
  54  			var vw reflect.Value         // pointer to wrapper type
  55  			vi := p.AsValueOf(ft).Elem() // oneof field value of interface kind
  56  			if !vi.IsNil() && !vi.Elem().IsNil() && vi.Elem().Elem().Type() == ot {
  57  				vw = vi.Elem()
  58  			} else {
  59  				vw = reflect.New(ot)
  60  			}
  61  			out, err := cf.funcs.unmarshal(b, pointerOfValue(vw).Apply(zeroOffset), wtyp, &cf, opts)
  62  			if err != nil {
  63  				return out, err
  64  			}
  65  			if cf.funcs.isInit == nil {
  66  				out.initialized = true
  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 makeMessageFieldCoder(fd protoreflect.FieldDescriptor, ft reflect.Type) pointerCoderFuncs {
 122  	if mi := getMessageInfo(ft); mi != nil {
 123  		funcs := pointerCoderFuncs{
 124  			size:      sizeMessageInfo,
 125  			marshal:   appendMessageInfo,
 126  			unmarshal: consumeMessageInfo,
 127  			merge:     mergeMessage,
 128  		}
 129  		if needsInitCheck(mi.Desc) {
 130  			funcs.isInit = isInitMessageInfo
 131  		}
 132  		return funcs
 133  	} else {
 134  		return pointerCoderFuncs{
 135  			size: func(p pointer, f *coderFieldInfo, opts marshalOptions) int {
 136  				m := asMessage(p.AsValueOf(ft).Elem())
 137  				return sizeMessage(m, f.tagsize, opts)
 138  			},
 139  			marshal: func(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
 140  				m := asMessage(p.AsValueOf(ft).Elem())
 141  				return appendMessage(b, m, f.wiretag, opts)
 142  			},
 143  			unmarshal: func(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (unmarshalOutput, error) {
 144  				mp := p.AsValueOf(ft).Elem()
 145  				if mp.IsNil() {
 146  					mp.Set(reflect.New(ft.Elem()))
 147  				}
 148  				return consumeMessage(b, asMessage(mp), wtyp, opts)
 149  			},
 150  			isInit: func(p pointer, f *coderFieldInfo) error {
 151  				m := asMessage(p.AsValueOf(ft).Elem())
 152  				return proto.CheckInitialized(m)
 153  			},
 154  			merge: mergeMessage,
 155  		}
 156  	}
 157  }
 158  
 159  func sizeMessageInfo(p pointer, f *coderFieldInfo, opts marshalOptions) int {
 160  	return protowire.SizeBytes(f.mi.sizePointer(p.Elem(), opts)) + f.tagsize
 161  }
 162  
 163  func appendMessageInfo(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
 164  	calculatedSize := f.mi.sizePointer(p.Elem(), opts)
 165  	b = protowire.AppendVarint(b, f.wiretag)
 166  	b = protowire.AppendVarint(b, uint64(calculatedSize))
 167  	before := len(b)
 168  	b, err := f.mi.marshalAppendPointer(b, p.Elem(), opts)
 169  	if measuredSize := len(b) - before; calculatedSize != measuredSize && err == nil {
 170  		return nil, errors.MismatchedSizeCalculation(calculatedSize, measuredSize)
 171  	}
 172  	return b, err
 173  }
 174  
 175  func consumeMessageInfo(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (out unmarshalOutput, err error) {
 176  	if wtyp != protowire.BytesType {
 177  		return out, errUnknown
 178  	}
 179  	v, n := protowire.ConsumeBytes(b)
 180  	if n < 0 {
 181  		return out, errDecode
 182  	}
 183  	if p.Elem().IsNil() {
 184  		p.SetPointer(pointerOfValue(reflect.New(f.mi.GoReflectType.Elem())))
 185  	}
 186  	o, err := f.mi.unmarshalPointer(v, p.Elem(), 0, opts)
 187  	if err != nil {
 188  		return out, err
 189  	}
 190  	out.n = n
 191  	out.initialized = o.initialized
 192  	return out, nil
 193  }
 194  
 195  func isInitMessageInfo(p pointer, f *coderFieldInfo) error {
 196  	return f.mi.checkInitializedPointer(p.Elem())
 197  }
 198  
 199  func sizeMessage(m proto.Message, tagsize int, opts marshalOptions) int {
 200  	return protowire.SizeBytes(opts.Options().Size(m)) + tagsize
 201  }
 202  
 203  func appendMessage(b []byte, m proto.Message, wiretag uint64, opts marshalOptions) ([]byte, error) {
 204  	mopts := opts.Options()
 205  	calculatedSize := mopts.Size(m)
 206  	b = protowire.AppendVarint(b, wiretag)
 207  	b = protowire.AppendVarint(b, uint64(calculatedSize))
 208  	before := len(b)
 209  	b, err := mopts.MarshalAppend(b, m)
 210  	if measuredSize := len(b) - before; calculatedSize != measuredSize && err == nil {
 211  		return nil, errors.MismatchedSizeCalculation(calculatedSize, measuredSize)
 212  	}
 213  	return b, err
 214  }
 215  
 216  func consumeMessage(b []byte, m proto.Message, wtyp protowire.Type, opts unmarshalOptions) (out unmarshalOutput, err error) {
 217  	if wtyp != protowire.BytesType {
 218  		return out, errUnknown
 219  	}
 220  	v, n := protowire.ConsumeBytes(b)
 221  	if n < 0 {
 222  		return out, errDecode
 223  	}
 224  	o, err := opts.Options().UnmarshalState(protoiface.UnmarshalInput{
 225  		Buf:     v,
 226  		Message: m.ProtoReflect(),
 227  	})
 228  	if err != nil {
 229  		return out, err
 230  	}
 231  	out.n = n
 232  	out.initialized = o.Flags&protoiface.UnmarshalInitialized != 0
 233  	return out, nil
 234  }
 235  
 236  func sizeMessageValue(v protoreflect.Value, tagsize int, opts marshalOptions) int {
 237  	m := v.Message().Interface()
 238  	return sizeMessage(m, tagsize, opts)
 239  }
 240  
 241  func appendMessageValue(b []byte, v protoreflect.Value, wiretag uint64, opts marshalOptions) ([]byte, error) {
 242  	m := v.Message().Interface()
 243  	return appendMessage(b, m, wiretag, opts)
 244  }
 245  
 246  func consumeMessageValue(b []byte, v protoreflect.Value, _ protowire.Number, wtyp protowire.Type, opts unmarshalOptions) (protoreflect.Value, unmarshalOutput, error) {
 247  	m := v.Message().Interface()
 248  	out, err := consumeMessage(b, m, wtyp, opts)
 249  	return v, out, err
 250  }
 251  
 252  func isInitMessageValue(v protoreflect.Value) error {
 253  	m := v.Message().Interface()
 254  	return proto.CheckInitialized(m)
 255  }
 256  
 257  var coderMessageValue = valueCoderFuncs{
 258  	size:      sizeMessageValue,
 259  	marshal:   appendMessageValue,
 260  	unmarshal: consumeMessageValue,
 261  	isInit:    isInitMessageValue,
 262  	merge:     mergeMessageValue,
 263  }
 264  
 265  func sizeGroupValue(v protoreflect.Value, tagsize int, opts marshalOptions) int {
 266  	m := v.Message().Interface()
 267  	return sizeGroup(m, tagsize, opts)
 268  }
 269  
 270  func appendGroupValue(b []byte, v protoreflect.Value, wiretag uint64, opts marshalOptions) ([]byte, error) {
 271  	m := v.Message().Interface()
 272  	return appendGroup(b, m, wiretag, opts)
 273  }
 274  
 275  func consumeGroupValue(b []byte, v protoreflect.Value, num protowire.Number, wtyp protowire.Type, opts unmarshalOptions) (protoreflect.Value, unmarshalOutput, error) {
 276  	m := v.Message().Interface()
 277  	out, err := consumeGroup(b, m, num, wtyp, opts)
 278  	return v, out, err
 279  }
 280  
 281  var coderGroupValue = valueCoderFuncs{
 282  	size:      sizeGroupValue,
 283  	marshal:   appendGroupValue,
 284  	unmarshal: consumeGroupValue,
 285  	isInit:    isInitMessageValue,
 286  	merge:     mergeMessageValue,
 287  }
 288  
 289  func makeGroupFieldCoder(fd protoreflect.FieldDescriptor, ft reflect.Type) pointerCoderFuncs {
 290  	num := fd.Number()
 291  	if mi := getMessageInfo(ft); mi != nil {
 292  		funcs := pointerCoderFuncs{
 293  			size:      sizeGroupType,
 294  			marshal:   appendGroupType,
 295  			unmarshal: consumeGroupType,
 296  			merge:     mergeMessage,
 297  		}
 298  		if needsInitCheck(mi.Desc) {
 299  			funcs.isInit = isInitMessageInfo
 300  		}
 301  		return funcs
 302  	} else {
 303  		return pointerCoderFuncs{
 304  			size: func(p pointer, f *coderFieldInfo, opts marshalOptions) int {
 305  				m := asMessage(p.AsValueOf(ft).Elem())
 306  				return sizeGroup(m, f.tagsize, opts)
 307  			},
 308  			marshal: func(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
 309  				m := asMessage(p.AsValueOf(ft).Elem())
 310  				return appendGroup(b, m, f.wiretag, opts)
 311  			},
 312  			unmarshal: func(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (unmarshalOutput, error) {
 313  				mp := p.AsValueOf(ft).Elem()
 314  				if mp.IsNil() {
 315  					mp.Set(reflect.New(ft.Elem()))
 316  				}
 317  				return consumeGroup(b, asMessage(mp), num, wtyp, opts)
 318  			},
 319  			isInit: func(p pointer, f *coderFieldInfo) error {
 320  				m := asMessage(p.AsValueOf(ft).Elem())
 321  				return proto.CheckInitialized(m)
 322  			},
 323  			merge: mergeMessage,
 324  		}
 325  	}
 326  }
 327  
 328  func sizeGroupType(p pointer, f *coderFieldInfo, opts marshalOptions) int {
 329  	return 2*f.tagsize + f.mi.sizePointer(p.Elem(), opts)
 330  }
 331  
 332  func appendGroupType(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
 333  	b = protowire.AppendVarint(b, f.wiretag) // start group
 334  	b, err := f.mi.marshalAppendPointer(b, p.Elem(), opts)
 335  	b = protowire.AppendVarint(b, f.wiretag+1) // end group
 336  	return b, err
 337  }
 338  
 339  func consumeGroupType(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (out unmarshalOutput, err error) {
 340  	if wtyp != protowire.StartGroupType {
 341  		return out, errUnknown
 342  	}
 343  	if p.Elem().IsNil() {
 344  		p.SetPointer(pointerOfValue(reflect.New(f.mi.GoReflectType.Elem())))
 345  	}
 346  	return f.mi.unmarshalPointer(b, p.Elem(), f.num, opts)
 347  }
 348  
 349  func sizeGroup(m proto.Message, tagsize int, opts marshalOptions) int {
 350  	return 2*tagsize + opts.Options().Size(m)
 351  }
 352  
 353  func appendGroup(b []byte, m proto.Message, wiretag uint64, opts marshalOptions) ([]byte, error) {
 354  	b = protowire.AppendVarint(b, wiretag) // start group
 355  	b, err := opts.Options().MarshalAppend(b, m)
 356  	b = protowire.AppendVarint(b, wiretag+1) // end group
 357  	return b, err
 358  }
 359  
 360  func consumeGroup(b []byte, m proto.Message, num protowire.Number, wtyp protowire.Type, opts unmarshalOptions) (out unmarshalOutput, err error) {
 361  	if wtyp != protowire.StartGroupType {
 362  		return out, errUnknown
 363  	}
 364  	b, n := protowire.ConsumeGroup(num, b)
 365  	if n < 0 {
 366  		return out, errDecode
 367  	}
 368  	o, err := opts.Options().UnmarshalState(protoiface.UnmarshalInput{
 369  		Buf:     b,
 370  		Message: m.ProtoReflect(),
 371  	})
 372  	if err != nil {
 373  		return out, err
 374  	}
 375  	out.n = n
 376  	out.initialized = o.Flags&protoiface.UnmarshalInitialized != 0
 377  	return out, nil
 378  }
 379  
 380  func makeMessageSliceFieldCoder(fd protoreflect.FieldDescriptor, ft reflect.Type) pointerCoderFuncs {
 381  	if mi := getMessageInfo(ft); mi != nil {
 382  		funcs := pointerCoderFuncs{
 383  			size:      sizeMessageSliceInfo,
 384  			marshal:   appendMessageSliceInfo,
 385  			unmarshal: consumeMessageSliceInfo,
 386  			merge:     mergeMessageSlice,
 387  		}
 388  		if needsInitCheck(mi.Desc) {
 389  			funcs.isInit = isInitMessageSliceInfo
 390  		}
 391  		return funcs
 392  	}
 393  	return pointerCoderFuncs{
 394  		size: func(p pointer, f *coderFieldInfo, opts marshalOptions) int {
 395  			return sizeMessageSlice(p, ft, f.tagsize, opts)
 396  		},
 397  		marshal: func(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
 398  			return appendMessageSlice(b, p, f.wiretag, ft, opts)
 399  		},
 400  		unmarshal: func(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (unmarshalOutput, error) {
 401  			return consumeMessageSlice(b, p, ft, wtyp, opts)
 402  		},
 403  		isInit: func(p pointer, f *coderFieldInfo) error {
 404  			return isInitMessageSlice(p, ft)
 405  		},
 406  		merge: mergeMessageSlice,
 407  	}
 408  }
 409  
 410  func sizeMessageSliceInfo(p pointer, f *coderFieldInfo, opts marshalOptions) int {
 411  	s := p.PointerSlice()
 412  	n := 0
 413  	for _, v := range s {
 414  		n += protowire.SizeBytes(f.mi.sizePointer(v, opts)) + f.tagsize
 415  	}
 416  	return n
 417  }
 418  
 419  func appendMessageSliceInfo(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
 420  	s := p.PointerSlice()
 421  	var err error
 422  	for _, v := range s {
 423  		b = protowire.AppendVarint(b, f.wiretag)
 424  		siz := f.mi.sizePointer(v, opts)
 425  		b = protowire.AppendVarint(b, uint64(siz))
 426  		before := len(b)
 427  		b, err = f.mi.marshalAppendPointer(b, v, opts)
 428  		if err != nil {
 429  			return b, err
 430  		}
 431  		if measuredSize := len(b) - before; siz != measuredSize {
 432  			return nil, errors.MismatchedSizeCalculation(siz, measuredSize)
 433  		}
 434  	}
 435  	return b, nil
 436  }
 437  
 438  func consumeMessageSliceInfo(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (out unmarshalOutput, err error) {
 439  	if wtyp != protowire.BytesType {
 440  		return out, errUnknown
 441  	}
 442  	v, n := protowire.ConsumeBytes(b)
 443  	if n < 0 {
 444  		return out, errDecode
 445  	}
 446  	m := reflect.New(f.mi.GoReflectType.Elem()).Interface()
 447  	mp := pointerOfIface(m)
 448  	o, err := f.mi.unmarshalPointer(v, mp, 0, opts)
 449  	if err != nil {
 450  		return out, err
 451  	}
 452  	p.AppendPointerSlice(mp)
 453  	out.n = n
 454  	out.initialized = o.initialized
 455  	return out, nil
 456  }
 457  
 458  func isInitMessageSliceInfo(p pointer, f *coderFieldInfo) error {
 459  	s := p.PointerSlice()
 460  	for _, v := range s {
 461  		if err := f.mi.checkInitializedPointer(v); err != nil {
 462  			return err
 463  		}
 464  	}
 465  	return nil
 466  }
 467  
 468  func sizeMessageSlice(p pointer, goType reflect.Type, tagsize int, opts marshalOptions) int {
 469  	mopts := opts.Options()
 470  	s := p.PointerSlice()
 471  	n := 0
 472  	for _, v := range s {
 473  		m := asMessage(v.AsValueOf(goType.Elem()))
 474  		n += protowire.SizeBytes(mopts.Size(m)) + tagsize
 475  	}
 476  	return n
 477  }
 478  
 479  func appendMessageSlice(b []byte, p pointer, wiretag uint64, goType reflect.Type, opts marshalOptions) ([]byte, error) {
 480  	mopts := opts.Options()
 481  	s := p.PointerSlice()
 482  	var err error
 483  	for _, v := range s {
 484  		m := asMessage(v.AsValueOf(goType.Elem()))
 485  		b = protowire.AppendVarint(b, wiretag)
 486  		siz := mopts.Size(m)
 487  		b = protowire.AppendVarint(b, uint64(siz))
 488  		before := len(b)
 489  		b, err = mopts.MarshalAppend(b, m)
 490  		if err != nil {
 491  			return b, err
 492  		}
 493  		if measuredSize := len(b) - before; siz != measuredSize {
 494  			return nil, errors.MismatchedSizeCalculation(siz, measuredSize)
 495  		}
 496  	}
 497  	return b, nil
 498  }
 499  
 500  func consumeMessageSlice(b []byte, p pointer, goType reflect.Type, wtyp protowire.Type, opts unmarshalOptions) (out unmarshalOutput, err error) {
 501  	if wtyp != protowire.BytesType {
 502  		return out, errUnknown
 503  	}
 504  	v, n := protowire.ConsumeBytes(b)
 505  	if n < 0 {
 506  		return out, errDecode
 507  	}
 508  	mp := reflect.New(goType.Elem())
 509  	o, err := opts.Options().UnmarshalState(protoiface.UnmarshalInput{
 510  		Buf:     v,
 511  		Message: asMessage(mp).ProtoReflect(),
 512  	})
 513  	if err != nil {
 514  		return out, err
 515  	}
 516  	p.AppendPointerSlice(pointerOfValue(mp))
 517  	out.n = n
 518  	out.initialized = o.Flags&protoiface.UnmarshalInitialized != 0
 519  	return out, nil
 520  }
 521  
 522  func isInitMessageSlice(p pointer, goType reflect.Type) error {
 523  	s := p.PointerSlice()
 524  	for _, v := range s {
 525  		m := asMessage(v.AsValueOf(goType.Elem()))
 526  		if err := proto.CheckInitialized(m); err != nil {
 527  			return err
 528  		}
 529  	}
 530  	return nil
 531  }
 532  
 533  // Slices of messages
 534  
 535  func sizeMessageSliceValue(listv protoreflect.Value, tagsize int, opts marshalOptions) int {
 536  	mopts := opts.Options()
 537  	list := listv.List()
 538  	n := 0
 539  	for i, llen := 0, list.Len(); i < llen; i++ {
 540  		m := list.Get(i).Message().Interface()
 541  		n += protowire.SizeBytes(mopts.Size(m)) + tagsize
 542  	}
 543  	return n
 544  }
 545  
 546  func appendMessageSliceValue(b []byte, listv protoreflect.Value, wiretag uint64, opts marshalOptions) ([]byte, error) {
 547  	list := listv.List()
 548  	mopts := opts.Options()
 549  	for i, llen := 0, list.Len(); i < llen; i++ {
 550  		m := list.Get(i).Message().Interface()
 551  		b = protowire.AppendVarint(b, wiretag)
 552  		siz := mopts.Size(m)
 553  		b = protowire.AppendVarint(b, uint64(siz))
 554  		before := len(b)
 555  		var err error
 556  		b, err = mopts.MarshalAppend(b, m)
 557  		if err != nil {
 558  			return b, err
 559  		}
 560  		if measuredSize := len(b) - before; siz != measuredSize {
 561  			return nil, errors.MismatchedSizeCalculation(siz, measuredSize)
 562  		}
 563  	}
 564  	return b, nil
 565  }
 566  
 567  func consumeMessageSliceValue(b []byte, listv protoreflect.Value, _ protowire.Number, wtyp protowire.Type, opts unmarshalOptions) (_ protoreflect.Value, out unmarshalOutput, err error) {
 568  	list := listv.List()
 569  	if wtyp != protowire.BytesType {
 570  		return protoreflect.Value{}, out, errUnknown
 571  	}
 572  	v, n := protowire.ConsumeBytes(b)
 573  	if n < 0 {
 574  		return protoreflect.Value{}, out, errDecode
 575  	}
 576  	m := list.NewElement()
 577  	o, err := opts.Options().UnmarshalState(protoiface.UnmarshalInput{
 578  		Buf:     v,
 579  		Message: m.Message(),
 580  	})
 581  	if err != nil {
 582  		return protoreflect.Value{}, out, err
 583  	}
 584  	list.Append(m)
 585  	out.n = n
 586  	out.initialized = o.Flags&protoiface.UnmarshalInitialized != 0
 587  	return listv, out, nil
 588  }
 589  
 590  func isInitMessageSliceValue(listv protoreflect.Value) error {
 591  	list := listv.List()
 592  	for i, llen := 0, list.Len(); i < llen; i++ {
 593  		m := list.Get(i).Message().Interface()
 594  		if err := proto.CheckInitialized(m); err != nil {
 595  			return err
 596  		}
 597  	}
 598  	return nil
 599  }
 600  
 601  var coderMessageSliceValue = valueCoderFuncs{
 602  	size:      sizeMessageSliceValue,
 603  	marshal:   appendMessageSliceValue,
 604  	unmarshal: consumeMessageSliceValue,
 605  	isInit:    isInitMessageSliceValue,
 606  	merge:     mergeMessageListValue,
 607  }
 608  
 609  func sizeGroupSliceValue(listv protoreflect.Value, tagsize int, opts marshalOptions) int {
 610  	mopts := opts.Options()
 611  	list := listv.List()
 612  	n := 0
 613  	for i, llen := 0, list.Len(); i < llen; i++ {
 614  		m := list.Get(i).Message().Interface()
 615  		n += 2*tagsize + mopts.Size(m)
 616  	}
 617  	return n
 618  }
 619  
 620  func appendGroupSliceValue(b []byte, listv protoreflect.Value, wiretag uint64, opts marshalOptions) ([]byte, error) {
 621  	list := listv.List()
 622  	mopts := opts.Options()
 623  	for i, llen := 0, list.Len(); i < llen; i++ {
 624  		m := list.Get(i).Message().Interface()
 625  		b = protowire.AppendVarint(b, wiretag) // start group
 626  		var err error
 627  		b, err = mopts.MarshalAppend(b, m)
 628  		if err != nil {
 629  			return b, err
 630  		}
 631  		b = protowire.AppendVarint(b, wiretag+1) // end group
 632  	}
 633  	return b, nil
 634  }
 635  
 636  func consumeGroupSliceValue(b []byte, listv protoreflect.Value, num protowire.Number, wtyp protowire.Type, opts unmarshalOptions) (_ protoreflect.Value, out unmarshalOutput, err error) {
 637  	list := listv.List()
 638  	if wtyp != protowire.StartGroupType {
 639  		return protoreflect.Value{}, out, errUnknown
 640  	}
 641  	b, n := protowire.ConsumeGroup(num, b)
 642  	if n < 0 {
 643  		return protoreflect.Value{}, out, errDecode
 644  	}
 645  	m := list.NewElement()
 646  	o, err := opts.Options().UnmarshalState(protoiface.UnmarshalInput{
 647  		Buf:     b,
 648  		Message: m.Message(),
 649  	})
 650  	if err != nil {
 651  		return protoreflect.Value{}, out, err
 652  	}
 653  	list.Append(m)
 654  	out.n = n
 655  	out.initialized = o.Flags&protoiface.UnmarshalInitialized != 0
 656  	return listv, out, nil
 657  }
 658  
 659  var coderGroupSliceValue = valueCoderFuncs{
 660  	size:      sizeGroupSliceValue,
 661  	marshal:   appendGroupSliceValue,
 662  	unmarshal: consumeGroupSliceValue,
 663  	isInit:    isInitMessageSliceValue,
 664  	merge:     mergeMessageListValue,
 665  }
 666  
 667  func makeGroupSliceFieldCoder(fd protoreflect.FieldDescriptor, ft reflect.Type) pointerCoderFuncs {
 668  	num := fd.Number()
 669  	if mi := getMessageInfo(ft); mi != nil {
 670  		funcs := pointerCoderFuncs{
 671  			size:      sizeGroupSliceInfo,
 672  			marshal:   appendGroupSliceInfo,
 673  			unmarshal: consumeGroupSliceInfo,
 674  			merge:     mergeMessageSlice,
 675  		}
 676  		if needsInitCheck(mi.Desc) {
 677  			funcs.isInit = isInitMessageSliceInfo
 678  		}
 679  		return funcs
 680  	}
 681  	return pointerCoderFuncs{
 682  		size: func(p pointer, f *coderFieldInfo, opts marshalOptions) int {
 683  			return sizeGroupSlice(p, ft, f.tagsize, opts)
 684  		},
 685  		marshal: func(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
 686  			return appendGroupSlice(b, p, f.wiretag, ft, opts)
 687  		},
 688  		unmarshal: func(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (unmarshalOutput, error) {
 689  			return consumeGroupSlice(b, p, num, wtyp, ft, opts)
 690  		},
 691  		isInit: func(p pointer, f *coderFieldInfo) error {
 692  			return isInitMessageSlice(p, ft)
 693  		},
 694  		merge: mergeMessageSlice,
 695  	}
 696  }
 697  
 698  func sizeGroupSlice(p pointer, messageType reflect.Type, tagsize int, opts marshalOptions) int {
 699  	mopts := opts.Options()
 700  	s := p.PointerSlice()
 701  	n := 0
 702  	for _, v := range s {
 703  		m := asMessage(v.AsValueOf(messageType.Elem()))
 704  		n += 2*tagsize + mopts.Size(m)
 705  	}
 706  	return n
 707  }
 708  
 709  func appendGroupSlice(b []byte, p pointer, wiretag uint64, messageType reflect.Type, opts marshalOptions) ([]byte, error) {
 710  	s := p.PointerSlice()
 711  	var err error
 712  	for _, v := range s {
 713  		m := asMessage(v.AsValueOf(messageType.Elem()))
 714  		b = protowire.AppendVarint(b, wiretag) // start group
 715  		b, err = opts.Options().MarshalAppend(b, m)
 716  		if err != nil {
 717  			return b, err
 718  		}
 719  		b = protowire.AppendVarint(b, wiretag+1) // end group
 720  	}
 721  	return b, nil
 722  }
 723  
 724  func consumeGroupSlice(b []byte, p pointer, num protowire.Number, wtyp protowire.Type, goType reflect.Type, opts unmarshalOptions) (out unmarshalOutput, err error) {
 725  	if wtyp != protowire.StartGroupType {
 726  		return out, errUnknown
 727  	}
 728  	b, n := protowire.ConsumeGroup(num, b)
 729  	if n < 0 {
 730  		return out, errDecode
 731  	}
 732  	mp := reflect.New(goType.Elem())
 733  	o, err := opts.Options().UnmarshalState(protoiface.UnmarshalInput{
 734  		Buf:     b,
 735  		Message: asMessage(mp).ProtoReflect(),
 736  	})
 737  	if err != nil {
 738  		return out, err
 739  	}
 740  	p.AppendPointerSlice(pointerOfValue(mp))
 741  	out.n = n
 742  	out.initialized = o.Flags&protoiface.UnmarshalInitialized != 0
 743  	return out, nil
 744  }
 745  
 746  func sizeGroupSliceInfo(p pointer, f *coderFieldInfo, opts marshalOptions) int {
 747  	s := p.PointerSlice()
 748  	n := 0
 749  	for _, v := range s {
 750  		n += 2*f.tagsize + f.mi.sizePointer(v, opts)
 751  	}
 752  	return n
 753  }
 754  
 755  func appendGroupSliceInfo(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
 756  	s := p.PointerSlice()
 757  	var err error
 758  	for _, v := range s {
 759  		b = protowire.AppendVarint(b, f.wiretag) // start group
 760  		b, err = f.mi.marshalAppendPointer(b, v, opts)
 761  		if err != nil {
 762  			return b, err
 763  		}
 764  		b = protowire.AppendVarint(b, f.wiretag+1) // end group
 765  	}
 766  	return b, nil
 767  }
 768  
 769  func consumeGroupSliceInfo(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (unmarshalOutput, error) {
 770  	if wtyp != protowire.StartGroupType {
 771  		return unmarshalOutput{}, errUnknown
 772  	}
 773  	m := reflect.New(f.mi.GoReflectType.Elem()).Interface()
 774  	mp := pointerOfIface(m)
 775  	out, err := f.mi.unmarshalPointer(b, mp, f.num, opts)
 776  	if err != nil {
 777  		return out, err
 778  	}
 779  	p.AppendPointerSlice(mp)
 780  	return out, nil
 781  }
 782  
 783  func asMessage(v reflect.Value) protoreflect.ProtoMessage {
 784  	if m, ok := v.Interface().(protoreflect.ProtoMessage); ok {
 785  		return m
 786  	}
 787  	return legacyWrapMessage(v).Interface()
 788  }
 789