// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package impl

import (
	"fmt"
	"reflect"
	"sync"

	"google.golang.org/protobuf/internal/encoding/wire"
	"google.golang.org/protobuf/proto"
	pref "google.golang.org/protobuf/reflect/protoreflect"
	preg "google.golang.org/protobuf/reflect/protoregistry"
	piface "google.golang.org/protobuf/runtime/protoiface"
)

type errInvalidUTF8 struct{}

func (errInvalidUTF8) Error() string     { return "string field contains invalid UTF-8" }
func (errInvalidUTF8) InvalidUTF8() bool { return true }

// initOneofFieldCoders initializes the fast-path functions for the fields in a oneof.
//
// For size, marshal, and isInit operations, functions are set only on the first field
// in the oneof. The functions are called when the oneof is non-nil, and will dispatch
// to the appropriate field-specific function as necessary.
//
// The unmarshal function is set on each field individually as usual.
func (mi *MessageInfo) initOneofFieldCoders(od pref.OneofDescriptor, si structInfo) {
	fs := si.oneofsByName[od.Name()]
	ft := fs.Type
	oneofFields := make(map[reflect.Type]*coderFieldInfo)
	needIsInit := false
	fields := od.Fields()
	for i, lim := 0, fields.Len(); i < lim; i++ {
		fd := od.Fields().Get(i)
		num := fd.Number()
		// Make a copy of the original coderFieldInfo for use in unmarshaling.
		//
		// oneofFields[oneofType].funcs.marshal is the field-specific marshal function.
		//
		// mi.coderFields[num].marshal is set on only the first field in the oneof,
		// and dispatches to the field-specific marshaler in oneofFields.
		cf := *mi.coderFields[num]
		ot := si.oneofWrappersByNumber[num]
		cf.mi, cf.funcs = fieldCoder(fd, ot.Field(0).Type)
		oneofFields[ot] = &cf
		if cf.funcs.isInit != nil {
			needIsInit = true
		}
		mi.coderFields[num].funcs.unmarshal = func(b []byte, p pointer, wtyp wire.Type, f *coderFieldInfo, opts unmarshalOptions) (unmarshalOutput, error) {
			var vw reflect.Value         // pointer to wrapper type
			vi := p.AsValueOf(ft).Elem() // oneof field value of interface kind
			if !vi.IsNil() && !vi.Elem().IsNil() && vi.Elem().Elem().Type() == ot {
				vw = vi.Elem()
			} else {
				vw = reflect.New(ot)
			}
			out, err := cf.funcs.unmarshal(b, pointerOfValue(vw).Apply(zeroOffset), wtyp, &cf, opts)
			if err != nil {
				return out, err
			}
			vi.Set(vw)
			return out, nil
		}
	}
	getInfo := func(p pointer) (pointer, *coderFieldInfo) {
		v := p.AsValueOf(ft).Elem()
		if v.IsNil() {
			return pointer{}, nil
		}
		v = v.Elem() // interface -> *struct
		if v.IsNil() {
			return pointer{}, nil
		}
		return pointerOfValue(v).Apply(zeroOffset), oneofFields[v.Elem().Type()]
	}
	first := mi.coderFields[od.Fields().Get(0).Number()]
	first.funcs.size = func(p pointer, _ *coderFieldInfo, opts marshalOptions) int {
		p, info := getInfo(p)
		if info == nil || info.funcs.size == nil {
			return 0
		}
		return info.funcs.size(p, info, opts)
	}
	first.funcs.marshal = func(b []byte, p pointer, _ *coderFieldInfo, opts marshalOptions) ([]byte, error) {
		p, info := getInfo(p)
		if info == nil || info.funcs.marshal == nil {
			return b, nil
		}
		return info.funcs.marshal(b, p, info, opts)
	}
	if needIsInit {
		first.funcs.isInit = func(p pointer, _ *coderFieldInfo) error {
			p, info := getInfo(p)
			if info == nil || info.funcs.isInit == nil {
				return nil
			}
			return info.funcs.isInit(p, info)
		}
	}
}

func makeWeakMessageFieldCoder(fd pref.FieldDescriptor) pointerCoderFuncs {
	var once sync.Once
	var messageType pref.MessageType
	lazyInit := func() {
		once.Do(func() {
			messageName := fd.Message().FullName()
			messageType, _ = preg.GlobalTypes.FindMessageByName(messageName)
		})
	}

	num := fd.Number()
	return pointerCoderFuncs{
		size: func(p pointer, f *coderFieldInfo, opts marshalOptions) int {
			m, ok := p.WeakFields().get(num)
			if !ok {
				return 0
			}
			lazyInit()
			if messageType == nil {
				panic(fmt.Sprintf("weak message %v is not linked in", fd.Message().FullName()))
			}
			return sizeMessage(m, f.tagsize, opts)
		},
		marshal: func(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
			m, ok := p.WeakFields().get(num)
			if !ok {
				return b, nil
			}
			lazyInit()
			if messageType == nil {
				panic(fmt.Sprintf("weak message %v is not linked in", fd.Message().FullName()))
			}
			return appendMessage(b, m, f.wiretag, opts)
		},
		unmarshal: func(b []byte, p pointer, wtyp wire.Type, f *coderFieldInfo, opts unmarshalOptions) (unmarshalOutput, error) {
			fs := p.WeakFields()
			m, ok := fs.get(num)
			if !ok {
				lazyInit()
				if messageType == nil {
					return unmarshalOutput{}, errUnknown
				}
				m = messageType.New().Interface()
				fs.set(num, m)
			}
			return consumeMessage(b, m, wtyp, opts)
		},
		isInit: func(p pointer, f *coderFieldInfo) error {
			m, ok := p.WeakFields().get(num)
			if !ok {
				return nil
			}
			return proto.IsInitialized(m)
		},
	}
}

func makeMessageFieldCoder(fd pref.FieldDescriptor, ft reflect.Type) pointerCoderFuncs {
	if mi := getMessageInfo(ft); mi != nil {
		funcs := pointerCoderFuncs{
			size:      sizeMessageInfo,
			marshal:   appendMessageInfo,
			unmarshal: consumeMessageInfo,
		}
		if needsInitCheck(mi.Desc) {
			funcs.isInit = isInitMessageInfo
		}
		return funcs
	} else {
		return pointerCoderFuncs{
			size: func(p pointer, f *coderFieldInfo, opts marshalOptions) int {
				m := asMessage(p.AsValueOf(ft).Elem())
				return sizeMessage(m, f.tagsize, opts)
			},
			marshal: func(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
				m := asMessage(p.AsValueOf(ft).Elem())
				return appendMessage(b, m, f.wiretag, opts)
			},
			unmarshal: func(b []byte, p pointer, wtyp wire.Type, f *coderFieldInfo, opts unmarshalOptions) (unmarshalOutput, error) {
				mp := p.AsValueOf(ft).Elem()
				if mp.IsNil() {
					mp.Set(reflect.New(ft.Elem()))
				}
				return consumeMessage(b, asMessage(mp), wtyp, opts)
			},
			isInit: func(p pointer, f *coderFieldInfo) error {
				m := asMessage(p.AsValueOf(ft).Elem())
				return proto.IsInitialized(m)
			},
		}
	}
}

func sizeMessageInfo(p pointer, f *coderFieldInfo, opts marshalOptions) int {
	return wire.SizeBytes(f.mi.sizePointer(p.Elem(), opts)) + f.tagsize
}

func appendMessageInfo(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
	b = wire.AppendVarint(b, f.wiretag)
	b = wire.AppendVarint(b, uint64(f.mi.sizePointer(p.Elem(), opts)))
	return f.mi.marshalAppendPointer(b, p.Elem(), opts)
}

func consumeMessageInfo(b []byte, p pointer, wtyp wire.Type, f *coderFieldInfo, opts unmarshalOptions) (out unmarshalOutput, err error) {
	if wtyp != wire.BytesType {
		return out, errUnknown
	}
	v, n := wire.ConsumeBytes(b)
	if n < 0 {
		return out, wire.ParseError(n)
	}
	if p.Elem().IsNil() {
		p.SetPointer(pointerOfValue(reflect.New(f.mi.GoReflectType.Elem())))
	}
	o, err := f.mi.unmarshalPointer(v, p.Elem(), 0, opts)
	if err != nil {
		return out, err
	}
	out.n = n
	out.initialized = o.initialized
	return out, nil
}

func isInitMessageInfo(p pointer, f *coderFieldInfo) error {
	return f.mi.isInitializedPointer(p.Elem())
}

func sizeMessage(m proto.Message, tagsize int, _ marshalOptions) int {
	return wire.SizeBytes(proto.Size(m)) + tagsize
}

func appendMessage(b []byte, m proto.Message, wiretag uint64, opts marshalOptions) ([]byte, error) {
	b = wire.AppendVarint(b, wiretag)
	b = wire.AppendVarint(b, uint64(proto.Size(m)))
	return opts.Options().MarshalAppend(b, m)
}

func consumeMessage(b []byte, m proto.Message, wtyp wire.Type, opts unmarshalOptions) (out unmarshalOutput, err error) {
	if wtyp != wire.BytesType {
		return out, errUnknown
	}
	v, n := wire.ConsumeBytes(b)
	if n < 0 {
		return out, wire.ParseError(n)
	}
	o, err := opts.Options().UnmarshalState(m, piface.UnmarshalInput{
		Buf: v,
	})
	if err != nil {
		return out, err
	}
	out.n = n
	out.initialized = o.Initialized
	return out, nil
}

func sizeMessageValue(v pref.Value, tagsize int, opts marshalOptions) int {
	m := v.Message().Interface()
	return sizeMessage(m, tagsize, opts)
}

func appendMessageValue(b []byte, v pref.Value, wiretag uint64, opts marshalOptions) ([]byte, error) {
	m := v.Message().Interface()
	return appendMessage(b, m, wiretag, opts)
}

func consumeMessageValue(b []byte, v pref.Value, _ wire.Number, wtyp wire.Type, opts unmarshalOptions) (pref.Value, unmarshalOutput, error) {
	m := v.Message().Interface()
	out, err := consumeMessage(b, m, wtyp, opts)
	return v, out, err
}

func isInitMessageValue(v pref.Value) error {
	m := v.Message().Interface()
	return proto.IsInitialized(m)
}

var coderMessageValue = valueCoderFuncs{
	size:      sizeMessageValue,
	marshal:   appendMessageValue,
	unmarshal: consumeMessageValue,
	isInit:    isInitMessageValue,
}

func sizeGroupValue(v pref.Value, tagsize int, opts marshalOptions) int {
	m := v.Message().Interface()
	return sizeGroup(m, tagsize, opts)
}

func appendGroupValue(b []byte, v pref.Value, wiretag uint64, opts marshalOptions) ([]byte, error) {
	m := v.Message().Interface()
	return appendGroup(b, m, wiretag, opts)
}

func consumeGroupValue(b []byte, v pref.Value, num wire.Number, wtyp wire.Type, opts unmarshalOptions) (pref.Value, unmarshalOutput, error) {
	m := v.Message().Interface()
	out, err := consumeGroup(b, m, num, wtyp, opts)
	return v, out, err
}

var coderGroupValue = valueCoderFuncs{
	size:      sizeGroupValue,
	marshal:   appendGroupValue,
	unmarshal: consumeGroupValue,
	isInit:    isInitMessageValue,
}

func makeGroupFieldCoder(fd pref.FieldDescriptor, ft reflect.Type) pointerCoderFuncs {
	num := fd.Number()
	if mi := getMessageInfo(ft); mi != nil {
		funcs := pointerCoderFuncs{
			size:      sizeGroupType,
			marshal:   appendGroupType,
			unmarshal: consumeGroupType,
		}
		if needsInitCheck(mi.Desc) {
			funcs.isInit = isInitMessageInfo
		}
		return funcs
	} else {
		return pointerCoderFuncs{
			size: func(p pointer, f *coderFieldInfo, opts marshalOptions) int {
				m := asMessage(p.AsValueOf(ft).Elem())
				return sizeGroup(m, f.tagsize, opts)
			},
			marshal: func(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
				m := asMessage(p.AsValueOf(ft).Elem())
				return appendGroup(b, m, f.wiretag, opts)
			},
			unmarshal: func(b []byte, p pointer, wtyp wire.Type, f *coderFieldInfo, opts unmarshalOptions) (unmarshalOutput, error) {
				mp := p.AsValueOf(ft).Elem()
				if mp.IsNil() {
					mp.Set(reflect.New(ft.Elem()))
				}
				return consumeGroup(b, asMessage(mp), num, wtyp, opts)
			},
			isInit: func(p pointer, f *coderFieldInfo) error {
				m := asMessage(p.AsValueOf(ft).Elem())
				return proto.IsInitialized(m)
			},
		}
	}
}

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

func appendGroupType(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
	b = wire.AppendVarint(b, f.wiretag) // start group
	b, err := f.mi.marshalAppendPointer(b, p.Elem(), opts)
	b = wire.AppendVarint(b, f.wiretag+1) // end group
	return b, err
}

func consumeGroupType(b []byte, p pointer, wtyp wire.Type, f *coderFieldInfo, opts unmarshalOptions) (out unmarshalOutput, err error) {
	if wtyp != wire.StartGroupType {
		return out, errUnknown
	}
	if p.Elem().IsNil() {
		p.SetPointer(pointerOfValue(reflect.New(f.mi.GoReflectType.Elem())))
	}
	return f.mi.unmarshalPointer(b, p.Elem(), f.num, opts)
}

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

func appendGroup(b []byte, m proto.Message, wiretag uint64, opts marshalOptions) ([]byte, error) {
	b = wire.AppendVarint(b, wiretag) // start group
	b, err := opts.Options().MarshalAppend(b, m)
	b = wire.AppendVarint(b, wiretag+1) // end group
	return b, err
}

func consumeGroup(b []byte, m proto.Message, num wire.Number, wtyp wire.Type, opts unmarshalOptions) (out unmarshalOutput, err error) {
	if wtyp != wire.StartGroupType {
		return out, errUnknown
	}
	b, n := wire.ConsumeGroup(num, b)
	if n < 0 {
		return out, wire.ParseError(n)
	}
	o, err := opts.Options().UnmarshalState(m, piface.UnmarshalInput{
		Buf: b,
	})
	if err != nil {
		return out, err
	}
	out.n = n
	out.initialized = o.Initialized
	return out, nil
}

func makeMessageSliceFieldCoder(fd pref.FieldDescriptor, ft reflect.Type) pointerCoderFuncs {
	if mi := getMessageInfo(ft); mi != nil {
		funcs := pointerCoderFuncs{
			size:      sizeMessageSliceInfo,
			marshal:   appendMessageSliceInfo,
			unmarshal: consumeMessageSliceInfo,
		}
		if needsInitCheck(mi.Desc) {
			funcs.isInit = isInitMessageSliceInfo
		}
		return funcs
	}
	return pointerCoderFuncs{
		size: func(p pointer, f *coderFieldInfo, opts marshalOptions) int {
			return sizeMessageSlice(p, ft, f.tagsize, opts)
		},
		marshal: func(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
			return appendMessageSlice(b, p, f.wiretag, ft, opts)
		},
		unmarshal: func(b []byte, p pointer, wtyp wire.Type, f *coderFieldInfo, opts unmarshalOptions) (unmarshalOutput, error) {
			return consumeMessageSlice(b, p, ft, wtyp, opts)
		},
		isInit: func(p pointer, f *coderFieldInfo) error {
			return isInitMessageSlice(p, ft)
		},
	}
}

func sizeMessageSliceInfo(p pointer, f *coderFieldInfo, opts marshalOptions) int {
	s := p.PointerSlice()
	n := 0
	for _, v := range s {
		n += wire.SizeBytes(f.mi.sizePointer(v, opts)) + f.tagsize
	}
	return n
}

func appendMessageSliceInfo(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
	s := p.PointerSlice()
	var err error
	for _, v := range s {
		b = wire.AppendVarint(b, f.wiretag)
		siz := f.mi.sizePointer(v, opts)
		b = wire.AppendVarint(b, uint64(siz))
		b, err = f.mi.marshalAppendPointer(b, v, opts)
		if err != nil {
			return b, err
		}
	}
	return b, nil
}

func consumeMessageSliceInfo(b []byte, p pointer, wtyp wire.Type, f *coderFieldInfo, opts unmarshalOptions) (out unmarshalOutput, err error) {
	if wtyp != wire.BytesType {
		return out, errUnknown
	}
	v, n := wire.ConsumeBytes(b)
	if n < 0 {
		return out, wire.ParseError(n)
	}
	m := reflect.New(f.mi.GoReflectType.Elem()).Interface()
	mp := pointerOfIface(m)
	o, err := f.mi.unmarshalPointer(v, mp, 0, opts)
	if err != nil {
		return out, err
	}
	p.AppendPointerSlice(mp)
	out.n = n
	out.initialized = o.initialized
	return out, nil
}

func isInitMessageSliceInfo(p pointer, f *coderFieldInfo) error {
	s := p.PointerSlice()
	for _, v := range s {
		if err := f.mi.isInitializedPointer(v); err != nil {
			return err
		}
	}
	return nil
}

func sizeMessageSlice(p pointer, goType reflect.Type, tagsize int, _ marshalOptions) int {
	s := p.PointerSlice()
	n := 0
	for _, v := range s {
		m := asMessage(v.AsValueOf(goType.Elem()))
		n += wire.SizeBytes(proto.Size(m)) + tagsize
	}
	return n
}

func appendMessageSlice(b []byte, p pointer, wiretag uint64, goType reflect.Type, opts marshalOptions) ([]byte, error) {
	s := p.PointerSlice()
	var err error
	for _, v := range s {
		m := asMessage(v.AsValueOf(goType.Elem()))
		b = wire.AppendVarint(b, wiretag)
		siz := proto.Size(m)
		b = wire.AppendVarint(b, uint64(siz))
		b, err = opts.Options().MarshalAppend(b, m)
		if err != nil {
			return b, err
		}
	}
	return b, nil
}

func consumeMessageSlice(b []byte, p pointer, goType reflect.Type, wtyp wire.Type, opts unmarshalOptions) (out unmarshalOutput, err error) {
	if wtyp != wire.BytesType {
		return out, errUnknown
	}
	v, n := wire.ConsumeBytes(b)
	if n < 0 {
		return out, wire.ParseError(n)
	}
	mp := reflect.New(goType.Elem())
	o, err := opts.Options().UnmarshalState(asMessage(mp), piface.UnmarshalInput{
		Buf: v,
	})
	if err != nil {
		return out, err
	}
	p.AppendPointerSlice(pointerOfValue(mp))
	out.n = n
	out.initialized = o.Initialized
	return out, nil
}

func isInitMessageSlice(p pointer, goType reflect.Type) error {
	s := p.PointerSlice()
	for _, v := range s {
		m := asMessage(v.AsValueOf(goType.Elem()))
		if err := proto.IsInitialized(m); err != nil {
			return err
		}
	}
	return nil
}

// Slices of messages

func sizeMessageSliceValue(listv pref.Value, tagsize int, opts marshalOptions) int {
	list := listv.List()
	n := 0
	for i, llen := 0, list.Len(); i < llen; i++ {
		m := list.Get(i).Message().Interface()
		n += wire.SizeBytes(proto.Size(m)) + tagsize
	}
	return n
}

func appendMessageSliceValue(b []byte, listv pref.Value, wiretag uint64, opts marshalOptions) ([]byte, error) {
	list := listv.List()
	mopts := opts.Options()
	for i, llen := 0, list.Len(); i < llen; i++ {
		m := list.Get(i).Message().Interface()
		b = wire.AppendVarint(b, wiretag)
		siz := proto.Size(m)
		b = wire.AppendVarint(b, uint64(siz))
		var err error
		b, err = mopts.MarshalAppend(b, m)
		if err != nil {
			return b, err
		}
	}
	return b, nil
}

func consumeMessageSliceValue(b []byte, listv pref.Value, _ wire.Number, wtyp wire.Type, opts unmarshalOptions) (_ pref.Value, out unmarshalOutput, err error) {
	list := listv.List()
	if wtyp != wire.BytesType {
		return pref.Value{}, out, errUnknown
	}
	v, n := wire.ConsumeBytes(b)
	if n < 0 {
		return pref.Value{}, out, wire.ParseError(n)
	}
	m := list.NewElement()
	o, err := opts.Options().UnmarshalState(m.Message().Interface(), piface.UnmarshalInput{
		Buf: v,
	})
	if err != nil {
		return pref.Value{}, out, err
	}
	list.Append(m)
	out.n = n
	out.initialized = o.Initialized
	return listv, out, nil
}

func isInitMessageSliceValue(listv pref.Value) error {
	list := listv.List()
	for i, llen := 0, list.Len(); i < llen; i++ {
		m := list.Get(i).Message().Interface()
		if err := proto.IsInitialized(m); err != nil {
			return err
		}
	}
	return nil
}

var coderMessageSliceValue = valueCoderFuncs{
	size:      sizeMessageSliceValue,
	marshal:   appendMessageSliceValue,
	unmarshal: consumeMessageSliceValue,
	isInit:    isInitMessageSliceValue,
}

func sizeGroupSliceValue(listv pref.Value, tagsize int, opts marshalOptions) int {
	list := listv.List()
	n := 0
	for i, llen := 0, list.Len(); i < llen; i++ {
		m := list.Get(i).Message().Interface()
		n += 2*tagsize + proto.Size(m)
	}
	return n
}

func appendGroupSliceValue(b []byte, listv pref.Value, wiretag uint64, opts marshalOptions) ([]byte, error) {
	list := listv.List()
	mopts := opts.Options()
	for i, llen := 0, list.Len(); i < llen; i++ {
		m := list.Get(i).Message().Interface()
		b = wire.AppendVarint(b, wiretag) // start group
		var err error
		b, err = mopts.MarshalAppend(b, m)
		if err != nil {
			return b, err
		}
		b = wire.AppendVarint(b, wiretag+1) // end group
	}
	return b, nil
}

func consumeGroupSliceValue(b []byte, listv pref.Value, num wire.Number, wtyp wire.Type, opts unmarshalOptions) (_ pref.Value, out unmarshalOutput, err error) {
	list := listv.List()
	if wtyp != wire.StartGroupType {
		return pref.Value{}, out, errUnknown
	}
	b, n := wire.ConsumeGroup(num, b)
	if n < 0 {
		return pref.Value{}, out, wire.ParseError(n)
	}
	m := list.NewElement()
	o, err := opts.Options().UnmarshalState(m.Message().Interface(), piface.UnmarshalInput{
		Buf: b,
	})
	if err != nil {
		return pref.Value{}, out, err
	}
	list.Append(m)
	out.n = n
	out.initialized = o.Initialized
	return listv, out, nil
}

var coderGroupSliceValue = valueCoderFuncs{
	size:      sizeGroupSliceValue,
	marshal:   appendGroupSliceValue,
	unmarshal: consumeGroupSliceValue,
	isInit:    isInitMessageSliceValue,
}

func makeGroupSliceFieldCoder(fd pref.FieldDescriptor, ft reflect.Type) pointerCoderFuncs {
	num := fd.Number()
	if mi := getMessageInfo(ft); mi != nil {
		funcs := pointerCoderFuncs{
			size:      sizeGroupSliceInfo,
			marshal:   appendGroupSliceInfo,
			unmarshal: consumeGroupSliceInfo,
		}
		if needsInitCheck(mi.Desc) {
			funcs.isInit = isInitMessageSliceInfo
		}
		return funcs
	}
	return pointerCoderFuncs{
		size: func(p pointer, f *coderFieldInfo, opts marshalOptions) int {
			return sizeGroupSlice(p, ft, f.tagsize, opts)
		},
		marshal: func(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
			return appendGroupSlice(b, p, f.wiretag, ft, opts)
		},
		unmarshal: func(b []byte, p pointer, wtyp wire.Type, f *coderFieldInfo, opts unmarshalOptions) (unmarshalOutput, error) {
			return consumeGroupSlice(b, p, num, wtyp, ft, opts)
		},
		isInit: func(p pointer, f *coderFieldInfo) error {
			return isInitMessageSlice(p, ft)
		},
	}
}

func sizeGroupSlice(p pointer, messageType reflect.Type, tagsize int, _ marshalOptions) int {
	s := p.PointerSlice()
	n := 0
	for _, v := range s {
		m := asMessage(v.AsValueOf(messageType.Elem()))
		n += 2*tagsize + proto.Size(m)
	}
	return n
}

func appendGroupSlice(b []byte, p pointer, wiretag uint64, messageType reflect.Type, opts marshalOptions) ([]byte, error) {
	s := p.PointerSlice()
	var err error
	for _, v := range s {
		m := asMessage(v.AsValueOf(messageType.Elem()))
		b = wire.AppendVarint(b, wiretag) // start group
		b, err = opts.Options().MarshalAppend(b, m)
		if err != nil {
			return b, err
		}
		b = wire.AppendVarint(b, wiretag+1) // end group
	}
	return b, nil
}

func consumeGroupSlice(b []byte, p pointer, num wire.Number, wtyp wire.Type, goType reflect.Type, opts unmarshalOptions) (out unmarshalOutput, err error) {
	if wtyp != wire.StartGroupType {
		return out, errUnknown
	}
	b, n := wire.ConsumeGroup(num, b)
	if n < 0 {
		return out, wire.ParseError(n)
	}
	mp := reflect.New(goType.Elem())
	o, err := opts.Options().UnmarshalState(asMessage(mp), piface.UnmarshalInput{
		Buf: b,
	})
	if err != nil {
		return out, err
	}
	p.AppendPointerSlice(pointerOfValue(mp))
	out.n = n
	out.initialized = o.Initialized
	return out, nil
}

func sizeGroupSliceInfo(p pointer, f *coderFieldInfo, opts marshalOptions) int {
	s := p.PointerSlice()
	n := 0
	for _, v := range s {
		n += 2*f.tagsize + f.mi.sizePointer(v, opts)
	}
	return n
}

func appendGroupSliceInfo(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
	s := p.PointerSlice()
	var err error
	for _, v := range s {
		b = wire.AppendVarint(b, f.wiretag) // start group
		b, err = f.mi.marshalAppendPointer(b, v, opts)
		if err != nil {
			return b, err
		}
		b = wire.AppendVarint(b, f.wiretag+1) // end group
	}
	return b, nil
}

func consumeGroupSliceInfo(b []byte, p pointer, wtyp wire.Type, f *coderFieldInfo, opts unmarshalOptions) (unmarshalOutput, error) {
	if wtyp != wire.StartGroupType {
		return unmarshalOutput{}, errUnknown
	}
	m := reflect.New(f.mi.GoReflectType.Elem()).Interface()
	mp := pointerOfIface(m)
	out, err := f.mi.unmarshalPointer(b, mp, f.num, opts)
	if err != nil {
		return out, err
	}
	p.AppendPointerSlice(mp)
	return out, nil
}

func asMessage(v reflect.Value) pref.ProtoMessage {
	if m, ok := v.Interface().(pref.ProtoMessage); ok {
		return m
	}
	return legacyWrapMessage(v)
}
