internal/impl: store extension values as Values

Change the storage type of ExtensionField from interface{} to
protoreflect.Value.

Replace the codec functions operating on interface{}s with ones
operating on Values.

Values are potentially more efficient, since they can represent
non-pointer types without allocation. This also reduces the number of
types used to represent field values.

Additionally, this change lays groundwork for changing the
user-visible representation of repeated extension fields from
*[]T to []T. The storage type for extension fields must support mutation
(thus *[]T currently); changing the storage type to a Value permits this
without the need to introduce yet another view on field values.

Change-Id: Ida336be14112bb940f655236eb58df21bf312525
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/192218
Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
diff --git a/internal/cmd/generate-types/impl.go b/internal/cmd/generate-types/impl.go
index 8be3e02..582ecae 100644
--- a/internal/cmd/generate-types/impl.go
+++ b/internal/cmd/generate-types/impl.go
@@ -39,6 +39,16 @@
 {{- end -}}
 {{- end -}}
 
+{{- define "SizeValue" -}}
+{{- if .WireType.ConstSize -}}
+wire.Size{{.WireType}}()
+{{- else if eq .WireType "Bytes" -}}
+wire.SizeBytes(len({{.FromValue}}))
+{{- else -}}
+wire.Size{{.WireType}}({{.FromValue}})
+{{- end -}}
+{{- end -}}
+
 {{- /*
   Append is a set of statements appending 'v' to 'b'.
 */ -}}
@@ -50,6 +60,14 @@
 {{- end -}}
 {{- end -}}
 
+{{- define "AppendValue" -}}
+{{- if eq .Name "String" -}}
+b = wire.AppendString(b, {{.FromValue}})
+{{- else -}}
+b = wire.Append{{.WireType}}(b, {{.FromValue}})
+{{- end -}}
+{{- end -}}
+
 {{- define "Consume" -}}
 {{- if eq .Name "String" -}}
 wire.ConsumeString(b)
@@ -59,6 +77,7 @@
 {{- end -}}
 
 {{- range .}}
+
 {{- if .FromGoType }}
 // size{{.Name}} returns the size of wire encoding a {{.GoType}} pointer as a {{.Name}}.
 func size{{.Name}}(p pointer, tagsize int, _ marshalOptions) (size int) {
@@ -405,184 +424,184 @@
 }
 {{end}}
 
-// size{{.Name}}Iface returns the size of wire encoding a {{.GoType}} value as a {{.Name}}.
-func size{{.Name}}Iface(ival interface{}, tagsize int, _ marshalOptions) int {
-	{{- if not .WireType.ConstSize}}
-	v := ival.({{.GoType}})
-	{{end -}}
-	return tagsize + {{template "Size" .}}
+{{end -}}
+
+{{- if not .NoValueCodec}}
+// size{{.Name}}Value returns the size of wire encoding a {{.GoType}} value as a {{.Name}}.
+func size{{.Name}}Value(v protoreflect.Value, tagsize int, _ marshalOptions) int {
+	return tagsize + {{template "SizeValue" .}}
 }
 
-// append{{.Name}}Iface encodes a {{.GoType}} value as a {{.Name}}.
-func append{{.Name}}Iface(b []byte, ival interface{}, wiretag uint64, _ marshalOptions) ([]byte, error) {
-	v := ival.({{.GoType}})
+// append{{.Name}}Value encodes a {{.GoType}} value as a {{.Name}}.
+func append{{.Name}}Value(b []byte, v protoreflect.Value, wiretag uint64, _ marshalOptions) ([]byte, error) {
 	b = wire.AppendVarint(b, wiretag)
-	{{template "Append" .}}
+	{{template "AppendValue" .}}
 	return b, nil
 }
 
-// consume{{.Name}}Iface decodes a {{.GoType}} value as a {{.Name}}.
-func consume{{.Name}}Iface(b []byte, _ interface{}, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (interface{}, int, error) {
+// consume{{.Name}}Value decodes a {{.GoType}} value as a {{.Name}}.
+func consume{{.Name}}Value(b []byte, _ protoreflect.Value, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (protoreflect.Value, int, error) {
 	if wtyp != {{.WireType.Expr}} {
-		return nil, 0, errUnknown
+		return protoreflect.Value{}, 0, errUnknown
 	}
 	v, n := {{template "Consume" .}}
 	if n < 0 {
-		return nil, 0, wire.ParseError(n)
+		return protoreflect.Value{}, 0, wire.ParseError(n)
 	}
-	return {{.ToGoType}}, n, nil
+	return {{.ToValue}}, n, nil
 }
 
-var coder{{.Name}}Iface = ifaceCoderFuncs{
-	size:    size{{.Name}}Iface,
-	marshal: append{{.Name}}Iface,
-	unmarshal: consume{{.Name}}Iface,
+var coder{{.Name}}Value = valueCoderFuncs{
+	size:    size{{.Name}}Value,
+	marshal: append{{.Name}}Value,
+	unmarshal: consume{{.Name}}Value,
 }
 
 {{if or (eq .Name "Bytes") (eq .Name "String")}}
-// append{{.Name}}IfaceValidateUTF8 encodes a {{.GoType}} value as a {{.Name}}.
-func append{{.Name}}IfaceValidateUTF8(b []byte, ival interface{}, wiretag uint64, _ marshalOptions) ([]byte, error) {
-	v := ival.({{.GoType}})
+// append{{.Name}}ValueValidateUTF8 encodes a {{.GoType}} value as a {{.Name}}.
+func append{{.Name}}ValueValidateUTF8(b []byte, v protoreflect.Value, wiretag uint64, _ marshalOptions) ([]byte, error) {
 	b = wire.AppendVarint(b, wiretag)
-	{{template "Append" .}}
-	if !utf8.Valid{{if eq .Name "String"}}String{{end}}(v) {
+	{{template "AppendValue" .}}
+	if !utf8.Valid{{if eq .Name "String"}}String{{end}}({{.FromValue}}) {
 		return b, errInvalidUTF8{}
 	}
 	return b, nil
 }
 
-// consume{{.Name}}IfaceValidateUTF8 decodes a {{.GoType}} value as a {{.Name}}.
-func consume{{.Name}}IfaceValidateUTF8(b []byte, _ interface{}, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (interface{}, int, error) {
+// consume{{.Name}}ValueValidateUTF8 decodes a {{.GoType}} value as a {{.Name}}.
+func consume{{.Name}}ValueValidateUTF8(b []byte, _ protoreflect.Value, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (protoreflect.Value, int, error) {
 	if wtyp != {{.WireType.Expr}} {
-		return nil, 0, errUnknown
+		return protoreflect.Value{}, 0, errUnknown
 	}
 	v, n := {{template "Consume" .}}
 	if n < 0 {
-		return nil, 0, wire.ParseError(n)
+		return protoreflect.Value{}, 0, wire.ParseError(n)
 	}
 	if !utf8.Valid{{if eq .Name "String"}}String{{end}}(v) {
-		return nil, 0, errInvalidUTF8{}
+		return protoreflect.Value{}, 0, errInvalidUTF8{}
 	}
-	return {{.ToGoType}}, n, nil
+	return {{.ToValue}}, n, nil
 }
 
-var coder{{.Name}}IfaceValidateUTF8 = ifaceCoderFuncs{
-	size:    size{{.Name}}Iface,
-	marshal: append{{.Name}}IfaceValidateUTF8,
-	unmarshal: consume{{.Name}}IfaceValidateUTF8,
+var coder{{.Name}}ValueValidateUTF8 = valueCoderFuncs{
+	size:      size{{.Name}}Value,
+	marshal:   append{{.Name}}ValueValidateUTF8,
+	unmarshal: consume{{.Name}}ValueValidateUTF8,
 }
 {{end}}
 
-// size{{.Name}}SliceIface returns the size of wire encoding a []{{.GoType}} value as a repeated {{.Name}}.
-func size{{.Name}}SliceIface(ival interface{}, tagsize int, _ marshalOptions) (size int) {
-	s := *ival.(*[]{{.GoType}})
+// size{{.Name}}SliceValue returns the size of wire encoding a []{{.GoType}} value as a repeated {{.Name}}.
+func size{{.Name}}SliceValue(listv protoreflect.Value, tagsize int, _ marshalOptions) (size int) {
+	list := listv.List()
 	{{if .WireType.ConstSize -}}
-	size = len(s) * (tagsize + {{template "Size" .}})
+	size = list.Len() * (tagsize + {{template "SizeValue" .}})
 	{{- else -}}
-	for _, v := range s {
-		size += tagsize + {{template "Size" .}}
+	for i, llen := 0, list.Len(); i < llen; i++ {
+		v := list.Get(i)
+		size += tagsize + {{template "SizeValue" .}}
 	}
 	{{- end}}
 	return size
 }
 
-// append{{.Name}}SliceIface encodes a []{{.GoType}} value as a repeated {{.Name}}.
-func append{{.Name}}SliceIface(b []byte, ival interface{}, wiretag uint64, _ marshalOptions) ([]byte, error) {
-	s := *ival.(*[]{{.GoType}})
-	for _, v := range s {
+// append{{.Name}}SliceValue encodes a []{{.GoType}} value as a repeated {{.Name}}.
+func append{{.Name}}SliceValue(b []byte, listv protoreflect.Value, wiretag uint64, _ marshalOptions) ([]byte, error) {
+	list := listv.List()
+	for i, llen := 0, list.Len(); i < llen; i++ {
+		v := list.Get(i)
 		b = wire.AppendVarint(b, wiretag)
-		{{template "Append" .}}
+		{{template "AppendValue" .}}
 	}
 	return b, nil
 }
 
-// consume{{.Name}}SliceIface wire decodes a []{{.GoType}} value as a repeated {{.Name}}.
-func consume{{.Name}}SliceIface(b []byte, ival interface{}, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (_ interface{}, n int, err error) {
-	sp := ival.(*[]{{.GoType}})
+// consume{{.Name}}SliceValue wire decodes a []{{.GoType}} value as a repeated {{.Name}}.
+func consume{{.Name}}SliceValue(b []byte, listv protoreflect.Value, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (_ protoreflect.Value, n int, err error) {
+	list := listv.List()
 	{{- if .WireType.Packable}}
 	if wtyp == wire.BytesType {
-		s := *sp
 		b, n = wire.ConsumeBytes(b)
 		if n < 0 {
-			return nil, 0, wire.ParseError(n)
+			return protoreflect.Value{}, 0, wire.ParseError(n)
 		}
 		for len(b) > 0 {
 			v, n := {{template "Consume" .}}
 			if n < 0 {
-				return nil, 0, wire.ParseError(n)
+				return protoreflect.Value{}, 0, wire.ParseError(n)
 			}
-			s = append(s, {{.ToGoType}})
+			list.Append({{.ToValue}})
 			b = b[n:]
 		}
-		*sp = s
-		return ival, n, nil
+		return listv, n, nil
 	}
 	{{- end}}
 	if wtyp != {{.WireType.Expr}} {
-		return nil, 0, errUnknown
+		return protoreflect.Value{}, 0, errUnknown
 	}
 	v, n := {{template "Consume" .}}
 	if n < 0 {
-		return nil, 0, wire.ParseError(n)
+		return protoreflect.Value{}, 0, wire.ParseError(n)
 	}
-	*sp = append(*sp, {{.ToGoType}})
-	return ival, n, nil
+	list.Append({{.ToValue}})
+	return listv, n, nil
 }
 
-var coder{{.Name}}SliceIface = ifaceCoderFuncs{
-	size:      size{{.Name}}SliceIface,
-	marshal:   append{{.Name}}SliceIface,
-	unmarshal: consume{{.Name}}SliceIface,
+var coder{{.Name}}SliceValue = valueCoderFuncs{
+	size:      size{{.Name}}SliceValue,
+	marshal:   append{{.Name}}SliceValue,
+	unmarshal: consume{{.Name}}SliceValue,
 }
 
 {{if or (eq .WireType "Varint") (eq .WireType "Fixed32") (eq .WireType "Fixed64")}}
-// size{{.Name}}PackedSliceIface returns the size of wire encoding a []{{.GoType}} value as a packed repeated {{.Name}}.
-func size{{.Name}}PackedSliceIface(ival interface{}, tagsize int, _ marshalOptions) (size int) {
-	s := *ival.(*[]{{.GoType}})
-	if len(s) == 0 {
-		return 0
-	}
+// size{{.Name}}PackedSliceValue returns the size of wire encoding a []{{.GoType}} value as a packed repeated {{.Name}}.
+func size{{.Name}}PackedSliceValue(listv protoreflect.Value, tagsize int, _ marshalOptions) (size int) {
+	list := listv.List()
 	{{if .WireType.ConstSize -}}
-	n := len(s) * {{template "Size" .}}
+	n := list.Len() * {{template "SizeValue" .}}
 	{{- else -}}
 	n := 0
-	for _, v := range s {
-		n += {{template "Size" .}}
+	for i, llen := 0, list.Len(); i < llen; i++ {
+		v := list.Get(i)
+		n += {{template "SizeValue" .}}
 	}
 	{{- end}}
 	return tagsize + wire.SizeBytes(n)
 }
 
-// append{{.Name}}PackedSliceIface encodes a []{{.GoType}} value as a packed repeated {{.Name}}.
-func append{{.Name}}PackedSliceIface(b []byte, ival interface{}, wiretag uint64, _ marshalOptions) ([]byte, error) {
-	s := *ival.(*[]{{.GoType}})
-	if len(s) == 0 {
+// append{{.Name}}PackedSliceValue encodes a []{{.GoType}} value as a packed repeated {{.Name}}.
+func append{{.Name}}PackedSliceValue(b []byte, listv protoreflect.Value, wiretag uint64, _ marshalOptions) ([]byte, error) {
+	list := listv.List()
+	llen := list.Len()
+	if llen == 0 {
 		return b, nil
 	}
 	b = wire.AppendVarint(b, wiretag)
 	{{if .WireType.ConstSize -}}
-	n := len(s) * {{template "Size" .}}
+	n := llen * {{template "SizeValue" .}}
 	{{- else -}}
 	n := 0
-	for _, v := range s {
-		n += {{template "Size" .}}
+	for i := 0; i < llen; i++ {
+		v := list.Get(i)
+		n += {{template "SizeValue" .}}
 	}
 	{{- end}}
 	b = wire.AppendVarint(b, uint64(n))
-	for _, v := range s {
-		{{template "Append" .}}
+	for i := 0; i < llen; i++ {
+		v := list.Get(i)
+		{{template "AppendValue" .}}
 	}
 	return b, nil
 }
 
-var coder{{.Name}}PackedSliceIface = ifaceCoderFuncs{
-	size:      size{{.Name}}PackedSliceIface,
-	marshal:   append{{.Name}}PackedSliceIface,
-	unmarshal: consume{{.Name}}SliceIface,
+var coder{{.Name}}PackedSliceValue = valueCoderFuncs{
+	size:      size{{.Name}}PackedSliceValue,
+	marshal:   append{{.Name}}PackedSliceValue,
+	unmarshal: consume{{.Name}}SliceValue,
 }
 {{end}}
 
-{{end -}}
+{{- end}}{{/* if not .NoValueCodec */}}
+
 {{end -}}
 
 // We append to an empty array rather than a nil []byte to get non-nil zero-length byte slices.
diff --git a/internal/impl/codec_extension.go b/internal/impl/codec_extension.go
index 8a999ef..442628e 100644
--- a/internal/impl/codec_extension.go
+++ b/internal/impl/codec_extension.go
@@ -16,7 +16,7 @@
 	wiretag             uint64
 	tagsize             int
 	unmarshalNeedsValue bool
-	funcs               ifaceCoderFuncs
+	funcs               valueCoderFuncs
 }
 
 func (mi *MessageInfo) extensionFieldInfo(xt pref.ExtensionType) *extensionFieldInfo {
@@ -66,60 +66,80 @@
 
 	// value is either the value of GetValue,
 	// or a *lazyExtensionValue that then returns the value of GetValue.
-	value interface{} // TODO: switch to protoreflect.Value
+	value pref.Value
+	lazy  *lazyExtensionValue
 }
 
-func (f ExtensionField) HasType() bool {
-	return f.typ != nil
-}
-func (f ExtensionField) GetType() pref.ExtensionType {
-	return f.typ
-}
-func (f *ExtensionField) SetType(t pref.ExtensionType) {
+// Set sets the type and value of the extension field.
+// This must not be called concurrently.
+func (f *ExtensionField) Set(t pref.ExtensionType, v pref.Value) {
 	f.typ = t
+	f.value = v
 }
 
-// HasValue reports whether a value is set for the extension field.
-// This may be called concurrently.
-func (f ExtensionField) HasValue() bool {
-	return f.value != nil
+// SetLazy sets the type and a value that is to be lazily evaluated upon first use.
+// This must not be called concurrently.
+func (f *ExtensionField) SetLazy(t pref.ExtensionType, fn func() pref.Value) {
+	f.typ = t
+	f.lazy = &lazyExtensionValue{value: fn}
 }
 
-// GetValue returns the concrete value for the extension field.
-// Let the type of Desc.ExtensionType be the "API type" and
-// the type of GetValue be the "storage type".
-// The API type and storage type are the same except:
-//	* for scalars (except []byte), where the API type uses *T,
-//	while the storage type uses T.
-//	* for repeated fields, where the API type uses []T,
-//	while the storage type uses *[]T.
-//
-// The reason for the divergence is so that the storage type more naturally
-// matches what is expected of when retrieving the values through the
-// protobuf reflection APIs.
-//
-// GetValue is only populated if Desc is also populated.
+// Value returns the value of the extension field.
 // This may be called concurrently.
-//
-// TODO: switch interface{} to protoreflect.Value
-func (f ExtensionField) GetValue() interface{} {
-	if f, ok := f.value.(*lazyExtensionValue); ok {
-		return f.GetValue()
+func (f *ExtensionField) Value() pref.Value {
+	if f.lazy != nil {
+		return f.lazy.GetValue()
 	}
 	return f.value
 }
 
-// SetEagerValue sets the current value of the extension.
-// This must not be called concurrently.
-func (f *ExtensionField) SetEagerValue(v interface{}) {
-	f.value = v
+// Type returns the type of the extension field.
+// This may be called concurrently.
+func (f ExtensionField) Type() pref.ExtensionType {
+	return f.typ
 }
 
-// SetLazyValue sets a value that is to be lazily evaluated upon first use.
-// The returned value must not be nil.
-// This must not be called concurrently.
-func (f *ExtensionField) SetLazyValue(v func() interface{}) {
-	f.value = &lazyExtensionValue{value: v}
+// IsSet returns whether the extension field is set.
+// This may be called concurrently.
+func (f ExtensionField) IsSet() bool {
+	return f.typ != nil
+}
+
+// Deprecated: Do not use.
+func (f ExtensionField) HasType() bool {
+	return f.typ != nil
+}
+
+// Deprecated: Do not use.
+func (f ExtensionField) GetType() pref.ExtensionType {
+	return f.typ
+}
+
+// Deprecated: Do not use.
+func (f *ExtensionField) SetType(t pref.ExtensionType) {
+	f.typ = t
+}
+
+// Deprecated: Do not use.
+func (f ExtensionField) HasValue() bool {
+	return f.value.IsValid() || f.lazy != nil
+}
+
+// Deprecated: Do not use.
+func (f ExtensionField) GetValue() interface{} {
+	return f.typ.InterfaceOf(f.Value())
+}
+
+// Deprecated: Do not use.
+func (f *ExtensionField) SetEagerValue(ival interface{}) {
+	f.value = f.typ.ValueOf(ival)
+}
+
+// Deprecated: Do not use.
+func (f *ExtensionField) SetLazyValue(fn func() interface{}) {
+	f.lazy = &lazyExtensionValue{value: func() interface{} {
+		return f.typ.ValueOf(fn())
+	}}
 }
 
 type lazyExtensionValue struct {
@@ -128,14 +148,14 @@
 	value interface{} // either the value itself or a func() interface{}
 }
 
-func (v *lazyExtensionValue) GetValue() interface{} {
+func (v *lazyExtensionValue) GetValue() pref.Value {
 	if atomic.LoadUint32(&v.once) == 0 {
 		v.mu.Lock()
-		if f, ok := v.value.(func() interface{}); ok {
+		if f, ok := v.value.(func() pref.Value); ok {
 			v.value = f()
 		}
 		atomic.StoreUint32(&v.once, 1)
 		v.mu.Unlock()
 	}
-	return v.value
+	return v.value.(pref.Value)
 }
diff --git a/internal/impl/codec_field.go b/internal/impl/codec_field.go
index af6ce05..5414635 100644
--- a/internal/impl/codec_field.go
+++ b/internal/impl/codec_field.go
@@ -170,32 +170,55 @@
 	return n, nil
 }
 
-func sizeMessageIface(ival interface{}, tagsize int, opts marshalOptions) int {
-	m := Export{}.MessageOf(ival).Interface()
+func sizeMessageValue(v pref.Value, tagsize int, opts marshalOptions) int {
+	m := v.Message().Interface()
 	return sizeMessage(m, tagsize, opts)
 }
 
-func appendMessageIface(b []byte, ival interface{}, wiretag uint64, opts marshalOptions) ([]byte, error) {
-	m := Export{}.MessageOf(ival).Interface()
+func appendMessageValue(b []byte, v pref.Value, wiretag uint64, opts marshalOptions) ([]byte, error) {
+	m := v.Message().Interface()
 	return appendMessage(b, m, wiretag, opts)
 }
 
-func consumeMessageIface(b []byte, ival interface{}, _ wire.Number, wtyp wire.Type, opts unmarshalOptions) (interface{}, int, error) {
-	m := Export{}.MessageOf(ival).Interface()
+func consumeMessageValue(b []byte, v pref.Value, _ wire.Number, wtyp wire.Type, opts unmarshalOptions) (pref.Value, int, error) {
+	m := v.Message().Interface()
 	n, err := consumeMessage(b, m, wtyp, opts)
-	return ival, n, err
+	return v, n, err
 }
 
-func isInitMessageIface(ival interface{}) error {
-	m := Export{}.MessageOf(ival).Interface()
+func isInitMessageValue(v pref.Value) error {
+	m := v.Message().Interface()
 	return proto.IsInitialized(m)
 }
 
-var coderMessageIface = ifaceCoderFuncs{
-	size:      sizeMessageIface,
-	marshal:   appendMessageIface,
-	unmarshal: consumeMessageIface,
-	isInit:    isInitMessageIface,
+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, int, error) {
+	m := v.Message().Interface()
+	n, err := consumeGroup(b, m, num, wtyp, opts)
+	return v, n, err
+}
+
+var coderGroupValue = valueCoderFuncs{
+	size:      sizeGroupValue,
+	marshal:   appendGroupValue,
+	unmarshal: consumeGroupValue,
+	isInit:    isInitMessageValue,
 }
 
 func makeGroupFieldCoder(fd pref.FieldDescriptor, ft reflect.Type) pointerCoderFuncs {
@@ -283,25 +306,6 @@
 	return n, opts.Options().Unmarshal(b, m)
 }
 
-func makeGroupValueCoder(fd pref.FieldDescriptor, ft reflect.Type) ifaceCoderFuncs {
-	return ifaceCoderFuncs{
-		size: func(ival interface{}, tagsize int, opts marshalOptions) int {
-			m := Export{}.MessageOf(ival).Interface()
-			return sizeGroup(m, tagsize, opts)
-		},
-		marshal: func(b []byte, ival interface{}, wiretag uint64, opts marshalOptions) ([]byte, error) {
-			m := Export{}.MessageOf(ival).Interface()
-			return appendGroup(b, m, wiretag, opts)
-		},
-		unmarshal: func(b []byte, ival interface{}, num wire.Number, wtyp wire.Type, opts unmarshalOptions) (interface{}, int, error) {
-			m := Export{}.MessageOf(ival).Interface()
-			n, err := consumeGroup(b, m, num, wtyp, opts)
-			return ival, n, err
-		},
-		isInit: isInitMessageIface,
-	}
-}
-
 func makeMessageSliceFieldCoder(fd pref.FieldDescriptor, ft reflect.Type) pointerCoderFuncs {
 	if mi := getMessageInfo(ft); mi != nil {
 		return pointerCoderFuncs{
@@ -441,32 +445,116 @@
 
 // Slices of messages
 
-func sizeMessageSliceIface(ival interface{}, tagsize int, opts marshalOptions) int {
-	p := pointerOfIface(ival)
-	return sizeMessageSlice(p, reflect.TypeOf(ival).Elem().Elem(), tagsize, opts)
+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 appendMessageSliceIface(b []byte, ival interface{}, wiretag uint64, opts marshalOptions) ([]byte, error) {
-	p := pointerOfIface(ival)
-	return appendMessageSlice(b, p, wiretag, reflect.TypeOf(ival).Elem().Elem(), opts)
+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 consumeMessageSliceIface(b []byte, ival interface{}, _ wire.Number, wtyp wire.Type, opts unmarshalOptions) (interface{}, int, error) {
-	p := pointerOfIface(ival)
-	n, err := consumeMessageSlice(b, p, reflect.TypeOf(ival).Elem().Elem(), wtyp, opts)
-	return ival, n, err
+func consumeMessageSliceValue(b []byte, listv pref.Value, _ wire.Number, wtyp wire.Type, opts unmarshalOptions) (pref.Value, int, error) {
+	list := listv.List()
+	if wtyp != wire.BytesType {
+		return pref.Value{}, 0, errUnknown
+	}
+	v, n := wire.ConsumeBytes(b)
+	if n < 0 {
+		return pref.Value{}, 0, wire.ParseError(n)
+	}
+	m := list.NewElement()
+	if err := opts.Options().Unmarshal(v, m.Message().Interface()); err != nil {
+		return pref.Value{}, 0, err
+	}
+	list.Append(m)
+	return listv, n, nil
 }
 
-func isInitMessageSliceIface(ival interface{}) error {
-	p := pointerOfIface(ival)
-	return isInitMessageSlice(p, reflect.TypeOf(ival).Elem().Elem())
+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 coderMessageSliceIface = ifaceCoderFuncs{
-	size:      sizeMessageSliceIface,
-	marshal:   appendMessageSliceIface,
-	unmarshal: consumeMessageSliceIface,
-	isInit:    isInitMessageSliceIface,
+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, int, error) {
+	list := listv.List()
+	if wtyp != wire.StartGroupType {
+		return pref.Value{}, 0, errUnknown
+	}
+	b, n := wire.ConsumeGroup(num, b)
+	if n < 0 {
+		return pref.Value{}, 0, wire.ParseError(n)
+	}
+	m := list.NewElement()
+	if err := opts.Options().Unmarshal(b, m.Message().Interface()); err != nil {
+		return pref.Value{}, 0, err
+	}
+	list.Append(m)
+	return listv, n, nil
+}
+
+var coderGroupSliceValue = valueCoderFuncs{
+	size:      sizeGroupSliceValue,
+	marshal:   appendGroupSliceValue,
+	unmarshal: consumeGroupSliceValue,
+	isInit:    isInitMessageSliceValue,
 }
 
 func makeGroupSliceFieldCoder(fd pref.FieldDescriptor, ft reflect.Type) pointerCoderFuncs {
@@ -581,171 +669,6 @@
 	return n, nil
 }
 
-func sizeGroupSliceIface(ival interface{}, tagsize int, opts marshalOptions) int {
-	p := pointerOfIface(ival)
-	return sizeGroupSlice(p, reflect.TypeOf(ival).Elem().Elem(), tagsize, opts)
-}
-
-func appendGroupSliceIface(b []byte, ival interface{}, wiretag uint64, opts marshalOptions) ([]byte, error) {
-	p := pointerOfIface(ival)
-	return appendGroupSlice(b, p, wiretag, reflect.TypeOf(ival).Elem().Elem(), opts)
-}
-
-func consumeGroupSliceIface(b []byte, ival interface{}, num wire.Number, wtyp wire.Type, opts unmarshalOptions) (interface{}, int, error) {
-	p := pointerOfIface(ival)
-	n, err := consumeGroupSlice(b, p, num, wtyp, reflect.TypeOf(ival).Elem().Elem(), opts)
-	return ival, n, err
-}
-
-var coderGroupSliceIface = ifaceCoderFuncs{
-	size:      sizeGroupSliceIface,
-	marshal:   appendGroupSliceIface,
-	unmarshal: consumeGroupSliceIface,
-	isInit:    isInitMessageSliceIface,
-}
-
-// Enums
-
-func sizeEnumIface(ival interface{}, tagsize int, _ marshalOptions) (n int) {
-	v := reflect.ValueOf(ival).Int()
-	return wire.SizeVarint(uint64(v)) + tagsize
-}
-
-func appendEnumIface(b []byte, ival interface{}, wiretag uint64, _ marshalOptions) ([]byte, error) {
-	v := reflect.ValueOf(ival).Int()
-	b = wire.AppendVarint(b, wiretag)
-	b = wire.AppendVarint(b, uint64(v))
-	return b, nil
-}
-
-func consumeEnumIface(b []byte, ival interface{}, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (interface{}, int, error) {
-	if wtyp != wire.VarintType {
-		return nil, 0, errUnknown
-	}
-	v, n := wire.ConsumeVarint(b)
-	if n < 0 {
-		return nil, 0, wire.ParseError(n)
-	}
-	rv := reflect.New(reflect.TypeOf(ival)).Elem()
-	rv.SetInt(int64(v))
-	return rv.Interface(), n, nil
-}
-
-var coderEnumIface = ifaceCoderFuncs{
-	size:      sizeEnumIface,
-	marshal:   appendEnumIface,
-	unmarshal: consumeEnumIface,
-}
-
-func sizeEnumSliceIface(ival interface{}, tagsize int, opts marshalOptions) (size int) {
-	return sizeEnumSliceReflect(reflect.ValueOf(ival).Elem(), tagsize, opts)
-}
-
-func sizeEnumSliceReflect(s reflect.Value, tagsize int, _ marshalOptions) (size int) {
-	for i, llen := 0, s.Len(); i < llen; i++ {
-		size += wire.SizeVarint(uint64(s.Index(i).Int())) + tagsize
-	}
-	return size
-}
-
-func appendEnumSliceIface(b []byte, ival interface{}, wiretag uint64, opts marshalOptions) ([]byte, error) {
-	return appendEnumSliceReflect(b, reflect.ValueOf(ival).Elem(), wiretag, opts)
-}
-
-func appendEnumSliceReflect(b []byte, s reflect.Value, wiretag uint64, opts marshalOptions) ([]byte, error) {
-	for i, llen := 0, s.Len(); i < llen; i++ {
-		b = wire.AppendVarint(b, wiretag)
-		b = wire.AppendVarint(b, uint64(s.Index(i).Int()))
-	}
-	return b, nil
-}
-
-func consumeEnumSliceIface(b []byte, ival interface{}, _ wire.Number, wtyp wire.Type, opts unmarshalOptions) (interface{}, int, error) {
-	n, err := consumeEnumSliceReflect(b, reflect.ValueOf(ival), wtyp, opts)
-	return ival, n, err
-}
-
-func consumeEnumSliceReflect(b []byte, s reflect.Value, wtyp wire.Type, _ unmarshalOptions) (n int, err error) {
-	s = s.Elem() // *[]E -> []E
-	if wtyp == wire.BytesType {
-		b, n = wire.ConsumeBytes(b)
-		if n < 0 {
-			return 0, wire.ParseError(n)
-		}
-		for len(b) > 0 {
-			v, n := wire.ConsumeVarint(b)
-			if n < 0 {
-				return 0, wire.ParseError(n)
-			}
-			rv := reflect.New(s.Type().Elem()).Elem()
-			rv.SetInt(int64(v))
-			s.Set(reflect.Append(s, rv))
-			b = b[n:]
-		}
-		return n, nil
-	}
-	if wtyp != wire.VarintType {
-		return 0, errUnknown
-	}
-	v, n := wire.ConsumeVarint(b)
-	if n < 0 {
-		return 0, wire.ParseError(n)
-	}
-	rv := reflect.New(s.Type().Elem()).Elem()
-	rv.SetInt(int64(v))
-	s.Set(reflect.Append(s, rv))
-	return n, nil
-}
-
-var coderEnumSliceIface = ifaceCoderFuncs{
-	size:      sizeEnumSliceIface,
-	marshal:   appendEnumSliceIface,
-	unmarshal: consumeEnumSliceIface,
-}
-
-func sizeEnumPackedSliceIface(ival interface{}, tagsize int, opts marshalOptions) (size int) {
-	return sizeEnumPackedSliceReflect(reflect.ValueOf(ival).Elem(), tagsize, opts)
-}
-
-func sizeEnumPackedSliceReflect(s reflect.Value, tagsize int, _ marshalOptions) (size int) {
-	llen := s.Len()
-	if llen == 0 {
-		return 0
-	}
-	n := 0
-	for i := 0; i < llen; i++ {
-		n += wire.SizeVarint(uint64(s.Index(i).Int()))
-	}
-	return tagsize + wire.SizeBytes(n)
-}
-
-func appendEnumPackedSliceIface(b []byte, ival interface{}, wiretag uint64, opts marshalOptions) ([]byte, error) {
-	return appendEnumPackedSliceReflect(b, reflect.ValueOf(ival).Elem(), wiretag, opts)
-}
-
-func appendEnumPackedSliceReflect(b []byte, s reflect.Value, wiretag uint64, opts marshalOptions) ([]byte, error) {
-	llen := s.Len()
-	if llen == 0 {
-		return b, nil
-	}
-	b = wire.AppendVarint(b, wiretag)
-	n := 0
-	for i := 0; i < llen; i++ {
-		n += wire.SizeVarint(uint64(s.Index(i).Int()))
-	}
-	b = wire.AppendVarint(b, uint64(n))
-	for i := 0; i < llen; i++ {
-		b = wire.AppendVarint(b, uint64(s.Index(i).Int()))
-	}
-	return b, nil
-}
-
-var coderEnumPackedSliceIface = ifaceCoderFuncs{
-	size:      sizeEnumPackedSliceIface,
-	marshal:   appendEnumPackedSliceIface,
-	unmarshal: consumeEnumSliceIface,
-}
-
 func asMessage(v reflect.Value) pref.ProtoMessage {
 	if m, ok := v.Interface().(pref.ProtoMessage); ok {
 		return m
diff --git a/internal/impl/codec_gen.go b/internal/impl/codec_gen.go
index f40af3d..3d47dcc 100644
--- a/internal/impl/codec_gen.go
+++ b/internal/impl/codec_gen.go
@@ -207,129 +207,252 @@
 	unmarshal: consumeBoolSlice,
 }
 
-// sizeBoolIface returns the size of wire encoding a bool value as a Bool.
-func sizeBoolIface(ival interface{}, tagsize int, _ marshalOptions) int {
-	v := ival.(bool)
-	return tagsize + wire.SizeVarint(wire.EncodeBool(v))
+// sizeBoolValue returns the size of wire encoding a bool value as a Bool.
+func sizeBoolValue(v protoreflect.Value, tagsize int, _ marshalOptions) int {
+	return tagsize + wire.SizeVarint(wire.EncodeBool(v.Bool()))
 }
 
-// appendBoolIface encodes a bool value as a Bool.
-func appendBoolIface(b []byte, ival interface{}, wiretag uint64, _ marshalOptions) ([]byte, error) {
-	v := ival.(bool)
+// appendBoolValue encodes a bool value as a Bool.
+func appendBoolValue(b []byte, v protoreflect.Value, wiretag uint64, _ marshalOptions) ([]byte, error) {
 	b = wire.AppendVarint(b, wiretag)
-	b = wire.AppendVarint(b, wire.EncodeBool(v))
+	b = wire.AppendVarint(b, wire.EncodeBool(v.Bool()))
 	return b, nil
 }
 
-// consumeBoolIface decodes a bool value as a Bool.
-func consumeBoolIface(b []byte, _ interface{}, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (interface{}, int, error) {
+// consumeBoolValue decodes a bool value as a Bool.
+func consumeBoolValue(b []byte, _ protoreflect.Value, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (protoreflect.Value, int, error) {
 	if wtyp != wire.VarintType {
-		return nil, 0, errUnknown
+		return protoreflect.Value{}, 0, errUnknown
 	}
 	v, n := wire.ConsumeVarint(b)
 	if n < 0 {
-		return nil, 0, wire.ParseError(n)
+		return protoreflect.Value{}, 0, wire.ParseError(n)
 	}
-	return wire.DecodeBool(v), n, nil
+	return protoreflect.ValueOfBool(wire.DecodeBool(v)), n, nil
 }
 
-var coderBoolIface = ifaceCoderFuncs{
-	size:      sizeBoolIface,
-	marshal:   appendBoolIface,
-	unmarshal: consumeBoolIface,
+var coderBoolValue = valueCoderFuncs{
+	size:      sizeBoolValue,
+	marshal:   appendBoolValue,
+	unmarshal: consumeBoolValue,
 }
 
-// sizeBoolSliceIface returns the size of wire encoding a []bool value as a repeated Bool.
-func sizeBoolSliceIface(ival interface{}, tagsize int, _ marshalOptions) (size int) {
-	s := *ival.(*[]bool)
-	for _, v := range s {
-		size += tagsize + wire.SizeVarint(wire.EncodeBool(v))
+// sizeBoolSliceValue returns the size of wire encoding a []bool value as a repeated Bool.
+func sizeBoolSliceValue(listv protoreflect.Value, tagsize int, _ marshalOptions) (size int) {
+	list := listv.List()
+	for i, llen := 0, list.Len(); i < llen; i++ {
+		v := list.Get(i)
+		size += tagsize + wire.SizeVarint(wire.EncodeBool(v.Bool()))
 	}
 	return size
 }
 
-// appendBoolSliceIface encodes a []bool value as a repeated Bool.
-func appendBoolSliceIface(b []byte, ival interface{}, wiretag uint64, _ marshalOptions) ([]byte, error) {
-	s := *ival.(*[]bool)
-	for _, v := range s {
+// appendBoolSliceValue encodes a []bool value as a repeated Bool.
+func appendBoolSliceValue(b []byte, listv protoreflect.Value, wiretag uint64, _ marshalOptions) ([]byte, error) {
+	list := listv.List()
+	for i, llen := 0, list.Len(); i < llen; i++ {
+		v := list.Get(i)
 		b = wire.AppendVarint(b, wiretag)
-		b = wire.AppendVarint(b, wire.EncodeBool(v))
+		b = wire.AppendVarint(b, wire.EncodeBool(v.Bool()))
 	}
 	return b, nil
 }
 
-// consumeBoolSliceIface wire decodes a []bool value as a repeated Bool.
-func consumeBoolSliceIface(b []byte, ival interface{}, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (_ interface{}, n int, err error) {
-	sp := ival.(*[]bool)
+// consumeBoolSliceValue wire decodes a []bool value as a repeated Bool.
+func consumeBoolSliceValue(b []byte, listv protoreflect.Value, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (_ protoreflect.Value, n int, err error) {
+	list := listv.List()
 	if wtyp == wire.BytesType {
-		s := *sp
 		b, n = wire.ConsumeBytes(b)
 		if n < 0 {
-			return nil, 0, wire.ParseError(n)
+			return protoreflect.Value{}, 0, wire.ParseError(n)
 		}
 		for len(b) > 0 {
 			v, n := wire.ConsumeVarint(b)
 			if n < 0 {
-				return nil, 0, wire.ParseError(n)
+				return protoreflect.Value{}, 0, wire.ParseError(n)
 			}
-			s = append(s, wire.DecodeBool(v))
+			list.Append(protoreflect.ValueOfBool(wire.DecodeBool(v)))
 			b = b[n:]
 		}
-		*sp = s
-		return ival, n, nil
+		return listv, n, nil
 	}
 	if wtyp != wire.VarintType {
-		return nil, 0, errUnknown
+		return protoreflect.Value{}, 0, errUnknown
 	}
 	v, n := wire.ConsumeVarint(b)
 	if n < 0 {
-		return nil, 0, wire.ParseError(n)
+		return protoreflect.Value{}, 0, wire.ParseError(n)
 	}
-	*sp = append(*sp, wire.DecodeBool(v))
-	return ival, n, nil
+	list.Append(protoreflect.ValueOfBool(wire.DecodeBool(v)))
+	return listv, n, nil
 }
 
-var coderBoolSliceIface = ifaceCoderFuncs{
-	size:      sizeBoolSliceIface,
-	marshal:   appendBoolSliceIface,
-	unmarshal: consumeBoolSliceIface,
+var coderBoolSliceValue = valueCoderFuncs{
+	size:      sizeBoolSliceValue,
+	marshal:   appendBoolSliceValue,
+	unmarshal: consumeBoolSliceValue,
 }
 
-// sizeBoolPackedSliceIface returns the size of wire encoding a []bool value as a packed repeated Bool.
-func sizeBoolPackedSliceIface(ival interface{}, tagsize int, _ marshalOptions) (size int) {
-	s := *ival.(*[]bool)
-	if len(s) == 0 {
-		return 0
-	}
+// sizeBoolPackedSliceValue returns the size of wire encoding a []bool value as a packed repeated Bool.
+func sizeBoolPackedSliceValue(listv protoreflect.Value, tagsize int, _ marshalOptions) (size int) {
+	list := listv.List()
 	n := 0
-	for _, v := range s {
-		n += wire.SizeVarint(wire.EncodeBool(v))
+	for i, llen := 0, list.Len(); i < llen; i++ {
+		v := list.Get(i)
+		n += wire.SizeVarint(wire.EncodeBool(v.Bool()))
 	}
 	return tagsize + wire.SizeBytes(n)
 }
 
-// appendBoolPackedSliceIface encodes a []bool value as a packed repeated Bool.
-func appendBoolPackedSliceIface(b []byte, ival interface{}, wiretag uint64, _ marshalOptions) ([]byte, error) {
-	s := *ival.(*[]bool)
-	if len(s) == 0 {
+// appendBoolPackedSliceValue encodes a []bool value as a packed repeated Bool.
+func appendBoolPackedSliceValue(b []byte, listv protoreflect.Value, wiretag uint64, _ marshalOptions) ([]byte, error) {
+	list := listv.List()
+	llen := list.Len()
+	if llen == 0 {
 		return b, nil
 	}
 	b = wire.AppendVarint(b, wiretag)
 	n := 0
-	for _, v := range s {
-		n += wire.SizeVarint(wire.EncodeBool(v))
+	for i := 0; i < llen; i++ {
+		v := list.Get(i)
+		n += wire.SizeVarint(wire.EncodeBool(v.Bool()))
 	}
 	b = wire.AppendVarint(b, uint64(n))
-	for _, v := range s {
-		b = wire.AppendVarint(b, wire.EncodeBool(v))
+	for i := 0; i < llen; i++ {
+		v := list.Get(i)
+		b = wire.AppendVarint(b, wire.EncodeBool(v.Bool()))
 	}
 	return b, nil
 }
 
-var coderBoolPackedSliceIface = ifaceCoderFuncs{
-	size:      sizeBoolPackedSliceIface,
-	marshal:   appendBoolPackedSliceIface,
-	unmarshal: consumeBoolSliceIface,
+var coderBoolPackedSliceValue = valueCoderFuncs{
+	size:      sizeBoolPackedSliceValue,
+	marshal:   appendBoolPackedSliceValue,
+	unmarshal: consumeBoolSliceValue,
+}
+
+// sizeEnumValue returns the size of wire encoding a  value as a Enum.
+func sizeEnumValue(v protoreflect.Value, tagsize int, _ marshalOptions) int {
+	return tagsize + wire.SizeVarint(uint64(v.Enum()))
+}
+
+// appendEnumValue encodes a  value as a Enum.
+func appendEnumValue(b []byte, v protoreflect.Value, wiretag uint64, _ marshalOptions) ([]byte, error) {
+	b = wire.AppendVarint(b, wiretag)
+	b = wire.AppendVarint(b, uint64(v.Enum()))
+	return b, nil
+}
+
+// consumeEnumValue decodes a  value as a Enum.
+func consumeEnumValue(b []byte, _ protoreflect.Value, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (protoreflect.Value, int, error) {
+	if wtyp != wire.VarintType {
+		return protoreflect.Value{}, 0, errUnknown
+	}
+	v, n := wire.ConsumeVarint(b)
+	if n < 0 {
+		return protoreflect.Value{}, 0, wire.ParseError(n)
+	}
+	return protoreflect.ValueOfEnum(protoreflect.EnumNumber(v)), n, nil
+}
+
+var coderEnumValue = valueCoderFuncs{
+	size:      sizeEnumValue,
+	marshal:   appendEnumValue,
+	unmarshal: consumeEnumValue,
+}
+
+// sizeEnumSliceValue returns the size of wire encoding a [] value as a repeated Enum.
+func sizeEnumSliceValue(listv protoreflect.Value, tagsize int, _ marshalOptions) (size int) {
+	list := listv.List()
+	for i, llen := 0, list.Len(); i < llen; i++ {
+		v := list.Get(i)
+		size += tagsize + wire.SizeVarint(uint64(v.Enum()))
+	}
+	return size
+}
+
+// appendEnumSliceValue encodes a [] value as a repeated Enum.
+func appendEnumSliceValue(b []byte, listv protoreflect.Value, wiretag uint64, _ marshalOptions) ([]byte, error) {
+	list := listv.List()
+	for i, llen := 0, list.Len(); i < llen; i++ {
+		v := list.Get(i)
+		b = wire.AppendVarint(b, wiretag)
+		b = wire.AppendVarint(b, uint64(v.Enum()))
+	}
+	return b, nil
+}
+
+// consumeEnumSliceValue wire decodes a [] value as a repeated Enum.
+func consumeEnumSliceValue(b []byte, listv protoreflect.Value, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (_ protoreflect.Value, n int, err error) {
+	list := listv.List()
+	if wtyp == wire.BytesType {
+		b, n = wire.ConsumeBytes(b)
+		if n < 0 {
+			return protoreflect.Value{}, 0, wire.ParseError(n)
+		}
+		for len(b) > 0 {
+			v, n := wire.ConsumeVarint(b)
+			if n < 0 {
+				return protoreflect.Value{}, 0, wire.ParseError(n)
+			}
+			list.Append(protoreflect.ValueOfEnum(protoreflect.EnumNumber(v)))
+			b = b[n:]
+		}
+		return listv, n, nil
+	}
+	if wtyp != wire.VarintType {
+		return protoreflect.Value{}, 0, errUnknown
+	}
+	v, n := wire.ConsumeVarint(b)
+	if n < 0 {
+		return protoreflect.Value{}, 0, wire.ParseError(n)
+	}
+	list.Append(protoreflect.ValueOfEnum(protoreflect.EnumNumber(v)))
+	return listv, n, nil
+}
+
+var coderEnumSliceValue = valueCoderFuncs{
+	size:      sizeEnumSliceValue,
+	marshal:   appendEnumSliceValue,
+	unmarshal: consumeEnumSliceValue,
+}
+
+// sizeEnumPackedSliceValue returns the size of wire encoding a [] value as a packed repeated Enum.
+func sizeEnumPackedSliceValue(listv protoreflect.Value, tagsize int, _ marshalOptions) (size int) {
+	list := listv.List()
+	n := 0
+	for i, llen := 0, list.Len(); i < llen; i++ {
+		v := list.Get(i)
+		n += wire.SizeVarint(uint64(v.Enum()))
+	}
+	return tagsize + wire.SizeBytes(n)
+}
+
+// appendEnumPackedSliceValue encodes a [] value as a packed repeated Enum.
+func appendEnumPackedSliceValue(b []byte, listv protoreflect.Value, wiretag uint64, _ marshalOptions) ([]byte, error) {
+	list := listv.List()
+	llen := list.Len()
+	if llen == 0 {
+		return b, nil
+	}
+	b = wire.AppendVarint(b, wiretag)
+	n := 0
+	for i := 0; i < llen; i++ {
+		v := list.Get(i)
+		n += wire.SizeVarint(uint64(v.Enum()))
+	}
+	b = wire.AppendVarint(b, uint64(n))
+	for i := 0; i < llen; i++ {
+		v := list.Get(i)
+		b = wire.AppendVarint(b, uint64(v.Enum()))
+	}
+	return b, nil
+}
+
+var coderEnumPackedSliceValue = valueCoderFuncs{
+	size:      sizeEnumPackedSliceValue,
+	marshal:   appendEnumPackedSliceValue,
+	unmarshal: consumeEnumSliceValue,
 }
 
 // sizeInt32 returns the size of wire encoding a int32 pointer as a Int32.
@@ -525,129 +648,128 @@
 	unmarshal: consumeInt32Slice,
 }
 
-// sizeInt32Iface returns the size of wire encoding a int32 value as a Int32.
-func sizeInt32Iface(ival interface{}, tagsize int, _ marshalOptions) int {
-	v := ival.(int32)
-	return tagsize + wire.SizeVarint(uint64(v))
+// sizeInt32Value returns the size of wire encoding a int32 value as a Int32.
+func sizeInt32Value(v protoreflect.Value, tagsize int, _ marshalOptions) int {
+	return tagsize + wire.SizeVarint(uint64(int32(v.Int())))
 }
 
-// appendInt32Iface encodes a int32 value as a Int32.
-func appendInt32Iface(b []byte, ival interface{}, wiretag uint64, _ marshalOptions) ([]byte, error) {
-	v := ival.(int32)
+// appendInt32Value encodes a int32 value as a Int32.
+func appendInt32Value(b []byte, v protoreflect.Value, wiretag uint64, _ marshalOptions) ([]byte, error) {
 	b = wire.AppendVarint(b, wiretag)
-	b = wire.AppendVarint(b, uint64(v))
+	b = wire.AppendVarint(b, uint64(int32(v.Int())))
 	return b, nil
 }
 
-// consumeInt32Iface decodes a int32 value as a Int32.
-func consumeInt32Iface(b []byte, _ interface{}, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (interface{}, int, error) {
+// consumeInt32Value decodes a int32 value as a Int32.
+func consumeInt32Value(b []byte, _ protoreflect.Value, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (protoreflect.Value, int, error) {
 	if wtyp != wire.VarintType {
-		return nil, 0, errUnknown
+		return protoreflect.Value{}, 0, errUnknown
 	}
 	v, n := wire.ConsumeVarint(b)
 	if n < 0 {
-		return nil, 0, wire.ParseError(n)
+		return protoreflect.Value{}, 0, wire.ParseError(n)
 	}
-	return int32(v), n, nil
+	return protoreflect.ValueOfInt32(int32(v)), n, nil
 }
 
-var coderInt32Iface = ifaceCoderFuncs{
-	size:      sizeInt32Iface,
-	marshal:   appendInt32Iface,
-	unmarshal: consumeInt32Iface,
+var coderInt32Value = valueCoderFuncs{
+	size:      sizeInt32Value,
+	marshal:   appendInt32Value,
+	unmarshal: consumeInt32Value,
 }
 
-// sizeInt32SliceIface returns the size of wire encoding a []int32 value as a repeated Int32.
-func sizeInt32SliceIface(ival interface{}, tagsize int, _ marshalOptions) (size int) {
-	s := *ival.(*[]int32)
-	for _, v := range s {
-		size += tagsize + wire.SizeVarint(uint64(v))
+// sizeInt32SliceValue returns the size of wire encoding a []int32 value as a repeated Int32.
+func sizeInt32SliceValue(listv protoreflect.Value, tagsize int, _ marshalOptions) (size int) {
+	list := listv.List()
+	for i, llen := 0, list.Len(); i < llen; i++ {
+		v := list.Get(i)
+		size += tagsize + wire.SizeVarint(uint64(int32(v.Int())))
 	}
 	return size
 }
 
-// appendInt32SliceIface encodes a []int32 value as a repeated Int32.
-func appendInt32SliceIface(b []byte, ival interface{}, wiretag uint64, _ marshalOptions) ([]byte, error) {
-	s := *ival.(*[]int32)
-	for _, v := range s {
+// appendInt32SliceValue encodes a []int32 value as a repeated Int32.
+func appendInt32SliceValue(b []byte, listv protoreflect.Value, wiretag uint64, _ marshalOptions) ([]byte, error) {
+	list := listv.List()
+	for i, llen := 0, list.Len(); i < llen; i++ {
+		v := list.Get(i)
 		b = wire.AppendVarint(b, wiretag)
-		b = wire.AppendVarint(b, uint64(v))
+		b = wire.AppendVarint(b, uint64(int32(v.Int())))
 	}
 	return b, nil
 }
 
-// consumeInt32SliceIface wire decodes a []int32 value as a repeated Int32.
-func consumeInt32SliceIface(b []byte, ival interface{}, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (_ interface{}, n int, err error) {
-	sp := ival.(*[]int32)
+// consumeInt32SliceValue wire decodes a []int32 value as a repeated Int32.
+func consumeInt32SliceValue(b []byte, listv protoreflect.Value, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (_ protoreflect.Value, n int, err error) {
+	list := listv.List()
 	if wtyp == wire.BytesType {
-		s := *sp
 		b, n = wire.ConsumeBytes(b)
 		if n < 0 {
-			return nil, 0, wire.ParseError(n)
+			return protoreflect.Value{}, 0, wire.ParseError(n)
 		}
 		for len(b) > 0 {
 			v, n := wire.ConsumeVarint(b)
 			if n < 0 {
-				return nil, 0, wire.ParseError(n)
+				return protoreflect.Value{}, 0, wire.ParseError(n)
 			}
-			s = append(s, int32(v))
+			list.Append(protoreflect.ValueOfInt32(int32(v)))
 			b = b[n:]
 		}
-		*sp = s
-		return ival, n, nil
+		return listv, n, nil
 	}
 	if wtyp != wire.VarintType {
-		return nil, 0, errUnknown
+		return protoreflect.Value{}, 0, errUnknown
 	}
 	v, n := wire.ConsumeVarint(b)
 	if n < 0 {
-		return nil, 0, wire.ParseError(n)
+		return protoreflect.Value{}, 0, wire.ParseError(n)
 	}
-	*sp = append(*sp, int32(v))
-	return ival, n, nil
+	list.Append(protoreflect.ValueOfInt32(int32(v)))
+	return listv, n, nil
 }
 
-var coderInt32SliceIface = ifaceCoderFuncs{
-	size:      sizeInt32SliceIface,
-	marshal:   appendInt32SliceIface,
-	unmarshal: consumeInt32SliceIface,
+var coderInt32SliceValue = valueCoderFuncs{
+	size:      sizeInt32SliceValue,
+	marshal:   appendInt32SliceValue,
+	unmarshal: consumeInt32SliceValue,
 }
 
-// sizeInt32PackedSliceIface returns the size of wire encoding a []int32 value as a packed repeated Int32.
-func sizeInt32PackedSliceIface(ival interface{}, tagsize int, _ marshalOptions) (size int) {
-	s := *ival.(*[]int32)
-	if len(s) == 0 {
-		return 0
-	}
+// sizeInt32PackedSliceValue returns the size of wire encoding a []int32 value as a packed repeated Int32.
+func sizeInt32PackedSliceValue(listv protoreflect.Value, tagsize int, _ marshalOptions) (size int) {
+	list := listv.List()
 	n := 0
-	for _, v := range s {
-		n += wire.SizeVarint(uint64(v))
+	for i, llen := 0, list.Len(); i < llen; i++ {
+		v := list.Get(i)
+		n += wire.SizeVarint(uint64(int32(v.Int())))
 	}
 	return tagsize + wire.SizeBytes(n)
 }
 
-// appendInt32PackedSliceIface encodes a []int32 value as a packed repeated Int32.
-func appendInt32PackedSliceIface(b []byte, ival interface{}, wiretag uint64, _ marshalOptions) ([]byte, error) {
-	s := *ival.(*[]int32)
-	if len(s) == 0 {
+// appendInt32PackedSliceValue encodes a []int32 value as a packed repeated Int32.
+func appendInt32PackedSliceValue(b []byte, listv protoreflect.Value, wiretag uint64, _ marshalOptions) ([]byte, error) {
+	list := listv.List()
+	llen := list.Len()
+	if llen == 0 {
 		return b, nil
 	}
 	b = wire.AppendVarint(b, wiretag)
 	n := 0
-	for _, v := range s {
-		n += wire.SizeVarint(uint64(v))
+	for i := 0; i < llen; i++ {
+		v := list.Get(i)
+		n += wire.SizeVarint(uint64(int32(v.Int())))
 	}
 	b = wire.AppendVarint(b, uint64(n))
-	for _, v := range s {
-		b = wire.AppendVarint(b, uint64(v))
+	for i := 0; i < llen; i++ {
+		v := list.Get(i)
+		b = wire.AppendVarint(b, uint64(int32(v.Int())))
 	}
 	return b, nil
 }
 
-var coderInt32PackedSliceIface = ifaceCoderFuncs{
-	size:      sizeInt32PackedSliceIface,
-	marshal:   appendInt32PackedSliceIface,
-	unmarshal: consumeInt32SliceIface,
+var coderInt32PackedSliceValue = valueCoderFuncs{
+	size:      sizeInt32PackedSliceValue,
+	marshal:   appendInt32PackedSliceValue,
+	unmarshal: consumeInt32SliceValue,
 }
 
 // sizeSint32 returns the size of wire encoding a int32 pointer as a Sint32.
@@ -843,129 +965,128 @@
 	unmarshal: consumeSint32Slice,
 }
 
-// sizeSint32Iface returns the size of wire encoding a int32 value as a Sint32.
-func sizeSint32Iface(ival interface{}, tagsize int, _ marshalOptions) int {
-	v := ival.(int32)
-	return tagsize + wire.SizeVarint(wire.EncodeZigZag(int64(v)))
+// sizeSint32Value returns the size of wire encoding a int32 value as a Sint32.
+func sizeSint32Value(v protoreflect.Value, tagsize int, _ marshalOptions) int {
+	return tagsize + wire.SizeVarint(wire.EncodeZigZag(int64(int32(v.Int()))))
 }
 
-// appendSint32Iface encodes a int32 value as a Sint32.
-func appendSint32Iface(b []byte, ival interface{}, wiretag uint64, _ marshalOptions) ([]byte, error) {
-	v := ival.(int32)
+// appendSint32Value encodes a int32 value as a Sint32.
+func appendSint32Value(b []byte, v protoreflect.Value, wiretag uint64, _ marshalOptions) ([]byte, error) {
 	b = wire.AppendVarint(b, wiretag)
-	b = wire.AppendVarint(b, wire.EncodeZigZag(int64(v)))
+	b = wire.AppendVarint(b, wire.EncodeZigZag(int64(int32(v.Int()))))
 	return b, nil
 }
 
-// consumeSint32Iface decodes a int32 value as a Sint32.
-func consumeSint32Iface(b []byte, _ interface{}, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (interface{}, int, error) {
+// consumeSint32Value decodes a int32 value as a Sint32.
+func consumeSint32Value(b []byte, _ protoreflect.Value, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (protoreflect.Value, int, error) {
 	if wtyp != wire.VarintType {
-		return nil, 0, errUnknown
+		return protoreflect.Value{}, 0, errUnknown
 	}
 	v, n := wire.ConsumeVarint(b)
 	if n < 0 {
-		return nil, 0, wire.ParseError(n)
+		return protoreflect.Value{}, 0, wire.ParseError(n)
 	}
-	return int32(wire.DecodeZigZag(v & math.MaxUint32)), n, nil
+	return protoreflect.ValueOfInt32(int32(wire.DecodeZigZag(v & math.MaxUint32))), n, nil
 }
 
-var coderSint32Iface = ifaceCoderFuncs{
-	size:      sizeSint32Iface,
-	marshal:   appendSint32Iface,
-	unmarshal: consumeSint32Iface,
+var coderSint32Value = valueCoderFuncs{
+	size:      sizeSint32Value,
+	marshal:   appendSint32Value,
+	unmarshal: consumeSint32Value,
 }
 
-// sizeSint32SliceIface returns the size of wire encoding a []int32 value as a repeated Sint32.
-func sizeSint32SliceIface(ival interface{}, tagsize int, _ marshalOptions) (size int) {
-	s := *ival.(*[]int32)
-	for _, v := range s {
-		size += tagsize + wire.SizeVarint(wire.EncodeZigZag(int64(v)))
+// sizeSint32SliceValue returns the size of wire encoding a []int32 value as a repeated Sint32.
+func sizeSint32SliceValue(listv protoreflect.Value, tagsize int, _ marshalOptions) (size int) {
+	list := listv.List()
+	for i, llen := 0, list.Len(); i < llen; i++ {
+		v := list.Get(i)
+		size += tagsize + wire.SizeVarint(wire.EncodeZigZag(int64(int32(v.Int()))))
 	}
 	return size
 }
 
-// appendSint32SliceIface encodes a []int32 value as a repeated Sint32.
-func appendSint32SliceIface(b []byte, ival interface{}, wiretag uint64, _ marshalOptions) ([]byte, error) {
-	s := *ival.(*[]int32)
-	for _, v := range s {
+// appendSint32SliceValue encodes a []int32 value as a repeated Sint32.
+func appendSint32SliceValue(b []byte, listv protoreflect.Value, wiretag uint64, _ marshalOptions) ([]byte, error) {
+	list := listv.List()
+	for i, llen := 0, list.Len(); i < llen; i++ {
+		v := list.Get(i)
 		b = wire.AppendVarint(b, wiretag)
-		b = wire.AppendVarint(b, wire.EncodeZigZag(int64(v)))
+		b = wire.AppendVarint(b, wire.EncodeZigZag(int64(int32(v.Int()))))
 	}
 	return b, nil
 }
 
-// consumeSint32SliceIface wire decodes a []int32 value as a repeated Sint32.
-func consumeSint32SliceIface(b []byte, ival interface{}, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (_ interface{}, n int, err error) {
-	sp := ival.(*[]int32)
+// consumeSint32SliceValue wire decodes a []int32 value as a repeated Sint32.
+func consumeSint32SliceValue(b []byte, listv protoreflect.Value, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (_ protoreflect.Value, n int, err error) {
+	list := listv.List()
 	if wtyp == wire.BytesType {
-		s := *sp
 		b, n = wire.ConsumeBytes(b)
 		if n < 0 {
-			return nil, 0, wire.ParseError(n)
+			return protoreflect.Value{}, 0, wire.ParseError(n)
 		}
 		for len(b) > 0 {
 			v, n := wire.ConsumeVarint(b)
 			if n < 0 {
-				return nil, 0, wire.ParseError(n)
+				return protoreflect.Value{}, 0, wire.ParseError(n)
 			}
-			s = append(s, int32(wire.DecodeZigZag(v&math.MaxUint32)))
+			list.Append(protoreflect.ValueOfInt32(int32(wire.DecodeZigZag(v & math.MaxUint32))))
 			b = b[n:]
 		}
-		*sp = s
-		return ival, n, nil
+		return listv, n, nil
 	}
 	if wtyp != wire.VarintType {
-		return nil, 0, errUnknown
+		return protoreflect.Value{}, 0, errUnknown
 	}
 	v, n := wire.ConsumeVarint(b)
 	if n < 0 {
-		return nil, 0, wire.ParseError(n)
+		return protoreflect.Value{}, 0, wire.ParseError(n)
 	}
-	*sp = append(*sp, int32(wire.DecodeZigZag(v&math.MaxUint32)))
-	return ival, n, nil
+	list.Append(protoreflect.ValueOfInt32(int32(wire.DecodeZigZag(v & math.MaxUint32))))
+	return listv, n, nil
 }
 
-var coderSint32SliceIface = ifaceCoderFuncs{
-	size:      sizeSint32SliceIface,
-	marshal:   appendSint32SliceIface,
-	unmarshal: consumeSint32SliceIface,
+var coderSint32SliceValue = valueCoderFuncs{
+	size:      sizeSint32SliceValue,
+	marshal:   appendSint32SliceValue,
+	unmarshal: consumeSint32SliceValue,
 }
 
-// sizeSint32PackedSliceIface returns the size of wire encoding a []int32 value as a packed repeated Sint32.
-func sizeSint32PackedSliceIface(ival interface{}, tagsize int, _ marshalOptions) (size int) {
-	s := *ival.(*[]int32)
-	if len(s) == 0 {
-		return 0
-	}
+// sizeSint32PackedSliceValue returns the size of wire encoding a []int32 value as a packed repeated Sint32.
+func sizeSint32PackedSliceValue(listv protoreflect.Value, tagsize int, _ marshalOptions) (size int) {
+	list := listv.List()
 	n := 0
-	for _, v := range s {
-		n += wire.SizeVarint(wire.EncodeZigZag(int64(v)))
+	for i, llen := 0, list.Len(); i < llen; i++ {
+		v := list.Get(i)
+		n += wire.SizeVarint(wire.EncodeZigZag(int64(int32(v.Int()))))
 	}
 	return tagsize + wire.SizeBytes(n)
 }
 
-// appendSint32PackedSliceIface encodes a []int32 value as a packed repeated Sint32.
-func appendSint32PackedSliceIface(b []byte, ival interface{}, wiretag uint64, _ marshalOptions) ([]byte, error) {
-	s := *ival.(*[]int32)
-	if len(s) == 0 {
+// appendSint32PackedSliceValue encodes a []int32 value as a packed repeated Sint32.
+func appendSint32PackedSliceValue(b []byte, listv protoreflect.Value, wiretag uint64, _ marshalOptions) ([]byte, error) {
+	list := listv.List()
+	llen := list.Len()
+	if llen == 0 {
 		return b, nil
 	}
 	b = wire.AppendVarint(b, wiretag)
 	n := 0
-	for _, v := range s {
-		n += wire.SizeVarint(wire.EncodeZigZag(int64(v)))
+	for i := 0; i < llen; i++ {
+		v := list.Get(i)
+		n += wire.SizeVarint(wire.EncodeZigZag(int64(int32(v.Int()))))
 	}
 	b = wire.AppendVarint(b, uint64(n))
-	for _, v := range s {
-		b = wire.AppendVarint(b, wire.EncodeZigZag(int64(v)))
+	for i := 0; i < llen; i++ {
+		v := list.Get(i)
+		b = wire.AppendVarint(b, wire.EncodeZigZag(int64(int32(v.Int()))))
 	}
 	return b, nil
 }
 
-var coderSint32PackedSliceIface = ifaceCoderFuncs{
-	size:      sizeSint32PackedSliceIface,
-	marshal:   appendSint32PackedSliceIface,
-	unmarshal: consumeSint32SliceIface,
+var coderSint32PackedSliceValue = valueCoderFuncs{
+	size:      sizeSint32PackedSliceValue,
+	marshal:   appendSint32PackedSliceValue,
+	unmarshal: consumeSint32SliceValue,
 }
 
 // sizeUint32 returns the size of wire encoding a uint32 pointer as a Uint32.
@@ -1161,129 +1282,128 @@
 	unmarshal: consumeUint32Slice,
 }
 
-// sizeUint32Iface returns the size of wire encoding a uint32 value as a Uint32.
-func sizeUint32Iface(ival interface{}, tagsize int, _ marshalOptions) int {
-	v := ival.(uint32)
-	return tagsize + wire.SizeVarint(uint64(v))
+// sizeUint32Value returns the size of wire encoding a uint32 value as a Uint32.
+func sizeUint32Value(v protoreflect.Value, tagsize int, _ marshalOptions) int {
+	return tagsize + wire.SizeVarint(uint64(uint32(v.Uint())))
 }
 
-// appendUint32Iface encodes a uint32 value as a Uint32.
-func appendUint32Iface(b []byte, ival interface{}, wiretag uint64, _ marshalOptions) ([]byte, error) {
-	v := ival.(uint32)
+// appendUint32Value encodes a uint32 value as a Uint32.
+func appendUint32Value(b []byte, v protoreflect.Value, wiretag uint64, _ marshalOptions) ([]byte, error) {
 	b = wire.AppendVarint(b, wiretag)
-	b = wire.AppendVarint(b, uint64(v))
+	b = wire.AppendVarint(b, uint64(uint32(v.Uint())))
 	return b, nil
 }
 
-// consumeUint32Iface decodes a uint32 value as a Uint32.
-func consumeUint32Iface(b []byte, _ interface{}, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (interface{}, int, error) {
+// consumeUint32Value decodes a uint32 value as a Uint32.
+func consumeUint32Value(b []byte, _ protoreflect.Value, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (protoreflect.Value, int, error) {
 	if wtyp != wire.VarintType {
-		return nil, 0, errUnknown
+		return protoreflect.Value{}, 0, errUnknown
 	}
 	v, n := wire.ConsumeVarint(b)
 	if n < 0 {
-		return nil, 0, wire.ParseError(n)
+		return protoreflect.Value{}, 0, wire.ParseError(n)
 	}
-	return uint32(v), n, nil
+	return protoreflect.ValueOfUint32(uint32(v)), n, nil
 }
 
-var coderUint32Iface = ifaceCoderFuncs{
-	size:      sizeUint32Iface,
-	marshal:   appendUint32Iface,
-	unmarshal: consumeUint32Iface,
+var coderUint32Value = valueCoderFuncs{
+	size:      sizeUint32Value,
+	marshal:   appendUint32Value,
+	unmarshal: consumeUint32Value,
 }
 
-// sizeUint32SliceIface returns the size of wire encoding a []uint32 value as a repeated Uint32.
-func sizeUint32SliceIface(ival interface{}, tagsize int, _ marshalOptions) (size int) {
-	s := *ival.(*[]uint32)
-	for _, v := range s {
-		size += tagsize + wire.SizeVarint(uint64(v))
+// sizeUint32SliceValue returns the size of wire encoding a []uint32 value as a repeated Uint32.
+func sizeUint32SliceValue(listv protoreflect.Value, tagsize int, _ marshalOptions) (size int) {
+	list := listv.List()
+	for i, llen := 0, list.Len(); i < llen; i++ {
+		v := list.Get(i)
+		size += tagsize + wire.SizeVarint(uint64(uint32(v.Uint())))
 	}
 	return size
 }
 
-// appendUint32SliceIface encodes a []uint32 value as a repeated Uint32.
-func appendUint32SliceIface(b []byte, ival interface{}, wiretag uint64, _ marshalOptions) ([]byte, error) {
-	s := *ival.(*[]uint32)
-	for _, v := range s {
+// appendUint32SliceValue encodes a []uint32 value as a repeated Uint32.
+func appendUint32SliceValue(b []byte, listv protoreflect.Value, wiretag uint64, _ marshalOptions) ([]byte, error) {
+	list := listv.List()
+	for i, llen := 0, list.Len(); i < llen; i++ {
+		v := list.Get(i)
 		b = wire.AppendVarint(b, wiretag)
-		b = wire.AppendVarint(b, uint64(v))
+		b = wire.AppendVarint(b, uint64(uint32(v.Uint())))
 	}
 	return b, nil
 }
 
-// consumeUint32SliceIface wire decodes a []uint32 value as a repeated Uint32.
-func consumeUint32SliceIface(b []byte, ival interface{}, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (_ interface{}, n int, err error) {
-	sp := ival.(*[]uint32)
+// consumeUint32SliceValue wire decodes a []uint32 value as a repeated Uint32.
+func consumeUint32SliceValue(b []byte, listv protoreflect.Value, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (_ protoreflect.Value, n int, err error) {
+	list := listv.List()
 	if wtyp == wire.BytesType {
-		s := *sp
 		b, n = wire.ConsumeBytes(b)
 		if n < 0 {
-			return nil, 0, wire.ParseError(n)
+			return protoreflect.Value{}, 0, wire.ParseError(n)
 		}
 		for len(b) > 0 {
 			v, n := wire.ConsumeVarint(b)
 			if n < 0 {
-				return nil, 0, wire.ParseError(n)
+				return protoreflect.Value{}, 0, wire.ParseError(n)
 			}
-			s = append(s, uint32(v))
+			list.Append(protoreflect.ValueOfUint32(uint32(v)))
 			b = b[n:]
 		}
-		*sp = s
-		return ival, n, nil
+		return listv, n, nil
 	}
 	if wtyp != wire.VarintType {
-		return nil, 0, errUnknown
+		return protoreflect.Value{}, 0, errUnknown
 	}
 	v, n := wire.ConsumeVarint(b)
 	if n < 0 {
-		return nil, 0, wire.ParseError(n)
+		return protoreflect.Value{}, 0, wire.ParseError(n)
 	}
-	*sp = append(*sp, uint32(v))
-	return ival, n, nil
+	list.Append(protoreflect.ValueOfUint32(uint32(v)))
+	return listv, n, nil
 }
 
-var coderUint32SliceIface = ifaceCoderFuncs{
-	size:      sizeUint32SliceIface,
-	marshal:   appendUint32SliceIface,
-	unmarshal: consumeUint32SliceIface,
+var coderUint32SliceValue = valueCoderFuncs{
+	size:      sizeUint32SliceValue,
+	marshal:   appendUint32SliceValue,
+	unmarshal: consumeUint32SliceValue,
 }
 
-// sizeUint32PackedSliceIface returns the size of wire encoding a []uint32 value as a packed repeated Uint32.
-func sizeUint32PackedSliceIface(ival interface{}, tagsize int, _ marshalOptions) (size int) {
-	s := *ival.(*[]uint32)
-	if len(s) == 0 {
-		return 0
-	}
+// sizeUint32PackedSliceValue returns the size of wire encoding a []uint32 value as a packed repeated Uint32.
+func sizeUint32PackedSliceValue(listv protoreflect.Value, tagsize int, _ marshalOptions) (size int) {
+	list := listv.List()
 	n := 0
-	for _, v := range s {
-		n += wire.SizeVarint(uint64(v))
+	for i, llen := 0, list.Len(); i < llen; i++ {
+		v := list.Get(i)
+		n += wire.SizeVarint(uint64(uint32(v.Uint())))
 	}
 	return tagsize + wire.SizeBytes(n)
 }
 
-// appendUint32PackedSliceIface encodes a []uint32 value as a packed repeated Uint32.
-func appendUint32PackedSliceIface(b []byte, ival interface{}, wiretag uint64, _ marshalOptions) ([]byte, error) {
-	s := *ival.(*[]uint32)
-	if len(s) == 0 {
+// appendUint32PackedSliceValue encodes a []uint32 value as a packed repeated Uint32.
+func appendUint32PackedSliceValue(b []byte, listv protoreflect.Value, wiretag uint64, _ marshalOptions) ([]byte, error) {
+	list := listv.List()
+	llen := list.Len()
+	if llen == 0 {
 		return b, nil
 	}
 	b = wire.AppendVarint(b, wiretag)
 	n := 0
-	for _, v := range s {
-		n += wire.SizeVarint(uint64(v))
+	for i := 0; i < llen; i++ {
+		v := list.Get(i)
+		n += wire.SizeVarint(uint64(uint32(v.Uint())))
 	}
 	b = wire.AppendVarint(b, uint64(n))
-	for _, v := range s {
-		b = wire.AppendVarint(b, uint64(v))
+	for i := 0; i < llen; i++ {
+		v := list.Get(i)
+		b = wire.AppendVarint(b, uint64(uint32(v.Uint())))
 	}
 	return b, nil
 }
 
-var coderUint32PackedSliceIface = ifaceCoderFuncs{
-	size:      sizeUint32PackedSliceIface,
-	marshal:   appendUint32PackedSliceIface,
-	unmarshal: consumeUint32SliceIface,
+var coderUint32PackedSliceValue = valueCoderFuncs{
+	size:      sizeUint32PackedSliceValue,
+	marshal:   appendUint32PackedSliceValue,
+	unmarshal: consumeUint32SliceValue,
 }
 
 // sizeInt64 returns the size of wire encoding a int64 pointer as a Int64.
@@ -1479,129 +1599,128 @@
 	unmarshal: consumeInt64Slice,
 }
 
-// sizeInt64Iface returns the size of wire encoding a int64 value as a Int64.
-func sizeInt64Iface(ival interface{}, tagsize int, _ marshalOptions) int {
-	v := ival.(int64)
-	return tagsize + wire.SizeVarint(uint64(v))
+// sizeInt64Value returns the size of wire encoding a int64 value as a Int64.
+func sizeInt64Value(v protoreflect.Value, tagsize int, _ marshalOptions) int {
+	return tagsize + wire.SizeVarint(uint64(v.Int()))
 }
 
-// appendInt64Iface encodes a int64 value as a Int64.
-func appendInt64Iface(b []byte, ival interface{}, wiretag uint64, _ marshalOptions) ([]byte, error) {
-	v := ival.(int64)
+// appendInt64Value encodes a int64 value as a Int64.
+func appendInt64Value(b []byte, v protoreflect.Value, wiretag uint64, _ marshalOptions) ([]byte, error) {
 	b = wire.AppendVarint(b, wiretag)
-	b = wire.AppendVarint(b, uint64(v))
+	b = wire.AppendVarint(b, uint64(v.Int()))
 	return b, nil
 }
 
-// consumeInt64Iface decodes a int64 value as a Int64.
-func consumeInt64Iface(b []byte, _ interface{}, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (interface{}, int, error) {
+// consumeInt64Value decodes a int64 value as a Int64.
+func consumeInt64Value(b []byte, _ protoreflect.Value, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (protoreflect.Value, int, error) {
 	if wtyp != wire.VarintType {
-		return nil, 0, errUnknown
+		return protoreflect.Value{}, 0, errUnknown
 	}
 	v, n := wire.ConsumeVarint(b)
 	if n < 0 {
-		return nil, 0, wire.ParseError(n)
+		return protoreflect.Value{}, 0, wire.ParseError(n)
 	}
-	return int64(v), n, nil
+	return protoreflect.ValueOfInt64(int64(v)), n, nil
 }
 
-var coderInt64Iface = ifaceCoderFuncs{
-	size:      sizeInt64Iface,
-	marshal:   appendInt64Iface,
-	unmarshal: consumeInt64Iface,
+var coderInt64Value = valueCoderFuncs{
+	size:      sizeInt64Value,
+	marshal:   appendInt64Value,
+	unmarshal: consumeInt64Value,
 }
 
-// sizeInt64SliceIface returns the size of wire encoding a []int64 value as a repeated Int64.
-func sizeInt64SliceIface(ival interface{}, tagsize int, _ marshalOptions) (size int) {
-	s := *ival.(*[]int64)
-	for _, v := range s {
-		size += tagsize + wire.SizeVarint(uint64(v))
+// sizeInt64SliceValue returns the size of wire encoding a []int64 value as a repeated Int64.
+func sizeInt64SliceValue(listv protoreflect.Value, tagsize int, _ marshalOptions) (size int) {
+	list := listv.List()
+	for i, llen := 0, list.Len(); i < llen; i++ {
+		v := list.Get(i)
+		size += tagsize + wire.SizeVarint(uint64(v.Int()))
 	}
 	return size
 }
 
-// appendInt64SliceIface encodes a []int64 value as a repeated Int64.
-func appendInt64SliceIface(b []byte, ival interface{}, wiretag uint64, _ marshalOptions) ([]byte, error) {
-	s := *ival.(*[]int64)
-	for _, v := range s {
+// appendInt64SliceValue encodes a []int64 value as a repeated Int64.
+func appendInt64SliceValue(b []byte, listv protoreflect.Value, wiretag uint64, _ marshalOptions) ([]byte, error) {
+	list := listv.List()
+	for i, llen := 0, list.Len(); i < llen; i++ {
+		v := list.Get(i)
 		b = wire.AppendVarint(b, wiretag)
-		b = wire.AppendVarint(b, uint64(v))
+		b = wire.AppendVarint(b, uint64(v.Int()))
 	}
 	return b, nil
 }
 
-// consumeInt64SliceIface wire decodes a []int64 value as a repeated Int64.
-func consumeInt64SliceIface(b []byte, ival interface{}, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (_ interface{}, n int, err error) {
-	sp := ival.(*[]int64)
+// consumeInt64SliceValue wire decodes a []int64 value as a repeated Int64.
+func consumeInt64SliceValue(b []byte, listv protoreflect.Value, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (_ protoreflect.Value, n int, err error) {
+	list := listv.List()
 	if wtyp == wire.BytesType {
-		s := *sp
 		b, n = wire.ConsumeBytes(b)
 		if n < 0 {
-			return nil, 0, wire.ParseError(n)
+			return protoreflect.Value{}, 0, wire.ParseError(n)
 		}
 		for len(b) > 0 {
 			v, n := wire.ConsumeVarint(b)
 			if n < 0 {
-				return nil, 0, wire.ParseError(n)
+				return protoreflect.Value{}, 0, wire.ParseError(n)
 			}
-			s = append(s, int64(v))
+			list.Append(protoreflect.ValueOfInt64(int64(v)))
 			b = b[n:]
 		}
-		*sp = s
-		return ival, n, nil
+		return listv, n, nil
 	}
 	if wtyp != wire.VarintType {
-		return nil, 0, errUnknown
+		return protoreflect.Value{}, 0, errUnknown
 	}
 	v, n := wire.ConsumeVarint(b)
 	if n < 0 {
-		return nil, 0, wire.ParseError(n)
+		return protoreflect.Value{}, 0, wire.ParseError(n)
 	}
-	*sp = append(*sp, int64(v))
-	return ival, n, nil
+	list.Append(protoreflect.ValueOfInt64(int64(v)))
+	return listv, n, nil
 }
 
-var coderInt64SliceIface = ifaceCoderFuncs{
-	size:      sizeInt64SliceIface,
-	marshal:   appendInt64SliceIface,
-	unmarshal: consumeInt64SliceIface,
+var coderInt64SliceValue = valueCoderFuncs{
+	size:      sizeInt64SliceValue,
+	marshal:   appendInt64SliceValue,
+	unmarshal: consumeInt64SliceValue,
 }
 
-// sizeInt64PackedSliceIface returns the size of wire encoding a []int64 value as a packed repeated Int64.
-func sizeInt64PackedSliceIface(ival interface{}, tagsize int, _ marshalOptions) (size int) {
-	s := *ival.(*[]int64)
-	if len(s) == 0 {
-		return 0
-	}
+// sizeInt64PackedSliceValue returns the size of wire encoding a []int64 value as a packed repeated Int64.
+func sizeInt64PackedSliceValue(listv protoreflect.Value, tagsize int, _ marshalOptions) (size int) {
+	list := listv.List()
 	n := 0
-	for _, v := range s {
-		n += wire.SizeVarint(uint64(v))
+	for i, llen := 0, list.Len(); i < llen; i++ {
+		v := list.Get(i)
+		n += wire.SizeVarint(uint64(v.Int()))
 	}
 	return tagsize + wire.SizeBytes(n)
 }
 
-// appendInt64PackedSliceIface encodes a []int64 value as a packed repeated Int64.
-func appendInt64PackedSliceIface(b []byte, ival interface{}, wiretag uint64, _ marshalOptions) ([]byte, error) {
-	s := *ival.(*[]int64)
-	if len(s) == 0 {
+// appendInt64PackedSliceValue encodes a []int64 value as a packed repeated Int64.
+func appendInt64PackedSliceValue(b []byte, listv protoreflect.Value, wiretag uint64, _ marshalOptions) ([]byte, error) {
+	list := listv.List()
+	llen := list.Len()
+	if llen == 0 {
 		return b, nil
 	}
 	b = wire.AppendVarint(b, wiretag)
 	n := 0
-	for _, v := range s {
-		n += wire.SizeVarint(uint64(v))
+	for i := 0; i < llen; i++ {
+		v := list.Get(i)
+		n += wire.SizeVarint(uint64(v.Int()))
 	}
 	b = wire.AppendVarint(b, uint64(n))
-	for _, v := range s {
-		b = wire.AppendVarint(b, uint64(v))
+	for i := 0; i < llen; i++ {
+		v := list.Get(i)
+		b = wire.AppendVarint(b, uint64(v.Int()))
 	}
 	return b, nil
 }
 
-var coderInt64PackedSliceIface = ifaceCoderFuncs{
-	size:      sizeInt64PackedSliceIface,
-	marshal:   appendInt64PackedSliceIface,
-	unmarshal: consumeInt64SliceIface,
+var coderInt64PackedSliceValue = valueCoderFuncs{
+	size:      sizeInt64PackedSliceValue,
+	marshal:   appendInt64PackedSliceValue,
+	unmarshal: consumeInt64SliceValue,
 }
 
 // sizeSint64 returns the size of wire encoding a int64 pointer as a Sint64.
@@ -1797,129 +1916,128 @@
 	unmarshal: consumeSint64Slice,
 }
 
-// sizeSint64Iface returns the size of wire encoding a int64 value as a Sint64.
-func sizeSint64Iface(ival interface{}, tagsize int, _ marshalOptions) int {
-	v := ival.(int64)
-	return tagsize + wire.SizeVarint(wire.EncodeZigZag(v))
+// sizeSint64Value returns the size of wire encoding a int64 value as a Sint64.
+func sizeSint64Value(v protoreflect.Value, tagsize int, _ marshalOptions) int {
+	return tagsize + wire.SizeVarint(wire.EncodeZigZag(v.Int()))
 }
 
-// appendSint64Iface encodes a int64 value as a Sint64.
-func appendSint64Iface(b []byte, ival interface{}, wiretag uint64, _ marshalOptions) ([]byte, error) {
-	v := ival.(int64)
+// appendSint64Value encodes a int64 value as a Sint64.
+func appendSint64Value(b []byte, v protoreflect.Value, wiretag uint64, _ marshalOptions) ([]byte, error) {
 	b = wire.AppendVarint(b, wiretag)
-	b = wire.AppendVarint(b, wire.EncodeZigZag(v))
+	b = wire.AppendVarint(b, wire.EncodeZigZag(v.Int()))
 	return b, nil
 }
 
-// consumeSint64Iface decodes a int64 value as a Sint64.
-func consumeSint64Iface(b []byte, _ interface{}, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (interface{}, int, error) {
+// consumeSint64Value decodes a int64 value as a Sint64.
+func consumeSint64Value(b []byte, _ protoreflect.Value, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (protoreflect.Value, int, error) {
 	if wtyp != wire.VarintType {
-		return nil, 0, errUnknown
+		return protoreflect.Value{}, 0, errUnknown
 	}
 	v, n := wire.ConsumeVarint(b)
 	if n < 0 {
-		return nil, 0, wire.ParseError(n)
+		return protoreflect.Value{}, 0, wire.ParseError(n)
 	}
-	return wire.DecodeZigZag(v), n, nil
+	return protoreflect.ValueOfInt64(wire.DecodeZigZag(v)), n, nil
 }
 
-var coderSint64Iface = ifaceCoderFuncs{
-	size:      sizeSint64Iface,
-	marshal:   appendSint64Iface,
-	unmarshal: consumeSint64Iface,
+var coderSint64Value = valueCoderFuncs{
+	size:      sizeSint64Value,
+	marshal:   appendSint64Value,
+	unmarshal: consumeSint64Value,
 }
 
-// sizeSint64SliceIface returns the size of wire encoding a []int64 value as a repeated Sint64.
-func sizeSint64SliceIface(ival interface{}, tagsize int, _ marshalOptions) (size int) {
-	s := *ival.(*[]int64)
-	for _, v := range s {
-		size += tagsize + wire.SizeVarint(wire.EncodeZigZag(v))
+// sizeSint64SliceValue returns the size of wire encoding a []int64 value as a repeated Sint64.
+func sizeSint64SliceValue(listv protoreflect.Value, tagsize int, _ marshalOptions) (size int) {
+	list := listv.List()
+	for i, llen := 0, list.Len(); i < llen; i++ {
+		v := list.Get(i)
+		size += tagsize + wire.SizeVarint(wire.EncodeZigZag(v.Int()))
 	}
 	return size
 }
 
-// appendSint64SliceIface encodes a []int64 value as a repeated Sint64.
-func appendSint64SliceIface(b []byte, ival interface{}, wiretag uint64, _ marshalOptions) ([]byte, error) {
-	s := *ival.(*[]int64)
-	for _, v := range s {
+// appendSint64SliceValue encodes a []int64 value as a repeated Sint64.
+func appendSint64SliceValue(b []byte, listv protoreflect.Value, wiretag uint64, _ marshalOptions) ([]byte, error) {
+	list := listv.List()
+	for i, llen := 0, list.Len(); i < llen; i++ {
+		v := list.Get(i)
 		b = wire.AppendVarint(b, wiretag)
-		b = wire.AppendVarint(b, wire.EncodeZigZag(v))
+		b = wire.AppendVarint(b, wire.EncodeZigZag(v.Int()))
 	}
 	return b, nil
 }
 
-// consumeSint64SliceIface wire decodes a []int64 value as a repeated Sint64.
-func consumeSint64SliceIface(b []byte, ival interface{}, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (_ interface{}, n int, err error) {
-	sp := ival.(*[]int64)
+// consumeSint64SliceValue wire decodes a []int64 value as a repeated Sint64.
+func consumeSint64SliceValue(b []byte, listv protoreflect.Value, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (_ protoreflect.Value, n int, err error) {
+	list := listv.List()
 	if wtyp == wire.BytesType {
-		s := *sp
 		b, n = wire.ConsumeBytes(b)
 		if n < 0 {
-			return nil, 0, wire.ParseError(n)
+			return protoreflect.Value{}, 0, wire.ParseError(n)
 		}
 		for len(b) > 0 {
 			v, n := wire.ConsumeVarint(b)
 			if n < 0 {
-				return nil, 0, wire.ParseError(n)
+				return protoreflect.Value{}, 0, wire.ParseError(n)
 			}
-			s = append(s, wire.DecodeZigZag(v))
+			list.Append(protoreflect.ValueOfInt64(wire.DecodeZigZag(v)))
 			b = b[n:]
 		}
-		*sp = s
-		return ival, n, nil
+		return listv, n, nil
 	}
 	if wtyp != wire.VarintType {
-		return nil, 0, errUnknown
+		return protoreflect.Value{}, 0, errUnknown
 	}
 	v, n := wire.ConsumeVarint(b)
 	if n < 0 {
-		return nil, 0, wire.ParseError(n)
+		return protoreflect.Value{}, 0, wire.ParseError(n)
 	}
-	*sp = append(*sp, wire.DecodeZigZag(v))
-	return ival, n, nil
+	list.Append(protoreflect.ValueOfInt64(wire.DecodeZigZag(v)))
+	return listv, n, nil
 }
 
-var coderSint64SliceIface = ifaceCoderFuncs{
-	size:      sizeSint64SliceIface,
-	marshal:   appendSint64SliceIface,
-	unmarshal: consumeSint64SliceIface,
+var coderSint64SliceValue = valueCoderFuncs{
+	size:      sizeSint64SliceValue,
+	marshal:   appendSint64SliceValue,
+	unmarshal: consumeSint64SliceValue,
 }
 
-// sizeSint64PackedSliceIface returns the size of wire encoding a []int64 value as a packed repeated Sint64.
-func sizeSint64PackedSliceIface(ival interface{}, tagsize int, _ marshalOptions) (size int) {
-	s := *ival.(*[]int64)
-	if len(s) == 0 {
-		return 0
-	}
+// sizeSint64PackedSliceValue returns the size of wire encoding a []int64 value as a packed repeated Sint64.
+func sizeSint64PackedSliceValue(listv protoreflect.Value, tagsize int, _ marshalOptions) (size int) {
+	list := listv.List()
 	n := 0
-	for _, v := range s {
-		n += wire.SizeVarint(wire.EncodeZigZag(v))
+	for i, llen := 0, list.Len(); i < llen; i++ {
+		v := list.Get(i)
+		n += wire.SizeVarint(wire.EncodeZigZag(v.Int()))
 	}
 	return tagsize + wire.SizeBytes(n)
 }
 
-// appendSint64PackedSliceIface encodes a []int64 value as a packed repeated Sint64.
-func appendSint64PackedSliceIface(b []byte, ival interface{}, wiretag uint64, _ marshalOptions) ([]byte, error) {
-	s := *ival.(*[]int64)
-	if len(s) == 0 {
+// appendSint64PackedSliceValue encodes a []int64 value as a packed repeated Sint64.
+func appendSint64PackedSliceValue(b []byte, listv protoreflect.Value, wiretag uint64, _ marshalOptions) ([]byte, error) {
+	list := listv.List()
+	llen := list.Len()
+	if llen == 0 {
 		return b, nil
 	}
 	b = wire.AppendVarint(b, wiretag)
 	n := 0
-	for _, v := range s {
-		n += wire.SizeVarint(wire.EncodeZigZag(v))
+	for i := 0; i < llen; i++ {
+		v := list.Get(i)
+		n += wire.SizeVarint(wire.EncodeZigZag(v.Int()))
 	}
 	b = wire.AppendVarint(b, uint64(n))
-	for _, v := range s {
-		b = wire.AppendVarint(b, wire.EncodeZigZag(v))
+	for i := 0; i < llen; i++ {
+		v := list.Get(i)
+		b = wire.AppendVarint(b, wire.EncodeZigZag(v.Int()))
 	}
 	return b, nil
 }
 
-var coderSint64PackedSliceIface = ifaceCoderFuncs{
-	size:      sizeSint64PackedSliceIface,
-	marshal:   appendSint64PackedSliceIface,
-	unmarshal: consumeSint64SliceIface,
+var coderSint64PackedSliceValue = valueCoderFuncs{
+	size:      sizeSint64PackedSliceValue,
+	marshal:   appendSint64PackedSliceValue,
+	unmarshal: consumeSint64SliceValue,
 }
 
 // sizeUint64 returns the size of wire encoding a uint64 pointer as a Uint64.
@@ -2115,129 +2233,128 @@
 	unmarshal: consumeUint64Slice,
 }
 
-// sizeUint64Iface returns the size of wire encoding a uint64 value as a Uint64.
-func sizeUint64Iface(ival interface{}, tagsize int, _ marshalOptions) int {
-	v := ival.(uint64)
-	return tagsize + wire.SizeVarint(v)
+// sizeUint64Value returns the size of wire encoding a uint64 value as a Uint64.
+func sizeUint64Value(v protoreflect.Value, tagsize int, _ marshalOptions) int {
+	return tagsize + wire.SizeVarint(v.Uint())
 }
 
-// appendUint64Iface encodes a uint64 value as a Uint64.
-func appendUint64Iface(b []byte, ival interface{}, wiretag uint64, _ marshalOptions) ([]byte, error) {
-	v := ival.(uint64)
+// appendUint64Value encodes a uint64 value as a Uint64.
+func appendUint64Value(b []byte, v protoreflect.Value, wiretag uint64, _ marshalOptions) ([]byte, error) {
 	b = wire.AppendVarint(b, wiretag)
-	b = wire.AppendVarint(b, v)
+	b = wire.AppendVarint(b, v.Uint())
 	return b, nil
 }
 
-// consumeUint64Iface decodes a uint64 value as a Uint64.
-func consumeUint64Iface(b []byte, _ interface{}, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (interface{}, int, error) {
+// consumeUint64Value decodes a uint64 value as a Uint64.
+func consumeUint64Value(b []byte, _ protoreflect.Value, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (protoreflect.Value, int, error) {
 	if wtyp != wire.VarintType {
-		return nil, 0, errUnknown
+		return protoreflect.Value{}, 0, errUnknown
 	}
 	v, n := wire.ConsumeVarint(b)
 	if n < 0 {
-		return nil, 0, wire.ParseError(n)
+		return protoreflect.Value{}, 0, wire.ParseError(n)
 	}
-	return v, n, nil
+	return protoreflect.ValueOfUint64(v), n, nil
 }
 
-var coderUint64Iface = ifaceCoderFuncs{
-	size:      sizeUint64Iface,
-	marshal:   appendUint64Iface,
-	unmarshal: consumeUint64Iface,
+var coderUint64Value = valueCoderFuncs{
+	size:      sizeUint64Value,
+	marshal:   appendUint64Value,
+	unmarshal: consumeUint64Value,
 }
 
-// sizeUint64SliceIface returns the size of wire encoding a []uint64 value as a repeated Uint64.
-func sizeUint64SliceIface(ival interface{}, tagsize int, _ marshalOptions) (size int) {
-	s := *ival.(*[]uint64)
-	for _, v := range s {
-		size += tagsize + wire.SizeVarint(v)
+// sizeUint64SliceValue returns the size of wire encoding a []uint64 value as a repeated Uint64.
+func sizeUint64SliceValue(listv protoreflect.Value, tagsize int, _ marshalOptions) (size int) {
+	list := listv.List()
+	for i, llen := 0, list.Len(); i < llen; i++ {
+		v := list.Get(i)
+		size += tagsize + wire.SizeVarint(v.Uint())
 	}
 	return size
 }
 
-// appendUint64SliceIface encodes a []uint64 value as a repeated Uint64.
-func appendUint64SliceIface(b []byte, ival interface{}, wiretag uint64, _ marshalOptions) ([]byte, error) {
-	s := *ival.(*[]uint64)
-	for _, v := range s {
+// appendUint64SliceValue encodes a []uint64 value as a repeated Uint64.
+func appendUint64SliceValue(b []byte, listv protoreflect.Value, wiretag uint64, _ marshalOptions) ([]byte, error) {
+	list := listv.List()
+	for i, llen := 0, list.Len(); i < llen; i++ {
+		v := list.Get(i)
 		b = wire.AppendVarint(b, wiretag)
-		b = wire.AppendVarint(b, v)
+		b = wire.AppendVarint(b, v.Uint())
 	}
 	return b, nil
 }
 
-// consumeUint64SliceIface wire decodes a []uint64 value as a repeated Uint64.
-func consumeUint64SliceIface(b []byte, ival interface{}, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (_ interface{}, n int, err error) {
-	sp := ival.(*[]uint64)
+// consumeUint64SliceValue wire decodes a []uint64 value as a repeated Uint64.
+func consumeUint64SliceValue(b []byte, listv protoreflect.Value, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (_ protoreflect.Value, n int, err error) {
+	list := listv.List()
 	if wtyp == wire.BytesType {
-		s := *sp
 		b, n = wire.ConsumeBytes(b)
 		if n < 0 {
-			return nil, 0, wire.ParseError(n)
+			return protoreflect.Value{}, 0, wire.ParseError(n)
 		}
 		for len(b) > 0 {
 			v, n := wire.ConsumeVarint(b)
 			if n < 0 {
-				return nil, 0, wire.ParseError(n)
+				return protoreflect.Value{}, 0, wire.ParseError(n)
 			}
-			s = append(s, v)
+			list.Append(protoreflect.ValueOfUint64(v))
 			b = b[n:]
 		}
-		*sp = s
-		return ival, n, nil
+		return listv, n, nil
 	}
 	if wtyp != wire.VarintType {
-		return nil, 0, errUnknown
+		return protoreflect.Value{}, 0, errUnknown
 	}
 	v, n := wire.ConsumeVarint(b)
 	if n < 0 {
-		return nil, 0, wire.ParseError(n)
+		return protoreflect.Value{}, 0, wire.ParseError(n)
 	}
-	*sp = append(*sp, v)
-	return ival, n, nil
+	list.Append(protoreflect.ValueOfUint64(v))
+	return listv, n, nil
 }
 
-var coderUint64SliceIface = ifaceCoderFuncs{
-	size:      sizeUint64SliceIface,
-	marshal:   appendUint64SliceIface,
-	unmarshal: consumeUint64SliceIface,
+var coderUint64SliceValue = valueCoderFuncs{
+	size:      sizeUint64SliceValue,
+	marshal:   appendUint64SliceValue,
+	unmarshal: consumeUint64SliceValue,
 }
 
-// sizeUint64PackedSliceIface returns the size of wire encoding a []uint64 value as a packed repeated Uint64.
-func sizeUint64PackedSliceIface(ival interface{}, tagsize int, _ marshalOptions) (size int) {
-	s := *ival.(*[]uint64)
-	if len(s) == 0 {
-		return 0
-	}
+// sizeUint64PackedSliceValue returns the size of wire encoding a []uint64 value as a packed repeated Uint64.
+func sizeUint64PackedSliceValue(listv protoreflect.Value, tagsize int, _ marshalOptions) (size int) {
+	list := listv.List()
 	n := 0
-	for _, v := range s {
-		n += wire.SizeVarint(v)
+	for i, llen := 0, list.Len(); i < llen; i++ {
+		v := list.Get(i)
+		n += wire.SizeVarint(v.Uint())
 	}
 	return tagsize + wire.SizeBytes(n)
 }
 
-// appendUint64PackedSliceIface encodes a []uint64 value as a packed repeated Uint64.
-func appendUint64PackedSliceIface(b []byte, ival interface{}, wiretag uint64, _ marshalOptions) ([]byte, error) {
-	s := *ival.(*[]uint64)
-	if len(s) == 0 {
+// appendUint64PackedSliceValue encodes a []uint64 value as a packed repeated Uint64.
+func appendUint64PackedSliceValue(b []byte, listv protoreflect.Value, wiretag uint64, _ marshalOptions) ([]byte, error) {
+	list := listv.List()
+	llen := list.Len()
+	if llen == 0 {
 		return b, nil
 	}
 	b = wire.AppendVarint(b, wiretag)
 	n := 0
-	for _, v := range s {
-		n += wire.SizeVarint(v)
+	for i := 0; i < llen; i++ {
+		v := list.Get(i)
+		n += wire.SizeVarint(v.Uint())
 	}
 	b = wire.AppendVarint(b, uint64(n))
-	for _, v := range s {
-		b = wire.AppendVarint(b, v)
+	for i := 0; i < llen; i++ {
+		v := list.Get(i)
+		b = wire.AppendVarint(b, v.Uint())
 	}
 	return b, nil
 }
 
-var coderUint64PackedSliceIface = ifaceCoderFuncs{
-	size:      sizeUint64PackedSliceIface,
-	marshal:   appendUint64PackedSliceIface,
-	unmarshal: consumeUint64SliceIface,
+var coderUint64PackedSliceValue = valueCoderFuncs{
+	size:      sizeUint64PackedSliceValue,
+	marshal:   appendUint64PackedSliceValue,
+	unmarshal: consumeUint64SliceValue,
 }
 
 // sizeSfixed32 returns the size of wire encoding a int32 pointer as a Sfixed32.
@@ -2424,120 +2541,117 @@
 	unmarshal: consumeSfixed32Slice,
 }
 
-// sizeSfixed32Iface returns the size of wire encoding a int32 value as a Sfixed32.
-func sizeSfixed32Iface(ival interface{}, tagsize int, _ marshalOptions) int {
+// sizeSfixed32Value returns the size of wire encoding a int32 value as a Sfixed32.
+func sizeSfixed32Value(v protoreflect.Value, tagsize int, _ marshalOptions) int {
 	return tagsize + wire.SizeFixed32()
 }
 
-// appendSfixed32Iface encodes a int32 value as a Sfixed32.
-func appendSfixed32Iface(b []byte, ival interface{}, wiretag uint64, _ marshalOptions) ([]byte, error) {
-	v := ival.(int32)
+// appendSfixed32Value encodes a int32 value as a Sfixed32.
+func appendSfixed32Value(b []byte, v protoreflect.Value, wiretag uint64, _ marshalOptions) ([]byte, error) {
 	b = wire.AppendVarint(b, wiretag)
-	b = wire.AppendFixed32(b, uint32(v))
+	b = wire.AppendFixed32(b, uint32(v.Int()))
 	return b, nil
 }
 
-// consumeSfixed32Iface decodes a int32 value as a Sfixed32.
-func consumeSfixed32Iface(b []byte, _ interface{}, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (interface{}, int, error) {
+// consumeSfixed32Value decodes a int32 value as a Sfixed32.
+func consumeSfixed32Value(b []byte, _ protoreflect.Value, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (protoreflect.Value, int, error) {
 	if wtyp != wire.Fixed32Type {
-		return nil, 0, errUnknown
+		return protoreflect.Value{}, 0, errUnknown
 	}
 	v, n := wire.ConsumeFixed32(b)
 	if n < 0 {
-		return nil, 0, wire.ParseError(n)
+		return protoreflect.Value{}, 0, wire.ParseError(n)
 	}
-	return int32(v), n, nil
+	return protoreflect.ValueOfInt32(int32(v)), n, nil
 }
 
-var coderSfixed32Iface = ifaceCoderFuncs{
-	size:      sizeSfixed32Iface,
-	marshal:   appendSfixed32Iface,
-	unmarshal: consumeSfixed32Iface,
+var coderSfixed32Value = valueCoderFuncs{
+	size:      sizeSfixed32Value,
+	marshal:   appendSfixed32Value,
+	unmarshal: consumeSfixed32Value,
 }
 
-// sizeSfixed32SliceIface returns the size of wire encoding a []int32 value as a repeated Sfixed32.
-func sizeSfixed32SliceIface(ival interface{}, tagsize int, _ marshalOptions) (size int) {
-	s := *ival.(*[]int32)
-	size = len(s) * (tagsize + wire.SizeFixed32())
+// sizeSfixed32SliceValue returns the size of wire encoding a []int32 value as a repeated Sfixed32.
+func sizeSfixed32SliceValue(listv protoreflect.Value, tagsize int, _ marshalOptions) (size int) {
+	list := listv.List()
+	size = list.Len() * (tagsize + wire.SizeFixed32())
 	return size
 }
 
-// appendSfixed32SliceIface encodes a []int32 value as a repeated Sfixed32.
-func appendSfixed32SliceIface(b []byte, ival interface{}, wiretag uint64, _ marshalOptions) ([]byte, error) {
-	s := *ival.(*[]int32)
-	for _, v := range s {
+// appendSfixed32SliceValue encodes a []int32 value as a repeated Sfixed32.
+func appendSfixed32SliceValue(b []byte, listv protoreflect.Value, wiretag uint64, _ marshalOptions) ([]byte, error) {
+	list := listv.List()
+	for i, llen := 0, list.Len(); i < llen; i++ {
+		v := list.Get(i)
 		b = wire.AppendVarint(b, wiretag)
-		b = wire.AppendFixed32(b, uint32(v))
+		b = wire.AppendFixed32(b, uint32(v.Int()))
 	}
 	return b, nil
 }
 
-// consumeSfixed32SliceIface wire decodes a []int32 value as a repeated Sfixed32.
-func consumeSfixed32SliceIface(b []byte, ival interface{}, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (_ interface{}, n int, err error) {
-	sp := ival.(*[]int32)
+// consumeSfixed32SliceValue wire decodes a []int32 value as a repeated Sfixed32.
+func consumeSfixed32SliceValue(b []byte, listv protoreflect.Value, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (_ protoreflect.Value, n int, err error) {
+	list := listv.List()
 	if wtyp == wire.BytesType {
-		s := *sp
 		b, n = wire.ConsumeBytes(b)
 		if n < 0 {
-			return nil, 0, wire.ParseError(n)
+			return protoreflect.Value{}, 0, wire.ParseError(n)
 		}
 		for len(b) > 0 {
 			v, n := wire.ConsumeFixed32(b)
 			if n < 0 {
-				return nil, 0, wire.ParseError(n)
+				return protoreflect.Value{}, 0, wire.ParseError(n)
 			}
-			s = append(s, int32(v))
+			list.Append(protoreflect.ValueOfInt32(int32(v)))
 			b = b[n:]
 		}
-		*sp = s
-		return ival, n, nil
+		return listv, n, nil
 	}
 	if wtyp != wire.Fixed32Type {
-		return nil, 0, errUnknown
+		return protoreflect.Value{}, 0, errUnknown
 	}
 	v, n := wire.ConsumeFixed32(b)
 	if n < 0 {
-		return nil, 0, wire.ParseError(n)
+		return protoreflect.Value{}, 0, wire.ParseError(n)
 	}
-	*sp = append(*sp, int32(v))
-	return ival, n, nil
+	list.Append(protoreflect.ValueOfInt32(int32(v)))
+	return listv, n, nil
 }
 
-var coderSfixed32SliceIface = ifaceCoderFuncs{
-	size:      sizeSfixed32SliceIface,
-	marshal:   appendSfixed32SliceIface,
-	unmarshal: consumeSfixed32SliceIface,
+var coderSfixed32SliceValue = valueCoderFuncs{
+	size:      sizeSfixed32SliceValue,
+	marshal:   appendSfixed32SliceValue,
+	unmarshal: consumeSfixed32SliceValue,
 }
 
-// sizeSfixed32PackedSliceIface returns the size of wire encoding a []int32 value as a packed repeated Sfixed32.
-func sizeSfixed32PackedSliceIface(ival interface{}, tagsize int, _ marshalOptions) (size int) {
-	s := *ival.(*[]int32)
-	if len(s) == 0 {
-		return 0
-	}
-	n := len(s) * wire.SizeFixed32()
+// sizeSfixed32PackedSliceValue returns the size of wire encoding a []int32 value as a packed repeated Sfixed32.
+func sizeSfixed32PackedSliceValue(listv protoreflect.Value, tagsize int, _ marshalOptions) (size int) {
+	list := listv.List()
+	n := list.Len() * wire.SizeFixed32()
 	return tagsize + wire.SizeBytes(n)
 }
 
-// appendSfixed32PackedSliceIface encodes a []int32 value as a packed repeated Sfixed32.
-func appendSfixed32PackedSliceIface(b []byte, ival interface{}, wiretag uint64, _ marshalOptions) ([]byte, error) {
-	s := *ival.(*[]int32)
-	if len(s) == 0 {
+// appendSfixed32PackedSliceValue encodes a []int32 value as a packed repeated Sfixed32.
+func appendSfixed32PackedSliceValue(b []byte, listv protoreflect.Value, wiretag uint64, _ marshalOptions) ([]byte, error) {
+	list := listv.List()
+	llen := list.Len()
+	if llen == 0 {
 		return b, nil
 	}
 	b = wire.AppendVarint(b, wiretag)
-	n := len(s) * wire.SizeFixed32()
+	n := llen * wire.SizeFixed32()
 	b = wire.AppendVarint(b, uint64(n))
-	for _, v := range s {
-		b = wire.AppendFixed32(b, uint32(v))
+	for i := 0; i < llen; i++ {
+		v := list.Get(i)
+		b = wire.AppendFixed32(b, uint32(v.Int()))
 	}
 	return b, nil
 }
 
-var coderSfixed32PackedSliceIface = ifaceCoderFuncs{
-	size:      sizeSfixed32PackedSliceIface,
-	marshal:   appendSfixed32PackedSliceIface,
-	unmarshal: consumeSfixed32SliceIface,
+var coderSfixed32PackedSliceValue = valueCoderFuncs{
+	size:      sizeSfixed32PackedSliceValue,
+	marshal:   appendSfixed32PackedSliceValue,
+	unmarshal: consumeSfixed32SliceValue,
 }
 
 // sizeFixed32 returns the size of wire encoding a uint32 pointer as a Fixed32.
@@ -2724,120 +2838,117 @@
 	unmarshal: consumeFixed32Slice,
 }
 
-// sizeFixed32Iface returns the size of wire encoding a uint32 value as a Fixed32.
-func sizeFixed32Iface(ival interface{}, tagsize int, _ marshalOptions) int {
+// sizeFixed32Value returns the size of wire encoding a uint32 value as a Fixed32.
+func sizeFixed32Value(v protoreflect.Value, tagsize int, _ marshalOptions) int {
 	return tagsize + wire.SizeFixed32()
 }
 
-// appendFixed32Iface encodes a uint32 value as a Fixed32.
-func appendFixed32Iface(b []byte, ival interface{}, wiretag uint64, _ marshalOptions) ([]byte, error) {
-	v := ival.(uint32)
+// appendFixed32Value encodes a uint32 value as a Fixed32.
+func appendFixed32Value(b []byte, v protoreflect.Value, wiretag uint64, _ marshalOptions) ([]byte, error) {
 	b = wire.AppendVarint(b, wiretag)
-	b = wire.AppendFixed32(b, v)
+	b = wire.AppendFixed32(b, uint32(v.Uint()))
 	return b, nil
 }
 
-// consumeFixed32Iface decodes a uint32 value as a Fixed32.
-func consumeFixed32Iface(b []byte, _ interface{}, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (interface{}, int, error) {
+// consumeFixed32Value decodes a uint32 value as a Fixed32.
+func consumeFixed32Value(b []byte, _ protoreflect.Value, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (protoreflect.Value, int, error) {
 	if wtyp != wire.Fixed32Type {
-		return nil, 0, errUnknown
+		return protoreflect.Value{}, 0, errUnknown
 	}
 	v, n := wire.ConsumeFixed32(b)
 	if n < 0 {
-		return nil, 0, wire.ParseError(n)
+		return protoreflect.Value{}, 0, wire.ParseError(n)
 	}
-	return v, n, nil
+	return protoreflect.ValueOfUint32(uint32(v)), n, nil
 }
 
-var coderFixed32Iface = ifaceCoderFuncs{
-	size:      sizeFixed32Iface,
-	marshal:   appendFixed32Iface,
-	unmarshal: consumeFixed32Iface,
+var coderFixed32Value = valueCoderFuncs{
+	size:      sizeFixed32Value,
+	marshal:   appendFixed32Value,
+	unmarshal: consumeFixed32Value,
 }
 
-// sizeFixed32SliceIface returns the size of wire encoding a []uint32 value as a repeated Fixed32.
-func sizeFixed32SliceIface(ival interface{}, tagsize int, _ marshalOptions) (size int) {
-	s := *ival.(*[]uint32)
-	size = len(s) * (tagsize + wire.SizeFixed32())
+// sizeFixed32SliceValue returns the size of wire encoding a []uint32 value as a repeated Fixed32.
+func sizeFixed32SliceValue(listv protoreflect.Value, tagsize int, _ marshalOptions) (size int) {
+	list := listv.List()
+	size = list.Len() * (tagsize + wire.SizeFixed32())
 	return size
 }
 
-// appendFixed32SliceIface encodes a []uint32 value as a repeated Fixed32.
-func appendFixed32SliceIface(b []byte, ival interface{}, wiretag uint64, _ marshalOptions) ([]byte, error) {
-	s := *ival.(*[]uint32)
-	for _, v := range s {
+// appendFixed32SliceValue encodes a []uint32 value as a repeated Fixed32.
+func appendFixed32SliceValue(b []byte, listv protoreflect.Value, wiretag uint64, _ marshalOptions) ([]byte, error) {
+	list := listv.List()
+	for i, llen := 0, list.Len(); i < llen; i++ {
+		v := list.Get(i)
 		b = wire.AppendVarint(b, wiretag)
-		b = wire.AppendFixed32(b, v)
+		b = wire.AppendFixed32(b, uint32(v.Uint()))
 	}
 	return b, nil
 }
 
-// consumeFixed32SliceIface wire decodes a []uint32 value as a repeated Fixed32.
-func consumeFixed32SliceIface(b []byte, ival interface{}, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (_ interface{}, n int, err error) {
-	sp := ival.(*[]uint32)
+// consumeFixed32SliceValue wire decodes a []uint32 value as a repeated Fixed32.
+func consumeFixed32SliceValue(b []byte, listv protoreflect.Value, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (_ protoreflect.Value, n int, err error) {
+	list := listv.List()
 	if wtyp == wire.BytesType {
-		s := *sp
 		b, n = wire.ConsumeBytes(b)
 		if n < 0 {
-			return nil, 0, wire.ParseError(n)
+			return protoreflect.Value{}, 0, wire.ParseError(n)
 		}
 		for len(b) > 0 {
 			v, n := wire.ConsumeFixed32(b)
 			if n < 0 {
-				return nil, 0, wire.ParseError(n)
+				return protoreflect.Value{}, 0, wire.ParseError(n)
 			}
-			s = append(s, v)
+			list.Append(protoreflect.ValueOfUint32(uint32(v)))
 			b = b[n:]
 		}
-		*sp = s
-		return ival, n, nil
+		return listv, n, nil
 	}
 	if wtyp != wire.Fixed32Type {
-		return nil, 0, errUnknown
+		return protoreflect.Value{}, 0, errUnknown
 	}
 	v, n := wire.ConsumeFixed32(b)
 	if n < 0 {
-		return nil, 0, wire.ParseError(n)
+		return protoreflect.Value{}, 0, wire.ParseError(n)
 	}
-	*sp = append(*sp, v)
-	return ival, n, nil
+	list.Append(protoreflect.ValueOfUint32(uint32(v)))
+	return listv, n, nil
 }
 
-var coderFixed32SliceIface = ifaceCoderFuncs{
-	size:      sizeFixed32SliceIface,
-	marshal:   appendFixed32SliceIface,
-	unmarshal: consumeFixed32SliceIface,
+var coderFixed32SliceValue = valueCoderFuncs{
+	size:      sizeFixed32SliceValue,
+	marshal:   appendFixed32SliceValue,
+	unmarshal: consumeFixed32SliceValue,
 }
 
-// sizeFixed32PackedSliceIface returns the size of wire encoding a []uint32 value as a packed repeated Fixed32.
-func sizeFixed32PackedSliceIface(ival interface{}, tagsize int, _ marshalOptions) (size int) {
-	s := *ival.(*[]uint32)
-	if len(s) == 0 {
-		return 0
-	}
-	n := len(s) * wire.SizeFixed32()
+// sizeFixed32PackedSliceValue returns the size of wire encoding a []uint32 value as a packed repeated Fixed32.
+func sizeFixed32PackedSliceValue(listv protoreflect.Value, tagsize int, _ marshalOptions) (size int) {
+	list := listv.List()
+	n := list.Len() * wire.SizeFixed32()
 	return tagsize + wire.SizeBytes(n)
 }
 
-// appendFixed32PackedSliceIface encodes a []uint32 value as a packed repeated Fixed32.
-func appendFixed32PackedSliceIface(b []byte, ival interface{}, wiretag uint64, _ marshalOptions) ([]byte, error) {
-	s := *ival.(*[]uint32)
-	if len(s) == 0 {
+// appendFixed32PackedSliceValue encodes a []uint32 value as a packed repeated Fixed32.
+func appendFixed32PackedSliceValue(b []byte, listv protoreflect.Value, wiretag uint64, _ marshalOptions) ([]byte, error) {
+	list := listv.List()
+	llen := list.Len()
+	if llen == 0 {
 		return b, nil
 	}
 	b = wire.AppendVarint(b, wiretag)
-	n := len(s) * wire.SizeFixed32()
+	n := llen * wire.SizeFixed32()
 	b = wire.AppendVarint(b, uint64(n))
-	for _, v := range s {
-		b = wire.AppendFixed32(b, v)
+	for i := 0; i < llen; i++ {
+		v := list.Get(i)
+		b = wire.AppendFixed32(b, uint32(v.Uint()))
 	}
 	return b, nil
 }
 
-var coderFixed32PackedSliceIface = ifaceCoderFuncs{
-	size:      sizeFixed32PackedSliceIface,
-	marshal:   appendFixed32PackedSliceIface,
-	unmarshal: consumeFixed32SliceIface,
+var coderFixed32PackedSliceValue = valueCoderFuncs{
+	size:      sizeFixed32PackedSliceValue,
+	marshal:   appendFixed32PackedSliceValue,
+	unmarshal: consumeFixed32SliceValue,
 }
 
 // sizeFloat returns the size of wire encoding a float32 pointer as a Float.
@@ -3024,120 +3135,117 @@
 	unmarshal: consumeFloatSlice,
 }
 
-// sizeFloatIface returns the size of wire encoding a float32 value as a Float.
-func sizeFloatIface(ival interface{}, tagsize int, _ marshalOptions) int {
+// sizeFloatValue returns the size of wire encoding a float32 value as a Float.
+func sizeFloatValue(v protoreflect.Value, tagsize int, _ marshalOptions) int {
 	return tagsize + wire.SizeFixed32()
 }
 
-// appendFloatIface encodes a float32 value as a Float.
-func appendFloatIface(b []byte, ival interface{}, wiretag uint64, _ marshalOptions) ([]byte, error) {
-	v := ival.(float32)
+// appendFloatValue encodes a float32 value as a Float.
+func appendFloatValue(b []byte, v protoreflect.Value, wiretag uint64, _ marshalOptions) ([]byte, error) {
 	b = wire.AppendVarint(b, wiretag)
-	b = wire.AppendFixed32(b, math.Float32bits(v))
+	b = wire.AppendFixed32(b, math.Float32bits(float32(v.Float())))
 	return b, nil
 }
 
-// consumeFloatIface decodes a float32 value as a Float.
-func consumeFloatIface(b []byte, _ interface{}, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (interface{}, int, error) {
+// consumeFloatValue decodes a float32 value as a Float.
+func consumeFloatValue(b []byte, _ protoreflect.Value, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (protoreflect.Value, int, error) {
 	if wtyp != wire.Fixed32Type {
-		return nil, 0, errUnknown
+		return protoreflect.Value{}, 0, errUnknown
 	}
 	v, n := wire.ConsumeFixed32(b)
 	if n < 0 {
-		return nil, 0, wire.ParseError(n)
+		return protoreflect.Value{}, 0, wire.ParseError(n)
 	}
-	return math.Float32frombits(v), n, nil
+	return protoreflect.ValueOfFloat32(math.Float32frombits(uint32(v))), n, nil
 }
 
-var coderFloatIface = ifaceCoderFuncs{
-	size:      sizeFloatIface,
-	marshal:   appendFloatIface,
-	unmarshal: consumeFloatIface,
+var coderFloatValue = valueCoderFuncs{
+	size:      sizeFloatValue,
+	marshal:   appendFloatValue,
+	unmarshal: consumeFloatValue,
 }
 
-// sizeFloatSliceIface returns the size of wire encoding a []float32 value as a repeated Float.
-func sizeFloatSliceIface(ival interface{}, tagsize int, _ marshalOptions) (size int) {
-	s := *ival.(*[]float32)
-	size = len(s) * (tagsize + wire.SizeFixed32())
+// sizeFloatSliceValue returns the size of wire encoding a []float32 value as a repeated Float.
+func sizeFloatSliceValue(listv protoreflect.Value, tagsize int, _ marshalOptions) (size int) {
+	list := listv.List()
+	size = list.Len() * (tagsize + wire.SizeFixed32())
 	return size
 }
 
-// appendFloatSliceIface encodes a []float32 value as a repeated Float.
-func appendFloatSliceIface(b []byte, ival interface{}, wiretag uint64, _ marshalOptions) ([]byte, error) {
-	s := *ival.(*[]float32)
-	for _, v := range s {
+// appendFloatSliceValue encodes a []float32 value as a repeated Float.
+func appendFloatSliceValue(b []byte, listv protoreflect.Value, wiretag uint64, _ marshalOptions) ([]byte, error) {
+	list := listv.List()
+	for i, llen := 0, list.Len(); i < llen; i++ {
+		v := list.Get(i)
 		b = wire.AppendVarint(b, wiretag)
-		b = wire.AppendFixed32(b, math.Float32bits(v))
+		b = wire.AppendFixed32(b, math.Float32bits(float32(v.Float())))
 	}
 	return b, nil
 }
 
-// consumeFloatSliceIface wire decodes a []float32 value as a repeated Float.
-func consumeFloatSliceIface(b []byte, ival interface{}, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (_ interface{}, n int, err error) {
-	sp := ival.(*[]float32)
+// consumeFloatSliceValue wire decodes a []float32 value as a repeated Float.
+func consumeFloatSliceValue(b []byte, listv protoreflect.Value, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (_ protoreflect.Value, n int, err error) {
+	list := listv.List()
 	if wtyp == wire.BytesType {
-		s := *sp
 		b, n = wire.ConsumeBytes(b)
 		if n < 0 {
-			return nil, 0, wire.ParseError(n)
+			return protoreflect.Value{}, 0, wire.ParseError(n)
 		}
 		for len(b) > 0 {
 			v, n := wire.ConsumeFixed32(b)
 			if n < 0 {
-				return nil, 0, wire.ParseError(n)
+				return protoreflect.Value{}, 0, wire.ParseError(n)
 			}
-			s = append(s, math.Float32frombits(v))
+			list.Append(protoreflect.ValueOfFloat32(math.Float32frombits(uint32(v))))
 			b = b[n:]
 		}
-		*sp = s
-		return ival, n, nil
+		return listv, n, nil
 	}
 	if wtyp != wire.Fixed32Type {
-		return nil, 0, errUnknown
+		return protoreflect.Value{}, 0, errUnknown
 	}
 	v, n := wire.ConsumeFixed32(b)
 	if n < 0 {
-		return nil, 0, wire.ParseError(n)
+		return protoreflect.Value{}, 0, wire.ParseError(n)
 	}
-	*sp = append(*sp, math.Float32frombits(v))
-	return ival, n, nil
+	list.Append(protoreflect.ValueOfFloat32(math.Float32frombits(uint32(v))))
+	return listv, n, nil
 }
 
-var coderFloatSliceIface = ifaceCoderFuncs{
-	size:      sizeFloatSliceIface,
-	marshal:   appendFloatSliceIface,
-	unmarshal: consumeFloatSliceIface,
+var coderFloatSliceValue = valueCoderFuncs{
+	size:      sizeFloatSliceValue,
+	marshal:   appendFloatSliceValue,
+	unmarshal: consumeFloatSliceValue,
 }
 
-// sizeFloatPackedSliceIface returns the size of wire encoding a []float32 value as a packed repeated Float.
-func sizeFloatPackedSliceIface(ival interface{}, tagsize int, _ marshalOptions) (size int) {
-	s := *ival.(*[]float32)
-	if len(s) == 0 {
-		return 0
-	}
-	n := len(s) * wire.SizeFixed32()
+// sizeFloatPackedSliceValue returns the size of wire encoding a []float32 value as a packed repeated Float.
+func sizeFloatPackedSliceValue(listv protoreflect.Value, tagsize int, _ marshalOptions) (size int) {
+	list := listv.List()
+	n := list.Len() * wire.SizeFixed32()
 	return tagsize + wire.SizeBytes(n)
 }
 
-// appendFloatPackedSliceIface encodes a []float32 value as a packed repeated Float.
-func appendFloatPackedSliceIface(b []byte, ival interface{}, wiretag uint64, _ marshalOptions) ([]byte, error) {
-	s := *ival.(*[]float32)
-	if len(s) == 0 {
+// appendFloatPackedSliceValue encodes a []float32 value as a packed repeated Float.
+func appendFloatPackedSliceValue(b []byte, listv protoreflect.Value, wiretag uint64, _ marshalOptions) ([]byte, error) {
+	list := listv.List()
+	llen := list.Len()
+	if llen == 0 {
 		return b, nil
 	}
 	b = wire.AppendVarint(b, wiretag)
-	n := len(s) * wire.SizeFixed32()
+	n := llen * wire.SizeFixed32()
 	b = wire.AppendVarint(b, uint64(n))
-	for _, v := range s {
-		b = wire.AppendFixed32(b, math.Float32bits(v))
+	for i := 0; i < llen; i++ {
+		v := list.Get(i)
+		b = wire.AppendFixed32(b, math.Float32bits(float32(v.Float())))
 	}
 	return b, nil
 }
 
-var coderFloatPackedSliceIface = ifaceCoderFuncs{
-	size:      sizeFloatPackedSliceIface,
-	marshal:   appendFloatPackedSliceIface,
-	unmarshal: consumeFloatSliceIface,
+var coderFloatPackedSliceValue = valueCoderFuncs{
+	size:      sizeFloatPackedSliceValue,
+	marshal:   appendFloatPackedSliceValue,
+	unmarshal: consumeFloatSliceValue,
 }
 
 // sizeSfixed64 returns the size of wire encoding a int64 pointer as a Sfixed64.
@@ -3324,120 +3432,117 @@
 	unmarshal: consumeSfixed64Slice,
 }
 
-// sizeSfixed64Iface returns the size of wire encoding a int64 value as a Sfixed64.
-func sizeSfixed64Iface(ival interface{}, tagsize int, _ marshalOptions) int {
+// sizeSfixed64Value returns the size of wire encoding a int64 value as a Sfixed64.
+func sizeSfixed64Value(v protoreflect.Value, tagsize int, _ marshalOptions) int {
 	return tagsize + wire.SizeFixed64()
 }
 
-// appendSfixed64Iface encodes a int64 value as a Sfixed64.
-func appendSfixed64Iface(b []byte, ival interface{}, wiretag uint64, _ marshalOptions) ([]byte, error) {
-	v := ival.(int64)
+// appendSfixed64Value encodes a int64 value as a Sfixed64.
+func appendSfixed64Value(b []byte, v protoreflect.Value, wiretag uint64, _ marshalOptions) ([]byte, error) {
 	b = wire.AppendVarint(b, wiretag)
-	b = wire.AppendFixed64(b, uint64(v))
+	b = wire.AppendFixed64(b, uint64(v.Int()))
 	return b, nil
 }
 
-// consumeSfixed64Iface decodes a int64 value as a Sfixed64.
-func consumeSfixed64Iface(b []byte, _ interface{}, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (interface{}, int, error) {
+// consumeSfixed64Value decodes a int64 value as a Sfixed64.
+func consumeSfixed64Value(b []byte, _ protoreflect.Value, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (protoreflect.Value, int, error) {
 	if wtyp != wire.Fixed64Type {
-		return nil, 0, errUnknown
+		return protoreflect.Value{}, 0, errUnknown
 	}
 	v, n := wire.ConsumeFixed64(b)
 	if n < 0 {
-		return nil, 0, wire.ParseError(n)
+		return protoreflect.Value{}, 0, wire.ParseError(n)
 	}
-	return int64(v), n, nil
+	return protoreflect.ValueOfInt64(int64(v)), n, nil
 }
 
-var coderSfixed64Iface = ifaceCoderFuncs{
-	size:      sizeSfixed64Iface,
-	marshal:   appendSfixed64Iface,
-	unmarshal: consumeSfixed64Iface,
+var coderSfixed64Value = valueCoderFuncs{
+	size:      sizeSfixed64Value,
+	marshal:   appendSfixed64Value,
+	unmarshal: consumeSfixed64Value,
 }
 
-// sizeSfixed64SliceIface returns the size of wire encoding a []int64 value as a repeated Sfixed64.
-func sizeSfixed64SliceIface(ival interface{}, tagsize int, _ marshalOptions) (size int) {
-	s := *ival.(*[]int64)
-	size = len(s) * (tagsize + wire.SizeFixed64())
+// sizeSfixed64SliceValue returns the size of wire encoding a []int64 value as a repeated Sfixed64.
+func sizeSfixed64SliceValue(listv protoreflect.Value, tagsize int, _ marshalOptions) (size int) {
+	list := listv.List()
+	size = list.Len() * (tagsize + wire.SizeFixed64())
 	return size
 }
 
-// appendSfixed64SliceIface encodes a []int64 value as a repeated Sfixed64.
-func appendSfixed64SliceIface(b []byte, ival interface{}, wiretag uint64, _ marshalOptions) ([]byte, error) {
-	s := *ival.(*[]int64)
-	for _, v := range s {
+// appendSfixed64SliceValue encodes a []int64 value as a repeated Sfixed64.
+func appendSfixed64SliceValue(b []byte, listv protoreflect.Value, wiretag uint64, _ marshalOptions) ([]byte, error) {
+	list := listv.List()
+	for i, llen := 0, list.Len(); i < llen; i++ {
+		v := list.Get(i)
 		b = wire.AppendVarint(b, wiretag)
-		b = wire.AppendFixed64(b, uint64(v))
+		b = wire.AppendFixed64(b, uint64(v.Int()))
 	}
 	return b, nil
 }
 
-// consumeSfixed64SliceIface wire decodes a []int64 value as a repeated Sfixed64.
-func consumeSfixed64SliceIface(b []byte, ival interface{}, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (_ interface{}, n int, err error) {
-	sp := ival.(*[]int64)
+// consumeSfixed64SliceValue wire decodes a []int64 value as a repeated Sfixed64.
+func consumeSfixed64SliceValue(b []byte, listv protoreflect.Value, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (_ protoreflect.Value, n int, err error) {
+	list := listv.List()
 	if wtyp == wire.BytesType {
-		s := *sp
 		b, n = wire.ConsumeBytes(b)
 		if n < 0 {
-			return nil, 0, wire.ParseError(n)
+			return protoreflect.Value{}, 0, wire.ParseError(n)
 		}
 		for len(b) > 0 {
 			v, n := wire.ConsumeFixed64(b)
 			if n < 0 {
-				return nil, 0, wire.ParseError(n)
+				return protoreflect.Value{}, 0, wire.ParseError(n)
 			}
-			s = append(s, int64(v))
+			list.Append(protoreflect.ValueOfInt64(int64(v)))
 			b = b[n:]
 		}
-		*sp = s
-		return ival, n, nil
+		return listv, n, nil
 	}
 	if wtyp != wire.Fixed64Type {
-		return nil, 0, errUnknown
+		return protoreflect.Value{}, 0, errUnknown
 	}
 	v, n := wire.ConsumeFixed64(b)
 	if n < 0 {
-		return nil, 0, wire.ParseError(n)
+		return protoreflect.Value{}, 0, wire.ParseError(n)
 	}
-	*sp = append(*sp, int64(v))
-	return ival, n, nil
+	list.Append(protoreflect.ValueOfInt64(int64(v)))
+	return listv, n, nil
 }
 
-var coderSfixed64SliceIface = ifaceCoderFuncs{
-	size:      sizeSfixed64SliceIface,
-	marshal:   appendSfixed64SliceIface,
-	unmarshal: consumeSfixed64SliceIface,
+var coderSfixed64SliceValue = valueCoderFuncs{
+	size:      sizeSfixed64SliceValue,
+	marshal:   appendSfixed64SliceValue,
+	unmarshal: consumeSfixed64SliceValue,
 }
 
-// sizeSfixed64PackedSliceIface returns the size of wire encoding a []int64 value as a packed repeated Sfixed64.
-func sizeSfixed64PackedSliceIface(ival interface{}, tagsize int, _ marshalOptions) (size int) {
-	s := *ival.(*[]int64)
-	if len(s) == 0 {
-		return 0
-	}
-	n := len(s) * wire.SizeFixed64()
+// sizeSfixed64PackedSliceValue returns the size of wire encoding a []int64 value as a packed repeated Sfixed64.
+func sizeSfixed64PackedSliceValue(listv protoreflect.Value, tagsize int, _ marshalOptions) (size int) {
+	list := listv.List()
+	n := list.Len() * wire.SizeFixed64()
 	return tagsize + wire.SizeBytes(n)
 }
 
-// appendSfixed64PackedSliceIface encodes a []int64 value as a packed repeated Sfixed64.
-func appendSfixed64PackedSliceIface(b []byte, ival interface{}, wiretag uint64, _ marshalOptions) ([]byte, error) {
-	s := *ival.(*[]int64)
-	if len(s) == 0 {
+// appendSfixed64PackedSliceValue encodes a []int64 value as a packed repeated Sfixed64.
+func appendSfixed64PackedSliceValue(b []byte, listv protoreflect.Value, wiretag uint64, _ marshalOptions) ([]byte, error) {
+	list := listv.List()
+	llen := list.Len()
+	if llen == 0 {
 		return b, nil
 	}
 	b = wire.AppendVarint(b, wiretag)
-	n := len(s) * wire.SizeFixed64()
+	n := llen * wire.SizeFixed64()
 	b = wire.AppendVarint(b, uint64(n))
-	for _, v := range s {
-		b = wire.AppendFixed64(b, uint64(v))
+	for i := 0; i < llen; i++ {
+		v := list.Get(i)
+		b = wire.AppendFixed64(b, uint64(v.Int()))
 	}
 	return b, nil
 }
 
-var coderSfixed64PackedSliceIface = ifaceCoderFuncs{
-	size:      sizeSfixed64PackedSliceIface,
-	marshal:   appendSfixed64PackedSliceIface,
-	unmarshal: consumeSfixed64SliceIface,
+var coderSfixed64PackedSliceValue = valueCoderFuncs{
+	size:      sizeSfixed64PackedSliceValue,
+	marshal:   appendSfixed64PackedSliceValue,
+	unmarshal: consumeSfixed64SliceValue,
 }
 
 // sizeFixed64 returns the size of wire encoding a uint64 pointer as a Fixed64.
@@ -3624,120 +3729,117 @@
 	unmarshal: consumeFixed64Slice,
 }
 
-// sizeFixed64Iface returns the size of wire encoding a uint64 value as a Fixed64.
-func sizeFixed64Iface(ival interface{}, tagsize int, _ marshalOptions) int {
+// sizeFixed64Value returns the size of wire encoding a uint64 value as a Fixed64.
+func sizeFixed64Value(v protoreflect.Value, tagsize int, _ marshalOptions) int {
 	return tagsize + wire.SizeFixed64()
 }
 
-// appendFixed64Iface encodes a uint64 value as a Fixed64.
-func appendFixed64Iface(b []byte, ival interface{}, wiretag uint64, _ marshalOptions) ([]byte, error) {
-	v := ival.(uint64)
+// appendFixed64Value encodes a uint64 value as a Fixed64.
+func appendFixed64Value(b []byte, v protoreflect.Value, wiretag uint64, _ marshalOptions) ([]byte, error) {
 	b = wire.AppendVarint(b, wiretag)
-	b = wire.AppendFixed64(b, v)
+	b = wire.AppendFixed64(b, v.Uint())
 	return b, nil
 }
 
-// consumeFixed64Iface decodes a uint64 value as a Fixed64.
-func consumeFixed64Iface(b []byte, _ interface{}, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (interface{}, int, error) {
+// consumeFixed64Value decodes a uint64 value as a Fixed64.
+func consumeFixed64Value(b []byte, _ protoreflect.Value, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (protoreflect.Value, int, error) {
 	if wtyp != wire.Fixed64Type {
-		return nil, 0, errUnknown
+		return protoreflect.Value{}, 0, errUnknown
 	}
 	v, n := wire.ConsumeFixed64(b)
 	if n < 0 {
-		return nil, 0, wire.ParseError(n)
+		return protoreflect.Value{}, 0, wire.ParseError(n)
 	}
-	return v, n, nil
+	return protoreflect.ValueOfUint64(v), n, nil
 }
 
-var coderFixed64Iface = ifaceCoderFuncs{
-	size:      sizeFixed64Iface,
-	marshal:   appendFixed64Iface,
-	unmarshal: consumeFixed64Iface,
+var coderFixed64Value = valueCoderFuncs{
+	size:      sizeFixed64Value,
+	marshal:   appendFixed64Value,
+	unmarshal: consumeFixed64Value,
 }
 
-// sizeFixed64SliceIface returns the size of wire encoding a []uint64 value as a repeated Fixed64.
-func sizeFixed64SliceIface(ival interface{}, tagsize int, _ marshalOptions) (size int) {
-	s := *ival.(*[]uint64)
-	size = len(s) * (tagsize + wire.SizeFixed64())
+// sizeFixed64SliceValue returns the size of wire encoding a []uint64 value as a repeated Fixed64.
+func sizeFixed64SliceValue(listv protoreflect.Value, tagsize int, _ marshalOptions) (size int) {
+	list := listv.List()
+	size = list.Len() * (tagsize + wire.SizeFixed64())
 	return size
 }
 
-// appendFixed64SliceIface encodes a []uint64 value as a repeated Fixed64.
-func appendFixed64SliceIface(b []byte, ival interface{}, wiretag uint64, _ marshalOptions) ([]byte, error) {
-	s := *ival.(*[]uint64)
-	for _, v := range s {
+// appendFixed64SliceValue encodes a []uint64 value as a repeated Fixed64.
+func appendFixed64SliceValue(b []byte, listv protoreflect.Value, wiretag uint64, _ marshalOptions) ([]byte, error) {
+	list := listv.List()
+	for i, llen := 0, list.Len(); i < llen; i++ {
+		v := list.Get(i)
 		b = wire.AppendVarint(b, wiretag)
-		b = wire.AppendFixed64(b, v)
+		b = wire.AppendFixed64(b, v.Uint())
 	}
 	return b, nil
 }
 
-// consumeFixed64SliceIface wire decodes a []uint64 value as a repeated Fixed64.
-func consumeFixed64SliceIface(b []byte, ival interface{}, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (_ interface{}, n int, err error) {
-	sp := ival.(*[]uint64)
+// consumeFixed64SliceValue wire decodes a []uint64 value as a repeated Fixed64.
+func consumeFixed64SliceValue(b []byte, listv protoreflect.Value, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (_ protoreflect.Value, n int, err error) {
+	list := listv.List()
 	if wtyp == wire.BytesType {
-		s := *sp
 		b, n = wire.ConsumeBytes(b)
 		if n < 0 {
-			return nil, 0, wire.ParseError(n)
+			return protoreflect.Value{}, 0, wire.ParseError(n)
 		}
 		for len(b) > 0 {
 			v, n := wire.ConsumeFixed64(b)
 			if n < 0 {
-				return nil, 0, wire.ParseError(n)
+				return protoreflect.Value{}, 0, wire.ParseError(n)
 			}
-			s = append(s, v)
+			list.Append(protoreflect.ValueOfUint64(v))
 			b = b[n:]
 		}
-		*sp = s
-		return ival, n, nil
+		return listv, n, nil
 	}
 	if wtyp != wire.Fixed64Type {
-		return nil, 0, errUnknown
+		return protoreflect.Value{}, 0, errUnknown
 	}
 	v, n := wire.ConsumeFixed64(b)
 	if n < 0 {
-		return nil, 0, wire.ParseError(n)
+		return protoreflect.Value{}, 0, wire.ParseError(n)
 	}
-	*sp = append(*sp, v)
-	return ival, n, nil
+	list.Append(protoreflect.ValueOfUint64(v))
+	return listv, n, nil
 }
 
-var coderFixed64SliceIface = ifaceCoderFuncs{
-	size:      sizeFixed64SliceIface,
-	marshal:   appendFixed64SliceIface,
-	unmarshal: consumeFixed64SliceIface,
+var coderFixed64SliceValue = valueCoderFuncs{
+	size:      sizeFixed64SliceValue,
+	marshal:   appendFixed64SliceValue,
+	unmarshal: consumeFixed64SliceValue,
 }
 
-// sizeFixed64PackedSliceIface returns the size of wire encoding a []uint64 value as a packed repeated Fixed64.
-func sizeFixed64PackedSliceIface(ival interface{}, tagsize int, _ marshalOptions) (size int) {
-	s := *ival.(*[]uint64)
-	if len(s) == 0 {
-		return 0
-	}
-	n := len(s) * wire.SizeFixed64()
+// sizeFixed64PackedSliceValue returns the size of wire encoding a []uint64 value as a packed repeated Fixed64.
+func sizeFixed64PackedSliceValue(listv protoreflect.Value, tagsize int, _ marshalOptions) (size int) {
+	list := listv.List()
+	n := list.Len() * wire.SizeFixed64()
 	return tagsize + wire.SizeBytes(n)
 }
 
-// appendFixed64PackedSliceIface encodes a []uint64 value as a packed repeated Fixed64.
-func appendFixed64PackedSliceIface(b []byte, ival interface{}, wiretag uint64, _ marshalOptions) ([]byte, error) {
-	s := *ival.(*[]uint64)
-	if len(s) == 0 {
+// appendFixed64PackedSliceValue encodes a []uint64 value as a packed repeated Fixed64.
+func appendFixed64PackedSliceValue(b []byte, listv protoreflect.Value, wiretag uint64, _ marshalOptions) ([]byte, error) {
+	list := listv.List()
+	llen := list.Len()
+	if llen == 0 {
 		return b, nil
 	}
 	b = wire.AppendVarint(b, wiretag)
-	n := len(s) * wire.SizeFixed64()
+	n := llen * wire.SizeFixed64()
 	b = wire.AppendVarint(b, uint64(n))
-	for _, v := range s {
-		b = wire.AppendFixed64(b, v)
+	for i := 0; i < llen; i++ {
+		v := list.Get(i)
+		b = wire.AppendFixed64(b, v.Uint())
 	}
 	return b, nil
 }
 
-var coderFixed64PackedSliceIface = ifaceCoderFuncs{
-	size:      sizeFixed64PackedSliceIface,
-	marshal:   appendFixed64PackedSliceIface,
-	unmarshal: consumeFixed64SliceIface,
+var coderFixed64PackedSliceValue = valueCoderFuncs{
+	size:      sizeFixed64PackedSliceValue,
+	marshal:   appendFixed64PackedSliceValue,
+	unmarshal: consumeFixed64SliceValue,
 }
 
 // sizeDouble returns the size of wire encoding a float64 pointer as a Double.
@@ -3924,120 +4026,117 @@
 	unmarshal: consumeDoubleSlice,
 }
 
-// sizeDoubleIface returns the size of wire encoding a float64 value as a Double.
-func sizeDoubleIface(ival interface{}, tagsize int, _ marshalOptions) int {
+// sizeDoubleValue returns the size of wire encoding a float64 value as a Double.
+func sizeDoubleValue(v protoreflect.Value, tagsize int, _ marshalOptions) int {
 	return tagsize + wire.SizeFixed64()
 }
 
-// appendDoubleIface encodes a float64 value as a Double.
-func appendDoubleIface(b []byte, ival interface{}, wiretag uint64, _ marshalOptions) ([]byte, error) {
-	v := ival.(float64)
+// appendDoubleValue encodes a float64 value as a Double.
+func appendDoubleValue(b []byte, v protoreflect.Value, wiretag uint64, _ marshalOptions) ([]byte, error) {
 	b = wire.AppendVarint(b, wiretag)
-	b = wire.AppendFixed64(b, math.Float64bits(v))
+	b = wire.AppendFixed64(b, math.Float64bits(v.Float()))
 	return b, nil
 }
 
-// consumeDoubleIface decodes a float64 value as a Double.
-func consumeDoubleIface(b []byte, _ interface{}, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (interface{}, int, error) {
+// consumeDoubleValue decodes a float64 value as a Double.
+func consumeDoubleValue(b []byte, _ protoreflect.Value, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (protoreflect.Value, int, error) {
 	if wtyp != wire.Fixed64Type {
-		return nil, 0, errUnknown
+		return protoreflect.Value{}, 0, errUnknown
 	}
 	v, n := wire.ConsumeFixed64(b)
 	if n < 0 {
-		return nil, 0, wire.ParseError(n)
+		return protoreflect.Value{}, 0, wire.ParseError(n)
 	}
-	return math.Float64frombits(v), n, nil
+	return protoreflect.ValueOfFloat64(math.Float64frombits(v)), n, nil
 }
 
-var coderDoubleIface = ifaceCoderFuncs{
-	size:      sizeDoubleIface,
-	marshal:   appendDoubleIface,
-	unmarshal: consumeDoubleIface,
+var coderDoubleValue = valueCoderFuncs{
+	size:      sizeDoubleValue,
+	marshal:   appendDoubleValue,
+	unmarshal: consumeDoubleValue,
 }
 
-// sizeDoubleSliceIface returns the size of wire encoding a []float64 value as a repeated Double.
-func sizeDoubleSliceIface(ival interface{}, tagsize int, _ marshalOptions) (size int) {
-	s := *ival.(*[]float64)
-	size = len(s) * (tagsize + wire.SizeFixed64())
+// sizeDoubleSliceValue returns the size of wire encoding a []float64 value as a repeated Double.
+func sizeDoubleSliceValue(listv protoreflect.Value, tagsize int, _ marshalOptions) (size int) {
+	list := listv.List()
+	size = list.Len() * (tagsize + wire.SizeFixed64())
 	return size
 }
 
-// appendDoubleSliceIface encodes a []float64 value as a repeated Double.
-func appendDoubleSliceIface(b []byte, ival interface{}, wiretag uint64, _ marshalOptions) ([]byte, error) {
-	s := *ival.(*[]float64)
-	for _, v := range s {
+// appendDoubleSliceValue encodes a []float64 value as a repeated Double.
+func appendDoubleSliceValue(b []byte, listv protoreflect.Value, wiretag uint64, _ marshalOptions) ([]byte, error) {
+	list := listv.List()
+	for i, llen := 0, list.Len(); i < llen; i++ {
+		v := list.Get(i)
 		b = wire.AppendVarint(b, wiretag)
-		b = wire.AppendFixed64(b, math.Float64bits(v))
+		b = wire.AppendFixed64(b, math.Float64bits(v.Float()))
 	}
 	return b, nil
 }
 
-// consumeDoubleSliceIface wire decodes a []float64 value as a repeated Double.
-func consumeDoubleSliceIface(b []byte, ival interface{}, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (_ interface{}, n int, err error) {
-	sp := ival.(*[]float64)
+// consumeDoubleSliceValue wire decodes a []float64 value as a repeated Double.
+func consumeDoubleSliceValue(b []byte, listv protoreflect.Value, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (_ protoreflect.Value, n int, err error) {
+	list := listv.List()
 	if wtyp == wire.BytesType {
-		s := *sp
 		b, n = wire.ConsumeBytes(b)
 		if n < 0 {
-			return nil, 0, wire.ParseError(n)
+			return protoreflect.Value{}, 0, wire.ParseError(n)
 		}
 		for len(b) > 0 {
 			v, n := wire.ConsumeFixed64(b)
 			if n < 0 {
-				return nil, 0, wire.ParseError(n)
+				return protoreflect.Value{}, 0, wire.ParseError(n)
 			}
-			s = append(s, math.Float64frombits(v))
+			list.Append(protoreflect.ValueOfFloat64(math.Float64frombits(v)))
 			b = b[n:]
 		}
-		*sp = s
-		return ival, n, nil
+		return listv, n, nil
 	}
 	if wtyp != wire.Fixed64Type {
-		return nil, 0, errUnknown
+		return protoreflect.Value{}, 0, errUnknown
 	}
 	v, n := wire.ConsumeFixed64(b)
 	if n < 0 {
-		return nil, 0, wire.ParseError(n)
+		return protoreflect.Value{}, 0, wire.ParseError(n)
 	}
-	*sp = append(*sp, math.Float64frombits(v))
-	return ival, n, nil
+	list.Append(protoreflect.ValueOfFloat64(math.Float64frombits(v)))
+	return listv, n, nil
 }
 
-var coderDoubleSliceIface = ifaceCoderFuncs{
-	size:      sizeDoubleSliceIface,
-	marshal:   appendDoubleSliceIface,
-	unmarshal: consumeDoubleSliceIface,
+var coderDoubleSliceValue = valueCoderFuncs{
+	size:      sizeDoubleSliceValue,
+	marshal:   appendDoubleSliceValue,
+	unmarshal: consumeDoubleSliceValue,
 }
 
-// sizeDoublePackedSliceIface returns the size of wire encoding a []float64 value as a packed repeated Double.
-func sizeDoublePackedSliceIface(ival interface{}, tagsize int, _ marshalOptions) (size int) {
-	s := *ival.(*[]float64)
-	if len(s) == 0 {
-		return 0
-	}
-	n := len(s) * wire.SizeFixed64()
+// sizeDoublePackedSliceValue returns the size of wire encoding a []float64 value as a packed repeated Double.
+func sizeDoublePackedSliceValue(listv protoreflect.Value, tagsize int, _ marshalOptions) (size int) {
+	list := listv.List()
+	n := list.Len() * wire.SizeFixed64()
 	return tagsize + wire.SizeBytes(n)
 }
 
-// appendDoublePackedSliceIface encodes a []float64 value as a packed repeated Double.
-func appendDoublePackedSliceIface(b []byte, ival interface{}, wiretag uint64, _ marshalOptions) ([]byte, error) {
-	s := *ival.(*[]float64)
-	if len(s) == 0 {
+// appendDoublePackedSliceValue encodes a []float64 value as a packed repeated Double.
+func appendDoublePackedSliceValue(b []byte, listv protoreflect.Value, wiretag uint64, _ marshalOptions) ([]byte, error) {
+	list := listv.List()
+	llen := list.Len()
+	if llen == 0 {
 		return b, nil
 	}
 	b = wire.AppendVarint(b, wiretag)
-	n := len(s) * wire.SizeFixed64()
+	n := llen * wire.SizeFixed64()
 	b = wire.AppendVarint(b, uint64(n))
-	for _, v := range s {
-		b = wire.AppendFixed64(b, math.Float64bits(v))
+	for i := 0; i < llen; i++ {
+		v := list.Get(i)
+		b = wire.AppendFixed64(b, math.Float64bits(v.Float()))
 	}
 	return b, nil
 }
 
-var coderDoublePackedSliceIface = ifaceCoderFuncs{
-	size:      sizeDoublePackedSliceIface,
-	marshal:   appendDoublePackedSliceIface,
-	unmarshal: consumeDoubleSliceIface,
+var coderDoublePackedSliceValue = valueCoderFuncs{
+	size:      sizeDoublePackedSliceValue,
+	marshal:   appendDoublePackedSliceValue,
+	unmarshal: consumeDoubleSliceValue,
 }
 
 // sizeString returns the size of wire encoding a string pointer as a String.
@@ -4269,107 +4368,106 @@
 	unmarshal: consumeStringSliceValidateUTF8,
 }
 
-// sizeStringIface returns the size of wire encoding a string value as a String.
-func sizeStringIface(ival interface{}, tagsize int, _ marshalOptions) int {
-	v := ival.(string)
-	return tagsize + wire.SizeBytes(len(v))
+// sizeStringValue returns the size of wire encoding a string value as a String.
+func sizeStringValue(v protoreflect.Value, tagsize int, _ marshalOptions) int {
+	return tagsize + wire.SizeBytes(len(v.String()))
 }
 
-// appendStringIface encodes a string value as a String.
-func appendStringIface(b []byte, ival interface{}, wiretag uint64, _ marshalOptions) ([]byte, error) {
-	v := ival.(string)
+// appendStringValue encodes a string value as a String.
+func appendStringValue(b []byte, v protoreflect.Value, wiretag uint64, _ marshalOptions) ([]byte, error) {
 	b = wire.AppendVarint(b, wiretag)
-	b = wire.AppendString(b, v)
+	b = wire.AppendString(b, v.String())
 	return b, nil
 }
 
-// consumeStringIface decodes a string value as a String.
-func consumeStringIface(b []byte, _ interface{}, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (interface{}, int, error) {
+// consumeStringValue decodes a string value as a String.
+func consumeStringValue(b []byte, _ protoreflect.Value, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (protoreflect.Value, int, error) {
 	if wtyp != wire.BytesType {
-		return nil, 0, errUnknown
+		return protoreflect.Value{}, 0, errUnknown
 	}
 	v, n := wire.ConsumeString(b)
 	if n < 0 {
-		return nil, 0, wire.ParseError(n)
+		return protoreflect.Value{}, 0, wire.ParseError(n)
 	}
-	return v, n, nil
+	return protoreflect.ValueOfString(string(v)), n, nil
 }
 
-var coderStringIface = ifaceCoderFuncs{
-	size:      sizeStringIface,
-	marshal:   appendStringIface,
-	unmarshal: consumeStringIface,
+var coderStringValue = valueCoderFuncs{
+	size:      sizeStringValue,
+	marshal:   appendStringValue,
+	unmarshal: consumeStringValue,
 }
 
-// appendStringIfaceValidateUTF8 encodes a string value as a String.
-func appendStringIfaceValidateUTF8(b []byte, ival interface{}, wiretag uint64, _ marshalOptions) ([]byte, error) {
-	v := ival.(string)
+// appendStringValueValidateUTF8 encodes a string value as a String.
+func appendStringValueValidateUTF8(b []byte, v protoreflect.Value, wiretag uint64, _ marshalOptions) ([]byte, error) {
 	b = wire.AppendVarint(b, wiretag)
-	b = wire.AppendString(b, v)
-	if !utf8.ValidString(v) {
+	b = wire.AppendString(b, v.String())
+	if !utf8.ValidString(v.String()) {
 		return b, errInvalidUTF8{}
 	}
 	return b, nil
 }
 
-// consumeStringIfaceValidateUTF8 decodes a string value as a String.
-func consumeStringIfaceValidateUTF8(b []byte, _ interface{}, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (interface{}, int, error) {
+// consumeStringValueValidateUTF8 decodes a string value as a String.
+func consumeStringValueValidateUTF8(b []byte, _ protoreflect.Value, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (protoreflect.Value, int, error) {
 	if wtyp != wire.BytesType {
-		return nil, 0, errUnknown
+		return protoreflect.Value{}, 0, errUnknown
 	}
 	v, n := wire.ConsumeString(b)
 	if n < 0 {
-		return nil, 0, wire.ParseError(n)
+		return protoreflect.Value{}, 0, wire.ParseError(n)
 	}
 	if !utf8.ValidString(v) {
-		return nil, 0, errInvalidUTF8{}
+		return protoreflect.Value{}, 0, errInvalidUTF8{}
 	}
-	return v, n, nil
+	return protoreflect.ValueOfString(string(v)), n, nil
 }
 
-var coderStringIfaceValidateUTF8 = ifaceCoderFuncs{
-	size:      sizeStringIface,
-	marshal:   appendStringIfaceValidateUTF8,
-	unmarshal: consumeStringIfaceValidateUTF8,
+var coderStringValueValidateUTF8 = valueCoderFuncs{
+	size:      sizeStringValue,
+	marshal:   appendStringValueValidateUTF8,
+	unmarshal: consumeStringValueValidateUTF8,
 }
 
-// sizeStringSliceIface returns the size of wire encoding a []string value as a repeated String.
-func sizeStringSliceIface(ival interface{}, tagsize int, _ marshalOptions) (size int) {
-	s := *ival.(*[]string)
-	for _, v := range s {
-		size += tagsize + wire.SizeBytes(len(v))
+// sizeStringSliceValue returns the size of wire encoding a []string value as a repeated String.
+func sizeStringSliceValue(listv protoreflect.Value, tagsize int, _ marshalOptions) (size int) {
+	list := listv.List()
+	for i, llen := 0, list.Len(); i < llen; i++ {
+		v := list.Get(i)
+		size += tagsize + wire.SizeBytes(len(v.String()))
 	}
 	return size
 }
 
-// appendStringSliceIface encodes a []string value as a repeated String.
-func appendStringSliceIface(b []byte, ival interface{}, wiretag uint64, _ marshalOptions) ([]byte, error) {
-	s := *ival.(*[]string)
-	for _, v := range s {
+// appendStringSliceValue encodes a []string value as a repeated String.
+func appendStringSliceValue(b []byte, listv protoreflect.Value, wiretag uint64, _ marshalOptions) ([]byte, error) {
+	list := listv.List()
+	for i, llen := 0, list.Len(); i < llen; i++ {
+		v := list.Get(i)
 		b = wire.AppendVarint(b, wiretag)
-		b = wire.AppendString(b, v)
+		b = wire.AppendString(b, v.String())
 	}
 	return b, nil
 }
 
-// consumeStringSliceIface wire decodes a []string value as a repeated String.
-func consumeStringSliceIface(b []byte, ival interface{}, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (_ interface{}, n int, err error) {
-	sp := ival.(*[]string)
+// consumeStringSliceValue wire decodes a []string value as a repeated String.
+func consumeStringSliceValue(b []byte, listv protoreflect.Value, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (_ protoreflect.Value, n int, err error) {
+	list := listv.List()
 	if wtyp != wire.BytesType {
-		return nil, 0, errUnknown
+		return protoreflect.Value{}, 0, errUnknown
 	}
 	v, n := wire.ConsumeString(b)
 	if n < 0 {
-		return nil, 0, wire.ParseError(n)
+		return protoreflect.Value{}, 0, wire.ParseError(n)
 	}
-	*sp = append(*sp, v)
-	return ival, n, nil
+	list.Append(protoreflect.ValueOfString(string(v)))
+	return listv, n, nil
 }
 
-var coderStringSliceIface = ifaceCoderFuncs{
-	size:      sizeStringSliceIface,
-	marshal:   appendStringSliceIface,
-	unmarshal: consumeStringSliceIface,
+var coderStringSliceValue = valueCoderFuncs{
+	size:      sizeStringSliceValue,
+	marshal:   appendStringSliceValue,
+	unmarshal: consumeStringSliceValue,
 }
 
 // sizeBytes returns the size of wire encoding a []byte pointer as a Bytes.
@@ -4592,107 +4690,106 @@
 	unmarshal: consumeBytesSliceValidateUTF8,
 }
 
-// sizeBytesIface returns the size of wire encoding a []byte value as a Bytes.
-func sizeBytesIface(ival interface{}, tagsize int, _ marshalOptions) int {
-	v := ival.([]byte)
-	return tagsize + wire.SizeBytes(len(v))
+// sizeBytesValue returns the size of wire encoding a []byte value as a Bytes.
+func sizeBytesValue(v protoreflect.Value, tagsize int, _ marshalOptions) int {
+	return tagsize + wire.SizeBytes(len(v.Bytes()))
 }
 
-// appendBytesIface encodes a []byte value as a Bytes.
-func appendBytesIface(b []byte, ival interface{}, wiretag uint64, _ marshalOptions) ([]byte, error) {
-	v := ival.([]byte)
+// appendBytesValue encodes a []byte value as a Bytes.
+func appendBytesValue(b []byte, v protoreflect.Value, wiretag uint64, _ marshalOptions) ([]byte, error) {
 	b = wire.AppendVarint(b, wiretag)
-	b = wire.AppendBytes(b, v)
+	b = wire.AppendBytes(b, v.Bytes())
 	return b, nil
 }
 
-// consumeBytesIface decodes a []byte value as a Bytes.
-func consumeBytesIface(b []byte, _ interface{}, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (interface{}, int, error) {
+// consumeBytesValue decodes a []byte value as a Bytes.
+func consumeBytesValue(b []byte, _ protoreflect.Value, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (protoreflect.Value, int, error) {
 	if wtyp != wire.BytesType {
-		return nil, 0, errUnknown
+		return protoreflect.Value{}, 0, errUnknown
 	}
 	v, n := wire.ConsumeBytes(b)
 	if n < 0 {
-		return nil, 0, wire.ParseError(n)
+		return protoreflect.Value{}, 0, wire.ParseError(n)
 	}
-	return append(emptyBuf[:], v...), n, nil
+	return protoreflect.ValueOfBytes(append(([]byte)(nil), v...)), n, nil
 }
 
-var coderBytesIface = ifaceCoderFuncs{
-	size:      sizeBytesIface,
-	marshal:   appendBytesIface,
-	unmarshal: consumeBytesIface,
+var coderBytesValue = valueCoderFuncs{
+	size:      sizeBytesValue,
+	marshal:   appendBytesValue,
+	unmarshal: consumeBytesValue,
 }
 
-// appendBytesIfaceValidateUTF8 encodes a []byte value as a Bytes.
-func appendBytesIfaceValidateUTF8(b []byte, ival interface{}, wiretag uint64, _ marshalOptions) ([]byte, error) {
-	v := ival.([]byte)
+// appendBytesValueValidateUTF8 encodes a []byte value as a Bytes.
+func appendBytesValueValidateUTF8(b []byte, v protoreflect.Value, wiretag uint64, _ marshalOptions) ([]byte, error) {
 	b = wire.AppendVarint(b, wiretag)
-	b = wire.AppendBytes(b, v)
-	if !utf8.Valid(v) {
+	b = wire.AppendBytes(b, v.Bytes())
+	if !utf8.Valid(v.Bytes()) {
 		return b, errInvalidUTF8{}
 	}
 	return b, nil
 }
 
-// consumeBytesIfaceValidateUTF8 decodes a []byte value as a Bytes.
-func consumeBytesIfaceValidateUTF8(b []byte, _ interface{}, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (interface{}, int, error) {
+// consumeBytesValueValidateUTF8 decodes a []byte value as a Bytes.
+func consumeBytesValueValidateUTF8(b []byte, _ protoreflect.Value, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (protoreflect.Value, int, error) {
 	if wtyp != wire.BytesType {
-		return nil, 0, errUnknown
+		return protoreflect.Value{}, 0, errUnknown
 	}
 	v, n := wire.ConsumeBytes(b)
 	if n < 0 {
-		return nil, 0, wire.ParseError(n)
+		return protoreflect.Value{}, 0, wire.ParseError(n)
 	}
 	if !utf8.Valid(v) {
-		return nil, 0, errInvalidUTF8{}
+		return protoreflect.Value{}, 0, errInvalidUTF8{}
 	}
-	return append(emptyBuf[:], v...), n, nil
+	return protoreflect.ValueOfBytes(append(([]byte)(nil), v...)), n, nil
 }
 
-var coderBytesIfaceValidateUTF8 = ifaceCoderFuncs{
-	size:      sizeBytesIface,
-	marshal:   appendBytesIfaceValidateUTF8,
-	unmarshal: consumeBytesIfaceValidateUTF8,
+var coderBytesValueValidateUTF8 = valueCoderFuncs{
+	size:      sizeBytesValue,
+	marshal:   appendBytesValueValidateUTF8,
+	unmarshal: consumeBytesValueValidateUTF8,
 }
 
-// sizeBytesSliceIface returns the size of wire encoding a [][]byte value as a repeated Bytes.
-func sizeBytesSliceIface(ival interface{}, tagsize int, _ marshalOptions) (size int) {
-	s := *ival.(*[][]byte)
-	for _, v := range s {
-		size += tagsize + wire.SizeBytes(len(v))
+// sizeBytesSliceValue returns the size of wire encoding a [][]byte value as a repeated Bytes.
+func sizeBytesSliceValue(listv protoreflect.Value, tagsize int, _ marshalOptions) (size int) {
+	list := listv.List()
+	for i, llen := 0, list.Len(); i < llen; i++ {
+		v := list.Get(i)
+		size += tagsize + wire.SizeBytes(len(v.Bytes()))
 	}
 	return size
 }
 
-// appendBytesSliceIface encodes a [][]byte value as a repeated Bytes.
-func appendBytesSliceIface(b []byte, ival interface{}, wiretag uint64, _ marshalOptions) ([]byte, error) {
-	s := *ival.(*[][]byte)
-	for _, v := range s {
+// appendBytesSliceValue encodes a [][]byte value as a repeated Bytes.
+func appendBytesSliceValue(b []byte, listv protoreflect.Value, wiretag uint64, _ marshalOptions) ([]byte, error) {
+	list := listv.List()
+	for i, llen := 0, list.Len(); i < llen; i++ {
+		v := list.Get(i)
 		b = wire.AppendVarint(b, wiretag)
-		b = wire.AppendBytes(b, v)
+		b = wire.AppendBytes(b, v.Bytes())
 	}
 	return b, nil
 }
 
-// consumeBytesSliceIface wire decodes a [][]byte value as a repeated Bytes.
-func consumeBytesSliceIface(b []byte, ival interface{}, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (_ interface{}, n int, err error) {
-	sp := ival.(*[][]byte)
+// consumeBytesSliceValue wire decodes a [][]byte value as a repeated Bytes.
+func consumeBytesSliceValue(b []byte, listv protoreflect.Value, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (_ protoreflect.Value, n int, err error) {
+	list := listv.List()
 	if wtyp != wire.BytesType {
-		return nil, 0, errUnknown
+		return protoreflect.Value{}, 0, errUnknown
 	}
 	v, n := wire.ConsumeBytes(b)
 	if n < 0 {
-		return nil, 0, wire.ParseError(n)
+		return protoreflect.Value{}, 0, wire.ParseError(n)
 	}
-	*sp = append(*sp, append(emptyBuf[:], v...))
-	return ival, n, nil
+	list.Append(protoreflect.ValueOfBytes(append(([]byte)(nil), v...)))
+	return listv, n, nil
 }
 
-var coderBytesSliceIface = ifaceCoderFuncs{
-	size:      sizeBytesSliceIface,
-	marshal:   appendBytesSliceIface,
-	unmarshal: consumeBytesSliceIface,
+var coderBytesSliceValue = valueCoderFuncs{
+	size:      sizeBytesSliceValue,
+	marshal:   appendBytesSliceValue,
+	unmarshal: consumeBytesSliceValue,
 }
 
 // We append to an empty array rather than a nil []byte to get non-nil zero-length byte slices.
diff --git a/internal/impl/codec_map.go b/internal/impl/codec_map.go
index 4916704..00d6511 100644
--- a/internal/impl/codec_map.go
+++ b/internal/impl/codec_map.go
@@ -5,11 +5,10 @@
 package impl
 
 import (
-	"fmt"
 	"reflect"
-	"sort"
 
 	"google.golang.org/protobuf/internal/encoding/wire"
+	"google.golang.org/protobuf/internal/mapsort"
 	pref "google.golang.org/protobuf/reflect/protoreflect"
 )
 
@@ -17,11 +16,10 @@
 	goType     reflect.Type
 	keyWiretag uint64
 	valWiretag uint64
-	keyFuncs   ifaceCoderFuncs
-	valFuncs   ifaceCoderFuncs
-	keyZero    interface{}
-	valZero    interface{}
-	newVal     func() interface{}
+	keyFuncs   valueCoderFuncs
+	valFuncs   valueCoderFuncs
+	keyZero    pref.Value
+	keyKind    pref.Kind
 }
 
 func encoderFuncsForMap(fd pref.FieldDescriptor, ft reflect.Type) (funcs pointerCoderFuncs) {
@@ -32,6 +30,7 @@
 	valWiretag := wire.EncodeTag(2, wireTypes[valField.Kind()])
 	keyFuncs := encoderFuncsForValue(keyField, ft.Key())
 	valFuncs := encoderFuncsForValue(valField, ft.Elem())
+	conv := NewConverter(ft, fd)
 
 	mapi := &mapInfo{
 		goType:     ft,
@@ -39,30 +38,32 @@
 		valWiretag: valWiretag,
 		keyFuncs:   keyFuncs,
 		valFuncs:   valFuncs,
-		keyZero:    reflect.Zero(ft.Key()).Interface(),
-		valZero:    reflect.Zero(ft.Elem()).Interface(),
-	}
-	switch valField.Kind() {
-	case pref.GroupKind, pref.MessageKind:
-		mapi.newVal = func() interface{} {
-			return reflect.New(ft.Elem().Elem()).Interface()
-		}
+		keyZero:    keyField.Default(),
+		keyKind:    keyField.Kind(),
 	}
 
 	funcs = pointerCoderFuncs{
 		size: func(p pointer, tagsize int, opts marshalOptions) int {
-			return sizeMap(p, tagsize, ft, keyFuncs, valFuncs, opts)
+			mapv := conv.PBValueOf(p.AsValueOf(ft).Elem()).Map()
+			return sizeMap(mapv, tagsize, mapi, opts)
 		},
 		marshal: func(b []byte, p pointer, wiretag uint64, opts marshalOptions) ([]byte, error) {
-			return appendMap(b, p, wiretag, keyWiretag, valWiretag, ft, keyFuncs, valFuncs, opts)
+			mapv := conv.PBValueOf(p.AsValueOf(ft).Elem()).Map()
+			return appendMap(b, mapv, wiretag, mapi, opts)
 		},
 		unmarshal: func(b []byte, p pointer, wtyp wire.Type, opts unmarshalOptions) (int, error) {
-			return consumeMap(b, p, wtyp, mapi, opts)
+			mp := p.AsValueOf(ft)
+			if mp.Elem().IsNil() {
+				mp.Elem().Set(reflect.MakeMap(mapi.goType))
+			}
+			mapv := conv.PBValueOf(mp.Elem()).Map()
+			return consumeMap(b, mapv, wtyp, mapi, opts)
 		},
 	}
 	if valFuncs.isInit != nil {
 		funcs.isInit = func(p pointer) error {
-			return isInitMap(p, ft, valFuncs.isInit)
+			mapv := conv.PBValueOf(p.AsValueOf(ft).Elem()).Map()
+			return isInitMap(mapv, mapi)
 		}
 	}
 	return funcs
@@ -73,13 +74,21 @@
 	mapValTagSize = 1 // field 2, tag size 2.
 )
 
-func consumeMap(b []byte, p pointer, wtyp wire.Type, mapi *mapInfo, opts unmarshalOptions) (int, error) {
-	mp := p.AsValueOf(mapi.goType)
-	if mp.Elem().IsNil() {
-		mp.Elem().Set(reflect.MakeMap(mapi.goType))
+func sizeMap(mapv pref.Map, tagsize int, mapi *mapInfo, opts marshalOptions) int {
+	if mapv.Len() == 0 {
+		return 0
 	}
-	m := mp.Elem()
+	n := 0
+	mapv.Range(func(key pref.MapKey, value pref.Value) bool {
+		n += tagsize + wire.SizeBytes(
+			mapi.keyFuncs.size(key.Value(), mapKeyTagSize, opts)+
+				mapi.valFuncs.size(value, mapValTagSize, opts))
+		return true
+	})
+	return n
+}
 
+func consumeMap(b []byte, mapv pref.Map, wtyp wire.Type, mapi *mapInfo, opts unmarshalOptions) (int, error) {
 	if wtyp != wire.BytesType {
 		return 0, errUnknown
 	}
@@ -89,11 +98,8 @@
 	}
 	var (
 		key = mapi.keyZero
-		val = mapi.valZero
+		val = mapv.NewValue()
 	)
-	if mapi.newVal != nil {
-		val = mapi.newVal()
-	}
 	for len(b) > 0 {
 		num, wtyp, n := wire.ConsumeTag(b)
 		if n < 0 {
@@ -103,14 +109,14 @@
 		err := errUnknown
 		switch num {
 		case 1:
-			var v interface{}
+			var v pref.Value
 			v, n, err = mapi.keyFuncs.unmarshal(b, key, num, wtyp, opts)
 			if err != nil {
 				break
 			}
 			key = v
 		case 2:
-			var v interface{}
+			var v pref.Value
 			v, n, err = mapi.valFuncs.unmarshal(b, val, num, wtyp, opts)
 			if err != nil {
 				break
@@ -127,119 +133,44 @@
 		}
 		b = b[n:]
 	}
-	m.SetMapIndex(reflect.ValueOf(key), reflect.ValueOf(val))
+	mapv.Set(key.MapKey(), val)
 	return n, nil
 }
 
-func sizeMap(p pointer, tagsize int, goType reflect.Type, keyFuncs, valFuncs ifaceCoderFuncs, opts marshalOptions) int {
-	m := p.AsValueOf(goType).Elem()
-	n := 0
-	if m.Len() == 0 {
-		return 0
+func appendMap(b []byte, mapv pref.Map, wiretag uint64, mapi *mapInfo, opts marshalOptions) ([]byte, error) {
+	if mapv.Len() == 0 {
+		return b, nil
 	}
-	iter := mapRange(m)
-	for iter.Next() {
-		ki := iter.Key().Interface()
-		vi := iter.Value().Interface()
-		size := keyFuncs.size(ki, mapKeyTagSize, opts) + valFuncs.size(vi, mapValTagSize, opts)
-		n += wire.SizeBytes(size) + tagsize
-	}
-	return n
-}
-
-func appendMap(b []byte, p pointer, wiretag, keyWiretag, valWiretag uint64, goType reflect.Type, keyFuncs, valFuncs ifaceCoderFuncs, opts marshalOptions) ([]byte, error) {
-	m := p.AsValueOf(goType).Elem()
 	var err error
-
-	if m.Len() == 0 {
-		return b, nil
-	}
-
-	if opts.Deterministic() {
-		keys := m.MapKeys()
-		sort.Sort(mapKeys(keys))
-		for _, k := range keys {
-			b, err = appendMapElement(b, k, m.MapIndex(k), wiretag, keyWiretag, valWiretag, keyFuncs, valFuncs, opts)
-			if err != nil {
-				return b, err
-			}
-		}
-		return b, nil
-	}
-
-	iter := mapRange(m)
-	for iter.Next() {
-		b, err = appendMapElement(b, iter.Key(), iter.Value(), wiretag, keyWiretag, valWiretag, keyFuncs, valFuncs, opts)
+	fn := func(key pref.MapKey, value pref.Value) bool {
+		b = wire.AppendVarint(b, wiretag)
+		size := 0
+		size += mapi.keyFuncs.size(key.Value(), mapKeyTagSize, opts)
+		size += mapi.valFuncs.size(value, mapValTagSize, opts)
+		b = wire.AppendVarint(b, uint64(size))
+		b, err = mapi.keyFuncs.marshal(b, key.Value(), mapi.keyWiretag, opts)
 		if err != nil {
-			return b, err
+			return false
 		}
-	}
-	return b, nil
-}
-
-func appendMapElement(b []byte, key, value reflect.Value, wiretag, keyWiretag, valWiretag uint64, keyFuncs, valFuncs ifaceCoderFuncs, opts marshalOptions) ([]byte, error) {
-	ki := key.Interface()
-	vi := value.Interface()
-	b = wire.AppendVarint(b, wiretag)
-	size := keyFuncs.size(ki, mapKeyTagSize, opts) + valFuncs.size(vi, mapValTagSize, opts)
-	b = wire.AppendVarint(b, uint64(size))
-	b, err := keyFuncs.marshal(b, ki, keyWiretag, opts)
-	if err != nil {
-		return b, err
-	}
-	b, err = valFuncs.marshal(b, vi, valWiretag, opts)
-	if err != nil {
-		return b, err
-	}
-	return b, nil
-}
-
-func isInitMap(p pointer, goType reflect.Type, isInit func(interface{}) error) error {
-	m := p.AsValueOf(goType).Elem()
-	if m.Len() == 0 {
-		return nil
-	}
-	iter := mapRange(m)
-	for iter.Next() {
-		if err := isInit(iter.Value().Interface()); err != nil {
-			return err
+		b, err = mapi.valFuncs.marshal(b, value, mapi.valWiretag, opts)
+		if err != nil {
+			return false
 		}
+		return true
 	}
-	return nil
+	if opts.Deterministic() {
+		mapsort.Range(mapv, mapi.keyKind, fn)
+	} else {
+		mapv.Range(fn)
+	}
+	return b, err
 }
 
-// mapKeys returns a sort.Interface to be used for sorting the map keys.
-// Map fields may have key types of non-float scalars, strings and enums.
-func mapKeys(vs []reflect.Value) sort.Interface {
-	s := mapKeySorter{vs: vs}
-
-	// Type specialization per https://developers.google.com/protocol-buffers/docs/proto#maps.
-	if len(vs) == 0 {
-		return s
-	}
-	switch vs[0].Kind() {
-	case reflect.Int32, reflect.Int64:
-		s.less = func(a, b reflect.Value) bool { return a.Int() < b.Int() }
-	case reflect.Uint32, reflect.Uint64:
-		s.less = func(a, b reflect.Value) bool { return a.Uint() < b.Uint() }
-	case reflect.Bool:
-		s.less = func(a, b reflect.Value) bool { return !a.Bool() && b.Bool() } // false < true
-	case reflect.String:
-		s.less = func(a, b reflect.Value) bool { return a.String() < b.String() }
-	default:
-		panic(fmt.Sprintf("unsupported map key type: %v", vs[0].Kind()))
-	}
-
-	return s
-}
-
-type mapKeySorter struct {
-	vs   []reflect.Value
-	less func(a, b reflect.Value) bool
-}
-
-func (s mapKeySorter) Len() int      { return len(s.vs) }
-func (s mapKeySorter) Swap(i, j int) { s.vs[i], s.vs[j] = s.vs[j], s.vs[i] }
-func (s mapKeySorter) Less(i, j int) bool {
-	return s.less(s.vs[i], s.vs[j])
+func isInitMap(mapv pref.Map, mapi *mapInfo) error {
+	var err error
+	mapv.Range(func(_ pref.MapKey, value pref.Value) bool {
+		err = mapi.valFuncs.isInit(value)
+		return err == nil
+	})
+	return err
 }
diff --git a/internal/impl/codec_messageset.go b/internal/impl/codec_messageset.go
index d5fb444..2493028 100644
--- a/internal/impl/codec_messageset.go
+++ b/internal/impl/codec_messageset.go
@@ -39,7 +39,7 @@
 		}
 		num, _ := wire.DecodeTag(xi.wiretag)
 		n += messageset.SizeField(num)
-		n += xi.funcs.size(x.GetValue(), wire.SizeTag(messageset.FieldMessage), opts)
+		n += xi.funcs.size(x.Value(), wire.SizeTag(messageset.FieldMessage), opts)
 	}
 	return n
 }
@@ -88,7 +88,7 @@
 	xi := mi.extensionFieldInfo(x.GetType())
 	num, _ := wire.DecodeTag(xi.wiretag)
 	b = messageset.AppendFieldStart(b, num)
-	b, err := xi.funcs.marshal(b, x.GetValue(), wire.EncodeTag(messageset.FieldMessage, wire.BytesType), opts)
+	b, err := xi.funcs.marshal(b, x.Value(), wire.EncodeTag(messageset.FieldMessage, wire.BytesType), opts)
 	if err != nil {
 		return b, err
 	}
diff --git a/internal/impl/codec_reflect.go b/internal/impl/codec_reflect.go
index b83a3b3..5884ee4 100644
--- a/internal/impl/codec_reflect.go
+++ b/internal/impl/codec_reflect.go
@@ -87,15 +87,52 @@
 }
 
 func sizeEnumSlice(p pointer, tagsize int, opts marshalOptions) (size int) {
-	return sizeEnumSliceReflect(p.v.Elem(), tagsize, opts)
+	s := p.v.Elem()
+	for i, llen := 0, s.Len(); i < llen; i++ {
+		size += wire.SizeVarint(uint64(s.Index(i).Int())) + tagsize
+	}
+	return size
 }
 
 func appendEnumSlice(b []byte, p pointer, wiretag uint64, opts marshalOptions) ([]byte, error) {
-	return appendEnumSliceReflect(b, p.v.Elem(), wiretag, opts)
+	s := p.v.Elem()
+	for i, llen := 0, s.Len(); i < llen; i++ {
+		b = wire.AppendVarint(b, wiretag)
+		b = wire.AppendVarint(b, uint64(s.Index(i).Int()))
+	}
+	return b, nil
 }
 
 func consumeEnumSlice(b []byte, p pointer, wtyp wire.Type, opts unmarshalOptions) (n int, err error) {
-	return consumeEnumSliceReflect(b, p.v, wtyp, opts)
+	s := p.v.Elem()
+	if wtyp == wire.BytesType {
+		b, n = wire.ConsumeBytes(b)
+		if n < 0 {
+			return 0, wire.ParseError(n)
+		}
+		for len(b) > 0 {
+			v, n := wire.ConsumeVarint(b)
+			if n < 0 {
+				return 0, wire.ParseError(n)
+			}
+			rv := reflect.New(s.Type().Elem()).Elem()
+			rv.SetInt(int64(v))
+			s.Set(reflect.Append(s, rv))
+			b = b[n:]
+		}
+		return n, nil
+	}
+	if wtyp != wire.VarintType {
+		return 0, errUnknown
+	}
+	v, n := wire.ConsumeVarint(b)
+	if n < 0 {
+		return 0, wire.ParseError(n)
+	}
+	rv := reflect.New(s.Type().Elem()).Elem()
+	rv.SetInt(int64(v))
+	s.Set(reflect.Append(s, rv))
+	return n, nil
 }
 
 var coderEnumSlice = pointerCoderFuncs{
@@ -105,11 +142,34 @@
 }
 
 func sizeEnumPackedSlice(p pointer, tagsize int, opts marshalOptions) (size int) {
-	return sizeEnumPackedSliceReflect(p.v.Elem(), tagsize, opts)
+	s := p.v.Elem()
+	llen := s.Len()
+	if llen == 0 {
+		return 0
+	}
+	n := 0
+	for i := 0; i < llen; i++ {
+		n += wire.SizeVarint(uint64(s.Index(i).Int()))
+	}
+	return tagsize + wire.SizeBytes(n)
 }
 
 func appendEnumPackedSlice(b []byte, p pointer, wiretag uint64, opts marshalOptions) ([]byte, error) {
-	return appendEnumPackedSliceReflect(b, p.v.Elem(), wiretag, opts)
+	s := p.v.Elem()
+	llen := s.Len()
+	if llen == 0 {
+		return b, nil
+	}
+	b = wire.AppendVarint(b, wiretag)
+	n := 0
+	for i := 0; i < llen; i++ {
+		n += wire.SizeVarint(uint64(s.Index(i).Int()))
+	}
+	b = wire.AppendVarint(b, uint64(n))
+	for i := 0; i < llen; i++ {
+		b = wire.AppendVarint(b, uint64(s.Index(i).Int()))
+	}
+	return b, nil
 }
 
 var coderEnumPackedSlice = pointerCoderFuncs{
diff --git a/internal/impl/codec_tables.go b/internal/impl/codec_tables.go
index 3ff4260..31fc412 100644
--- a/internal/impl/codec_tables.go
+++ b/internal/impl/codec_tables.go
@@ -21,12 +21,12 @@
 	isInit    func(p pointer) error
 }
 
-// ifaceCoderFuncs is a set of interface{} encoding functions.
-type ifaceCoderFuncs struct {
-	size      func(ival interface{}, tagsize int, opts marshalOptions) int
-	marshal   func(b []byte, ival interface{}, wiretag uint64, opts marshalOptions) ([]byte, error)
-	unmarshal func(b []byte, ival interface{}, num wire.Number, wtyp wire.Type, opts unmarshalOptions) (interface{}, int, error)
-	isInit    func(ival interface{}) error
+// valueCoderFuncs is a set of protoreflect.Value encoding functions.
+type valueCoderFuncs struct {
+	size      func(v pref.Value, tagsize int, opts marshalOptions) int
+	marshal   func(b []byte, v pref.Value, wiretag uint64, opts marshalOptions) ([]byte, error)
+	unmarshal func(b []byte, v pref.Value, num wire.Number, wtyp wire.Type, opts unmarshalOptions) (pref.Value, int, error)
+	isInit    func(v pref.Value) error
 }
 
 // fieldCoder returns pointer functions for a field, used for operating on
@@ -428,7 +428,7 @@
 
 // encoderFuncsForValue returns interface{} value functions for a field, used for
 // extension values and map encoding.
-func encoderFuncsForValue(fd pref.FieldDescriptor, ft reflect.Type) ifaceCoderFuncs {
+func encoderFuncsForValue(fd pref.FieldDescriptor, ft reflect.Type) valueCoderFuncs {
 	switch {
 	case fd.Cardinality() == pref.Repeated && !fd.IsPacked():
 		if ft.Kind() != reflect.Ptr || ft.Elem().Kind() != reflect.Slice {
@@ -438,78 +438,78 @@
 		switch fd.Kind() {
 		case pref.BoolKind:
 			if ft.Kind() == reflect.Bool {
-				return coderBoolSliceIface
+				return coderBoolSliceValue
 			}
 		case pref.EnumKind:
 			if ft.Kind() == reflect.Int32 {
-				return coderEnumSliceIface
+				return coderEnumSliceValue
 			}
 		case pref.Int32Kind:
 			if ft.Kind() == reflect.Int32 {
-				return coderInt32SliceIface
+				return coderInt32SliceValue
 			}
 		case pref.Sint32Kind:
 			if ft.Kind() == reflect.Int32 {
-				return coderSint32SliceIface
+				return coderSint32SliceValue
 			}
 		case pref.Uint32Kind:
 			if ft.Kind() == reflect.Uint32 {
-				return coderUint32SliceIface
+				return coderUint32SliceValue
 			}
 		case pref.Int64Kind:
 			if ft.Kind() == reflect.Int64 {
-				return coderInt64SliceIface
+				return coderInt64SliceValue
 			}
 		case pref.Sint64Kind:
 			if ft.Kind() == reflect.Int64 {
-				return coderSint64SliceIface
+				return coderSint64SliceValue
 			}
 		case pref.Uint64Kind:
 			if ft.Kind() == reflect.Uint64 {
-				return coderUint64SliceIface
+				return coderUint64SliceValue
 			}
 		case pref.Sfixed32Kind:
 			if ft.Kind() == reflect.Int32 {
-				return coderSfixed32SliceIface
+				return coderSfixed32SliceValue
 			}
 		case pref.Fixed32Kind:
 			if ft.Kind() == reflect.Uint32 {
-				return coderFixed32SliceIface
+				return coderFixed32SliceValue
 			}
 		case pref.FloatKind:
 			if ft.Kind() == reflect.Float32 {
-				return coderFloatSliceIface
+				return coderFloatSliceValue
 			}
 		case pref.Sfixed64Kind:
 			if ft.Kind() == reflect.Int64 {
-				return coderSfixed64SliceIface
+				return coderSfixed64SliceValue
 			}
 		case pref.Fixed64Kind:
 			if ft.Kind() == reflect.Uint64 {
-				return coderFixed64SliceIface
+				return coderFixed64SliceValue
 			}
 		case pref.DoubleKind:
 			if ft.Kind() == reflect.Float64 {
-				return coderDoubleSliceIface
+				return coderDoubleSliceValue
 			}
 		case pref.StringKind:
 			if ft.Kind() == reflect.String {
-				return coderStringSliceIface
+				return coderStringSliceValue
 			}
 			if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 {
-				return coderBytesSliceIface
+				return coderBytesSliceValue
 			}
 		case pref.BytesKind:
 			if ft.Kind() == reflect.String {
-				return coderStringSliceIface
+				return coderStringSliceValue
 			}
 			if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 {
-				return coderBytesSliceIface
+				return coderBytesSliceValue
 			}
 		case pref.MessageKind:
-			return coderMessageSliceIface
+			return coderMessageSliceValue
 		case pref.GroupKind:
-			return coderGroupSliceIface
+			return coderGroupSliceValue
 		}
 	case fd.Cardinality() == pref.Repeated && fd.IsPacked():
 		if ft.Kind() != reflect.Ptr || ft.Elem().Kind() != reflect.Slice {
@@ -519,143 +519,144 @@
 		switch fd.Kind() {
 		case pref.BoolKind:
 			if ft.Kind() == reflect.Bool {
-				return coderBoolPackedSliceIface
+				return coderBoolPackedSliceValue
 			}
 		case pref.EnumKind:
 			if ft.Kind() == reflect.Int32 {
-				return coderEnumPackedSliceIface
+				return coderEnumPackedSliceValue
 			}
 		case pref.Int32Kind:
 			if ft.Kind() == reflect.Int32 {
-				return coderInt32PackedSliceIface
+				return coderInt32PackedSliceValue
 			}
 		case pref.Sint32Kind:
 			if ft.Kind() == reflect.Int32 {
-				return coderSint32PackedSliceIface
+				return coderSint32PackedSliceValue
 			}
 		case pref.Uint32Kind:
 			if ft.Kind() == reflect.Uint32 {
-				return coderUint32PackedSliceIface
+				return coderUint32PackedSliceValue
 			}
 		case pref.Int64Kind:
 			if ft.Kind() == reflect.Int64 {
-				return coderInt64PackedSliceIface
+				return coderInt64PackedSliceValue
 			}
 		case pref.Sint64Kind:
 			if ft.Kind() == reflect.Int64 {
-				return coderSint64PackedSliceIface
+				return coderSint64PackedSliceValue
 			}
 		case pref.Uint64Kind:
 			if ft.Kind() == reflect.Uint64 {
-				return coderUint64PackedSliceIface
+				return coderUint64PackedSliceValue
 			}
 		case pref.Sfixed32Kind:
 			if ft.Kind() == reflect.Int32 {
-				return coderSfixed32PackedSliceIface
+				return coderSfixed32PackedSliceValue
 			}
 		case pref.Fixed32Kind:
 			if ft.Kind() == reflect.Uint32 {
-				return coderFixed32PackedSliceIface
+				return coderFixed32PackedSliceValue
 			}
 		case pref.FloatKind:
 			if ft.Kind() == reflect.Float32 {
-				return coderFloatPackedSliceIface
+				return coderFloatPackedSliceValue
 			}
 		case pref.Sfixed64Kind:
 			if ft.Kind() == reflect.Int64 {
-				return coderSfixed64PackedSliceIface
+				return coderSfixed64PackedSliceValue
 			}
 		case pref.Fixed64Kind:
 			if ft.Kind() == reflect.Uint64 {
-				return coderFixed64PackedSliceIface
+				return coderFixed64PackedSliceValue
 			}
 		case pref.DoubleKind:
 			if ft.Kind() == reflect.Float64 {
-				return coderDoublePackedSliceIface
+				return coderDoublePackedSliceValue
 			}
 		}
 	default:
 		switch fd.Kind() {
+		default:
 		case pref.BoolKind:
 			if ft.Kind() == reflect.Bool {
-				return coderBoolIface
+				return coderBoolValue
 			}
 		case pref.EnumKind:
 			if ft.Kind() == reflect.Int32 {
-				return coderEnumIface
+				return coderEnumValue
 			}
 		case pref.Int32Kind:
 			if ft.Kind() == reflect.Int32 {
-				return coderInt32Iface
+				return coderInt32Value
 			}
 		case pref.Sint32Kind:
 			if ft.Kind() == reflect.Int32 {
-				return coderSint32Iface
+				return coderSint32Value
 			}
 		case pref.Uint32Kind:
 			if ft.Kind() == reflect.Uint32 {
-				return coderUint32Iface
+				return coderUint32Value
 			}
 		case pref.Int64Kind:
 			if ft.Kind() == reflect.Int64 {
-				return coderInt64Iface
+				return coderInt64Value
 			}
 		case pref.Sint64Kind:
 			if ft.Kind() == reflect.Int64 {
-				return coderSint64Iface
+				return coderSint64Value
 			}
 		case pref.Uint64Kind:
 			if ft.Kind() == reflect.Uint64 {
-				return coderUint64Iface
+				return coderUint64Value
 			}
 		case pref.Sfixed32Kind:
 			if ft.Kind() == reflect.Int32 {
-				return coderSfixed32Iface
+				return coderSfixed32Value
 			}
 		case pref.Fixed32Kind:
 			if ft.Kind() == reflect.Uint32 {
-				return coderFixed32Iface
+				return coderFixed32Value
 			}
 		case pref.FloatKind:
 			if ft.Kind() == reflect.Float32 {
-				return coderFloatIface
+				return coderFloatValue
 			}
 		case pref.Sfixed64Kind:
 			if ft.Kind() == reflect.Int64 {
-				return coderSfixed64Iface
+				return coderSfixed64Value
 			}
 		case pref.Fixed64Kind:
 			if ft.Kind() == reflect.Uint64 {
-				return coderFixed64Iface
+				return coderFixed64Value
 			}
 		case pref.DoubleKind:
 			if ft.Kind() == reflect.Float64 {
-				return coderDoubleIface
+				return coderDoubleValue
 			}
 		case pref.StringKind:
 			if ft.Kind() == reflect.String && strs.EnforceUTF8(fd) {
-				return coderStringIfaceValidateUTF8
+				return coderStringValueValidateUTF8
 			}
 			if ft.Kind() == reflect.String {
-				return coderStringIface
+				return coderStringValue
 			}
 			if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 && strs.EnforceUTF8(fd) {
-				return coderBytesIfaceValidateUTF8
+				return coderBytesValueValidateUTF8
 			}
 			if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 {
-				return coderBytesIface
+				return coderBytesValue
 			}
 		case pref.BytesKind:
 			if ft.Kind() == reflect.String {
-				return coderStringIface
+				return coderStringValue
 			}
 			if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 {
-				return coderBytesIface
+				return coderBytesValue
 			}
 		case pref.MessageKind:
-			return coderMessageIface
+			return coderMessageValue
 		case pref.GroupKind:
-			return makeGroupValueCoder(fd, ft)
+			return coderGroupValue
 		}
 	}
 	panic(fmt.Errorf("invalid type: no encoder for %v %v %v/%v", fd.FullName(), fd.Cardinality(), fd.Kind(), ft))
diff --git a/internal/impl/convert_map.go b/internal/impl/convert_map.go
index 447a965..ca51819 100644
--- a/internal/impl/convert_map.go
+++ b/internal/impl/convert_map.go
@@ -90,13 +90,12 @@
 	ms.v.SetMapIndex(rk, reflect.Value{})
 }
 func (ms *mapReflect) Range(f func(pref.MapKey, pref.Value) bool) {
-	for _, k := range ms.v.MapKeys() {
-		if v := ms.v.MapIndex(k); v.IsValid() {
-			pk := ms.keyConv.PBValueOf(k).MapKey()
-			pv := ms.valConv.PBValueOf(v)
-			if !f(pk, pv) {
-				return
-			}
+	iter := mapRange(ms.v)
+	for iter.Next() {
+		k := ms.keyConv.PBValueOf(iter.Key()).MapKey()
+		v := ms.valConv.PBValueOf(iter.Value())
+		if !f(k, v) {
+			return
 		}
 	}
 }
diff --git a/internal/impl/decode.go b/internal/impl/decode.go
index 3bc25e0..f71d19d 100644
--- a/internal/impl/decode.go
+++ b/internal/impl/decode.go
@@ -145,24 +145,23 @@
 			}
 			return 0, err
 		}
-		x.SetType(xt)
 	}
 	xi := mi.extensionFieldInfo(xt)
 	if xi.funcs.unmarshal == nil {
 		return 0, errUnknown
 	}
-	ival := x.GetValue()
-	if ival == nil && xi.unmarshalNeedsValue {
+	ival := x.Value()
+	if !ival.IsValid() && xi.unmarshalNeedsValue {
 		// Create a new message, list, or map value to fill in.
 		// For enums, create a prototype value to let the unmarshal func know the
 		// concrete type.
-		ival = xt.InterfaceOf(xt.New())
+		ival = xt.New()
 	}
 	v, n, err := xi.funcs.unmarshal(b, ival, num, wtyp, opts)
 	if err != nil {
 		return 0, err
 	}
-	x.SetEagerValue(v)
+	x.Set(xt, v)
 	exts[int32(num)] = x
 	return n, nil
 }
diff --git a/internal/impl/encode.go b/internal/impl/encode.go
index 08daf55..d7dc892 100644
--- a/internal/impl/encode.go
+++ b/internal/impl/encode.go
@@ -144,11 +144,11 @@
 		return 0
 	}
 	for _, x := range *ext {
-		xi := mi.extensionFieldInfo(x.GetType())
+		xi := mi.extensionFieldInfo(x.Type())
 		if xi.funcs.size == nil {
 			continue
 		}
-		n += xi.funcs.size(x.GetValue(), xi.tagsize, opts)
+		n += xi.funcs.size(x.Value(), xi.tagsize, opts)
 	}
 	return n
 }
@@ -165,8 +165,8 @@
 		// Fast-path for one extension: Don't bother sorting the keys.
 		var err error
 		for _, x := range *ext {
-			xi := mi.extensionFieldInfo(x.GetType())
-			b, err = xi.funcs.marshal(b, x.GetValue(), xi.wiretag, opts)
+			xi := mi.extensionFieldInfo(x.Type())
+			b, err = xi.funcs.marshal(b, x.Value(), xi.wiretag, opts)
 		}
 		return b, err
 	default:
@@ -180,8 +180,8 @@
 		var err error
 		for _, k := range keys {
 			x := (*ext)[int32(k)]
-			xi := mi.extensionFieldInfo(x.GetType())
-			b, err = xi.funcs.marshal(b, x.GetValue(), xi.wiretag, opts)
+			xi := mi.extensionFieldInfo(x.Type())
+			b, err = xi.funcs.marshal(b, x.Value(), xi.wiretag, opts)
 			if err != nil {
 				return b, err
 			}
diff --git a/internal/impl/isinit.go b/internal/impl/isinit.go
index ffc65e9..3fd3674 100644
--- a/internal/impl/isinit.go
+++ b/internal/impl/isinit.go
@@ -66,12 +66,12 @@
 		return nil
 	}
 	for _, x := range *ext {
-		ei := mi.extensionFieldInfo(x.GetType())
+		ei := mi.extensionFieldInfo(x.Type())
 		if ei.funcs.isInit == nil {
 			continue
 		}
-		v := x.GetValue()
-		if v == nil {
+		v := x.Value()
+		if !v.IsValid() {
 			continue
 		}
 		if err := ei.funcs.isInit(v); err != nil {
diff --git a/internal/impl/message_reflect.go b/internal/impl/message_reflect.go
index 8ed7cc5..469b255 100644
--- a/internal/impl/message_reflect.go
+++ b/internal/impl/message_reflect.go
@@ -119,7 +119,7 @@
 	if m != nil {
 		for _, x := range *m {
 			xt := x.GetType()
-			if !f(xt.TypeDescriptor(), xt.ValueOf(x.GetValue())) {
+			if !f(xt.TypeDescriptor(), x.Value()) {
 				return
 			}
 		}
@@ -138,18 +138,20 @@
 	xd := xt.TypeDescriptor()
 	if m != nil {
 		if x, ok := (*m)[int32(xd.Number())]; ok {
-			return xt.ValueOf(x.GetValue())
+			return x.Value()
 		}
 	}
 	return xt.Zero()
 }
 func (m *extensionMap) Set(xt pref.ExtensionType, v pref.Value) {
+	if !xt.IsValidValue(v) {
+		panic(fmt.Errorf("%v: assigning invalid value", xt.TypeDescriptor().FullName()))
+	}
 	if *m == nil {
 		*m = make(map[int32]ExtensionField)
 	}
 	var x ExtensionField
-	x.SetType(xt)
-	x.SetEagerValue(xt.InterfaceOf(v))
+	x.Set(xt, v)
 	(*m)[int32(xt.TypeDescriptor().Number())] = x
 }
 func (m *extensionMap) Mutable(xt pref.ExtensionType) pref.Value {
@@ -158,7 +160,7 @@
 		panic("invalid Mutable on field with non-composite type")
 	}
 	if x, ok := (*m)[int32(xd.Number())]; ok {
-		return xt.ValueOf(x.GetValue())
+		return x.Value()
 	}
 	v := xt.New()
 	m.Set(xt, v)