diff --git a/vendor/google.golang.org/protobuf/internal/impl/api_export.go b/vendor/google.golang.org/protobuf/internal/impl/api_export.go
new file mode 100644
index 0000000..4d22c96
--- /dev/null
+++ b/vendor/google.golang.org/protobuf/internal/impl/api_export.go
@@ -0,0 +1,170 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package impl
+
+import (
+	"fmt"
+	"reflect"
+	"strconv"
+
+	"google.golang.org/protobuf/encoding/prototext"
+	"google.golang.org/protobuf/proto"
+	pref "google.golang.org/protobuf/reflect/protoreflect"
+	piface "google.golang.org/protobuf/runtime/protoiface"
+)
+
+// Export is a zero-length named type that exists only to export a set of
+// functions that we do not want to appear in godoc.
+type Export struct{}
+
+// enum is any enum type generated by protoc-gen-go
+// and must be a named int32 type.
+type enum = interface{}
+
+// EnumOf returns the protoreflect.Enum interface over e.
+// It returns nil if e is nil.
+func (Export) EnumOf(e enum) pref.Enum {
+	switch e := e.(type) {
+	case nil:
+		return nil
+	case pref.Enum:
+		return e
+	default:
+		return legacyWrapEnum(reflect.ValueOf(e))
+	}
+}
+
+// EnumDescriptorOf returns the protoreflect.EnumDescriptor for e.
+// It returns nil if e is nil.
+func (Export) EnumDescriptorOf(e enum) pref.EnumDescriptor {
+	switch e := e.(type) {
+	case nil:
+		return nil
+	case pref.Enum:
+		return e.Descriptor()
+	default:
+		return LegacyLoadEnumDesc(reflect.TypeOf(e))
+	}
+}
+
+// EnumTypeOf returns the protoreflect.EnumType for e.
+// It returns nil if e is nil.
+func (Export) EnumTypeOf(e enum) pref.EnumType {
+	switch e := e.(type) {
+	case nil:
+		return nil
+	case pref.Enum:
+		return e.Type()
+	default:
+		return legacyLoadEnumType(reflect.TypeOf(e))
+	}
+}
+
+// EnumStringOf returns the enum value as a string, either as the name if
+// the number is resolvable, or the number formatted as a string.
+func (Export) EnumStringOf(ed pref.EnumDescriptor, n pref.EnumNumber) string {
+	ev := ed.Values().ByNumber(n)
+	if ev != nil {
+		return string(ev.Name())
+	}
+	return strconv.Itoa(int(n))
+}
+
+// message is any message type generated by protoc-gen-go
+// and must be a pointer to a named struct type.
+type message = interface{}
+
+// legacyMessageWrapper wraps a v2 message as a v1 message.
+type legacyMessageWrapper struct{ m pref.ProtoMessage }
+
+func (m legacyMessageWrapper) Reset()         { proto.Reset(m.m) }
+func (m legacyMessageWrapper) String() string { return Export{}.MessageStringOf(m.m) }
+func (m legacyMessageWrapper) ProtoMessage()  {}
+
+// ProtoMessageV1Of converts either a v1 or v2 message to a v1 message.
+// It returns nil if m is nil.
+func (Export) ProtoMessageV1Of(m message) piface.MessageV1 {
+	switch mv := m.(type) {
+	case nil:
+		return nil
+	case piface.MessageV1:
+		return mv
+	case unwrapper:
+		return Export{}.ProtoMessageV1Of(mv.protoUnwrap())
+	case pref.ProtoMessage:
+		return legacyMessageWrapper{mv}
+	default:
+		panic(fmt.Sprintf("message %T is neither a v1 or v2 Message", m))
+	}
+}
+
+func (Export) protoMessageV2Of(m message) pref.ProtoMessage {
+	switch mv := m.(type) {
+	case nil:
+		return nil
+	case pref.ProtoMessage:
+		return mv
+	case legacyMessageWrapper:
+		return mv.m
+	case piface.MessageV1:
+		return nil
+	default:
+		panic(fmt.Sprintf("message %T is neither a v1 or v2 Message", m))
+	}
+}
+
+// ProtoMessageV2Of converts either a v1 or v2 message to a v2 message.
+// It returns nil if m is nil.
+func (Export) ProtoMessageV2Of(m message) pref.ProtoMessage {
+	if m == nil {
+		return nil
+	}
+	if mv := (Export{}).protoMessageV2Of(m); mv != nil {
+		return mv
+	}
+	return legacyWrapMessage(reflect.ValueOf(m)).Interface()
+}
+
+// MessageOf returns the protoreflect.Message interface over m.
+// It returns nil if m is nil.
+func (Export) MessageOf(m message) pref.Message {
+	if m == nil {
+		return nil
+	}
+	if mv := (Export{}).protoMessageV2Of(m); mv != nil {
+		return mv.ProtoReflect()
+	}
+	return legacyWrapMessage(reflect.ValueOf(m))
+}
+
+// MessageDescriptorOf returns the protoreflect.MessageDescriptor for m.
+// It returns nil if m is nil.
+func (Export) MessageDescriptorOf(m message) pref.MessageDescriptor {
+	if m == nil {
+		return nil
+	}
+	if mv := (Export{}).protoMessageV2Of(m); mv != nil {
+		return mv.ProtoReflect().Descriptor()
+	}
+	return LegacyLoadMessageDesc(reflect.TypeOf(m))
+}
+
+// MessageTypeOf returns the protoreflect.MessageType for m.
+// It returns nil if m is nil.
+func (Export) MessageTypeOf(m message) pref.MessageType {
+	if m == nil {
+		return nil
+	}
+	if mv := (Export{}).protoMessageV2Of(m); mv != nil {
+		return mv.ProtoReflect().Type()
+	}
+	return legacyLoadMessageInfo(reflect.TypeOf(m), "")
+}
+
+// MessageStringOf returns the message value as a string,
+// which is the message serialized in the protobuf text format.
+func (Export) MessageStringOf(m pref.ProtoMessage) string {
+	return prototext.MarshalOptions{Multiline: false}.Format(m)
+}
diff --git a/vendor/google.golang.org/protobuf/internal/impl/checkinit.go b/vendor/google.golang.org/protobuf/internal/impl/checkinit.go
new file mode 100644
index 0000000..b82341e
--- /dev/null
+++ b/vendor/google.golang.org/protobuf/internal/impl/checkinit.go
@@ -0,0 +1,141 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package impl
+
+import (
+	"sync"
+
+	"google.golang.org/protobuf/internal/errors"
+	pref "google.golang.org/protobuf/reflect/protoreflect"
+	piface "google.golang.org/protobuf/runtime/protoiface"
+)
+
+func (mi *MessageInfo) checkInitialized(in piface.CheckInitializedInput) (piface.CheckInitializedOutput, error) {
+	var p pointer
+	if ms, ok := in.Message.(*messageState); ok {
+		p = ms.pointer()
+	} else {
+		p = in.Message.(*messageReflectWrapper).pointer()
+	}
+	return piface.CheckInitializedOutput{}, mi.checkInitializedPointer(p)
+}
+
+func (mi *MessageInfo) checkInitializedPointer(p pointer) error {
+	mi.init()
+	if !mi.needsInitCheck {
+		return nil
+	}
+	if p.IsNil() {
+		for _, f := range mi.orderedCoderFields {
+			if f.isRequired {
+				return errors.RequiredNotSet(string(mi.Desc.Fields().ByNumber(f.num).FullName()))
+			}
+		}
+		return nil
+	}
+	if mi.extensionOffset.IsValid() {
+		e := p.Apply(mi.extensionOffset).Extensions()
+		if err := mi.isInitExtensions(e); err != nil {
+			return err
+		}
+	}
+	for _, f := range mi.orderedCoderFields {
+		if !f.isRequired && f.funcs.isInit == nil {
+			continue
+		}
+		fptr := p.Apply(f.offset)
+		if f.isPointer && fptr.Elem().IsNil() {
+			if f.isRequired {
+				return errors.RequiredNotSet(string(mi.Desc.Fields().ByNumber(f.num).FullName()))
+			}
+			continue
+		}
+		if f.funcs.isInit == nil {
+			continue
+		}
+		if err := f.funcs.isInit(fptr, f); err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+func (mi *MessageInfo) isInitExtensions(ext *map[int32]ExtensionField) error {
+	if ext == nil {
+		return nil
+	}
+	for _, x := range *ext {
+		ei := getExtensionFieldInfo(x.Type())
+		if ei.funcs.isInit == nil {
+			continue
+		}
+		v := x.Value()
+		if !v.IsValid() {
+			continue
+		}
+		if err := ei.funcs.isInit(v); err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+var (
+	needsInitCheckMu  sync.Mutex
+	needsInitCheckMap sync.Map
+)
+
+// needsInitCheck reports whether a message needs to be checked for partial initialization.
+//
+// It returns true if the message transitively includes any required or extension fields.
+func needsInitCheck(md pref.MessageDescriptor) bool {
+	if v, ok := needsInitCheckMap.Load(md); ok {
+		if has, ok := v.(bool); ok {
+			return has
+		}
+	}
+	needsInitCheckMu.Lock()
+	defer needsInitCheckMu.Unlock()
+	return needsInitCheckLocked(md)
+}
+
+func needsInitCheckLocked(md pref.MessageDescriptor) (has bool) {
+	if v, ok := needsInitCheckMap.Load(md); ok {
+		// If has is true, we've previously determined that this message
+		// needs init checks.
+		//
+		// If has is false, we've previously determined that it can never
+		// be uninitialized.
+		//
+		// If has is not a bool, we've just encountered a cycle in the
+		// message graph. In this case, it is safe to return false: If
+		// the message does have required fields, we'll detect them later
+		// in the graph traversal.
+		has, ok := v.(bool)
+		return ok && has
+	}
+	needsInitCheckMap.Store(md, struct{}{}) // avoid cycles while descending into this message
+	defer func() {
+		needsInitCheckMap.Store(md, has)
+	}()
+	if md.RequiredNumbers().Len() > 0 {
+		return true
+	}
+	if md.ExtensionRanges().Len() > 0 {
+		return true
+	}
+	for i := 0; i < md.Fields().Len(); i++ {
+		fd := md.Fields().Get(i)
+		// Map keys are never messages, so just consider the map value.
+		if fd.IsMap() {
+			fd = fd.MapValue()
+		}
+		fmd := fd.Message()
+		if fmd != nil && needsInitCheckLocked(fmd) {
+			return true
+		}
+	}
+	return false
+}
diff --git a/vendor/google.golang.org/protobuf/internal/impl/codec_extension.go b/vendor/google.golang.org/protobuf/internal/impl/codec_extension.go
new file mode 100644
index 0000000..08d3517
--- /dev/null
+++ b/vendor/google.golang.org/protobuf/internal/impl/codec_extension.go
@@ -0,0 +1,223 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package impl
+
+import (
+	"sync"
+	"sync/atomic"
+
+	"google.golang.org/protobuf/encoding/protowire"
+	"google.golang.org/protobuf/internal/errors"
+	pref "google.golang.org/protobuf/reflect/protoreflect"
+)
+
+type extensionFieldInfo struct {
+	wiretag             uint64
+	tagsize             int
+	unmarshalNeedsValue bool
+	funcs               valueCoderFuncs
+	validation          validationInfo
+}
+
+var legacyExtensionFieldInfoCache sync.Map // map[protoreflect.ExtensionType]*extensionFieldInfo
+
+func getExtensionFieldInfo(xt pref.ExtensionType) *extensionFieldInfo {
+	if xi, ok := xt.(*ExtensionInfo); ok {
+		xi.lazyInit()
+		return xi.info
+	}
+	return legacyLoadExtensionFieldInfo(xt)
+}
+
+// legacyLoadExtensionFieldInfo dynamically loads a *ExtensionInfo for xt.
+func legacyLoadExtensionFieldInfo(xt pref.ExtensionType) *extensionFieldInfo {
+	if xi, ok := legacyExtensionFieldInfoCache.Load(xt); ok {
+		return xi.(*extensionFieldInfo)
+	}
+	e := makeExtensionFieldInfo(xt.TypeDescriptor())
+	if e, ok := legacyMessageTypeCache.LoadOrStore(xt, e); ok {
+		return e.(*extensionFieldInfo)
+	}
+	return e
+}
+
+func makeExtensionFieldInfo(xd pref.ExtensionDescriptor) *extensionFieldInfo {
+	var wiretag uint64
+	if !xd.IsPacked() {
+		wiretag = protowire.EncodeTag(xd.Number(), wireTypes[xd.Kind()])
+	} else {
+		wiretag = protowire.EncodeTag(xd.Number(), protowire.BytesType)
+	}
+	e := &extensionFieldInfo{
+		wiretag: wiretag,
+		tagsize: protowire.SizeVarint(wiretag),
+		funcs:   encoderFuncsForValue(xd),
+	}
+	// Does the unmarshal function need a value passed to it?
+	// This is true for composite types, where we pass in a message, list, or map to fill in,
+	// and for enums, where we pass in a prototype value to specify the concrete enum type.
+	switch xd.Kind() {
+	case pref.MessageKind, pref.GroupKind, pref.EnumKind:
+		e.unmarshalNeedsValue = true
+	default:
+		if xd.Cardinality() == pref.Repeated {
+			e.unmarshalNeedsValue = true
+		}
+	}
+	return e
+}
+
+type lazyExtensionValue struct {
+	atomicOnce uint32 // atomically set if value is valid
+	mu         sync.Mutex
+	xi         *extensionFieldInfo
+	value      pref.Value
+	b          []byte
+	fn         func() pref.Value
+}
+
+type ExtensionField struct {
+	typ pref.ExtensionType
+
+	// value is either the value of GetValue,
+	// or a *lazyExtensionValue that then returns the value of GetValue.
+	value pref.Value
+	lazy  *lazyExtensionValue
+}
+
+func (f *ExtensionField) appendLazyBytes(xt pref.ExtensionType, xi *extensionFieldInfo, num protowire.Number, wtyp protowire.Type, b []byte) {
+	if f.lazy == nil {
+		f.lazy = &lazyExtensionValue{xi: xi}
+	}
+	f.typ = xt
+	f.lazy.xi = xi
+	f.lazy.b = protowire.AppendTag(f.lazy.b, num, wtyp)
+	f.lazy.b = append(f.lazy.b, b...)
+}
+
+func (f *ExtensionField) canLazy(xt pref.ExtensionType) bool {
+	if f.typ == nil {
+		return true
+	}
+	if f.typ == xt && f.lazy != nil && atomic.LoadUint32(&f.lazy.atomicOnce) == 0 {
+		return true
+	}
+	return false
+}
+
+func (f *ExtensionField) lazyInit() {
+	f.lazy.mu.Lock()
+	defer f.lazy.mu.Unlock()
+	if atomic.LoadUint32(&f.lazy.atomicOnce) == 1 {
+		return
+	}
+	if f.lazy.xi != nil {
+		b := f.lazy.b
+		val := f.typ.New()
+		for len(b) > 0 {
+			var tag uint64
+			if b[0] < 0x80 {
+				tag = uint64(b[0])
+				b = b[1:]
+			} else if len(b) >= 2 && b[1] < 128 {
+				tag = uint64(b[0]&0x7f) + uint64(b[1])<<7
+				b = b[2:]
+			} else {
+				var n int
+				tag, n = protowire.ConsumeVarint(b)
+				if n < 0 {
+					panic(errors.New("bad tag in lazy extension decoding"))
+				}
+				b = b[n:]
+			}
+			num := protowire.Number(tag >> 3)
+			wtyp := protowire.Type(tag & 7)
+			var out unmarshalOutput
+			var err error
+			val, out, err = f.lazy.xi.funcs.unmarshal(b, val, num, wtyp, lazyUnmarshalOptions)
+			if err != nil {
+				panic(errors.New("decode failure in lazy extension decoding: %v", err))
+			}
+			b = b[out.n:]
+		}
+		f.lazy.value = val
+	} else {
+		f.lazy.value = f.lazy.fn()
+	}
+	f.lazy.xi = nil
+	f.lazy.fn = nil
+	f.lazy.b = nil
+	atomic.StoreUint32(&f.lazy.atomicOnce, 1)
+}
+
+// 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
+	f.lazy = 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{fn: fn}
+}
+
+// Value returns the value of the extension field.
+// This may be called concurrently.
+func (f *ExtensionField) Value() pref.Value {
+	if f.lazy != nil {
+		if atomic.LoadUint32(&f.lazy.atomicOnce) == 0 {
+			f.lazyInit()
+		}
+		return f.lazy.value
+	}
+	return f.value
+}
+
+// Type returns the type of the extension field.
+// This may be called concurrently.
+func (f ExtensionField) Type() pref.ExtensionType {
+	return f.typ
+}
+
+// IsSet returns whether the extension field is set.
+// This may be called concurrently.
+func (f ExtensionField) IsSet() bool {
+	return f.typ != nil
+}
+
+// IsLazy reports whether a field is lazily encoded.
+// It is exported for testing.
+func IsLazy(m pref.Message, fd pref.FieldDescriptor) bool {
+	var mi *MessageInfo
+	var p pointer
+	switch m := m.(type) {
+	case *messageState:
+		mi = m.messageInfo()
+		p = m.pointer()
+	case *messageReflectWrapper:
+		mi = m.messageInfo()
+		p = m.pointer()
+	default:
+		return false
+	}
+	xd, ok := fd.(pref.ExtensionTypeDescriptor)
+	if !ok {
+		return false
+	}
+	xt := xd.Type()
+	ext := mi.extensionMap(p)
+	if ext == nil {
+		return false
+	}
+	f, ok := (*ext)[int32(fd.Number())]
+	if !ok {
+		return false
+	}
+	return f.typ == xt && f.lazy != nil && atomic.LoadUint32(&f.lazy.atomicOnce) == 0
+}
diff --git a/vendor/google.golang.org/protobuf/internal/impl/codec_field.go b/vendor/google.golang.org/protobuf/internal/impl/codec_field.go
new file mode 100644
index 0000000..c00744d
--- /dev/null
+++ b/vendor/google.golang.org/protobuf/internal/impl/codec_field.go
@@ -0,0 +1,828 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package impl
+
+import (
+	"fmt"
+	"reflect"
+	"sync"
+
+	"google.golang.org/protobuf/encoding/protowire"
+	"google.golang.org/protobuf/proto"
+	pref "google.golang.org/protobuf/reflect/protoreflect"
+	preg "google.golang.org/protobuf/reflect/protoregistry"
+	piface "google.golang.org/protobuf/runtime/protoiface"
+)
+
+type errInvalidUTF8 struct{}
+
+func (errInvalidUTF8) Error() string     { return "string field contains invalid UTF-8" }
+func (errInvalidUTF8) InvalidUTF8() bool { return true }
+
+// initOneofFieldCoders initializes the fast-path functions for the fields in a oneof.
+//
+// For size, marshal, and isInit operations, functions are set only on the first field
+// in the oneof. The functions are called when the oneof is non-nil, and will dispatch
+// to the appropriate field-specific function as necessary.
+//
+// The unmarshal function is set on each field individually as usual.
+func (mi *MessageInfo) initOneofFieldCoders(od pref.OneofDescriptor, si structInfo) {
+	fs := si.oneofsByName[od.Name()]
+	ft := fs.Type
+	oneofFields := make(map[reflect.Type]*coderFieldInfo)
+	needIsInit := false
+	fields := od.Fields()
+	for i, lim := 0, fields.Len(); i < lim; i++ {
+		fd := od.Fields().Get(i)
+		num := fd.Number()
+		// Make a copy of the original coderFieldInfo for use in unmarshaling.
+		//
+		// oneofFields[oneofType].funcs.marshal is the field-specific marshal function.
+		//
+		// mi.coderFields[num].marshal is set on only the first field in the oneof,
+		// and dispatches to the field-specific marshaler in oneofFields.
+		cf := *mi.coderFields[num]
+		ot := si.oneofWrappersByNumber[num]
+		cf.ft = ot.Field(0).Type
+		cf.mi, cf.funcs = fieldCoder(fd, cf.ft)
+		oneofFields[ot] = &cf
+		if cf.funcs.isInit != nil {
+			needIsInit = true
+		}
+		mi.coderFields[num].funcs.unmarshal = func(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (unmarshalOutput, error) {
+			var vw reflect.Value         // pointer to wrapper type
+			vi := p.AsValueOf(ft).Elem() // oneof field value of interface kind
+			if !vi.IsNil() && !vi.Elem().IsNil() && vi.Elem().Elem().Type() == ot {
+				vw = vi.Elem()
+			} else {
+				vw = reflect.New(ot)
+			}
+			out, err := cf.funcs.unmarshal(b, pointerOfValue(vw).Apply(zeroOffset), wtyp, &cf, opts)
+			if err != nil {
+				return out, err
+			}
+			vi.Set(vw)
+			return out, nil
+		}
+	}
+	getInfo := func(p pointer) (pointer, *coderFieldInfo) {
+		v := p.AsValueOf(ft).Elem()
+		if v.IsNil() {
+			return pointer{}, nil
+		}
+		v = v.Elem() // interface -> *struct
+		if v.IsNil() {
+			return pointer{}, nil
+		}
+		return pointerOfValue(v).Apply(zeroOffset), oneofFields[v.Elem().Type()]
+	}
+	first := mi.coderFields[od.Fields().Get(0).Number()]
+	first.funcs.size = func(p pointer, _ *coderFieldInfo, opts marshalOptions) int {
+		p, info := getInfo(p)
+		if info == nil || info.funcs.size == nil {
+			return 0
+		}
+		return info.funcs.size(p, info, opts)
+	}
+	first.funcs.marshal = func(b []byte, p pointer, _ *coderFieldInfo, opts marshalOptions) ([]byte, error) {
+		p, info := getInfo(p)
+		if info == nil || info.funcs.marshal == nil {
+			return b, nil
+		}
+		return info.funcs.marshal(b, p, info, opts)
+	}
+	first.funcs.merge = func(dst, src pointer, _ *coderFieldInfo, opts mergeOptions) {
+		srcp, srcinfo := getInfo(src)
+		if srcinfo == nil || srcinfo.funcs.merge == nil {
+			return
+		}
+		dstp, dstinfo := getInfo(dst)
+		if dstinfo != srcinfo {
+			dst.AsValueOf(ft).Elem().Set(reflect.New(src.AsValueOf(ft).Elem().Elem().Elem().Type()))
+			dstp = pointerOfValue(dst.AsValueOf(ft).Elem().Elem()).Apply(zeroOffset)
+		}
+		srcinfo.funcs.merge(dstp, srcp, srcinfo, opts)
+	}
+	if needIsInit {
+		first.funcs.isInit = func(p pointer, _ *coderFieldInfo) error {
+			p, info := getInfo(p)
+			if info == nil || info.funcs.isInit == nil {
+				return nil
+			}
+			return info.funcs.isInit(p, info)
+		}
+	}
+}
+
+func makeWeakMessageFieldCoder(fd pref.FieldDescriptor) pointerCoderFuncs {
+	var once sync.Once
+	var messageType pref.MessageType
+	lazyInit := func() {
+		once.Do(func() {
+			messageName := fd.Message().FullName()
+			messageType, _ = preg.GlobalTypes.FindMessageByName(messageName)
+		})
+	}
+
+	return pointerCoderFuncs{
+		size: func(p pointer, f *coderFieldInfo, opts marshalOptions) int {
+			m, ok := p.WeakFields().get(f.num)
+			if !ok {
+				return 0
+			}
+			lazyInit()
+			if messageType == nil {
+				panic(fmt.Sprintf("weak message %v is not linked in", fd.Message().FullName()))
+			}
+			return sizeMessage(m, f.tagsize, opts)
+		},
+		marshal: func(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
+			m, ok := p.WeakFields().get(f.num)
+			if !ok {
+				return b, nil
+			}
+			lazyInit()
+			if messageType == nil {
+				panic(fmt.Sprintf("weak message %v is not linked in", fd.Message().FullName()))
+			}
+			return appendMessage(b, m, f.wiretag, opts)
+		},
+		unmarshal: func(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (unmarshalOutput, error) {
+			fs := p.WeakFields()
+			m, ok := fs.get(f.num)
+			if !ok {
+				lazyInit()
+				if messageType == nil {
+					return unmarshalOutput{}, errUnknown
+				}
+				m = messageType.New().Interface()
+				fs.set(f.num, m)
+			}
+			return consumeMessage(b, m, wtyp, opts)
+		},
+		isInit: func(p pointer, f *coderFieldInfo) error {
+			m, ok := p.WeakFields().get(f.num)
+			if !ok {
+				return nil
+			}
+			return proto.CheckInitialized(m)
+		},
+		merge: func(dst, src pointer, f *coderFieldInfo, opts mergeOptions) {
+			sm, ok := src.WeakFields().get(f.num)
+			if !ok {
+				return
+			}
+			dm, ok := dst.WeakFields().get(f.num)
+			if !ok {
+				lazyInit()
+				if messageType == nil {
+					panic(fmt.Sprintf("weak message %v is not linked in", fd.Message().FullName()))
+				}
+				dm = messageType.New().Interface()
+				dst.WeakFields().set(f.num, dm)
+			}
+			opts.Merge(dm, sm)
+		},
+	}
+}
+
+func makeMessageFieldCoder(fd pref.FieldDescriptor, ft reflect.Type) pointerCoderFuncs {
+	if mi := getMessageInfo(ft); mi != nil {
+		funcs := pointerCoderFuncs{
+			size:      sizeMessageInfo,
+			marshal:   appendMessageInfo,
+			unmarshal: consumeMessageInfo,
+			merge:     mergeMessage,
+		}
+		if needsInitCheck(mi.Desc) {
+			funcs.isInit = isInitMessageInfo
+		}
+		return funcs
+	} else {
+		return pointerCoderFuncs{
+			size: func(p pointer, f *coderFieldInfo, opts marshalOptions) int {
+				m := asMessage(p.AsValueOf(ft).Elem())
+				return sizeMessage(m, f.tagsize, opts)
+			},
+			marshal: func(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
+				m := asMessage(p.AsValueOf(ft).Elem())
+				return appendMessage(b, m, f.wiretag, opts)
+			},
+			unmarshal: func(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (unmarshalOutput, error) {
+				mp := p.AsValueOf(ft).Elem()
+				if mp.IsNil() {
+					mp.Set(reflect.New(ft.Elem()))
+				}
+				return consumeMessage(b, asMessage(mp), wtyp, opts)
+			},
+			isInit: func(p pointer, f *coderFieldInfo) error {
+				m := asMessage(p.AsValueOf(ft).Elem())
+				return proto.CheckInitialized(m)
+			},
+			merge: mergeMessage,
+		}
+	}
+}
+
+func sizeMessageInfo(p pointer, f *coderFieldInfo, opts marshalOptions) int {
+	return protowire.SizeBytes(f.mi.sizePointer(p.Elem(), opts)) + f.tagsize
+}
+
+func appendMessageInfo(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
+	b = protowire.AppendVarint(b, f.wiretag)
+	b = protowire.AppendVarint(b, uint64(f.mi.sizePointer(p.Elem(), opts)))
+	return f.mi.marshalAppendPointer(b, p.Elem(), opts)
+}
+
+func consumeMessageInfo(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (out unmarshalOutput, err error) {
+	if wtyp != protowire.BytesType {
+		return out, errUnknown
+	}
+	v, n := protowire.ConsumeBytes(b)
+	if n < 0 {
+		return out, protowire.ParseError(n)
+	}
+	if p.Elem().IsNil() {
+		p.SetPointer(pointerOfValue(reflect.New(f.mi.GoReflectType.Elem())))
+	}
+	o, err := f.mi.unmarshalPointer(v, p.Elem(), 0, opts)
+	if err != nil {
+		return out, err
+	}
+	out.n = n
+	out.initialized = o.initialized
+	return out, nil
+}
+
+func isInitMessageInfo(p pointer, f *coderFieldInfo) error {
+	return f.mi.checkInitializedPointer(p.Elem())
+}
+
+func sizeMessage(m proto.Message, tagsize int, _ marshalOptions) int {
+	return protowire.SizeBytes(proto.Size(m)) + tagsize
+}
+
+func appendMessage(b []byte, m proto.Message, wiretag uint64, opts marshalOptions) ([]byte, error) {
+	b = protowire.AppendVarint(b, wiretag)
+	b = protowire.AppendVarint(b, uint64(proto.Size(m)))
+	return opts.Options().MarshalAppend(b, m)
+}
+
+func consumeMessage(b []byte, m proto.Message, wtyp protowire.Type, opts unmarshalOptions) (out unmarshalOutput, err error) {
+	if wtyp != protowire.BytesType {
+		return out, errUnknown
+	}
+	v, n := protowire.ConsumeBytes(b)
+	if n < 0 {
+		return out, protowire.ParseError(n)
+	}
+	o, err := opts.Options().UnmarshalState(piface.UnmarshalInput{
+		Buf:     v,
+		Message: m.ProtoReflect(),
+	})
+	if err != nil {
+		return out, err
+	}
+	out.n = n
+	out.initialized = o.Flags&piface.UnmarshalInitialized != 0
+	return out, nil
+}
+
+func sizeMessageValue(v pref.Value, tagsize int, opts marshalOptions) int {
+	m := v.Message().Interface()
+	return sizeMessage(m, tagsize, opts)
+}
+
+func appendMessageValue(b []byte, v pref.Value, wiretag uint64, opts marshalOptions) ([]byte, error) {
+	m := v.Message().Interface()
+	return appendMessage(b, m, wiretag, opts)
+}
+
+func consumeMessageValue(b []byte, v pref.Value, _ protowire.Number, wtyp protowire.Type, opts unmarshalOptions) (pref.Value, unmarshalOutput, error) {
+	m := v.Message().Interface()
+	out, err := consumeMessage(b, m, wtyp, opts)
+	return v, out, err
+}
+
+func isInitMessageValue(v pref.Value) error {
+	m := v.Message().Interface()
+	return proto.CheckInitialized(m)
+}
+
+var coderMessageValue = valueCoderFuncs{
+	size:      sizeMessageValue,
+	marshal:   appendMessageValue,
+	unmarshal: consumeMessageValue,
+	isInit:    isInitMessageValue,
+	merge:     mergeMessageValue,
+}
+
+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 protowire.Number, wtyp protowire.Type, opts unmarshalOptions) (pref.Value, unmarshalOutput, error) {
+	m := v.Message().Interface()
+	out, err := consumeGroup(b, m, num, wtyp, opts)
+	return v, out, err
+}
+
+var coderGroupValue = valueCoderFuncs{
+	size:      sizeGroupValue,
+	marshal:   appendGroupValue,
+	unmarshal: consumeGroupValue,
+	isInit:    isInitMessageValue,
+	merge:     mergeMessageValue,
+}
+
+func makeGroupFieldCoder(fd pref.FieldDescriptor, ft reflect.Type) pointerCoderFuncs {
+	num := fd.Number()
+	if mi := getMessageInfo(ft); mi != nil {
+		funcs := pointerCoderFuncs{
+			size:      sizeGroupType,
+			marshal:   appendGroupType,
+			unmarshal: consumeGroupType,
+			merge:     mergeMessage,
+		}
+		if needsInitCheck(mi.Desc) {
+			funcs.isInit = isInitMessageInfo
+		}
+		return funcs
+	} else {
+		return pointerCoderFuncs{
+			size: func(p pointer, f *coderFieldInfo, opts marshalOptions) int {
+				m := asMessage(p.AsValueOf(ft).Elem())
+				return sizeGroup(m, f.tagsize, opts)
+			},
+			marshal: func(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
+				m := asMessage(p.AsValueOf(ft).Elem())
+				return appendGroup(b, m, f.wiretag, opts)
+			},
+			unmarshal: func(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (unmarshalOutput, error) {
+				mp := p.AsValueOf(ft).Elem()
+				if mp.IsNil() {
+					mp.Set(reflect.New(ft.Elem()))
+				}
+				return consumeGroup(b, asMessage(mp), num, wtyp, opts)
+			},
+			isInit: func(p pointer, f *coderFieldInfo) error {
+				m := asMessage(p.AsValueOf(ft).Elem())
+				return proto.CheckInitialized(m)
+			},
+			merge: mergeMessage,
+		}
+	}
+}
+
+func sizeGroupType(p pointer, f *coderFieldInfo, opts marshalOptions) int {
+	return 2*f.tagsize + f.mi.sizePointer(p.Elem(), opts)
+}
+
+func appendGroupType(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
+	b = protowire.AppendVarint(b, f.wiretag) // start group
+	b, err := f.mi.marshalAppendPointer(b, p.Elem(), opts)
+	b = protowire.AppendVarint(b, f.wiretag+1) // end group
+	return b, err
+}
+
+func consumeGroupType(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (out unmarshalOutput, err error) {
+	if wtyp != protowire.StartGroupType {
+		return out, errUnknown
+	}
+	if p.Elem().IsNil() {
+		p.SetPointer(pointerOfValue(reflect.New(f.mi.GoReflectType.Elem())))
+	}
+	return f.mi.unmarshalPointer(b, p.Elem(), f.num, opts)
+}
+
+func sizeGroup(m proto.Message, tagsize int, _ marshalOptions) int {
+	return 2*tagsize + proto.Size(m)
+}
+
+func appendGroup(b []byte, m proto.Message, wiretag uint64, opts marshalOptions) ([]byte, error) {
+	b = protowire.AppendVarint(b, wiretag) // start group
+	b, err := opts.Options().MarshalAppend(b, m)
+	b = protowire.AppendVarint(b, wiretag+1) // end group
+	return b, err
+}
+
+func consumeGroup(b []byte, m proto.Message, num protowire.Number, wtyp protowire.Type, opts unmarshalOptions) (out unmarshalOutput, err error) {
+	if wtyp != protowire.StartGroupType {
+		return out, errUnknown
+	}
+	b, n := protowire.ConsumeGroup(num, b)
+	if n < 0 {
+		return out, protowire.ParseError(n)
+	}
+	o, err := opts.Options().UnmarshalState(piface.UnmarshalInput{
+		Buf:     b,
+		Message: m.ProtoReflect(),
+	})
+	if err != nil {
+		return out, err
+	}
+	out.n = n
+	out.initialized = o.Flags&piface.UnmarshalInitialized != 0
+	return out, nil
+}
+
+func makeMessageSliceFieldCoder(fd pref.FieldDescriptor, ft reflect.Type) pointerCoderFuncs {
+	if mi := getMessageInfo(ft); mi != nil {
+		funcs := pointerCoderFuncs{
+			size:      sizeMessageSliceInfo,
+			marshal:   appendMessageSliceInfo,
+			unmarshal: consumeMessageSliceInfo,
+			merge:     mergeMessageSlice,
+		}
+		if needsInitCheck(mi.Desc) {
+			funcs.isInit = isInitMessageSliceInfo
+		}
+		return funcs
+	}
+	return pointerCoderFuncs{
+		size: func(p pointer, f *coderFieldInfo, opts marshalOptions) int {
+			return sizeMessageSlice(p, ft, f.tagsize, opts)
+		},
+		marshal: func(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
+			return appendMessageSlice(b, p, f.wiretag, ft, opts)
+		},
+		unmarshal: func(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (unmarshalOutput, error) {
+			return consumeMessageSlice(b, p, ft, wtyp, opts)
+		},
+		isInit: func(p pointer, f *coderFieldInfo) error {
+			return isInitMessageSlice(p, ft)
+		},
+		merge: mergeMessageSlice,
+	}
+}
+
+func sizeMessageSliceInfo(p pointer, f *coderFieldInfo, opts marshalOptions) int {
+	s := p.PointerSlice()
+	n := 0
+	for _, v := range s {
+		n += protowire.SizeBytes(f.mi.sizePointer(v, opts)) + f.tagsize
+	}
+	return n
+}
+
+func appendMessageSliceInfo(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
+	s := p.PointerSlice()
+	var err error
+	for _, v := range s {
+		b = protowire.AppendVarint(b, f.wiretag)
+		siz := f.mi.sizePointer(v, opts)
+		b = protowire.AppendVarint(b, uint64(siz))
+		b, err = f.mi.marshalAppendPointer(b, v, opts)
+		if err != nil {
+			return b, err
+		}
+	}
+	return b, nil
+}
+
+func consumeMessageSliceInfo(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (out unmarshalOutput, err error) {
+	if wtyp != protowire.BytesType {
+		return out, errUnknown
+	}
+	v, n := protowire.ConsumeBytes(b)
+	if n < 0 {
+		return out, protowire.ParseError(n)
+	}
+	m := reflect.New(f.mi.GoReflectType.Elem()).Interface()
+	mp := pointerOfIface(m)
+	o, err := f.mi.unmarshalPointer(v, mp, 0, opts)
+	if err != nil {
+		return out, err
+	}
+	p.AppendPointerSlice(mp)
+	out.n = n
+	out.initialized = o.initialized
+	return out, nil
+}
+
+func isInitMessageSliceInfo(p pointer, f *coderFieldInfo) error {
+	s := p.PointerSlice()
+	for _, v := range s {
+		if err := f.mi.checkInitializedPointer(v); err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+func sizeMessageSlice(p pointer, goType reflect.Type, tagsize int, _ marshalOptions) int {
+	s := p.PointerSlice()
+	n := 0
+	for _, v := range s {
+		m := asMessage(v.AsValueOf(goType.Elem()))
+		n += protowire.SizeBytes(proto.Size(m)) + tagsize
+	}
+	return n
+}
+
+func appendMessageSlice(b []byte, p pointer, wiretag uint64, goType reflect.Type, opts marshalOptions) ([]byte, error) {
+	s := p.PointerSlice()
+	var err error
+	for _, v := range s {
+		m := asMessage(v.AsValueOf(goType.Elem()))
+		b = protowire.AppendVarint(b, wiretag)
+		siz := proto.Size(m)
+		b = protowire.AppendVarint(b, uint64(siz))
+		b, err = opts.Options().MarshalAppend(b, m)
+		if err != nil {
+			return b, err
+		}
+	}
+	return b, nil
+}
+
+func consumeMessageSlice(b []byte, p pointer, goType reflect.Type, wtyp protowire.Type, opts unmarshalOptions) (out unmarshalOutput, err error) {
+	if wtyp != protowire.BytesType {
+		return out, errUnknown
+	}
+	v, n := protowire.ConsumeBytes(b)
+	if n < 0 {
+		return out, protowire.ParseError(n)
+	}
+	mp := reflect.New(goType.Elem())
+	o, err := opts.Options().UnmarshalState(piface.UnmarshalInput{
+		Buf:     v,
+		Message: asMessage(mp).ProtoReflect(),
+	})
+	if err != nil {
+		return out, err
+	}
+	p.AppendPointerSlice(pointerOfValue(mp))
+	out.n = n
+	out.initialized = o.Flags&piface.UnmarshalInitialized != 0
+	return out, nil
+}
+
+func isInitMessageSlice(p pointer, goType reflect.Type) error {
+	s := p.PointerSlice()
+	for _, v := range s {
+		m := asMessage(v.AsValueOf(goType.Elem()))
+		if err := proto.CheckInitialized(m); err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+// Slices of messages
+
+func sizeMessageSliceValue(listv pref.Value, tagsize int, opts marshalOptions) int {
+	list := listv.List()
+	n := 0
+	for i, llen := 0, list.Len(); i < llen; i++ {
+		m := list.Get(i).Message().Interface()
+		n += protowire.SizeBytes(proto.Size(m)) + tagsize
+	}
+	return n
+}
+
+func appendMessageSliceValue(b []byte, listv pref.Value, wiretag uint64, opts marshalOptions) ([]byte, error) {
+	list := listv.List()
+	mopts := opts.Options()
+	for i, llen := 0, list.Len(); i < llen; i++ {
+		m := list.Get(i).Message().Interface()
+		b = protowire.AppendVarint(b, wiretag)
+		siz := proto.Size(m)
+		b = protowire.AppendVarint(b, uint64(siz))
+		var err error
+		b, err = mopts.MarshalAppend(b, m)
+		if err != nil {
+			return b, err
+		}
+	}
+	return b, nil
+}
+
+func consumeMessageSliceValue(b []byte, listv pref.Value, _ protowire.Number, wtyp protowire.Type, opts unmarshalOptions) (_ pref.Value, out unmarshalOutput, err error) {
+	list := listv.List()
+	if wtyp != protowire.BytesType {
+		return pref.Value{}, out, errUnknown
+	}
+	v, n := protowire.ConsumeBytes(b)
+	if n < 0 {
+		return pref.Value{}, out, protowire.ParseError(n)
+	}
+	m := list.NewElement()
+	o, err := opts.Options().UnmarshalState(piface.UnmarshalInput{
+		Buf:     v,
+		Message: m.Message(),
+	})
+	if err != nil {
+		return pref.Value{}, out, err
+	}
+	list.Append(m)
+	out.n = n
+	out.initialized = o.Flags&piface.UnmarshalInitialized != 0
+	return listv, out, nil
+}
+
+func isInitMessageSliceValue(listv pref.Value) error {
+	list := listv.List()
+	for i, llen := 0, list.Len(); i < llen; i++ {
+		m := list.Get(i).Message().Interface()
+		if err := proto.CheckInitialized(m); err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+var coderMessageSliceValue = valueCoderFuncs{
+	size:      sizeMessageSliceValue,
+	marshal:   appendMessageSliceValue,
+	unmarshal: consumeMessageSliceValue,
+	isInit:    isInitMessageSliceValue,
+	merge:     mergeMessageListValue,
+}
+
+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 = protowire.AppendVarint(b, wiretag) // start group
+		var err error
+		b, err = mopts.MarshalAppend(b, m)
+		if err != nil {
+			return b, err
+		}
+		b = protowire.AppendVarint(b, wiretag+1) // end group
+	}
+	return b, nil
+}
+
+func consumeGroupSliceValue(b []byte, listv pref.Value, num protowire.Number, wtyp protowire.Type, opts unmarshalOptions) (_ pref.Value, out unmarshalOutput, err error) {
+	list := listv.List()
+	if wtyp != protowire.StartGroupType {
+		return pref.Value{}, out, errUnknown
+	}
+	b, n := protowire.ConsumeGroup(num, b)
+	if n < 0 {
+		return pref.Value{}, out, protowire.ParseError(n)
+	}
+	m := list.NewElement()
+	o, err := opts.Options().UnmarshalState(piface.UnmarshalInput{
+		Buf:     b,
+		Message: m.Message(),
+	})
+	if err != nil {
+		return pref.Value{}, out, err
+	}
+	list.Append(m)
+	out.n = n
+	out.initialized = o.Flags&piface.UnmarshalInitialized != 0
+	return listv, out, nil
+}
+
+var coderGroupSliceValue = valueCoderFuncs{
+	size:      sizeGroupSliceValue,
+	marshal:   appendGroupSliceValue,
+	unmarshal: consumeGroupSliceValue,
+	isInit:    isInitMessageSliceValue,
+	merge:     mergeMessageListValue,
+}
+
+func makeGroupSliceFieldCoder(fd pref.FieldDescriptor, ft reflect.Type) pointerCoderFuncs {
+	num := fd.Number()
+	if mi := getMessageInfo(ft); mi != nil {
+		funcs := pointerCoderFuncs{
+			size:      sizeGroupSliceInfo,
+			marshal:   appendGroupSliceInfo,
+			unmarshal: consumeGroupSliceInfo,
+			merge:     mergeMessageSlice,
+		}
+		if needsInitCheck(mi.Desc) {
+			funcs.isInit = isInitMessageSliceInfo
+		}
+		return funcs
+	}
+	return pointerCoderFuncs{
+		size: func(p pointer, f *coderFieldInfo, opts marshalOptions) int {
+			return sizeGroupSlice(p, ft, f.tagsize, opts)
+		},
+		marshal: func(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
+			return appendGroupSlice(b, p, f.wiretag, ft, opts)
+		},
+		unmarshal: func(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (unmarshalOutput, error) {
+			return consumeGroupSlice(b, p, num, wtyp, ft, opts)
+		},
+		isInit: func(p pointer, f *coderFieldInfo) error {
+			return isInitMessageSlice(p, ft)
+		},
+		merge: mergeMessageSlice,
+	}
+}
+
+func sizeGroupSlice(p pointer, messageType reflect.Type, tagsize int, _ marshalOptions) int {
+	s := p.PointerSlice()
+	n := 0
+	for _, v := range s {
+		m := asMessage(v.AsValueOf(messageType.Elem()))
+		n += 2*tagsize + proto.Size(m)
+	}
+	return n
+}
+
+func appendGroupSlice(b []byte, p pointer, wiretag uint64, messageType reflect.Type, opts marshalOptions) ([]byte, error) {
+	s := p.PointerSlice()
+	var err error
+	for _, v := range s {
+		m := asMessage(v.AsValueOf(messageType.Elem()))
+		b = protowire.AppendVarint(b, wiretag) // start group
+		b, err = opts.Options().MarshalAppend(b, m)
+		if err != nil {
+			return b, err
+		}
+		b = protowire.AppendVarint(b, wiretag+1) // end group
+	}
+	return b, nil
+}
+
+func consumeGroupSlice(b []byte, p pointer, num protowire.Number, wtyp protowire.Type, goType reflect.Type, opts unmarshalOptions) (out unmarshalOutput, err error) {
+	if wtyp != protowire.StartGroupType {
+		return out, errUnknown
+	}
+	b, n := protowire.ConsumeGroup(num, b)
+	if n < 0 {
+		return out, protowire.ParseError(n)
+	}
+	mp := reflect.New(goType.Elem())
+	o, err := opts.Options().UnmarshalState(piface.UnmarshalInput{
+		Buf:     b,
+		Message: asMessage(mp).ProtoReflect(),
+	})
+	if err != nil {
+		return out, err
+	}
+	p.AppendPointerSlice(pointerOfValue(mp))
+	out.n = n
+	out.initialized = o.Flags&piface.UnmarshalInitialized != 0
+	return out, nil
+}
+
+func sizeGroupSliceInfo(p pointer, f *coderFieldInfo, opts marshalOptions) int {
+	s := p.PointerSlice()
+	n := 0
+	for _, v := range s {
+		n += 2*f.tagsize + f.mi.sizePointer(v, opts)
+	}
+	return n
+}
+
+func appendGroupSliceInfo(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
+	s := p.PointerSlice()
+	var err error
+	for _, v := range s {
+		b = protowire.AppendVarint(b, f.wiretag) // start group
+		b, err = f.mi.marshalAppendPointer(b, v, opts)
+		if err != nil {
+			return b, err
+		}
+		b = protowire.AppendVarint(b, f.wiretag+1) // end group
+	}
+	return b, nil
+}
+
+func consumeGroupSliceInfo(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (unmarshalOutput, error) {
+	if wtyp != protowire.StartGroupType {
+		return unmarshalOutput{}, errUnknown
+	}
+	m := reflect.New(f.mi.GoReflectType.Elem()).Interface()
+	mp := pointerOfIface(m)
+	out, err := f.mi.unmarshalPointer(b, mp, f.num, opts)
+	if err != nil {
+		return out, err
+	}
+	p.AppendPointerSlice(mp)
+	return out, nil
+}
+
+func asMessage(v reflect.Value) pref.ProtoMessage {
+	if m, ok := v.Interface().(pref.ProtoMessage); ok {
+		return m
+	}
+	return legacyWrapMessage(v).Interface()
+}
diff --git a/vendor/google.golang.org/protobuf/internal/impl/codec_gen.go b/vendor/google.golang.org/protobuf/internal/impl/codec_gen.go
new file mode 100644
index 0000000..ff198d0
--- /dev/null
+++ b/vendor/google.golang.org/protobuf/internal/impl/codec_gen.go
@@ -0,0 +1,5637 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Code generated by generate-types. DO NOT EDIT.
+
+package impl
+
+import (
+	"math"
+	"unicode/utf8"
+
+	"google.golang.org/protobuf/encoding/protowire"
+	"google.golang.org/protobuf/reflect/protoreflect"
+)
+
+// sizeBool returns the size of wire encoding a bool pointer as a Bool.
+func sizeBool(p pointer, f *coderFieldInfo, _ marshalOptions) (size int) {
+	v := *p.Bool()
+	return f.tagsize + protowire.SizeVarint(protowire.EncodeBool(v))
+}
+
+// appendBool wire encodes a bool pointer as a Bool.
+func appendBool(b []byte, p pointer, f *coderFieldInfo, _ marshalOptions) ([]byte, error) {
+	v := *p.Bool()
+	b = protowire.AppendVarint(b, f.wiretag)
+	b = protowire.AppendVarint(b, protowire.EncodeBool(v))
+	return b, nil
+}
+
+// consumeBool wire decodes a bool pointer as a Bool.
+func consumeBool(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, _ unmarshalOptions) (out unmarshalOutput, err error) {
+	if wtyp != protowire.VarintType {
+		return out, errUnknown
+	}
+	var v uint64
+	var n int
+	if len(b) >= 1 && b[0] < 0x80 {
+		v = uint64(b[0])
+		n = 1
+	} else if len(b) >= 2 && b[1] < 128 {
+		v = uint64(b[0]&0x7f) + uint64(b[1])<<7
+		n = 2
+	} else {
+		v, n = protowire.ConsumeVarint(b)
+	}
+	if n < 0 {
+		return out, protowire.ParseError(n)
+	}
+	*p.Bool() = protowire.DecodeBool(v)
+	out.n = n
+	return out, nil
+}
+
+var coderBool = pointerCoderFuncs{
+	size:      sizeBool,
+	marshal:   appendBool,
+	unmarshal: consumeBool,
+	merge:     mergeBool,
+}
+
+// sizeBoolNoZero returns the size of wire encoding a bool pointer as a Bool.
+// The zero value is not encoded.
+func sizeBoolNoZero(p pointer, f *coderFieldInfo, _ marshalOptions) (size int) {
+	v := *p.Bool()
+	if v == false {
+		return 0
+	}
+	return f.tagsize + protowire.SizeVarint(protowire.EncodeBool(v))
+}
+
+// appendBoolNoZero wire encodes a bool pointer as a Bool.
+// The zero value is not encoded.
+func appendBoolNoZero(b []byte, p pointer, f *coderFieldInfo, _ marshalOptions) ([]byte, error) {
+	v := *p.Bool()
+	if v == false {
+		return b, nil
+	}
+	b = protowire.AppendVarint(b, f.wiretag)
+	b = protowire.AppendVarint(b, protowire.EncodeBool(v))
+	return b, nil
+}
+
+var coderBoolNoZero = pointerCoderFuncs{
+	size:      sizeBoolNoZero,
+	marshal:   appendBoolNoZero,
+	unmarshal: consumeBool,
+	merge:     mergeBoolNoZero,
+}
+
+// sizeBoolPtr returns the size of wire encoding a *bool pointer as a Bool.
+// It panics if the pointer is nil.
+func sizeBoolPtr(p pointer, f *coderFieldInfo, _ marshalOptions) (size int) {
+	v := **p.BoolPtr()
+	return f.tagsize + protowire.SizeVarint(protowire.EncodeBool(v))
+}
+
+// appendBoolPtr wire encodes a *bool pointer as a Bool.
+// It panics if the pointer is nil.
+func appendBoolPtr(b []byte, p pointer, f *coderFieldInfo, _ marshalOptions) ([]byte, error) {
+	v := **p.BoolPtr()
+	b = protowire.AppendVarint(b, f.wiretag)
+	b = protowire.AppendVarint(b, protowire.EncodeBool(v))
+	return b, nil
+}
+
+// consumeBoolPtr wire decodes a *bool pointer as a Bool.
+func consumeBoolPtr(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, _ unmarshalOptions) (out unmarshalOutput, err error) {
+	if wtyp != protowire.VarintType {
+		return out, errUnknown
+	}
+	var v uint64
+	var n int
+	if len(b) >= 1 && b[0] < 0x80 {
+		v = uint64(b[0])
+		n = 1
+	} else if len(b) >= 2 && b[1] < 128 {
+		v = uint64(b[0]&0x7f) + uint64(b[1])<<7
+		n = 2
+	} else {
+		v, n = protowire.ConsumeVarint(b)
+	}
+	if n < 0 {
+		return out, protowire.ParseError(n)
+	}
+	vp := p.BoolPtr()
+	if *vp == nil {
+		*vp = new(bool)
+	}
+	**vp = protowire.DecodeBool(v)
+	out.n = n
+	return out, nil
+}
+
+var coderBoolPtr = pointerCoderFuncs{
+	size:      sizeBoolPtr,
+	marshal:   appendBoolPtr,
+	unmarshal: consumeBoolPtr,
+	merge:     mergeBoolPtr,
+}
+
+// sizeBoolSlice returns the size of wire encoding a []bool pointer as a repeated Bool.
+func sizeBoolSlice(p pointer, f *coderFieldInfo, _ marshalOptions) (size int) {
+	s := *p.BoolSlice()
+	for _, v := range s {
+		size += f.tagsize + protowire.SizeVarint(protowire.EncodeBool(v))
+	}
+	return size
+}
+
+// appendBoolSlice encodes a []bool pointer as a repeated Bool.
+func appendBoolSlice(b []byte, p pointer, f *coderFieldInfo, _ marshalOptions) ([]byte, error) {
+	s := *p.BoolSlice()
+	for _, v := range s {
+		b = protowire.AppendVarint(b, f.wiretag)
+		b = protowire.AppendVarint(b, protowire.EncodeBool(v))
+	}
+	return b, nil
+}
+
+// consumeBoolSlice wire decodes a []bool pointer as a repeated Bool.
+func consumeBoolSlice(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, _ unmarshalOptions) (out unmarshalOutput, err error) {
+	sp := p.BoolSlice()
+	if wtyp == protowire.BytesType {
+		s := *sp
+		b, n := protowire.ConsumeBytes(b)
+		if n < 0 {
+			return out, protowire.ParseError(n)
+		}
+		for len(b) > 0 {
+			var v uint64
+			var n int
+			if len(b) >= 1 && b[0] < 0x80 {
+				v = uint64(b[0])
+				n = 1
+			} else if len(b) >= 2 && b[1] < 128 {
+				v = uint64(b[0]&0x7f) + uint64(b[1])<<7
+				n = 2
+			} else {
+				v, n = protowire.ConsumeVarint(b)
+			}
+			if n < 0 {
+				return out, protowire.ParseError(n)
+			}
+			s = append(s, protowire.DecodeBool(v))
+			b = b[n:]
+		}
+		*sp = s
+		out.n = n
+		return out, nil
+	}
+	if wtyp != protowire.VarintType {
+		return out, errUnknown
+	}
+	var v uint64
+	var n int
+	if len(b) >= 1 && b[0] < 0x80 {
+		v = uint64(b[0])
+		n = 1
+	} else if len(b) >= 2 && b[1] < 128 {
+		v = uint64(b[0]&0x7f) + uint64(b[1])<<7
+		n = 2
+	} else {
+		v, n = protowire.ConsumeVarint(b)
+	}
+	if n < 0 {
+		return out, protowire.ParseError(n)
+	}
+	*sp = append(*sp, protowire.DecodeBool(v))
+	out.n = n
+	return out, nil
+}
+
+var coderBoolSlice = pointerCoderFuncs{
+	size:      sizeBoolSlice,
+	marshal:   appendBoolSlice,
+	unmarshal: consumeBoolSlice,
+	merge:     mergeBoolSlice,
+}
+
+// sizeBoolPackedSlice returns the size of wire encoding a []bool pointer as a packed repeated Bool.
+func sizeBoolPackedSlice(p pointer, f *coderFieldInfo, _ marshalOptions) (size int) {
+	s := *p.BoolSlice()
+	if len(s) == 0 {
+		return 0
+	}
+	n := 0
+	for _, v := range s {
+		n += protowire.SizeVarint(protowire.EncodeBool(v))
+	}
+	return f.tagsize + protowire.SizeBytes(n)
+}
+
+// appendBoolPackedSlice encodes a []bool pointer as a packed repeated Bool.
+func appendBoolPackedSlice(b []byte, p pointer, f *coderFieldInfo, _ marshalOptions) ([]byte, error) {
+	s := *p.BoolSlice()
+	if len(s) == 0 {
+		return b, nil
+	}
+	b = protowire.AppendVarint(b, f.wiretag)
+	n := 0
+	for _, v := range s {
+		n += protowire.SizeVarint(protowire.EncodeBool(v))
+	}
+	b = protowire.AppendVarint(b, uint64(n))
+	for _, v := range s {
+		b = protowire.AppendVarint(b, protowire.EncodeBool(v))
+	}
+	return b, nil
+}
+
+var coderBoolPackedSlice = pointerCoderFuncs{
+	size:      sizeBoolPackedSlice,
+	marshal:   appendBoolPackedSlice,
+	unmarshal: consumeBoolSlice,
+	merge:     mergeBoolSlice,
+}
+
+// sizeBoolValue returns the size of wire encoding a bool value as a Bool.
+func sizeBoolValue(v protoreflect.Value, tagsize int, _ marshalOptions) int {
+	return tagsize + protowire.SizeVarint(protowire.EncodeBool(v.Bool()))
+}
+
+// appendBoolValue encodes a bool value as a Bool.
+func appendBoolValue(b []byte, v protoreflect.Value, wiretag uint64, _ marshalOptions) ([]byte, error) {
+	b = protowire.AppendVarint(b, wiretag)
+	b = protowire.AppendVarint(b, protowire.EncodeBool(v.Bool()))
+	return b, nil
+}
+
+// consumeBoolValue decodes a bool value as a Bool.
+func consumeBoolValue(b []byte, _ protoreflect.Value, _ protowire.Number, wtyp protowire.Type, _ unmarshalOptions) (_ protoreflect.Value, out unmarshalOutput, err error) {
+	if wtyp != protowire.VarintType {
+		return protoreflect.Value{}, out, errUnknown
+	}
+	var v uint64
+	var n int
+	if len(b) >= 1 && b[0] < 0x80 {
+		v = uint64(b[0])
+		n = 1
+	} else if len(b) >= 2 && b[1] < 128 {
+		v = uint64(b[0]&0x7f) + uint64(b[1])<<7
+		n = 2
+	} else {
+		v, n = protowire.ConsumeVarint(b)
+	}
+	if n < 0 {
+		return protoreflect.Value{}, out, protowire.ParseError(n)
+	}
+	out.n = n
+	return protoreflect.ValueOfBool(protowire.DecodeBool(v)), out, nil
+}
+
+var coderBoolValue = valueCoderFuncs{
+	size:      sizeBoolValue,
+	marshal:   appendBoolValue,
+	unmarshal: consumeBoolValue,
+	merge:     mergeScalarValue,
+}
+
+// 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 + protowire.SizeVarint(protowire.EncodeBool(v.Bool()))
+	}
+	return size
+}
+
+// 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 = protowire.AppendVarint(b, wiretag)
+		b = protowire.AppendVarint(b, protowire.EncodeBool(v.Bool()))
+	}
+	return b, nil
+}
+
+// consumeBoolSliceValue wire decodes a []bool value as a repeated Bool.
+func consumeBoolSliceValue(b []byte, listv protoreflect.Value, _ protowire.Number, wtyp protowire.Type, _ unmarshalOptions) (_ protoreflect.Value, out unmarshalOutput, err error) {
+	list := listv.List()
+	if wtyp == protowire.BytesType {
+		b, n := protowire.ConsumeBytes(b)
+		if n < 0 {
+			return protoreflect.Value{}, out, protowire.ParseError(n)
+		}
+		for len(b) > 0 {
+			var v uint64
+			var n int
+			if len(b) >= 1 && b[0] < 0x80 {
+				v = uint64(b[0])
+				n = 1
+			} else if len(b) >= 2 && b[1] < 128 {
+				v = uint64(b[0]&0x7f) + uint64(b[1])<<7
+				n = 2
+			} else {
+				v, n = protowire.ConsumeVarint(b)
+			}
+			if n < 0 {
+				return protoreflect.Value{}, out, protowire.ParseError(n)
+			}
+			list.Append(protoreflect.ValueOfBool(protowire.DecodeBool(v)))
+			b = b[n:]
+		}
+		out.n = n
+		return listv, out, nil
+	}
+	if wtyp != protowire.VarintType {
+		return protoreflect.Value{}, out, errUnknown
+	}
+	var v uint64
+	var n int
+	if len(b) >= 1 && b[0] < 0x80 {
+		v = uint64(b[0])
+		n = 1
+	} else if len(b) >= 2 && b[1] < 128 {
+		v = uint64(b[0]&0x7f) + uint64(b[1])<<7
+		n = 2
+	} else {
+		v, n = protowire.ConsumeVarint(b)
+	}
+	if n < 0 {
+		return protoreflect.Value{}, out, protowire.ParseError(n)
+	}
+	list.Append(protoreflect.ValueOfBool(protowire.DecodeBool(v)))
+	out.n = n
+	return listv, out, nil
+}
+
+var coderBoolSliceValue = valueCoderFuncs{
+	size:      sizeBoolSliceValue,
+	marshal:   appendBoolSliceValue,
+	unmarshal: consumeBoolSliceValue,
+	merge:     mergeListValue,
+}
+
+// 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()
+	llen := list.Len()
+	if llen == 0 {
+		return 0
+	}
+	n := 0
+	for i, llen := 0, llen; i < llen; i++ {
+		v := list.Get(i)
+		n += protowire.SizeVarint(protowire.EncodeBool(v.Bool()))
+	}
+	return tagsize + protowire.SizeBytes(n)
+}
+
+// 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 = protowire.AppendVarint(b, wiretag)
+	n := 0
+	for i := 0; i < llen; i++ {
+		v := list.Get(i)
+		n += protowire.SizeVarint(protowire.EncodeBool(v.Bool()))
+	}
+	b = protowire.AppendVarint(b, uint64(n))
+	for i := 0; i < llen; i++ {
+		v := list.Get(i)
+		b = protowire.AppendVarint(b, protowire.EncodeBool(v.Bool()))
+	}
+	return b, nil
+}
+
+var coderBoolPackedSliceValue = valueCoderFuncs{
+	size:      sizeBoolPackedSliceValue,
+	marshal:   appendBoolPackedSliceValue,
+	unmarshal: consumeBoolSliceValue,
+	merge:     mergeListValue,
+}
+
+// sizeEnumValue returns the size of wire encoding a  value as a Enum.
+func sizeEnumValue(v protoreflect.Value, tagsize int, _ marshalOptions) int {
+	return tagsize + protowire.SizeVarint(uint64(v.Enum()))
+}
+
+// appendEnumValue encodes a  value as a Enum.
+func appendEnumValue(b []byte, v protoreflect.Value, wiretag uint64, _ marshalOptions) ([]byte, error) {
+	b = protowire.AppendVarint(b, wiretag)
+	b = protowire.AppendVarint(b, uint64(v.Enum()))
+	return b, nil
+}
+
+// consumeEnumValue decodes a  value as a Enum.
+func consumeEnumValue(b []byte, _ protoreflect.Value, _ protowire.Number, wtyp protowire.Type, _ unmarshalOptions) (_ protoreflect.Value, out unmarshalOutput, err error) {
+	if wtyp != protowire.VarintType {
+		return protoreflect.Value{}, out, errUnknown
+	}
+	var v uint64
+	var n int
+	if len(b) >= 1 && b[0] < 0x80 {
+		v = uint64(b[0])
+		n = 1
+	} else if len(b) >= 2 && b[1] < 128 {
+		v = uint64(b[0]&0x7f) + uint64(b[1])<<7
+		n = 2
+	} else {
+		v, n = protowire.ConsumeVarint(b)
+	}
+	if n < 0 {
+		return protoreflect.Value{}, out, protowire.ParseError(n)
+	}
+	out.n = n
+	return protoreflect.ValueOfEnum(protoreflect.EnumNumber(v)), out, nil
+}
+
+var coderEnumValue = valueCoderFuncs{
+	size:      sizeEnumValue,
+	marshal:   appendEnumValue,
+	unmarshal: consumeEnumValue,
+	merge:     mergeScalarValue,
+}
+
+// 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 + protowire.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 = protowire.AppendVarint(b, wiretag)
+		b = protowire.AppendVarint(b, uint64(v.Enum()))
+	}
+	return b, nil
+}
+
+// consumeEnumSliceValue wire decodes a [] value as a repeated Enum.
+func consumeEnumSliceValue(b []byte, listv protoreflect.Value, _ protowire.Number, wtyp protowire.Type, _ unmarshalOptions) (_ protoreflect.Value, out unmarshalOutput, err error) {
+	list := listv.List()
+	if wtyp == protowire.BytesType {
+		b, n := protowire.ConsumeBytes(b)
+		if n < 0 {
+			return protoreflect.Value{}, out, protowire.ParseError(n)
+		}
+		for len(b) > 0 {
+			var v uint64
+			var n int
+			if len(b) >= 1 && b[0] < 0x80 {
+				v = uint64(b[0])
+				n = 1
+			} else if len(b) >= 2 && b[1] < 128 {
+				v = uint64(b[0]&0x7f) + uint64(b[1])<<7
+				n = 2
+			} else {
+				v, n = protowire.ConsumeVarint(b)
+			}
+			if n < 0 {
+				return protoreflect.Value{}, out, protowire.ParseError(n)
+			}
+			list.Append(protoreflect.ValueOfEnum(protoreflect.EnumNumber(v)))
+			b = b[n:]
+		}
+		out.n = n
+		return listv, out, nil
+	}
+	if wtyp != protowire.VarintType {
+		return protoreflect.Value{}, out, errUnknown
+	}
+	var v uint64
+	var n int
+	if len(b) >= 1 && b[0] < 0x80 {
+		v = uint64(b[0])
+		n = 1
+	} else if len(b) >= 2 && b[1] < 128 {
+		v = uint64(b[0]&0x7f) + uint64(b[1])<<7
+		n = 2
+	} else {
+		v, n = protowire.ConsumeVarint(b)
+	}
+	if n < 0 {
+		return protoreflect.Value{}, out, protowire.ParseError(n)
+	}
+	list.Append(protoreflect.ValueOfEnum(protoreflect.EnumNumber(v)))
+	out.n = n
+	return listv, out, nil
+}
+
+var coderEnumSliceValue = valueCoderFuncs{
+	size:      sizeEnumSliceValue,
+	marshal:   appendEnumSliceValue,
+	unmarshal: consumeEnumSliceValue,
+	merge:     mergeListValue,
+}
+
+// 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()
+	llen := list.Len()
+	if llen == 0 {
+		return 0
+	}
+	n := 0
+	for i, llen := 0, llen; i < llen; i++ {
+		v := list.Get(i)
+		n += protowire.SizeVarint(uint64(v.Enum()))
+	}
+	return tagsize + protowire.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 = protowire.AppendVarint(b, wiretag)
+	n := 0
+	for i := 0; i < llen; i++ {
+		v := list.Get(i)
+		n += protowire.SizeVarint(uint64(v.Enum()))
+	}
+	b = protowire.AppendVarint(b, uint64(n))
+	for i := 0; i < llen; i++ {
+		v := list.Get(i)
+		b = protowire.AppendVarint(b, uint64(v.Enum()))
+	}
+	return b, nil
+}
+
+var coderEnumPackedSliceValue = valueCoderFuncs{
+	size:      sizeEnumPackedSliceValue,
+	marshal:   appendEnumPackedSliceValue,
+	unmarshal: consumeEnumSliceValue,
+	merge:     mergeListValue,
+}
+
+// sizeInt32 returns the size of wire encoding a int32 pointer as a Int32.
+func sizeInt32(p pointer, f *coderFieldInfo, _ marshalOptions) (size int) {
+	v := *p.Int32()
+	return f.tagsize + protowire.SizeVarint(uint64(v))
+}
+
+// appendInt32 wire encodes a int32 pointer as a Int32.
+func appendInt32(b []byte, p pointer, f *coderFieldInfo, _ marshalOptions) ([]byte, error) {
+	v := *p.Int32()
+	b = protowire.AppendVarint(b, f.wiretag)
+	b = protowire.AppendVarint(b, uint64(v))
+	return b, nil
+}
+
+// consumeInt32 wire decodes a int32 pointer as a Int32.
+func consumeInt32(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, _ unmarshalOptions) (out unmarshalOutput, err error) {
+	if wtyp != protowire.VarintType {
+		return out, errUnknown
+	}
+	var v uint64
+	var n int
+	if len(b) >= 1 && b[0] < 0x80 {
+		v = uint64(b[0])
+		n = 1
+	} else if len(b) >= 2 && b[1] < 128 {
+		v = uint64(b[0]&0x7f) + uint64(b[1])<<7
+		n = 2
+	} else {
+		v, n = protowire.ConsumeVarint(b)
+	}
+	if n < 0 {
+		return out, protowire.ParseError(n)
+	}
+	*p.Int32() = int32(v)
+	out.n = n
+	return out, nil
+}
+
+var coderInt32 = pointerCoderFuncs{
+	size:      sizeInt32,
+	marshal:   appendInt32,
+	unmarshal: consumeInt32,
+	merge:     mergeInt32,
+}
+
+// sizeInt32NoZero returns the size of wire encoding a int32 pointer as a Int32.
+// The zero value is not encoded.
+func sizeInt32NoZero(p pointer, f *coderFieldInfo, _ marshalOptions) (size int) {
+	v := *p.Int32()
+	if v == 0 {
+		return 0
+	}
+	return f.tagsize + protowire.SizeVarint(uint64(v))
+}
+
+// appendInt32NoZero wire encodes a int32 pointer as a Int32.
+// The zero value is not encoded.
+func appendInt32NoZero(b []byte, p pointer, f *coderFieldInfo, _ marshalOptions) ([]byte, error) {
+	v := *p.Int32()
+	if v == 0 {
+		return b, nil
+	}
+	b = protowire.AppendVarint(b, f.wiretag)
+	b = protowire.AppendVarint(b, uint64(v))
+	return b, nil
+}
+
+var coderInt32NoZero = pointerCoderFuncs{
+	size:      sizeInt32NoZero,
+	marshal:   appendInt32NoZero,
+	unmarshal: consumeInt32,
+	merge:     mergeInt32NoZero,
+}
+
+// sizeInt32Ptr returns the size of wire encoding a *int32 pointer as a Int32.
+// It panics if the pointer is nil.
+func sizeInt32Ptr(p pointer, f *coderFieldInfo, _ marshalOptions) (size int) {
+	v := **p.Int32Ptr()
+	return f.tagsize + protowire.SizeVarint(uint64(v))
+}
+
+// appendInt32Ptr wire encodes a *int32 pointer as a Int32.
+// It panics if the pointer is nil.
+func appendInt32Ptr(b []byte, p pointer, f *coderFieldInfo, _ marshalOptions) ([]byte, error) {
+	v := **p.Int32Ptr()
+	b = protowire.AppendVarint(b, f.wiretag)
+	b = protowire.AppendVarint(b, uint64(v))
+	return b, nil
+}
+
+// consumeInt32Ptr wire decodes a *int32 pointer as a Int32.
+func consumeInt32Ptr(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, _ unmarshalOptions) (out unmarshalOutput, err error) {
+	if wtyp != protowire.VarintType {
+		return out, errUnknown
+	}
+	var v uint64
+	var n int
+	if len(b) >= 1 && b[0] < 0x80 {
+		v = uint64(b[0])
+		n = 1
+	} else if len(b) >= 2 && b[1] < 128 {
+		v = uint64(b[0]&0x7f) + uint64(b[1])<<7
+		n = 2
+	} else {
+		v, n = protowire.ConsumeVarint(b)
+	}
+	if n < 0 {
+		return out, protowire.ParseError(n)
+	}
+	vp := p.Int32Ptr()
+	if *vp == nil {
+		*vp = new(int32)
+	}
+	**vp = int32(v)
+	out.n = n
+	return out, nil
+}
+
+var coderInt32Ptr = pointerCoderFuncs{
+	size:      sizeInt32Ptr,
+	marshal:   appendInt32Ptr,
+	unmarshal: consumeInt32Ptr,
+	merge:     mergeInt32Ptr,
+}
+
+// sizeInt32Slice returns the size of wire encoding a []int32 pointer as a repeated Int32.
+func sizeInt32Slice(p pointer, f *coderFieldInfo, _ marshalOptions) (size int) {
+	s := *p.Int32Slice()
+	for _, v := range s {
+		size += f.tagsize + protowire.SizeVarint(uint64(v))
+	}
+	return size
+}
+
+// appendInt32Slice encodes a []int32 pointer as a repeated Int32.
+func appendInt32Slice(b []byte, p pointer, f *coderFieldInfo, _ marshalOptions) ([]byte, error) {
+	s := *p.Int32Slice()
+	for _, v := range s {
+		b = protowire.AppendVarint(b, f.wiretag)
+		b = protowire.AppendVarint(b, uint64(v))
+	}
+	return b, nil
+}
+
+// consumeInt32Slice wire decodes a []int32 pointer as a repeated Int32.
+func consumeInt32Slice(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, _ unmarshalOptions) (out unmarshalOutput, err error) {
+	sp := p.Int32Slice()
+	if wtyp == protowire.BytesType {
+		s := *sp
+		b, n := protowire.ConsumeBytes(b)
+		if n < 0 {
+			return out, protowire.ParseError(n)
+		}
+		for len(b) > 0 {
+			var v uint64
+			var n int
+			if len(b) >= 1 && b[0] < 0x80 {
+				v = uint64(b[0])
+				n = 1
+			} else if len(b) >= 2 && b[1] < 128 {
+				v = uint64(b[0]&0x7f) + uint64(b[1])<<7
+				n = 2
+			} else {
+				v, n = protowire.ConsumeVarint(b)
+			}
+			if n < 0 {
+				return out, protowire.ParseError(n)
+			}
+			s = append(s, int32(v))
+			b = b[n:]
+		}
+		*sp = s
+		out.n = n
+		return out, nil
+	}
+	if wtyp != protowire.VarintType {
+		return out, errUnknown
+	}
+	var v uint64
+	var n int
+	if len(b) >= 1 && b[0] < 0x80 {
+		v = uint64(b[0])
+		n = 1
+	} else if len(b) >= 2 && b[1] < 128 {
+		v = uint64(b[0]&0x7f) + uint64(b[1])<<7
+		n = 2
+	} else {
+		v, n = protowire.ConsumeVarint(b)
+	}
+	if n < 0 {
+		return out, protowire.ParseError(n)
+	}
+	*sp = append(*sp, int32(v))
+	out.n = n
+	return out, nil
+}
+
+var coderInt32Slice = pointerCoderFuncs{
+	size:      sizeInt32Slice,
+	marshal:   appendInt32Slice,
+	unmarshal: consumeInt32Slice,
+	merge:     mergeInt32Slice,
+}
+
+// sizeInt32PackedSlice returns the size of wire encoding a []int32 pointer as a packed repeated Int32.
+func sizeInt32PackedSlice(p pointer, f *coderFieldInfo, _ marshalOptions) (size int) {
+	s := *p.Int32Slice()
+	if len(s) == 0 {
+		return 0
+	}
+	n := 0
+	for _, v := range s {
+		n += protowire.SizeVarint(uint64(v))
+	}
+	return f.tagsize + protowire.SizeBytes(n)
+}
+
+// appendInt32PackedSlice encodes a []int32 pointer as a packed repeated Int32.
+func appendInt32PackedSlice(b []byte, p pointer, f *coderFieldInfo, _ marshalOptions) ([]byte, error) {
+	s := *p.Int32Slice()
+	if len(s) == 0 {
+		return b, nil
+	}
+	b = protowire.AppendVarint(b, f.wiretag)
+	n := 0
+	for _, v := range s {
+		n += protowire.SizeVarint(uint64(v))
+	}
+	b = protowire.AppendVarint(b, uint64(n))
+	for _, v := range s {
+		b = protowire.AppendVarint(b, uint64(v))
+	}
+	return b, nil
+}
+
+var coderInt32PackedSlice = pointerCoderFuncs{
+	size:      sizeInt32PackedSlice,
+	marshal:   appendInt32PackedSlice,
+	unmarshal: consumeInt32Slice,
+	merge:     mergeInt32Slice,
+}
+
+// sizeInt32Value returns the size of wire encoding a int32 value as a Int32.
+func sizeInt32Value(v protoreflect.Value, tagsize int, _ marshalOptions) int {
+	return tagsize + protowire.SizeVarint(uint64(int32(v.Int())))
+}
+
+// appendInt32Value encodes a int32 value as a Int32.
+func appendInt32Value(b []byte, v protoreflect.Value, wiretag uint64, _ marshalOptions) ([]byte, error) {
+	b = protowire.AppendVarint(b, wiretag)
+	b = protowire.AppendVarint(b, uint64(int32(v.Int())))
+	return b, nil
+}
+
+// consumeInt32Value decodes a int32 value as a Int32.
+func consumeInt32Value(b []byte, _ protoreflect.Value, _ protowire.Number, wtyp protowire.Type, _ unmarshalOptions) (_ protoreflect.Value, out unmarshalOutput, err error) {
+	if wtyp != protowire.VarintType {
+		return protoreflect.Value{}, out, errUnknown
+	}
+	var v uint64
+	var n int
+	if len(b) >= 1 && b[0] < 0x80 {
+		v = uint64(b[0])
+		n = 1
+	} else if len(b) >= 2 && b[1] < 128 {
+		v = uint64(b[0]&0x7f) + uint64(b[1])<<7
+		n = 2
+	} else {
+		v, n = protowire.ConsumeVarint(b)
+	}
+	if n < 0 {
+		return protoreflect.Value{}, out, protowire.ParseError(n)
+	}
+	out.n = n
+	return protoreflect.ValueOfInt32(int32(v)), out, nil
+}
+
+var coderInt32Value = valueCoderFuncs{
+	size:      sizeInt32Value,
+	marshal:   appendInt32Value,
+	unmarshal: consumeInt32Value,
+	merge:     mergeScalarValue,
+}
+
+// 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 + protowire.SizeVarint(uint64(int32(v.Int())))
+	}
+	return size
+}
+
+// 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 = protowire.AppendVarint(b, wiretag)
+		b = protowire.AppendVarint(b, uint64(int32(v.Int())))
+	}
+	return b, nil
+}
+
+// consumeInt32SliceValue wire decodes a []int32 value as a repeated Int32.
+func consumeInt32SliceValue(b []byte, listv protoreflect.Value, _ protowire.Number, wtyp protowire.Type, _ unmarshalOptions) (_ protoreflect.Value, out unmarshalOutput, err error) {
+	list := listv.List()
+	if wtyp == protowire.BytesType {
+		b, n := protowire.ConsumeBytes(b)
+		if n < 0 {
+			return protoreflect.Value{}, out, protowire.ParseError(n)
+		}
+		for len(b) > 0 {
+			var v uint64
+			var n int
+			if len(b) >= 1 && b[0] < 0x80 {
+				v = uint64(b[0])
+				n = 1
+			} else if len(b) >= 2 && b[1] < 128 {
+				v = uint64(b[0]&0x7f) + uint64(b[1])<<7
+				n = 2
+			} else {
+				v, n = protowire.ConsumeVarint(b)
+			}
+			if n < 0 {
+				return protoreflect.Value{}, out, protowire.ParseError(n)
+			}
+			list.Append(protoreflect.ValueOfInt32(int32(v)))
+			b = b[n:]
+		}
+		out.n = n
+		return listv, out, nil
+	}
+	if wtyp != protowire.VarintType {
+		return protoreflect.Value{}, out, errUnknown
+	}
+	var v uint64
+	var n int
+	if len(b) >= 1 && b[0] < 0x80 {
+		v = uint64(b[0])
+		n = 1
+	} else if len(b) >= 2 && b[1] < 128 {
+		v = uint64(b[0]&0x7f) + uint64(b[1])<<7
+		n = 2
+	} else {
+		v, n = protowire.ConsumeVarint(b)
+	}
+	if n < 0 {
+		return protoreflect.Value{}, out, protowire.ParseError(n)
+	}
+	list.Append(protoreflect.ValueOfInt32(int32(v)))
+	out.n = n
+	return listv, out, nil
+}
+
+var coderInt32SliceValue = valueCoderFuncs{
+	size:      sizeInt32SliceValue,
+	marshal:   appendInt32SliceValue,
+	unmarshal: consumeInt32SliceValue,
+	merge:     mergeListValue,
+}
+
+// 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()
+	llen := list.Len()
+	if llen == 0 {
+		return 0
+	}
+	n := 0
+	for i, llen := 0, llen; i < llen; i++ {
+		v := list.Get(i)
+		n += protowire.SizeVarint(uint64(int32(v.Int())))
+	}
+	return tagsize + protowire.SizeBytes(n)
+}
+
+// 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 = protowire.AppendVarint(b, wiretag)
+	n := 0
+	for i := 0; i < llen; i++ {
+		v := list.Get(i)
+		n += protowire.SizeVarint(uint64(int32(v.Int())))
+	}
+	b = protowire.AppendVarint(b, uint64(n))
+	for i := 0; i < llen; i++ {
+		v := list.Get(i)
+		b = protowire.AppendVarint(b, uint64(int32(v.Int())))
+	}
+	return b, nil
+}
+
+var coderInt32PackedSliceValue = valueCoderFuncs{
+	size:      sizeInt32PackedSliceValue,
+	marshal:   appendInt32PackedSliceValue,
+	unmarshal: consumeInt32SliceValue,
+	merge:     mergeListValue,
+}
+
+// sizeSint32 returns the size of wire encoding a int32 pointer as a Sint32.
+func sizeSint32(p pointer, f *coderFieldInfo, _ marshalOptions) (size int) {
+	v := *p.Int32()
+	return f.tagsize + protowire.SizeVarint(protowire.EncodeZigZag(int64(v)))
+}
+
+// appendSint32 wire encodes a int32 pointer as a Sint32.
+func appendSint32(b []byte, p pointer, f *coderFieldInfo, _ marshalOptions) ([]byte, error) {
+	v := *p.Int32()
+	b = protowire.AppendVarint(b, f.wiretag)
+	b = protowire.AppendVarint(b, protowire.EncodeZigZag(int64(v)))
+	return b, nil
+}
+
+// consumeSint32 wire decodes a int32 pointer as a Sint32.
+func consumeSint32(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, _ unmarshalOptions) (out unmarshalOutput, err error) {
+	if wtyp != protowire.VarintType {
+		return out, errUnknown
+	}
+	var v uint64
+	var n int
+	if len(b) >= 1 && b[0] < 0x80 {
+		v = uint64(b[0])
+		n = 1
+	} else if len(b) >= 2 && b[1] < 128 {
+		v = uint64(b[0]&0x7f) + uint64(b[1])<<7
+		n = 2
+	} else {
+		v, n = protowire.ConsumeVarint(b)
+	}
+	if n < 0 {
+		return out, protowire.ParseError(n)
+	}
+	*p.Int32() = int32(protowire.DecodeZigZag(v & math.MaxUint32))
+	out.n = n
+	return out, nil
+}
+
+var coderSint32 = pointerCoderFuncs{
+	size:      sizeSint32,
+	marshal:   appendSint32,
+	unmarshal: consumeSint32,
+	merge:     mergeInt32,
+}
+
+// sizeSint32NoZero returns the size of wire encoding a int32 pointer as a Sint32.
+// The zero value is not encoded.
+func sizeSint32NoZero(p pointer, f *coderFieldInfo, _ marshalOptions) (size int) {
+	v := *p.Int32()
+	if v == 0 {
+		return 0
+	}
+	return f.tagsize + protowire.SizeVarint(protowire.EncodeZigZag(int64(v)))
+}
+
+// appendSint32NoZero wire encodes a int32 pointer as a Sint32.
+// The zero value is not encoded.
+func appendSint32NoZero(b []byte, p pointer, f *coderFieldInfo, _ marshalOptions) ([]byte, error) {
+	v := *p.Int32()
+	if v == 0 {
+		return b, nil
+	}
+	b = protowire.AppendVarint(b, f.wiretag)
+	b = protowire.AppendVarint(b, protowire.EncodeZigZag(int64(v)))
+	return b, nil
+}
+
+var coderSint32NoZero = pointerCoderFuncs{
+	size:      sizeSint32NoZero,
+	marshal:   appendSint32NoZero,
+	unmarshal: consumeSint32,
+	merge:     mergeInt32NoZero,
+}
+
+// sizeSint32Ptr returns the size of wire encoding a *int32 pointer as a Sint32.
+// It panics if the pointer is nil.
+func sizeSint32Ptr(p pointer, f *coderFieldInfo, _ marshalOptions) (size int) {
+	v := **p.Int32Ptr()
+	return f.tagsize + protowire.SizeVarint(protowire.EncodeZigZag(int64(v)))
+}
+
+// appendSint32Ptr wire encodes a *int32 pointer as a Sint32.
+// It panics if the pointer is nil.
+func appendSint32Ptr(b []byte, p pointer, f *coderFieldInfo, _ marshalOptions) ([]byte, error) {
+	v := **p.Int32Ptr()
+	b = protowire.AppendVarint(b, f.wiretag)
+	b = protowire.AppendVarint(b, protowire.EncodeZigZag(int64(v)))
+	return b, nil
+}
+
+// consumeSint32Ptr wire decodes a *int32 pointer as a Sint32.
+func consumeSint32Ptr(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, _ unmarshalOptions) (out unmarshalOutput, err error) {
+	if wtyp != protowire.VarintType {
+		return out, errUnknown
+	}
+	var v uint64
+	var n int
+	if len(b) >= 1 && b[0] < 0x80 {
+		v = uint64(b[0])
+		n = 1
+	} else if len(b) >= 2 && b[1] < 128 {
+		v = uint64(b[0]&0x7f) + uint64(b[1])<<7
+		n = 2
+	} else {
+		v, n = protowire.ConsumeVarint(b)
+	}
+	if n < 0 {
+		return out, protowire.ParseError(n)
+	}
+	vp := p.Int32Ptr()
+	if *vp == nil {
+		*vp = new(int32)
+	}
+	**vp = int32(protowire.DecodeZigZag(v & math.MaxUint32))
+	out.n = n
+	return out, nil
+}
+
+var coderSint32Ptr = pointerCoderFuncs{
+	size:      sizeSint32Ptr,
+	marshal:   appendSint32Ptr,
+	unmarshal: consumeSint32Ptr,
+	merge:     mergeInt32Ptr,
+}
+
+// sizeSint32Slice returns the size of wire encoding a []int32 pointer as a repeated Sint32.
+func sizeSint32Slice(p pointer, f *coderFieldInfo, _ marshalOptions) (size int) {
+	s := *p.Int32Slice()
+	for _, v := range s {
+		size += f.tagsize + protowire.SizeVarint(protowire.EncodeZigZag(int64(v)))
+	}
+	return size
+}
+
+// appendSint32Slice encodes a []int32 pointer as a repeated Sint32.
+func appendSint32Slice(b []byte, p pointer, f *coderFieldInfo, _ marshalOptions) ([]byte, error) {
+	s := *p.Int32Slice()
+	for _, v := range s {
+		b = protowire.AppendVarint(b, f.wiretag)
+		b = protowire.AppendVarint(b, protowire.EncodeZigZag(int64(v)))
+	}
+	return b, nil
+}
+
+// consumeSint32Slice wire decodes a []int32 pointer as a repeated Sint32.
+func consumeSint32Slice(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, _ unmarshalOptions) (out unmarshalOutput, err error) {
+	sp := p.Int32Slice()
+	if wtyp == protowire.BytesType {
+		s := *sp
+		b, n := protowire.ConsumeBytes(b)
+		if n < 0 {
+			return out, protowire.ParseError(n)
+		}
+		for len(b) > 0 {
+			var v uint64
+			var n int
+			if len(b) >= 1 && b[0] < 0x80 {
+				v = uint64(b[0])
+				n = 1
+			} else if len(b) >= 2 && b[1] < 128 {
+				v = uint64(b[0]&0x7f) + uint64(b[1])<<7
+				n = 2
+			} else {
+				v, n = protowire.ConsumeVarint(b)
+			}
+			if n < 0 {
+				return out, protowire.ParseError(n)
+			}
+			s = append(s, int32(protowire.DecodeZigZag(v&math.MaxUint32)))
+			b = b[n:]
+		}
+		*sp = s
+		out.n = n
+		return out, nil
+	}
+	if wtyp != protowire.VarintType {
+		return out, errUnknown
+	}
+	var v uint64
+	var n int
+	if len(b) >= 1 && b[0] < 0x80 {
+		v = uint64(b[0])
+		n = 1
+	} else if len(b) >= 2 && b[1] < 128 {
+		v = uint64(b[0]&0x7f) + uint64(b[1])<<7
+		n = 2
+	} else {
+		v, n = protowire.ConsumeVarint(b)
+	}
+	if n < 0 {
+		return out, protowire.ParseError(n)
+	}
+	*sp = append(*sp, int32(protowire.DecodeZigZag(v&math.MaxUint32)))
+	out.n = n
+	return out, nil
+}
+
+var coderSint32Slice = pointerCoderFuncs{
+	size:      sizeSint32Slice,
+	marshal:   appendSint32Slice,
+	unmarshal: consumeSint32Slice,
+	merge:     mergeInt32Slice,
+}
+
+// sizeSint32PackedSlice returns the size of wire encoding a []int32 pointer as a packed repeated Sint32.
+func sizeSint32PackedSlice(p pointer, f *coderFieldInfo, _ marshalOptions) (size int) {
+	s := *p.Int32Slice()
+	if len(s) == 0 {
+		return 0
+	}
+	n := 0
+	for _, v := range s {
+		n += protowire.SizeVarint(protowire.EncodeZigZag(int64(v)))
+	}
+	return f.tagsize + protowire.SizeBytes(n)
+}
+
+// appendSint32PackedSlice encodes a []int32 pointer as a packed repeated Sint32.
+func appendSint32PackedSlice(b []byte, p pointer, f *coderFieldInfo, _ marshalOptions) ([]byte, error) {
+	s := *p.Int32Slice()
+	if len(s) == 0 {
+		return b, nil
+	}
+	b = protowire.AppendVarint(b, f.wiretag)
+	n := 0
+	for _, v := range s {
+		n += protowire.SizeVarint(protowire.EncodeZigZag(int64(v)))
+	}
+	b = protowire.AppendVarint(b, uint64(n))
+	for _, v := range s {
+		b = protowire.AppendVarint(b, protowire.EncodeZigZag(int64(v)))
+	}
+	return b, nil
+}
+
+var coderSint32PackedSlice = pointerCoderFuncs{
+	size:      sizeSint32PackedSlice,
+	marshal:   appendSint32PackedSlice,
+	unmarshal: consumeSint32Slice,
+	merge:     mergeInt32Slice,
+}
+
+// sizeSint32Value returns the size of wire encoding a int32 value as a Sint32.
+func sizeSint32Value(v protoreflect.Value, tagsize int, _ marshalOptions) int {
+	return tagsize + protowire.SizeVarint(protowire.EncodeZigZag(int64(int32(v.Int()))))
+}
+
+// appendSint32Value encodes a int32 value as a Sint32.
+func appendSint32Value(b []byte, v protoreflect.Value, wiretag uint64, _ marshalOptions) ([]byte, error) {
+	b = protowire.AppendVarint(b, wiretag)
+	b = protowire.AppendVarint(b, protowire.EncodeZigZag(int64(int32(v.Int()))))
+	return b, nil
+}
+
+// consumeSint32Value decodes a int32 value as a Sint32.
+func consumeSint32Value(b []byte, _ protoreflect.Value, _ protowire.Number, wtyp protowire.Type, _ unmarshalOptions) (_ protoreflect.Value, out unmarshalOutput, err error) {
+	if wtyp != protowire.VarintType {
+		return protoreflect.Value{}, out, errUnknown
+	}
+	var v uint64
+	var n int
+	if len(b) >= 1 && b[0] < 0x80 {
+		v = uint64(b[0])
+		n = 1
+	} else if len(b) >= 2 && b[1] < 128 {
+		v = uint64(b[0]&0x7f) + uint64(b[1])<<7
+		n = 2
+	} else {
+		v, n = protowire.ConsumeVarint(b)
+	}
+	if n < 0 {
+		return protoreflect.Value{}, out, protowire.ParseError(n)
+	}
+	out.n = n
+	return protoreflect.ValueOfInt32(int32(protowire.DecodeZigZag(v & math.MaxUint32))), out, nil
+}
+
+var coderSint32Value = valueCoderFuncs{
+	size:      sizeSint32Value,
+	marshal:   appendSint32Value,
+	unmarshal: consumeSint32Value,
+	merge:     mergeScalarValue,
+}
+
+// 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 + protowire.SizeVarint(protowire.EncodeZigZag(int64(int32(v.Int()))))
+	}
+	return size
+}
+
+// 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 = protowire.AppendVarint(b, wiretag)
+		b = protowire.AppendVarint(b, protowire.EncodeZigZag(int64(int32(v.Int()))))
+	}
+	return b, nil
+}
+
+// consumeSint32SliceValue wire decodes a []int32 value as a repeated Sint32.
+func consumeSint32SliceValue(b []byte, listv protoreflect.Value, _ protowire.Number, wtyp protowire.Type, _ unmarshalOptions) (_ protoreflect.Value, out unmarshalOutput, err error) {
+	list := listv.List()
+	if wtyp == protowire.BytesType {
+		b, n := protowire.ConsumeBytes(b)
+		if n < 0 {
+			return protoreflect.Value{}, out, protowire.ParseError(n)
+		}
+		for len(b) > 0 {
+			var v uint64
+			var n int
+			if len(b) >= 1 && b[0] < 0x80 {
+				v = uint64(b[0])
+				n = 1
+			} else if len(b) >= 2 && b[1] < 128 {
+				v = uint64(b[0]&0x7f) + uint64(b[1])<<7
+				n = 2
+			} else {
+				v, n = protowire.ConsumeVarint(b)
+			}
+			if n < 0 {
+				return protoreflect.Value{}, out, protowire.ParseError(n)
+			}
+			list.Append(protoreflect.ValueOfInt32(int32(protowire.DecodeZigZag(v & math.MaxUint32))))
+			b = b[n:]
+		}
+		out.n = n
+		return listv, out, nil
+	}
+	if wtyp != protowire.VarintType {
+		return protoreflect.Value{}, out, errUnknown
+	}
+	var v uint64
+	var n int
+	if len(b) >= 1 && b[0] < 0x80 {
+		v = uint64(b[0])
+		n = 1
+	} else if len(b) >= 2 && b[1] < 128 {
+		v = uint64(b[0]&0x7f) + uint64(b[1])<<7
+		n = 2
+	} else {
+		v, n = protowire.ConsumeVarint(b)
+	}
+	if n < 0 {
+		return protoreflect.Value{}, out, protowire.ParseError(n)
+	}
+	list.Append(protoreflect.ValueOfInt32(int32(protowire.DecodeZigZag(v & math.MaxUint32))))
+	out.n = n
+	return listv, out, nil
+}
+
+var coderSint32SliceValue = valueCoderFuncs{
+	size:      sizeSint32SliceValue,
+	marshal:   appendSint32SliceValue,
+	unmarshal: consumeSint32SliceValue,
+	merge:     mergeListValue,
+}
+
+// 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()
+	llen := list.Len()
+	if llen == 0 {
+		return 0
+	}
+	n := 0
+	for i, llen := 0, llen; i < llen; i++ {
+		v := list.Get(i)
+		n += protowire.SizeVarint(protowire.EncodeZigZag(int64(int32(v.Int()))))
+	}
+	return tagsize + protowire.SizeBytes(n)
+}
+
+// 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 = protowire.AppendVarint(b, wiretag)
+	n := 0
+	for i := 0; i < llen; i++ {
+		v := list.Get(i)
+		n += protowire.SizeVarint(protowire.EncodeZigZag(int64(int32(v.Int()))))
+	}
+	b = protowire.AppendVarint(b, uint64(n))
+	for i := 0; i < llen; i++ {
+		v := list.Get(i)
+		b = protowire.AppendVarint(b, protowire.EncodeZigZag(int64(int32(v.Int()))))
+	}
+	return b, nil
+}
+
+var coderSint32PackedSliceValue = valueCoderFuncs{
+	size:      sizeSint32PackedSliceValue,
+	marshal:   appendSint32PackedSliceValue,
+	unmarshal: consumeSint32SliceValue,
+	merge:     mergeListValue,
+}
+
+// sizeUint32 returns the size of wire encoding a uint32 pointer as a Uint32.
+func sizeUint32(p pointer, f *coderFieldInfo, _ marshalOptions) (size int) {
+	v := *p.Uint32()
+	return f.tagsize + protowire.SizeVarint(uint64(v))
+}
+
+// appendUint32 wire encodes a uint32 pointer as a Uint32.
+func appendUint32(b []byte, p pointer, f *coderFieldInfo, _ marshalOptions) ([]byte, error) {
+	v := *p.Uint32()
+	b = protowire.AppendVarint(b, f.wiretag)
+	b = protowire.AppendVarint(b, uint64(v))
+	return b, nil
+}
+
+// consumeUint32 wire decodes a uint32 pointer as a Uint32.
+func consumeUint32(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, _ unmarshalOptions) (out unmarshalOutput, err error) {
+	if wtyp != protowire.VarintType {
+		return out, errUnknown
+	}
+	var v uint64
+	var n int
+	if len(b) >= 1 && b[0] < 0x80 {
+		v = uint64(b[0])
+		n = 1
+	} else if len(b) >= 2 && b[1] < 128 {
+		v = uint64(b[0]&0x7f) + uint64(b[1])<<7
+		n = 2
+	} else {
+		v, n = protowire.ConsumeVarint(b)
+	}
+	if n < 0 {
+		return out, protowire.ParseError(n)
+	}
+	*p.Uint32() = uint32(v)
+	out.n = n
+	return out, nil
+}
+
+var coderUint32 = pointerCoderFuncs{
+	size:      sizeUint32,
+	marshal:   appendUint32,
+	unmarshal: consumeUint32,
+	merge:     mergeUint32,
+}
+
+// sizeUint32NoZero returns the size of wire encoding a uint32 pointer as a Uint32.
+// The zero value is not encoded.
+func sizeUint32NoZero(p pointer, f *coderFieldInfo, _ marshalOptions) (size int) {
+	v := *p.Uint32()
+	if v == 0 {
+		return 0
+	}
+	return f.tagsize + protowire.SizeVarint(uint64(v))
+}
+
+// appendUint32NoZero wire encodes a uint32 pointer as a Uint32.
+// The zero value is not encoded.
+func appendUint32NoZero(b []byte, p pointer, f *coderFieldInfo, _ marshalOptions) ([]byte, error) {
+	v := *p.Uint32()
+	if v == 0 {
+		return b, nil
+	}
+	b = protowire.AppendVarint(b, f.wiretag)
+	b = protowire.AppendVarint(b, uint64(v))
+	return b, nil
+}
+
+var coderUint32NoZero = pointerCoderFuncs{
+	size:      sizeUint32NoZero,
+	marshal:   appendUint32NoZero,
+	unmarshal: consumeUint32,
+	merge:     mergeUint32NoZero,
+}
+
+// sizeUint32Ptr returns the size of wire encoding a *uint32 pointer as a Uint32.
+// It panics if the pointer is nil.
+func sizeUint32Ptr(p pointer, f *coderFieldInfo, _ marshalOptions) (size int) {
+	v := **p.Uint32Ptr()
+	return f.tagsize + protowire.SizeVarint(uint64(v))
+}
+
+// appendUint32Ptr wire encodes a *uint32 pointer as a Uint32.
+// It panics if the pointer is nil.
+func appendUint32Ptr(b []byte, p pointer, f *coderFieldInfo, _ marshalOptions) ([]byte, error) {
+	v := **p.Uint32Ptr()
+	b = protowire.AppendVarint(b, f.wiretag)
+	b = protowire.AppendVarint(b, uint64(v))
+	return b, nil
+}
+
+// consumeUint32Ptr wire decodes a *uint32 pointer as a Uint32.
+func consumeUint32Ptr(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, _ unmarshalOptions) (out unmarshalOutput, err error) {
+	if wtyp != protowire.VarintType {
+		return out, errUnknown
+	}
+	var v uint64
+	var n int
+	if len(b) >= 1 && b[0] < 0x80 {
+		v = uint64(b[0])
+		n = 1
+	} else if len(b) >= 2 && b[1] < 128 {
+		v = uint64(b[0]&0x7f) + uint64(b[1])<<7
+		n = 2
+	} else {
+		v, n = protowire.ConsumeVarint(b)
+	}
+	if n < 0 {
+		return out, protowire.ParseError(n)
+	}
+	vp := p.Uint32Ptr()
+	if *vp == nil {
+		*vp = new(uint32)
+	}
+	**vp = uint32(v)
+	out.n = n
+	return out, nil
+}
+
+var coderUint32Ptr = pointerCoderFuncs{
+	size:      sizeUint32Ptr,
+	marshal:   appendUint32Ptr,
+	unmarshal: consumeUint32Ptr,
+	merge:     mergeUint32Ptr,
+}
+
+// sizeUint32Slice returns the size of wire encoding a []uint32 pointer as a repeated Uint32.
+func sizeUint32Slice(p pointer, f *coderFieldInfo, _ marshalOptions) (size int) {
+	s := *p.Uint32Slice()
+	for _, v := range s {
+		size += f.tagsize + protowire.SizeVarint(uint64(v))
+	}
+	return size
+}
+
+// appendUint32Slice encodes a []uint32 pointer as a repeated Uint32.
+func appendUint32Slice(b []byte, p pointer, f *coderFieldInfo, _ marshalOptions) ([]byte, error) {
+	s := *p.Uint32Slice()
+	for _, v := range s {
+		b = protowire.AppendVarint(b, f.wiretag)
+		b = protowire.AppendVarint(b, uint64(v))
+	}
+	return b, nil
+}
+
+// consumeUint32Slice wire decodes a []uint32 pointer as a repeated Uint32.
+func consumeUint32Slice(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, _ unmarshalOptions) (out unmarshalOutput, err error) {
+	sp := p.Uint32Slice()
+	if wtyp == protowire.BytesType {
+		s := *sp
+		b, n := protowire.ConsumeBytes(b)
+		if n < 0 {
+			return out, protowire.ParseError(n)
+		}
+		for len(b) > 0 {
+			var v uint64
+			var n int
+			if len(b) >= 1 && b[0] < 0x80 {
+				v = uint64(b[0])
+				n = 1
+			} else if len(b) >= 2 && b[1] < 128 {
+				v = uint64(b[0]&0x7f) + uint64(b[1])<<7
+				n = 2
+			} else {
+				v, n = protowire.ConsumeVarint(b)
+			}
+			if n < 0 {
+				return out, protowire.ParseError(n)
+			}
+			s = append(s, uint32(v))
+			b = b[n:]
+		}
+		*sp = s
+		out.n = n
+		return out, nil
+	}
+	if wtyp != protowire.VarintType {
+		return out, errUnknown
+	}
+	var v uint64
+	var n int
+	if len(b) >= 1 && b[0] < 0x80 {
+		v = uint64(b[0])
+		n = 1
+	} else if len(b) >= 2 && b[1] < 128 {
+		v = uint64(b[0]&0x7f) + uint64(b[1])<<7
+		n = 2
+	} else {
+		v, n = protowire.ConsumeVarint(b)
+	}
+	if n < 0 {
+		return out, protowire.ParseError(n)
+	}
+	*sp = append(*sp, uint32(v))
+	out.n = n
+	return out, nil
+}
+
+var coderUint32Slice = pointerCoderFuncs{
+	size:      sizeUint32Slice,
+	marshal:   appendUint32Slice,
+	unmarshal: consumeUint32Slice,
+	merge:     mergeUint32Slice,
+}
+
+// sizeUint32PackedSlice returns the size of wire encoding a []uint32 pointer as a packed repeated Uint32.
+func sizeUint32PackedSlice(p pointer, f *coderFieldInfo, _ marshalOptions) (size int) {
+	s := *p.Uint32Slice()
+	if len(s) == 0 {
+		return 0
+	}
+	n := 0
+	for _, v := range s {
+		n += protowire.SizeVarint(uint64(v))
+	}
+	return f.tagsize + protowire.SizeBytes(n)
+}
+
+// appendUint32PackedSlice encodes a []uint32 pointer as a packed repeated Uint32.
+func appendUint32PackedSlice(b []byte, p pointer, f *coderFieldInfo, _ marshalOptions) ([]byte, error) {
+	s := *p.Uint32Slice()
+	if len(s) == 0 {
+		return b, nil
+	}
+	b = protowire.AppendVarint(b, f.wiretag)
+	n := 0
+	for _, v := range s {
+		n += protowire.SizeVarint(uint64(v))
+	}
+	b = protowire.AppendVarint(b, uint64(n))
+	for _, v := range s {
+		b = protowire.AppendVarint(b, uint64(v))
+	}
+	return b, nil
+}
+
+var coderUint32PackedSlice = pointerCoderFuncs{
+	size:      sizeUint32PackedSlice,
+	marshal:   appendUint32PackedSlice,
+	unmarshal: consumeUint32Slice,
+	merge:     mergeUint32Slice,
+}
+
+// sizeUint32Value returns the size of wire encoding a uint32 value as a Uint32.
+func sizeUint32Value(v protoreflect.Value, tagsize int, _ marshalOptions) int {
+	return tagsize + protowire.SizeVarint(uint64(uint32(v.Uint())))
+}
+
+// appendUint32Value encodes a uint32 value as a Uint32.
+func appendUint32Value(b []byte, v protoreflect.Value, wiretag uint64, _ marshalOptions) ([]byte, error) {
+	b = protowire.AppendVarint(b, wiretag)
+	b = protowire.AppendVarint(b, uint64(uint32(v.Uint())))
+	return b, nil
+}
+
+// consumeUint32Value decodes a uint32 value as a Uint32.
+func consumeUint32Value(b []byte, _ protoreflect.Value, _ protowire.Number, wtyp protowire.Type, _ unmarshalOptions) (_ protoreflect.Value, out unmarshalOutput, err error) {
+	if wtyp != protowire.VarintType {
+		return protoreflect.Value{}, out, errUnknown
+	}
+	var v uint64
+	var n int
+	if len(b) >= 1 && b[0] < 0x80 {
+		v = uint64(b[0])
+		n = 1
+	} else if len(b) >= 2 && b[1] < 128 {
+		v = uint64(b[0]&0x7f) + uint64(b[1])<<7
+		n = 2
+	} else {
+		v, n = protowire.ConsumeVarint(b)
+	}
+	if n < 0 {
+		return protoreflect.Value{}, out, protowire.ParseError(n)
+	}
+	out.n = n
+	return protoreflect.ValueOfUint32(uint32(v)), out, nil
+}
+
+var coderUint32Value = valueCoderFuncs{
+	size:      sizeUint32Value,
+	marshal:   appendUint32Value,
+	unmarshal: consumeUint32Value,
+	merge:     mergeScalarValue,
+}
+
+// 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 + protowire.SizeVarint(uint64(uint32(v.Uint())))
+	}
+	return size
+}
+
+// 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 = protowire.AppendVarint(b, wiretag)
+		b = protowire.AppendVarint(b, uint64(uint32(v.Uint())))
+	}
+	return b, nil
+}
+
+// consumeUint32SliceValue wire decodes a []uint32 value as a repeated Uint32.
+func consumeUint32SliceValue(b []byte, listv protoreflect.Value, _ protowire.Number, wtyp protowire.Type, _ unmarshalOptions) (_ protoreflect.Value, out unmarshalOutput, err error) {
+	list := listv.List()
+	if wtyp == protowire.BytesType {
+		b, n := protowire.ConsumeBytes(b)
+		if n < 0 {
+			return protoreflect.Value{}, out, protowire.ParseError(n)
+		}
+		for len(b) > 0 {
+			var v uint64
+			var n int
+			if len(b) >= 1 && b[0] < 0x80 {
+				v = uint64(b[0])
+				n = 1
+			} else if len(b) >= 2 && b[1] < 128 {
+				v = uint64(b[0]&0x7f) + uint64(b[1])<<7
+				n = 2
+			} else {
+				v, n = protowire.ConsumeVarint(b)
+			}
+			if n < 0 {
+				return protoreflect.Value{}, out, protowire.ParseError(n)
+			}
+			list.Append(protoreflect.ValueOfUint32(uint32(v)))
+			b = b[n:]
+		}
+		out.n = n
+		return listv, out, nil
+	}
+	if wtyp != protowire.VarintType {
+		return protoreflect.Value{}, out, errUnknown
+	}
+	var v uint64
+	var n int
+	if len(b) >= 1 && b[0] < 0x80 {
+		v = uint64(b[0])
+		n = 1
+	} else if len(b) >= 2 && b[1] < 128 {
+		v = uint64(b[0]&0x7f) + uint64(b[1])<<7
+		n = 2
+	} else {
+		v, n = protowire.ConsumeVarint(b)
+	}
+	if n < 0 {
+		return protoreflect.Value{}, out, protowire.ParseError(n)
+	}
+	list.Append(protoreflect.ValueOfUint32(uint32(v)))
+	out.n = n
+	return listv, out, nil
+}
+
+var coderUint32SliceValue = valueCoderFuncs{
+	size:      sizeUint32SliceValue,
+	marshal:   appendUint32SliceValue,
+	unmarshal: consumeUint32SliceValue,
+	merge:     mergeListValue,
+}
+
+// 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()
+	llen := list.Len()
+	if llen == 0 {
+		return 0
+	}
+	n := 0
+	for i, llen := 0, llen; i < llen; i++ {
+		v := list.Get(i)
+		n += protowire.SizeVarint(uint64(uint32(v.Uint())))
+	}
+	return tagsize + protowire.SizeBytes(n)
+}
+
+// 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 = protowire.AppendVarint(b, wiretag)
+	n := 0
+	for i := 0; i < llen; i++ {
+		v := list.Get(i)
+		n += protowire.SizeVarint(uint64(uint32(v.Uint())))
+	}
+	b = protowire.AppendVarint(b, uint64(n))
+	for i := 0; i < llen; i++ {
+		v := list.Get(i)
+		b = protowire.AppendVarint(b, uint64(uint32(v.Uint())))
+	}
+	return b, nil
+}
+
+var coderUint32PackedSliceValue = valueCoderFuncs{
+	size:      sizeUint32PackedSliceValue,
+	marshal:   appendUint32PackedSliceValue,
+	unmarshal: consumeUint32SliceValue,
+	merge:     mergeListValue,
+}
+
+// sizeInt64 returns the size of wire encoding a int64 pointer as a Int64.
+func sizeInt64(p pointer, f *coderFieldInfo, _ marshalOptions) (size int) {
+	v := *p.Int64()
+	return f.tagsize + protowire.SizeVarint(uint64(v))
+}
+
+// appendInt64 wire encodes a int64 pointer as a Int64.
+func appendInt64(b []byte, p pointer, f *coderFieldInfo, _ marshalOptions) ([]byte, error) {
+	v := *p.Int64()
+	b = protowire.AppendVarint(b, f.wiretag)
+	b = protowire.AppendVarint(b, uint64(v))
+	return b, nil
+}
+
+// consumeInt64 wire decodes a int64 pointer as a Int64.
+func consumeInt64(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, _ unmarshalOptions) (out unmarshalOutput, err error) {
+	if wtyp != protowire.VarintType {
+		return out, errUnknown
+	}
+	var v uint64
+	var n int
+	if len(b) >= 1 && b[0] < 0x80 {
+		v = uint64(b[0])
+		n = 1
+	} else if len(b) >= 2 && b[1] < 128 {
+		v = uint64(b[0]&0x7f) + uint64(b[1])<<7
+		n = 2
+	} else {
+		v, n = protowire.ConsumeVarint(b)
+	}
+	if n < 0 {
+		return out, protowire.ParseError(n)
+	}
+	*p.Int64() = int64(v)
+	out.n = n
+	return out, nil
+}
+
+var coderInt64 = pointerCoderFuncs{
+	size:      sizeInt64,
+	marshal:   appendInt64,
+	unmarshal: consumeInt64,
+	merge:     mergeInt64,
+}
+
+// sizeInt64NoZero returns the size of wire encoding a int64 pointer as a Int64.
+// The zero value is not encoded.
+func sizeInt64NoZero(p pointer, f *coderFieldInfo, _ marshalOptions) (size int) {
+	v := *p.Int64()
+	if v == 0 {
+		return 0
+	}
+	return f.tagsize + protowire.SizeVarint(uint64(v))
+}
+
+// appendInt64NoZero wire encodes a int64 pointer as a Int64.
+// The zero value is not encoded.
+func appendInt64NoZero(b []byte, p pointer, f *coderFieldInfo, _ marshalOptions) ([]byte, error) {
+	v := *p.Int64()
+	if v == 0 {
+		return b, nil
+	}
+	b = protowire.AppendVarint(b, f.wiretag)
+	b = protowire.AppendVarint(b, uint64(v))
+	return b, nil
+}
+
+var coderInt64NoZero = pointerCoderFuncs{
+	size:      sizeInt64NoZero,
+	marshal:   appendInt64NoZero,
+	unmarshal: consumeInt64,
+	merge:     mergeInt64NoZero,
+}
+
+// sizeInt64Ptr returns the size of wire encoding a *int64 pointer as a Int64.
+// It panics if the pointer is nil.
+func sizeInt64Ptr(p pointer, f *coderFieldInfo, _ marshalOptions) (size int) {
+	v := **p.Int64Ptr()
+	return f.tagsize + protowire.SizeVarint(uint64(v))
+}
+
+// appendInt64Ptr wire encodes a *int64 pointer as a Int64.
+// It panics if the pointer is nil.
+func appendInt64Ptr(b []byte, p pointer, f *coderFieldInfo, _ marshalOptions) ([]byte, error) {
+	v := **p.Int64Ptr()
+	b = protowire.AppendVarint(b, f.wiretag)
+	b = protowire.AppendVarint(b, uint64(v))
+	return b, nil
+}
+
+// consumeInt64Ptr wire decodes a *int64 pointer as a Int64.
+func consumeInt64Ptr(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, _ unmarshalOptions) (out unmarshalOutput, err error) {
+	if wtyp != protowire.VarintType {
+		return out, errUnknown
+	}
+	var v uint64
+	var n int
+	if len(b) >= 1 && b[0] < 0x80 {
+		v = uint64(b[0])
+		n = 1
+	} else if len(b) >= 2 && b[1] < 128 {
+		v = uint64(b[0]&0x7f) + uint64(b[1])<<7
+		n = 2
+	} else {
+		v, n = protowire.ConsumeVarint(b)
+	}
+	if n < 0 {
+		return out, protowire.ParseError(n)
+	}
+	vp := p.Int64Ptr()
+	if *vp == nil {
+		*vp = new(int64)
+	}
+	**vp = int64(v)
+	out.n = n
+	return out, nil
+}
+
+var coderInt64Ptr = pointerCoderFuncs{
+	size:      sizeInt64Ptr,
+	marshal:   appendInt64Ptr,
+	unmarshal: consumeInt64Ptr,
+	merge:     mergeInt64Ptr,
+}
+
+// sizeInt64Slice returns the size of wire encoding a []int64 pointer as a repeated Int64.
+func sizeInt64Slice(p pointer, f *coderFieldInfo, _ marshalOptions) (size int) {
+	s := *p.Int64Slice()
+	for _, v := range s {
+		size += f.tagsize + protowire.SizeVarint(uint64(v))
+	}
+	return size
+}
+
+// appendInt64Slice encodes a []int64 pointer as a repeated Int64.
+func appendInt64Slice(b []byte, p pointer, f *coderFieldInfo, _ marshalOptions) ([]byte, error) {
+	s := *p.Int64Slice()
+	for _, v := range s {
+		b = protowire.AppendVarint(b, f.wiretag)
+		b = protowire.AppendVarint(b, uint64(v))
+	}
+	return b, nil
+}
+
+// consumeInt64Slice wire decodes a []int64 pointer as a repeated Int64.
+func consumeInt64Slice(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, _ unmarshalOptions) (out unmarshalOutput, err error) {
+	sp := p.Int64Slice()
+	if wtyp == protowire.BytesType {
+		s := *sp
+		b, n := protowire.ConsumeBytes(b)
+		if n < 0 {
+			return out, protowire.ParseError(n)
+		}
+		for len(b) > 0 {
+			var v uint64
+			var n int
+			if len(b) >= 1 && b[0] < 0x80 {
+				v = uint64(b[0])
+				n = 1
+			} else if len(b) >= 2 && b[1] < 128 {
+				v = uint64(b[0]&0x7f) + uint64(b[1])<<7
+				n = 2
+			} else {
+				v, n = protowire.ConsumeVarint(b)
+			}
+			if n < 0 {
+				return out, protowire.ParseError(n)
+			}
+			s = append(s, int64(v))
+			b = b[n:]
+		}
+		*sp = s
+		out.n = n
+		return out, nil
+	}
+	if wtyp != protowire.VarintType {
+		return out, errUnknown
+	}
+	var v uint64
+	var n int
+	if len(b) >= 1 && b[0] < 0x80 {
+		v = uint64(b[0])
+		n = 1
+	} else if len(b) >= 2 && b[1] < 128 {
+		v = uint64(b[0]&0x7f) + uint64(b[1])<<7
+		n = 2
+	} else {
+		v, n = protowire.ConsumeVarint(b)
+	}
+	if n < 0 {
+		return out, protowire.ParseError(n)
+	}
+	*sp = append(*sp, int64(v))
+	out.n = n
+	return out, nil
+}
+
+var coderInt64Slice = pointerCoderFuncs{
+	size:      sizeInt64Slice,
+	marshal:   appendInt64Slice,
+	unmarshal: consumeInt64Slice,
+	merge:     mergeInt64Slice,
+}
+
+// sizeInt64PackedSlice returns the size of wire encoding a []int64 pointer as a packed repeated Int64.
+func sizeInt64PackedSlice(p pointer, f *coderFieldInfo, _ marshalOptions) (size int) {
+	s := *p.Int64Slice()
+	if len(s) == 0 {
+		return 0
+	}
+	n := 0
+	for _, v := range s {
+		n += protowire.SizeVarint(uint64(v))
+	}
+	return f.tagsize + protowire.SizeBytes(n)
+}
+
+// appendInt64PackedSlice encodes a []int64 pointer as a packed repeated Int64.
+func appendInt64PackedSlice(b []byte, p pointer, f *coderFieldInfo, _ marshalOptions) ([]byte, error) {
+	s := *p.Int64Slice()
+	if len(s) == 0 {
+		return b, nil
+	}
+	b = protowire.AppendVarint(b, f.wiretag)
+	n := 0
+	for _, v := range s {
+		n += protowire.SizeVarint(uint64(v))
+	}
+	b = protowire.AppendVarint(b, uint64(n))
+	for _, v := range s {
+		b = protowire.AppendVarint(b, uint64(v))
+	}
+	return b, nil
+}
+
+var coderInt64PackedSlice = pointerCoderFuncs{
+	size:      sizeInt64PackedSlice,
+	marshal:   appendInt64PackedSlice,
+	unmarshal: consumeInt64Slice,
+	merge:     mergeInt64Slice,
+}
+
+// sizeInt64Value returns the size of wire encoding a int64 value as a Int64.
+func sizeInt64Value(v protoreflect.Value, tagsize int, _ marshalOptions) int {
+	return tagsize + protowire.SizeVarint(uint64(v.Int()))
+}
+
+// appendInt64Value encodes a int64 value as a Int64.
+func appendInt64Value(b []byte, v protoreflect.Value, wiretag uint64, _ marshalOptions) ([]byte, error) {
+	b = protowire.AppendVarint(b, wiretag)
+	b = protowire.AppendVarint(b, uint64(v.Int()))
+	return b, nil
+}
+
+// consumeInt64Value decodes a int64 value as a Int64.
+func consumeInt64Value(b []byte, _ protoreflect.Value, _ protowire.Number, wtyp protowire.Type, _ unmarshalOptions) (_ protoreflect.Value, out unmarshalOutput, err error) {
+	if wtyp != protowire.VarintType {
+		return protoreflect.Value{}, out, errUnknown
+	}
+	var v uint64
+	var n int
+	if len(b) >= 1 && b[0] < 0x80 {
+		v = uint64(b[0])
+		n = 1
+	} else if len(b) >= 2 && b[1] < 128 {
+		v = uint64(b[0]&0x7f) + uint64(b[1])<<7
+		n = 2
+	} else {
+		v, n = protowire.ConsumeVarint(b)
+	}
+	if n < 0 {
+		return protoreflect.Value{}, out, protowire.ParseError(n)
+	}
+	out.n = n
+	return protoreflect.ValueOfInt64(int64(v)), out, nil
+}
+
+var coderInt64Value = valueCoderFuncs{
+	size:      sizeInt64Value,
+	marshal:   appendInt64Value,
+	unmarshal: consumeInt64Value,
+	merge:     mergeScalarValue,
+}
+
+// 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 + protowire.SizeVarint(uint64(v.Int()))
+	}
+	return size
+}
+
+// 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 = protowire.AppendVarint(b, wiretag)
+		b = protowire.AppendVarint(b, uint64(v.Int()))
+	}
+	return b, nil
+}
+
+// consumeInt64SliceValue wire decodes a []int64 value as a repeated Int64.
+func consumeInt64SliceValue(b []byte, listv protoreflect.Value, _ protowire.Number, wtyp protowire.Type, _ unmarshalOptions) (_ protoreflect.Value, out unmarshalOutput, err error) {
+	list := listv.List()
+	if wtyp == protowire.BytesType {
+		b, n := protowire.ConsumeBytes(b)
+		if n < 0 {
+			return protoreflect.Value{}, out, protowire.ParseError(n)
+		}
+		for len(b) > 0 {
+			var v uint64
+			var n int
+			if len(b) >= 1 && b[0] < 0x80 {
+				v = uint64(b[0])
+				n = 1
+			} else if len(b) >= 2 && b[1] < 128 {
+				v = uint64(b[0]&0x7f) + uint64(b[1])<<7
+				n = 2
+			} else {
+				v, n = protowire.ConsumeVarint(b)
+			}
+			if n < 0 {
+				return protoreflect.Value{}, out, protowire.ParseError(n)
+			}
+			list.Append(protoreflect.ValueOfInt64(int64(v)))
+			b = b[n:]
+		}
+		out.n = n
+		return listv, out, nil
+	}
+	if wtyp != protowire.VarintType {
+		return protoreflect.Value{}, out, errUnknown
+	}
+	var v uint64
+	var n int
+	if len(b) >= 1 && b[0] < 0x80 {
+		v = uint64(b[0])
+		n = 1
+	} else if len(b) >= 2 && b[1] < 128 {
+		v = uint64(b[0]&0x7f) + uint64(b[1])<<7
+		n = 2
+	} else {
+		v, n = protowire.ConsumeVarint(b)
+	}
+	if n < 0 {
+		return protoreflect.Value{}, out, protowire.ParseError(n)
+	}
+	list.Append(protoreflect.ValueOfInt64(int64(v)))
+	out.n = n
+	return listv, out, nil
+}
+
+var coderInt64SliceValue = valueCoderFuncs{
+	size:      sizeInt64SliceValue,
+	marshal:   appendInt64SliceValue,
+	unmarshal: consumeInt64SliceValue,
+	merge:     mergeListValue,
+}
+
+// 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()
+	llen := list.Len()
+	if llen == 0 {
+		return 0
+	}
+	n := 0
+	for i, llen := 0, llen; i < llen; i++ {
+		v := list.Get(i)
+		n += protowire.SizeVarint(uint64(v.Int()))
+	}
+	return tagsize + protowire.SizeBytes(n)
+}
+
+// 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 = protowire.AppendVarint(b, wiretag)
+	n := 0
+	for i := 0; i < llen; i++ {
+		v := list.Get(i)
+		n += protowire.SizeVarint(uint64(v.Int()))
+	}
+	b = protowire.AppendVarint(b, uint64(n))
+	for i := 0; i < llen; i++ {
+		v := list.Get(i)
+		b = protowire.AppendVarint(b, uint64(v.Int()))
+	}
+	return b, nil
+}
+
+var coderInt64PackedSliceValue = valueCoderFuncs{
+	size:      sizeInt64PackedSliceValue,
+	marshal:   appendInt64PackedSliceValue,
+	unmarshal: consumeInt64SliceValue,
+	merge:     mergeListValue,
+}
+
+// sizeSint64 returns the size of wire encoding a int64 pointer as a Sint64.
+func sizeSint64(p pointer, f *coderFieldInfo, _ marshalOptions) (size int) {
+	v := *p.Int64()
+	return f.tagsize + protowire.SizeVarint(protowire.EncodeZigZag(v))
+}
+
+// appendSint64 wire encodes a int64 pointer as a Sint64.
+func appendSint64(b []byte, p pointer, f *coderFieldInfo, _ marshalOptions) ([]byte, error) {
+	v := *p.Int64()
+	b = protowire.AppendVarint(b, f.wiretag)
+	b = protowire.AppendVarint(b, protowire.EncodeZigZag(v))
+	return b, nil
+}
+
+// consumeSint64 wire decodes a int64 pointer as a Sint64.
+func consumeSint64(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, _ unmarshalOptions) (out unmarshalOutput, err error) {
+	if wtyp != protowire.VarintType {
+		return out, errUnknown
+	}
+	var v uint64
+	var n int
+	if len(b) >= 1 && b[0] < 0x80 {
+		v = uint64(b[0])
+		n = 1
+	} else if len(b) >= 2 && b[1] < 128 {
+		v = uint64(b[0]&0x7f) + uint64(b[1])<<7
+		n = 2
+	} else {
+		v, n = protowire.ConsumeVarint(b)
+	}
+	if n < 0 {
+		return out, protowire.ParseError(n)
+	}
+	*p.Int64() = protowire.DecodeZigZag(v)
+	out.n = n
+	return out, nil
+}
+
+var coderSint64 = pointerCoderFuncs{
+	size:      sizeSint64,
+	marshal:   appendSint64,
+	unmarshal: consumeSint64,
+	merge:     mergeInt64,
+}
+
+// sizeSint64NoZero returns the size of wire encoding a int64 pointer as a Sint64.
+// The zero value is not encoded.
+func sizeSint64NoZero(p pointer, f *coderFieldInfo, _ marshalOptions) (size int) {
+	v := *p.Int64()
+	if v == 0 {
+		return 0
+	}
+	return f.tagsize + protowire.SizeVarint(protowire.EncodeZigZag(v))
+}
+
+// appendSint64NoZero wire encodes a int64 pointer as a Sint64.
+// The zero value is not encoded.
+func appendSint64NoZero(b []byte, p pointer, f *coderFieldInfo, _ marshalOptions) ([]byte, error) {
+	v := *p.Int64()
+	if v == 0 {
+		return b, nil
+	}
+	b = protowire.AppendVarint(b, f.wiretag)
+	b = protowire.AppendVarint(b, protowire.EncodeZigZag(v))
+	return b, nil
+}
+
+var coderSint64NoZero = pointerCoderFuncs{
+	size:      sizeSint64NoZero,
+	marshal:   appendSint64NoZero,
+	unmarshal: consumeSint64,
+	merge:     mergeInt64NoZero,
+}
+
+// sizeSint64Ptr returns the size of wire encoding a *int64 pointer as a Sint64.
+// It panics if the pointer is nil.
+func sizeSint64Ptr(p pointer, f *coderFieldInfo, _ marshalOptions) (size int) {
+	v := **p.Int64Ptr()
+	return f.tagsize + protowire.SizeVarint(protowire.EncodeZigZag(v))
+}
+
+// appendSint64Ptr wire encodes a *int64 pointer as a Sint64.
+// It panics if the pointer is nil.
+func appendSint64Ptr(b []byte, p pointer, f *coderFieldInfo, _ marshalOptions) ([]byte, error) {
+	v := **p.Int64Ptr()
+	b = protowire.AppendVarint(b, f.wiretag)
+	b = protowire.AppendVarint(b, protowire.EncodeZigZag(v))
+	return b, nil
+}
+
+// consumeSint64Ptr wire decodes a *int64 pointer as a Sint64.
+func consumeSint64Ptr(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, _ unmarshalOptions) (out unmarshalOutput, err error) {
+	if wtyp != protowire.VarintType {
+		return out, errUnknown
+	}
+	var v uint64
+	var n int
+	if len(b) >= 1 && b[0] < 0x80 {
+		v = uint64(b[0])
+		n = 1
+	} else if len(b) >= 2 && b[1] < 128 {
+		v = uint64(b[0]&0x7f) + uint64(b[1])<<7
+		n = 2
+	} else {
+		v, n = protowire.ConsumeVarint(b)
+	}
+	if n < 0 {
+		return out, protowire.ParseError(n)
+	}
+	vp := p.Int64Ptr()
+	if *vp == nil {
+		*vp = new(int64)
+	}
+	**vp = protowire.DecodeZigZag(v)
+	out.n = n
+	return out, nil
+}
+
+var coderSint64Ptr = pointerCoderFuncs{
+	size:      sizeSint64Ptr,
+	marshal:   appendSint64Ptr,
+	unmarshal: consumeSint64Ptr,
+	merge:     mergeInt64Ptr,
+}
+
+// sizeSint64Slice returns the size of wire encoding a []int64 pointer as a repeated Sint64.
+func sizeSint64Slice(p pointer, f *coderFieldInfo, _ marshalOptions) (size int) {
+	s := *p.Int64Slice()
+	for _, v := range s {
+		size += f.tagsize + protowire.SizeVarint(protowire.EncodeZigZag(v))
+	}
+	return size
+}
+
+// appendSint64Slice encodes a []int64 pointer as a repeated Sint64.
+func appendSint64Slice(b []byte, p pointer, f *coderFieldInfo, _ marshalOptions) ([]byte, error) {
+	s := *p.Int64Slice()
+	for _, v := range s {
+		b = protowire.AppendVarint(b, f.wiretag)
+		b = protowire.AppendVarint(b, protowire.EncodeZigZag(v))
+	}
+	return b, nil
+}
+
+// consumeSint64Slice wire decodes a []int64 pointer as a repeated Sint64.
+func consumeSint64Slice(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, _ unmarshalOptions) (out unmarshalOutput, err error) {
+	sp := p.Int64Slice()
+	if wtyp == protowire.BytesType {
+		s := *sp
+		b, n := protowire.ConsumeBytes(b)
+		if n < 0 {
+			return out, protowire.ParseError(n)
+		}
+		for len(b) > 0 {
+			var v uint64
+			var n int
+			if len(b) >= 1 && b[0] < 0x80 {
+				v = uint64(b[0])
+				n = 1
+			} else if len(b) >= 2 && b[1] < 128 {
+				v = uint64(b[0]&0x7f) + uint64(b[1])<<7
+				n = 2
+			} else {
+				v, n = protowire.ConsumeVarint(b)
+			}
+			if n < 0 {
+				return out, protowire.ParseError(n)
+			}
+			s = append(s, protowire.DecodeZigZag(v))
+			b = b[n:]
+		}
+		*sp = s
+		out.n = n
+		return out, nil
+	}
+	if wtyp != protowire.VarintType {
+		return out, errUnknown
+	}
+	var v uint64
+	var n int
+	if len(b) >= 1 && b[0] < 0x80 {
+		v = uint64(b[0])
+		n = 1
+	} else if len(b) >= 2 && b[1] < 128 {
+		v = uint64(b[0]&0x7f) + uint64(b[1])<<7
+		n = 2
+	} else {
+		v, n = protowire.ConsumeVarint(b)
+	}
+	if n < 0 {
+		return out, protowire.ParseError(n)
+	}
+	*sp = append(*sp, protowire.DecodeZigZag(v))
+	out.n = n
+	return out, nil
+}
+
+var coderSint64Slice = pointerCoderFuncs{
+	size:      sizeSint64Slice,
+	marshal:   appendSint64Slice,
+	unmarshal: consumeSint64Slice,
+	merge:     mergeInt64Slice,
+}
+
+// sizeSint64PackedSlice returns the size of wire encoding a []int64 pointer as a packed repeated Sint64.
+func sizeSint64PackedSlice(p pointer, f *coderFieldInfo, _ marshalOptions) (size int) {
+	s := *p.Int64Slice()
+	if len(s) == 0 {
+		return 0
+	}
+	n := 0
+	for _, v := range s {
+		n += protowire.SizeVarint(protowire.EncodeZigZag(v))
+	}
+	return f.tagsize + protowire.SizeBytes(n)
+}
+
+// appendSint64PackedSlice encodes a []int64 pointer as a packed repeated Sint64.
+func appendSint64PackedSlice(b []byte, p pointer, f *coderFieldInfo, _ marshalOptions) ([]byte, error) {
+	s := *p.Int64Slice()
+	if len(s) == 0 {
+		return b, nil
+	}
+	b = protowire.AppendVarint(b, f.wiretag)
+	n := 0
+	for _, v := range s {
+		n += protowire.SizeVarint(protowire.EncodeZigZag(v))
+	}
+	b = protowire.AppendVarint(b, uint64(n))
+	for _, v := range s {
+		b = protowire.AppendVarint(b, protowire.EncodeZigZag(v))
+	}
+	return b, nil
+}
+
+var coderSint64PackedSlice = pointerCoderFuncs{
+	size:      sizeSint64PackedSlice,
+	marshal:   appendSint64PackedSlice,
+	unmarshal: consumeSint64Slice,
+	merge:     mergeInt64Slice,
+}
+
+// sizeSint64Value returns the size of wire encoding a int64 value as a Sint64.
+func sizeSint64Value(v protoreflect.Value, tagsize int, _ marshalOptions) int {
+	return tagsize + protowire.SizeVarint(protowire.EncodeZigZag(v.Int()))
+}
+
+// appendSint64Value encodes a int64 value as a Sint64.
+func appendSint64Value(b []byte, v protoreflect.Value, wiretag uint64, _ marshalOptions) ([]byte, error) {
+	b = protowire.AppendVarint(b, wiretag)
+	b = protowire.AppendVarint(b, protowire.EncodeZigZag(v.Int()))
+	return b, nil
+}
+
+// consumeSint64Value decodes a int64 value as a Sint64.
+func consumeSint64Value(b []byte, _ protoreflect.Value, _ protowire.Number, wtyp protowire.Type, _ unmarshalOptions) (_ protoreflect.Value, out unmarshalOutput, err error) {
+	if wtyp != protowire.VarintType {
+		return protoreflect.Value{}, out, errUnknown
+	}
+	var v uint64
+	var n int
+	if len(b) >= 1 && b[0] < 0x80 {
+		v = uint64(b[0])
+		n = 1
+	} else if len(b) >= 2 && b[1] < 128 {
+		v = uint64(b[0]&0x7f) + uint64(b[1])<<7
+		n = 2
+	} else {
+		v, n = protowire.ConsumeVarint(b)
+	}
+	if n < 0 {
+		return protoreflect.Value{}, out, protowire.ParseError(n)
+	}
+	out.n = n
+	return protoreflect.ValueOfInt64(protowire.DecodeZigZag(v)), out, nil
+}
+
+var coderSint64Value = valueCoderFuncs{
+	size:      sizeSint64Value,
+	marshal:   appendSint64Value,
+	unmarshal: consumeSint64Value,
+	merge:     mergeScalarValue,
+}
+
+// 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 + protowire.SizeVarint(protowire.EncodeZigZag(v.Int()))
+	}
+	return size
+}
+
+// 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 = protowire.AppendVarint(b, wiretag)
+		b = protowire.AppendVarint(b, protowire.EncodeZigZag(v.Int()))
+	}
+	return b, nil
+}
+
+// consumeSint64SliceValue wire decodes a []int64 value as a repeated Sint64.
+func consumeSint64SliceValue(b []byte, listv protoreflect.Value, _ protowire.Number, wtyp protowire.Type, _ unmarshalOptions) (_ protoreflect.Value, out unmarshalOutput, err error) {
+	list := listv.List()
+	if wtyp == protowire.BytesType {
+		b, n := protowire.ConsumeBytes(b)
+		if n < 0 {
+			return protoreflect.Value{}, out, protowire.ParseError(n)
+		}
+		for len(b) > 0 {
+			var v uint64
+			var n int
+			if len(b) >= 1 && b[0] < 0x80 {
+				v = uint64(b[0])
+				n = 1
+			} else if len(b) >= 2 && b[1] < 128 {
+				v = uint64(b[0]&0x7f) + uint64(b[1])<<7
+				n = 2
+			} else {
+				v, n = protowire.ConsumeVarint(b)
+			}
+			if n < 0 {
+				return protoreflect.Value{}, out, protowire.ParseError(n)
+			}
+			list.Append(protoreflect.ValueOfInt64(protowire.DecodeZigZag(v)))
+			b = b[n:]
+		}
+		out.n = n
+		return listv, out, nil
+	}
+	if wtyp != protowire.VarintType {
+		return protoreflect.Value{}, out, errUnknown
+	}
+	var v uint64
+	var n int
+	if len(b) >= 1 && b[0] < 0x80 {
+		v = uint64(b[0])
+		n = 1
+	} else if len(b) >= 2 && b[1] < 128 {
+		v = uint64(b[0]&0x7f) + uint64(b[1])<<7
+		n = 2
+	} else {
+		v, n = protowire.ConsumeVarint(b)
+	}
+	if n < 0 {
+		return protoreflect.Value{}, out, protowire.ParseError(n)
+	}
+	list.Append(protoreflect.ValueOfInt64(protowire.DecodeZigZag(v)))
+	out.n = n
+	return listv, out, nil
+}
+
+var coderSint64SliceValue = valueCoderFuncs{
+	size:      sizeSint64SliceValue,
+	marshal:   appendSint64SliceValue,
+	unmarshal: consumeSint64SliceValue,
+	merge:     mergeListValue,
+}
+
+// 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()
+	llen := list.Len()
+	if llen == 0 {
+		return 0
+	}
+	n := 0
+	for i, llen := 0, llen; i < llen; i++ {
+		v := list.Get(i)
+		n += protowire.SizeVarint(protowire.EncodeZigZag(v.Int()))
+	}
+	return tagsize + protowire.SizeBytes(n)
+}
+
+// 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 = protowire.AppendVarint(b, wiretag)
+	n := 0
+	for i := 0; i < llen; i++ {
+		v := list.Get(i)
+		n += protowire.SizeVarint(protowire.EncodeZigZag(v.Int()))
+	}
+	b = protowire.AppendVarint(b, uint64(n))
+	for i := 0; i < llen; i++ {
+		v := list.Get(i)
+		b = protowire.AppendVarint(b, protowire.EncodeZigZag(v.Int()))
+	}
+	return b, nil
+}
+
+var coderSint64PackedSliceValue = valueCoderFuncs{
+	size:      sizeSint64PackedSliceValue,
+	marshal:   appendSint64PackedSliceValue,
+	unmarshal: consumeSint64SliceValue,
+	merge:     mergeListValue,
+}
+
+// sizeUint64 returns the size of wire encoding a uint64 pointer as a Uint64.
+func sizeUint64(p pointer, f *coderFieldInfo, _ marshalOptions) (size int) {
+	v := *p.Uint64()
+	return f.tagsize + protowire.SizeVarint(v)
+}
+
+// appendUint64 wire encodes a uint64 pointer as a Uint64.
+func appendUint64(b []byte, p pointer, f *coderFieldInfo, _ marshalOptions) ([]byte, error) {
+	v := *p.Uint64()
+	b = protowire.AppendVarint(b, f.wiretag)
+	b = protowire.AppendVarint(b, v)
+	return b, nil
+}
+
+// consumeUint64 wire decodes a uint64 pointer as a Uint64.
+func consumeUint64(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, _ unmarshalOptions) (out unmarshalOutput, err error) {
+	if wtyp != protowire.VarintType {
+		return out, errUnknown
+	}
+	var v uint64
+	var n int
+	if len(b) >= 1 && b[0] < 0x80 {
+		v = uint64(b[0])
+		n = 1
+	} else if len(b) >= 2 && b[1] < 128 {
+		v = uint64(b[0]&0x7f) + uint64(b[1])<<7
+		n = 2
+	} else {
+		v, n = protowire.ConsumeVarint(b)
+	}
+	if n < 0 {
+		return out, protowire.ParseError(n)
+	}
+	*p.Uint64() = v
+	out.n = n
+	return out, nil
+}
+
+var coderUint64 = pointerCoderFuncs{
+	size:      sizeUint64,
+	marshal:   appendUint64,
+	unmarshal: consumeUint64,
+	merge:     mergeUint64,
+}
+
+// sizeUint64NoZero returns the size of wire encoding a uint64 pointer as a Uint64.
+// The zero value is not encoded.
+func sizeUint64NoZero(p pointer, f *coderFieldInfo, _ marshalOptions) (size int) {
+	v := *p.Uint64()
+	if v == 0 {
+		return 0
+	}
+	return f.tagsize + protowire.SizeVarint(v)
+}
+
+// appendUint64NoZero wire encodes a uint64 pointer as a Uint64.
+// The zero value is not encoded.
+func appendUint64NoZero(b []byte, p pointer, f *coderFieldInfo, _ marshalOptions) ([]byte, error) {
+	v := *p.Uint64()
+	if v == 0 {
+		return b, nil
+	}
+	b = protowire.AppendVarint(b, f.wiretag)
+	b = protowire.AppendVarint(b, v)
+	return b, nil
+}
+
+var coderUint64NoZero = pointerCoderFuncs{
+	size:      sizeUint64NoZero,
+	marshal:   appendUint64NoZero,
+	unmarshal: consumeUint64,
+	merge:     mergeUint64NoZero,
+}
+
+// sizeUint64Ptr returns the size of wire encoding a *uint64 pointer as a Uint64.
+// It panics if the pointer is nil.
+func sizeUint64Ptr(p pointer, f *coderFieldInfo, _ marshalOptions) (size int) {
+	v := **p.Uint64Ptr()
+	return f.tagsize + protowire.SizeVarint(v)
+}
+
+// appendUint64Ptr wire encodes a *uint64 pointer as a Uint64.
+// It panics if the pointer is nil.
+func appendUint64Ptr(b []byte, p pointer, f *coderFieldInfo, _ marshalOptions) ([]byte, error) {
+	v := **p.Uint64Ptr()
+	b = protowire.AppendVarint(b, f.wiretag)
+	b = protowire.AppendVarint(b, v)
+	return b, nil
+}
+
+// consumeUint64Ptr wire decodes a *uint64 pointer as a Uint64.
+func consumeUint64Ptr(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, _ unmarshalOptions) (out unmarshalOutput, err error) {
+	if wtyp != protowire.VarintType {
+		return out, errUnknown
+	}
+	var v uint64
+	var n int
+	if len(b) >= 1 && b[0] < 0x80 {
+		v = uint64(b[0])
+		n = 1
+	} else if len(b) >= 2 && b[1] < 128 {
+		v = uint64(b[0]&0x7f) + uint64(b[1])<<7
+		n = 2
+	} else {
+		v, n = protowire.ConsumeVarint(b)
+	}
+	if n < 0 {
+		return out, protowire.ParseError(n)
+	}
+	vp := p.Uint64Ptr()
+	if *vp == nil {
+		*vp = new(uint64)
+	}
+	**vp = v
+	out.n = n
+	return out, nil
+}
+
+var coderUint64Ptr = pointerCoderFuncs{
+	size:      sizeUint64Ptr,
+	marshal:   appendUint64Ptr,
+	unmarshal: consumeUint64Ptr,
+	merge:     mergeUint64Ptr,
+}
+
+// sizeUint64Slice returns the size of wire encoding a []uint64 pointer as a repeated Uint64.
+func sizeUint64Slice(p pointer, f *coderFieldInfo, _ marshalOptions) (size int) {
+	s := *p.Uint64Slice()
+	for _, v := range s {
+		size += f.tagsize + protowire.SizeVarint(v)
+	}
+	return size
+}
+
+// appendUint64Slice encodes a []uint64 pointer as a repeated Uint64.
+func appendUint64Slice(b []byte, p pointer, f *coderFieldInfo, _ marshalOptions) ([]byte, error) {
+	s := *p.Uint64Slice()
+	for _, v := range s {
+		b = protowire.AppendVarint(b, f.wiretag)
+		b = protowire.AppendVarint(b, v)
+	}
+	return b, nil
+}
+
+// consumeUint64Slice wire decodes a []uint64 pointer as a repeated Uint64.
+func consumeUint64Slice(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, _ unmarshalOptions) (out unmarshalOutput, err error) {
+	sp := p.Uint64Slice()
+	if wtyp == protowire.BytesType {
+		s := *sp
+		b, n := protowire.ConsumeBytes(b)
+		if n < 0 {
+			return out, protowire.ParseError(n)
+		}
+		for len(b) > 0 {
+			var v uint64
+			var n int
+			if len(b) >= 1 && b[0] < 0x80 {
+				v = uint64(b[0])
+				n = 1
+			} else if len(b) >= 2 && b[1] < 128 {
+				v = uint64(b[0]&0x7f) + uint64(b[1])<<7
+				n = 2
+			} else {
+				v, n = protowire.ConsumeVarint(b)
+			}
+			if n < 0 {
+				return out, protowire.ParseError(n)
+			}
+			s = append(s, v)
+			b = b[n:]
+		}
+		*sp = s
+		out.n = n
+		return out, nil
+	}
+	if wtyp != protowire.VarintType {
+		return out, errUnknown
+	}
+	var v uint64
+	var n int
+	if len(b) >= 1 && b[0] < 0x80 {
+		v = uint64(b[0])
+		n = 1
+	} else if len(b) >= 2 && b[1] < 128 {
+		v = uint64(b[0]&0x7f) + uint64(b[1])<<7
+		n = 2
+	} else {
+		v, n = protowire.ConsumeVarint(b)
+	}
+	if n < 0 {
+		return out, protowire.ParseError(n)
+	}
+	*sp = append(*sp, v)
+	out.n = n
+	return out, nil
+}
+
+var coderUint64Slice = pointerCoderFuncs{
+	size:      sizeUint64Slice,
+	marshal:   appendUint64Slice,
+	unmarshal: consumeUint64Slice,
+	merge:     mergeUint64Slice,
+}
+
+// sizeUint64PackedSlice returns the size of wire encoding a []uint64 pointer as a packed repeated Uint64.
+func sizeUint64PackedSlice(p pointer, f *coderFieldInfo, _ marshalOptions) (size int) {
+	s := *p.Uint64Slice()
+	if len(s) == 0 {
+		return 0
+	}
+	n := 0
+	for _, v := range s {
+		n += protowire.SizeVarint(v)
+	}
+	return f.tagsize + protowire.SizeBytes(n)
+}
+
+// appendUint64PackedSlice encodes a []uint64 pointer as a packed repeated Uint64.
+func appendUint64PackedSlice(b []byte, p pointer, f *coderFieldInfo, _ marshalOptions) ([]byte, error) {
+	s := *p.Uint64Slice()
+	if len(s) == 0 {
+		return b, nil
+	}
+	b = protowire.AppendVarint(b, f.wiretag)
+	n := 0
+	for _, v := range s {
+		n += protowire.SizeVarint(v)
+	}
+	b = protowire.AppendVarint(b, uint64(n))
+	for _, v := range s {
+		b = protowire.AppendVarint(b, v)
+	}
+	return b, nil
+}
+
+var coderUint64PackedSlice = pointerCoderFuncs{
+	size:      sizeUint64PackedSlice,
+	marshal:   appendUint64PackedSlice,
+	unmarshal: consumeUint64Slice,
+	merge:     mergeUint64Slice,
+}
+
+// sizeUint64Value returns the size of wire encoding a uint64 value as a Uint64.
+func sizeUint64Value(v protoreflect.Value, tagsize int, _ marshalOptions) int {
+	return tagsize + protowire.SizeVarint(v.Uint())
+}
+
+// appendUint64Value encodes a uint64 value as a Uint64.
+func appendUint64Value(b []byte, v protoreflect.Value, wiretag uint64, _ marshalOptions) ([]byte, error) {
+	b = protowire.AppendVarint(b, wiretag)
+	b = protowire.AppendVarint(b, v.Uint())
+	return b, nil
+}
+
+// consumeUint64Value decodes a uint64 value as a Uint64.
+func consumeUint64Value(b []byte, _ protoreflect.Value, _ protowire.Number, wtyp protowire.Type, _ unmarshalOptions) (_ protoreflect.Value, out unmarshalOutput, err error) {
+	if wtyp != protowire.VarintType {
+		return protoreflect.Value{}, out, errUnknown
+	}
+	var v uint64
+	var n int
+	if len(b) >= 1 && b[0] < 0x80 {
+		v = uint64(b[0])
+		n = 1
+	} else if len(b) >= 2 && b[1] < 128 {
+		v = uint64(b[0]&0x7f) + uint64(b[1])<<7
+		n = 2
+	} else {
+		v, n = protowire.ConsumeVarint(b)
+	}
+	if n < 0 {
+		return protoreflect.Value{}, out, protowire.ParseError(n)
+	}
+	out.n = n
+	return protoreflect.ValueOfUint64(v), out, nil
+}
+
+var coderUint64Value = valueCoderFuncs{
+	size:      sizeUint64Value,
+	marshal:   appendUint64Value,
+	unmarshal: consumeUint64Value,
+	merge:     mergeScalarValue,
+}
+
+// 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 + protowire.SizeVarint(v.Uint())
+	}
+	return size
+}
+
+// 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 = protowire.AppendVarint(b, wiretag)
+		b = protowire.AppendVarint(b, v.Uint())
+	}
+	return b, nil
+}
+
+// consumeUint64SliceValue wire decodes a []uint64 value as a repeated Uint64.
+func consumeUint64SliceValue(b []byte, listv protoreflect.Value, _ protowire.Number, wtyp protowire.Type, _ unmarshalOptions) (_ protoreflect.Value, out unmarshalOutput, err error) {
+	list := listv.List()
+	if wtyp == protowire.BytesType {
+		b, n := protowire.ConsumeBytes(b)
+		if n < 0 {
+			return protoreflect.Value{}, out, protowire.ParseError(n)
+		}
+		for len(b) > 0 {
+			var v uint64
+			var n int
+			if len(b) >= 1 && b[0] < 0x80 {
+				v = uint64(b[0])
+				n = 1
+			} else if len(b) >= 2 && b[1] < 128 {
+				v = uint64(b[0]&0x7f) + uint64(b[1])<<7
+				n = 2
+			} else {
+				v, n = protowire.ConsumeVarint(b)
+			}
+			if n < 0 {
+				return protoreflect.Value{}, out, protowire.ParseError(n)
+			}
+			list.Append(protoreflect.ValueOfUint64(v))
+			b = b[n:]
+		}
+		out.n = n
+		return listv, out, nil
+	}
+	if wtyp != protowire.VarintType {
+		return protoreflect.Value{}, out, errUnknown
+	}
+	var v uint64
+	var n int
+	if len(b) >= 1 && b[0] < 0x80 {
+		v = uint64(b[0])
+		n = 1
+	} else if len(b) >= 2 && b[1] < 128 {
+		v = uint64(b[0]&0x7f) + uint64(b[1])<<7
+		n = 2
+	} else {
+		v, n = protowire.ConsumeVarint(b)
+	}
+	if n < 0 {
+		return protoreflect.Value{}, out, protowire.ParseError(n)
+	}
+	list.Append(protoreflect.ValueOfUint64(v))
+	out.n = n
+	return listv, out, nil
+}
+
+var coderUint64SliceValue = valueCoderFuncs{
+	size:      sizeUint64SliceValue,
+	marshal:   appendUint64SliceValue,
+	unmarshal: consumeUint64SliceValue,
+	merge:     mergeListValue,
+}
+
+// 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()
+	llen := list.Len()
+	if llen == 0 {
+		return 0
+	}
+	n := 0
+	for i, llen := 0, llen; i < llen; i++ {
+		v := list.Get(i)
+		n += protowire.SizeVarint(v.Uint())
+	}
+	return tagsize + protowire.SizeBytes(n)
+}
+
+// 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 = protowire.AppendVarint(b, wiretag)
+	n := 0
+	for i := 0; i < llen; i++ {
+		v := list.Get(i)
+		n += protowire.SizeVarint(v.Uint())
+	}
+	b = protowire.AppendVarint(b, uint64(n))
+	for i := 0; i < llen; i++ {
+		v := list.Get(i)
+		b = protowire.AppendVarint(b, v.Uint())
+	}
+	return b, nil
+}
+
+var coderUint64PackedSliceValue = valueCoderFuncs{
+	size:      sizeUint64PackedSliceValue,
+	marshal:   appendUint64PackedSliceValue,
+	unmarshal: consumeUint64SliceValue,
+	merge:     mergeListValue,
+}
+
+// sizeSfixed32 returns the size of wire encoding a int32 pointer as a Sfixed32.
+func sizeSfixed32(p pointer, f *coderFieldInfo, _ marshalOptions) (size int) {
+
+	return f.tagsize + protowire.SizeFixed32()
+}
+
+// appendSfixed32 wire encodes a int32 pointer as a Sfixed32.
+func appendSfixed32(b []byte, p pointer, f *coderFieldInfo, _ marshalOptions) ([]byte, error) {
+	v := *p.Int32()
+	b = protowire.AppendVarint(b, f.wiretag)
+	b = protowire.AppendFixed32(b, uint32(v))
+	return b, nil
+}
+
+// consumeSfixed32 wire decodes a int32 pointer as a Sfixed32.
+func consumeSfixed32(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, _ unmarshalOptions) (out unmarshalOutput, err error) {
+	if wtyp != protowire.Fixed32Type {
+		return out, errUnknown
+	}
+	v, n := protowire.ConsumeFixed32(b)
+	if n < 0 {
+		return out, protowire.ParseError(n)
+	}
+	*p.Int32() = int32(v)
+	out.n = n
+	return out, nil
+}
+
+var coderSfixed32 = pointerCoderFuncs{
+	size:      sizeSfixed32,
+	marshal:   appendSfixed32,
+	unmarshal: consumeSfixed32,
+	merge:     mergeInt32,
+}
+
+// sizeSfixed32NoZero returns the size of wire encoding a int32 pointer as a Sfixed32.
+// The zero value is not encoded.
+func sizeSfixed32NoZero(p pointer, f *coderFieldInfo, _ marshalOptions) (size int) {
+	v := *p.Int32()
+	if v == 0 {
+		return 0
+	}
+	return f.tagsize + protowire.SizeFixed32()
+}
+
+// appendSfixed32NoZero wire encodes a int32 pointer as a Sfixed32.
+// The zero value is not encoded.
+func appendSfixed32NoZero(b []byte, p pointer, f *coderFieldInfo, _ marshalOptions) ([]byte, error) {
+	v := *p.Int32()
+	if v == 0 {
+		return b, nil
+	}
+	b = protowire.AppendVarint(b, f.wiretag)
+	b = protowire.AppendFixed32(b, uint32(v))
+	return b, nil
+}
+
+var coderSfixed32NoZero = pointerCoderFuncs{
+	size:      sizeSfixed32NoZero,
+	marshal:   appendSfixed32NoZero,
+	unmarshal: consumeSfixed32,
+	merge:     mergeInt32NoZero,
+}
+
+// sizeSfixed32Ptr returns the size of wire encoding a *int32 pointer as a Sfixed32.
+// It panics if the pointer is nil.
+func sizeSfixed32Ptr(p pointer, f *coderFieldInfo, _ marshalOptions) (size int) {
+	return f.tagsize + protowire.SizeFixed32()
+}
+
+// appendSfixed32Ptr wire encodes a *int32 pointer as a Sfixed32.
+// It panics if the pointer is nil.
+func appendSfixed32Ptr(b []byte, p pointer, f *coderFieldInfo, _ marshalOptions) ([]byte, error) {
+	v := **p.Int32Ptr()
+	b = protowire.AppendVarint(b, f.wiretag)
+	b = protowire.AppendFixed32(b, uint32(v))
+	return b, nil
+}
+
+// consumeSfixed32Ptr wire decodes a *int32 pointer as a Sfixed32.
+func consumeSfixed32Ptr(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, _ unmarshalOptions) (out unmarshalOutput, err error) {
+	if wtyp != protowire.Fixed32Type {
+		return out, errUnknown
+	}
+	v, n := protowire.ConsumeFixed32(b)
+	if n < 0 {
+		return out, protowire.ParseError(n)
+	}
+	vp := p.Int32Ptr()
+	if *vp == nil {
+		*vp = new(int32)
+	}
+	**vp = int32(v)
+	out.n = n
+	return out, nil
+}
+
+var coderSfixed32Ptr = pointerCoderFuncs{
+	size:      sizeSfixed32Ptr,
+	marshal:   appendSfixed32Ptr,
+	unmarshal: consumeSfixed32Ptr,
+	merge:     mergeInt32Ptr,
+}
+
+// sizeSfixed32Slice returns the size of wire encoding a []int32 pointer as a repeated Sfixed32.
+func sizeSfixed32Slice(p pointer, f *coderFieldInfo, _ marshalOptions) (size int) {
+	s := *p.Int32Slice()
+	size = len(s) * (f.tagsize + protowire.SizeFixed32())
+	return size
+}
+
+// appendSfixed32Slice encodes a []int32 pointer as a repeated Sfixed32.
+func appendSfixed32Slice(b []byte, p pointer, f *coderFieldInfo, _ marshalOptions) ([]byte, error) {
+	s := *p.Int32Slice()
+	for _, v := range s {
+		b = protowire.AppendVarint(b, f.wiretag)
+		b = protowire.AppendFixed32(b, uint32(v))
+	}
+	return b, nil
+}
+
+// consumeSfixed32Slice wire decodes a []int32 pointer as a repeated Sfixed32.
+func consumeSfixed32Slice(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, _ unmarshalOptions) (out unmarshalOutput, err error) {
+	sp := p.Int32Slice()
+	if wtyp == protowire.BytesType {
+		s := *sp
+		b, n := protowire.ConsumeBytes(b)
+		if n < 0 {
+			return out, protowire.ParseError(n)
+		}
+		for len(b) > 0 {
+			v, n := protowire.ConsumeFixed32(b)
+			if n < 0 {
+				return out, protowire.ParseError(n)
+			}
+			s = append(s, int32(v))
+			b = b[n:]
+		}
+		*sp = s
+		out.n = n
+		return out, nil
+	}
+	if wtyp != protowire.Fixed32Type {
+		return out, errUnknown
+	}
+	v, n := protowire.ConsumeFixed32(b)
+	if n < 0 {
+		return out, protowire.ParseError(n)
+	}
+	*sp = append(*sp, int32(v))
+	out.n = n
+	return out, nil
+}
+
+var coderSfixed32Slice = pointerCoderFuncs{
+	size:      sizeSfixed32Slice,
+	marshal:   appendSfixed32Slice,
+	unmarshal: consumeSfixed32Slice,
+	merge:     mergeInt32Slice,
+}
+
+// sizeSfixed32PackedSlice returns the size of wire encoding a []int32 pointer as a packed repeated Sfixed32.
+func sizeSfixed32PackedSlice(p pointer, f *coderFieldInfo, _ marshalOptions) (size int) {
+	s := *p.Int32Slice()
+	if len(s) == 0 {
+		return 0
+	}
+	n := len(s) * protowire.SizeFixed32()
+	return f.tagsize + protowire.SizeBytes(n)
+}
+
+// appendSfixed32PackedSlice encodes a []int32 pointer as a packed repeated Sfixed32.
+func appendSfixed32PackedSlice(b []byte, p pointer, f *coderFieldInfo, _ marshalOptions) ([]byte, error) {
+	s := *p.Int32Slice()
+	if len(s) == 0 {
+		return b, nil
+	}
+	b = protowire.AppendVarint(b, f.wiretag)
+	n := len(s) * protowire.SizeFixed32()
+	b = protowire.AppendVarint(b, uint64(n))
+	for _, v := range s {
+		b = protowire.AppendFixed32(b, uint32(v))
+	}
+	return b, nil
+}
+
+var coderSfixed32PackedSlice = pointerCoderFuncs{
+	size:      sizeSfixed32PackedSlice,
+	marshal:   appendSfixed32PackedSlice,
+	unmarshal: consumeSfixed32Slice,
+	merge:     mergeInt32Slice,
+}
+
+// sizeSfixed32Value returns the size of wire encoding a int32 value as a Sfixed32.
+func sizeSfixed32Value(v protoreflect.Value, tagsize int, _ marshalOptions) int {
+	return tagsize + protowire.SizeFixed32()
+}
+
+// appendSfixed32Value encodes a int32 value as a Sfixed32.
+func appendSfixed32Value(b []byte, v protoreflect.Value, wiretag uint64, _ marshalOptions) ([]byte, error) {
+	b = protowire.AppendVarint(b, wiretag)
+	b = protowire.AppendFixed32(b, uint32(v.Int()))
+	return b, nil
+}
+
+// consumeSfixed32Value decodes a int32 value as a Sfixed32.
+func consumeSfixed32Value(b []byte, _ protoreflect.Value, _ protowire.Number, wtyp protowire.Type, _ unmarshalOptions) (_ protoreflect.Value, out unmarshalOutput, err error) {
+	if wtyp != protowire.Fixed32Type {
+		return protoreflect.Value{}, out, errUnknown
+	}
+	v, n := protowire.ConsumeFixed32(b)
+	if n < 0 {
+		return protoreflect.Value{}, out, protowire.ParseError(n)
+	}
+	out.n = n
+	return protoreflect.ValueOfInt32(int32(v)), out, nil
+}
+
+var coderSfixed32Value = valueCoderFuncs{
+	size:      sizeSfixed32Value,
+	marshal:   appendSfixed32Value,
+	unmarshal: consumeSfixed32Value,
+	merge:     mergeScalarValue,
+}
+
+// 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 + protowire.SizeFixed32())
+	return size
+}
+
+// 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 = protowire.AppendVarint(b, wiretag)
+		b = protowire.AppendFixed32(b, uint32(v.Int()))
+	}
+	return b, nil
+}
+
+// consumeSfixed32SliceValue wire decodes a []int32 value as a repeated Sfixed32.
+func consumeSfixed32SliceValue(b []byte, listv protoreflect.Value, _ protowire.Number, wtyp protowire.Type, _ unmarshalOptions) (_ protoreflect.Value, out unmarshalOutput, err error) {
+	list := listv.List()
+	if wtyp == protowire.BytesType {
+		b, n := protowire.ConsumeBytes(b)
+		if n < 0 {
+			return protoreflect.Value{}, out, protowire.ParseError(n)
+		}
+		for len(b) > 0 {
+			v, n := protowire.ConsumeFixed32(b)
+			if n < 0 {
+				return protoreflect.Value{}, out, protowire.ParseError(n)
+			}
+			list.Append(protoreflect.ValueOfInt32(int32(v)))
+			b = b[n:]
+		}
+		out.n = n
+		return listv, out, nil
+	}
+	if wtyp != protowire.Fixed32Type {
+		return protoreflect.Value{}, out, errUnknown
+	}
+	v, n := protowire.ConsumeFixed32(b)
+	if n < 0 {
+		return protoreflect.Value{}, out, protowire.ParseError(n)
+	}
+	list.Append(protoreflect.ValueOfInt32(int32(v)))
+	out.n = n
+	return listv, out, nil
+}
+
+var coderSfixed32SliceValue = valueCoderFuncs{
+	size:      sizeSfixed32SliceValue,
+	marshal:   appendSfixed32SliceValue,
+	unmarshal: consumeSfixed32SliceValue,
+	merge:     mergeListValue,
+}
+
+// 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()
+	llen := list.Len()
+	if llen == 0 {
+		return 0
+	}
+	n := llen * protowire.SizeFixed32()
+	return tagsize + protowire.SizeBytes(n)
+}
+
+// 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 = protowire.AppendVarint(b, wiretag)
+	n := llen * protowire.SizeFixed32()
+	b = protowire.AppendVarint(b, uint64(n))
+	for i := 0; i < llen; i++ {
+		v := list.Get(i)
+		b = protowire.AppendFixed32(b, uint32(v.Int()))
+	}
+	return b, nil
+}
+
+var coderSfixed32PackedSliceValue = valueCoderFuncs{
+	size:      sizeSfixed32PackedSliceValue,
+	marshal:   appendSfixed32PackedSliceValue,
+	unmarshal: consumeSfixed32SliceValue,
+	merge:     mergeListValue,
+}
+
+// sizeFixed32 returns the size of wire encoding a uint32 pointer as a Fixed32.
+func sizeFixed32(p pointer, f *coderFieldInfo, _ marshalOptions) (size int) {
+
+	return f.tagsize + protowire.SizeFixed32()
+}
+
+// appendFixed32 wire encodes a uint32 pointer as a Fixed32.
+func appendFixed32(b []byte, p pointer, f *coderFieldInfo, _ marshalOptions) ([]byte, error) {
+	v := *p.Uint32()
+	b = protowire.AppendVarint(b, f.wiretag)
+	b = protowire.AppendFixed32(b, v)
+	return b, nil
+}
+
+// consumeFixed32 wire decodes a uint32 pointer as a Fixed32.
+func consumeFixed32(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, _ unmarshalOptions) (out unmarshalOutput, err error) {
+	if wtyp != protowire.Fixed32Type {
+		return out, errUnknown
+	}
+	v, n := protowire.ConsumeFixed32(b)
+	if n < 0 {
+		return out, protowire.ParseError(n)
+	}
+	*p.Uint32() = v
+	out.n = n
+	return out, nil
+}
+
+var coderFixed32 = pointerCoderFuncs{
+	size:      sizeFixed32,
+	marshal:   appendFixed32,
+	unmarshal: consumeFixed32,
+	merge:     mergeUint32,
+}
+
+// sizeFixed32NoZero returns the size of wire encoding a uint32 pointer as a Fixed32.
+// The zero value is not encoded.
+func sizeFixed32NoZero(p pointer, f *coderFieldInfo, _ marshalOptions) (size int) {
+	v := *p.Uint32()
+	if v == 0 {
+		return 0
+	}
+	return f.tagsize + protowire.SizeFixed32()
+}
+
+// appendFixed32NoZero wire encodes a uint32 pointer as a Fixed32.
+// The zero value is not encoded.
+func appendFixed32NoZero(b []byte, p pointer, f *coderFieldInfo, _ marshalOptions) ([]byte, error) {
+	v := *p.Uint32()
+	if v == 0 {
+		return b, nil
+	}
+	b = protowire.AppendVarint(b, f.wiretag)
+	b = protowire.AppendFixed32(b, v)
+	return b, nil
+}
+
+var coderFixed32NoZero = pointerCoderFuncs{
+	size:      sizeFixed32NoZero,
+	marshal:   appendFixed32NoZero,
+	unmarshal: consumeFixed32,
+	merge:     mergeUint32NoZero,
+}
+
+// sizeFixed32Ptr returns the size of wire encoding a *uint32 pointer as a Fixed32.
+// It panics if the pointer is nil.
+func sizeFixed32Ptr(p pointer, f *coderFieldInfo, _ marshalOptions) (size int) {
+	return f.tagsize + protowire.SizeFixed32()
+}
+
+// appendFixed32Ptr wire encodes a *uint32 pointer as a Fixed32.
+// It panics if the pointer is nil.
+func appendFixed32Ptr(b []byte, p pointer, f *coderFieldInfo, _ marshalOptions) ([]byte, error) {
+	v := **p.Uint32Ptr()
+	b = protowire.AppendVarint(b, f.wiretag)
+	b = protowire.AppendFixed32(b, v)
+	return b, nil
+}
+
+// consumeFixed32Ptr wire decodes a *uint32 pointer as a Fixed32.
+func consumeFixed32Ptr(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, _ unmarshalOptions) (out unmarshalOutput, err error) {
+	if wtyp != protowire.Fixed32Type {
+		return out, errUnknown
+	}
+	v, n := protowire.ConsumeFixed32(b)
+	if n < 0 {
+		return out, protowire.ParseError(n)
+	}
+	vp := p.Uint32Ptr()
+	if *vp == nil {
+		*vp = new(uint32)
+	}
+	**vp = v
+	out.n = n
+	return out, nil
+}
+
+var coderFixed32Ptr = pointerCoderFuncs{
+	size:      sizeFixed32Ptr,
+	marshal:   appendFixed32Ptr,
+	unmarshal: consumeFixed32Ptr,
+	merge:     mergeUint32Ptr,
+}
+
+// sizeFixed32Slice returns the size of wire encoding a []uint32 pointer as a repeated Fixed32.
+func sizeFixed32Slice(p pointer, f *coderFieldInfo, _ marshalOptions) (size int) {
+	s := *p.Uint32Slice()
+	size = len(s) * (f.tagsize + protowire.SizeFixed32())
+	return size
+}
+
+// appendFixed32Slice encodes a []uint32 pointer as a repeated Fixed32.
+func appendFixed32Slice(b []byte, p pointer, f *coderFieldInfo, _ marshalOptions) ([]byte, error) {
+	s := *p.Uint32Slice()
+	for _, v := range s {
+		b = protowire.AppendVarint(b, f.wiretag)
+		b = protowire.AppendFixed32(b, v)
+	}
+	return b, nil
+}
+
+// consumeFixed32Slice wire decodes a []uint32 pointer as a repeated Fixed32.
+func consumeFixed32Slice(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, _ unmarshalOptions) (out unmarshalOutput, err error) {
+	sp := p.Uint32Slice()
+	if wtyp == protowire.BytesType {
+		s := *sp
+		b, n := protowire.ConsumeBytes(b)
+		if n < 0 {
+			return out, protowire.ParseError(n)
+		}
+		for len(b) > 0 {
+			v, n := protowire.ConsumeFixed32(b)
+			if n < 0 {
+				return out, protowire.ParseError(n)
+			}
+			s = append(s, v)
+			b = b[n:]
+		}
+		*sp = s
+		out.n = n
+		return out, nil
+	}
+	if wtyp != protowire.Fixed32Type {
+		return out, errUnknown
+	}
+	v, n := protowire.ConsumeFixed32(b)
+	if n < 0 {
+		return out, protowire.ParseError(n)
+	}
+	*sp = append(*sp, v)
+	out.n = n
+	return out, nil
+}
+
+var coderFixed32Slice = pointerCoderFuncs{
+	size:      sizeFixed32Slice,
+	marshal:   appendFixed32Slice,
+	unmarshal: consumeFixed32Slice,
+	merge:     mergeUint32Slice,
+}
+
+// sizeFixed32PackedSlice returns the size of wire encoding a []uint32 pointer as a packed repeated Fixed32.
+func sizeFixed32PackedSlice(p pointer, f *coderFieldInfo, _ marshalOptions) (size int) {
+	s := *p.Uint32Slice()
+	if len(s) == 0 {
+		return 0
+	}
+	n := len(s) * protowire.SizeFixed32()
+	return f.tagsize + protowire.SizeBytes(n)
+}
+
+// appendFixed32PackedSlice encodes a []uint32 pointer as a packed repeated Fixed32.
+func appendFixed32PackedSlice(b []byte, p pointer, f *coderFieldInfo, _ marshalOptions) ([]byte, error) {
+	s := *p.Uint32Slice()
+	if len(s) == 0 {
+		return b, nil
+	}
+	b = protowire.AppendVarint(b, f.wiretag)
+	n := len(s) * protowire.SizeFixed32()
+	b = protowire.AppendVarint(b, uint64(n))
+	for _, v := range s {
+		b = protowire.AppendFixed32(b, v)
+	}
+	return b, nil
+}
+
+var coderFixed32PackedSlice = pointerCoderFuncs{
+	size:      sizeFixed32PackedSlice,
+	marshal:   appendFixed32PackedSlice,
+	unmarshal: consumeFixed32Slice,
+	merge:     mergeUint32Slice,
+}
+
+// sizeFixed32Value returns the size of wire encoding a uint32 value as a Fixed32.
+func sizeFixed32Value(v protoreflect.Value, tagsize int, _ marshalOptions) int {
+	return tagsize + protowire.SizeFixed32()
+}
+
+// appendFixed32Value encodes a uint32 value as a Fixed32.
+func appendFixed32Value(b []byte, v protoreflect.Value, wiretag uint64, _ marshalOptions) ([]byte, error) {
+	b = protowire.AppendVarint(b, wiretag)
+	b = protowire.AppendFixed32(b, uint32(v.Uint()))
+	return b, nil
+}
+
+// consumeFixed32Value decodes a uint32 value as a Fixed32.
+func consumeFixed32Value(b []byte, _ protoreflect.Value, _ protowire.Number, wtyp protowire.Type, _ unmarshalOptions) (_ protoreflect.Value, out unmarshalOutput, err error) {
+	if wtyp != protowire.Fixed32Type {
+		return protoreflect.Value{}, out, errUnknown
+	}
+	v, n := protowire.ConsumeFixed32(b)
+	if n < 0 {
+		return protoreflect.Value{}, out, protowire.ParseError(n)
+	}
+	out.n = n
+	return protoreflect.ValueOfUint32(uint32(v)), out, nil
+}
+
+var coderFixed32Value = valueCoderFuncs{
+	size:      sizeFixed32Value,
+	marshal:   appendFixed32Value,
+	unmarshal: consumeFixed32Value,
+	merge:     mergeScalarValue,
+}
+
+// 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 + protowire.SizeFixed32())
+	return size
+}
+
+// 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 = protowire.AppendVarint(b, wiretag)
+		b = protowire.AppendFixed32(b, uint32(v.Uint()))
+	}
+	return b, nil
+}
+
+// consumeFixed32SliceValue wire decodes a []uint32 value as a repeated Fixed32.
+func consumeFixed32SliceValue(b []byte, listv protoreflect.Value, _ protowire.Number, wtyp protowire.Type, _ unmarshalOptions) (_ protoreflect.Value, out unmarshalOutput, err error) {
+	list := listv.List()
+	if wtyp == protowire.BytesType {
+		b, n := protowire.ConsumeBytes(b)
+		if n < 0 {
+			return protoreflect.Value{}, out, protowire.ParseError(n)
+		}
+		for len(b) > 0 {
+			v, n := protowire.ConsumeFixed32(b)
+			if n < 0 {
+				return protoreflect.Value{}, out, protowire.ParseError(n)
+			}
+			list.Append(protoreflect.ValueOfUint32(uint32(v)))
+			b = b[n:]
+		}
+		out.n = n
+		return listv, out, nil
+	}
+	if wtyp != protowire.Fixed32Type {
+		return protoreflect.Value{}, out, errUnknown
+	}
+	v, n := protowire.ConsumeFixed32(b)
+	if n < 0 {
+		return protoreflect.Value{}, out, protowire.ParseError(n)
+	}
+	list.Append(protoreflect.ValueOfUint32(uint32(v)))
+	out.n = n
+	return listv, out, nil
+}
+
+var coderFixed32SliceValue = valueCoderFuncs{
+	size:      sizeFixed32SliceValue,
+	marshal:   appendFixed32SliceValue,
+	unmarshal: consumeFixed32SliceValue,
+	merge:     mergeListValue,
+}
+
+// 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()
+	llen := list.Len()
+	if llen == 0 {
+		return 0
+	}
+	n := llen * protowire.SizeFixed32()
+	return tagsize + protowire.SizeBytes(n)
+}
+
+// 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 = protowire.AppendVarint(b, wiretag)
+	n := llen * protowire.SizeFixed32()
+	b = protowire.AppendVarint(b, uint64(n))
+	for i := 0; i < llen; i++ {
+		v := list.Get(i)
+		b = protowire.AppendFixed32(b, uint32(v.Uint()))
+	}
+	return b, nil
+}
+
+var coderFixed32PackedSliceValue = valueCoderFuncs{
+	size:      sizeFixed32PackedSliceValue,
+	marshal:   appendFixed32PackedSliceValue,
+	unmarshal: consumeFixed32SliceValue,
+	merge:     mergeListValue,
+}
+
+// sizeFloat returns the size of wire encoding a float32 pointer as a Float.
+func sizeFloat(p pointer, f *coderFieldInfo, _ marshalOptions) (size int) {
+
+	return f.tagsize + protowire.SizeFixed32()
+}
+
+// appendFloat wire encodes a float32 pointer as a Float.
+func appendFloat(b []byte, p pointer, f *coderFieldInfo, _ marshalOptions) ([]byte, error) {
+	v := *p.Float32()
+	b = protowire.AppendVarint(b, f.wiretag)
+	b = protowire.AppendFixed32(b, math.Float32bits(v))
+	return b, nil
+}
+
+// consumeFloat wire decodes a float32 pointer as a Float.
+func consumeFloat(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, _ unmarshalOptions) (out unmarshalOutput, err error) {
+	if wtyp != protowire.Fixed32Type {
+		return out, errUnknown
+	}
+	v, n := protowire.ConsumeFixed32(b)
+	if n < 0 {
+		return out, protowire.ParseError(n)
+	}
+	*p.Float32() = math.Float32frombits(v)
+	out.n = n
+	return out, nil
+}
+
+var coderFloat = pointerCoderFuncs{
+	size:      sizeFloat,
+	marshal:   appendFloat,
+	unmarshal: consumeFloat,
+	merge:     mergeFloat32,
+}
+
+// sizeFloatNoZero returns the size of wire encoding a float32 pointer as a Float.
+// The zero value is not encoded.
+func sizeFloatNoZero(p pointer, f *coderFieldInfo, _ marshalOptions) (size int) {
+	v := *p.Float32()
+	if v == 0 && !math.Signbit(float64(v)) {
+		return 0
+	}
+	return f.tagsize + protowire.SizeFixed32()
+}
+
+// appendFloatNoZero wire encodes a float32 pointer as a Float.
+// The zero value is not encoded.
+func appendFloatNoZero(b []byte, p pointer, f *coderFieldInfo, _ marshalOptions) ([]byte, error) {
+	v := *p.Float32()
+	if v == 0 && !math.Signbit(float64(v)) {
+		return b, nil
+	}
+	b = protowire.AppendVarint(b, f.wiretag)
+	b = protowire.AppendFixed32(b, math.Float32bits(v))
+	return b, nil
+}
+
+var coderFloatNoZero = pointerCoderFuncs{
+	size:      sizeFloatNoZero,
+	marshal:   appendFloatNoZero,
+	unmarshal: consumeFloat,
+	merge:     mergeFloat32NoZero,
+}
+
+// sizeFloatPtr returns the size of wire encoding a *float32 pointer as a Float.
+// It panics if the pointer is nil.
+func sizeFloatPtr(p pointer, f *coderFieldInfo, _ marshalOptions) (size int) {
+	return f.tagsize + protowire.SizeFixed32()
+}
+
+// appendFloatPtr wire encodes a *float32 pointer as a Float.
+// It panics if the pointer is nil.
+func appendFloatPtr(b []byte, p pointer, f *coderFieldInfo, _ marshalOptions) ([]byte, error) {
+	v := **p.Float32Ptr()
+	b = protowire.AppendVarint(b, f.wiretag)
+	b = protowire.AppendFixed32(b, math.Float32bits(v))
+	return b, nil
+}
+
+// consumeFloatPtr wire decodes a *float32 pointer as a Float.
+func consumeFloatPtr(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, _ unmarshalOptions) (out unmarshalOutput, err error) {
+	if wtyp != protowire.Fixed32Type {
+		return out, errUnknown
+	}
+	v, n := protowire.ConsumeFixed32(b)
+	if n < 0 {
+		return out, protowire.ParseError(n)
+	}
+	vp := p.Float32Ptr()
+	if *vp == nil {
+		*vp = new(float32)
+	}
+	**vp = math.Float32frombits(v)
+	out.n = n
+	return out, nil
+}
+
+var coderFloatPtr = pointerCoderFuncs{
+	size:      sizeFloatPtr,
+	marshal:   appendFloatPtr,
+	unmarshal: consumeFloatPtr,
+	merge:     mergeFloat32Ptr,
+}
+
+// sizeFloatSlice returns the size of wire encoding a []float32 pointer as a repeated Float.
+func sizeFloatSlice(p pointer, f *coderFieldInfo, _ marshalOptions) (size int) {
+	s := *p.Float32Slice()
+	size = len(s) * (f.tagsize + protowire.SizeFixed32())
+	return size
+}
+
+// appendFloatSlice encodes a []float32 pointer as a repeated Float.
+func appendFloatSlice(b []byte, p pointer, f *coderFieldInfo, _ marshalOptions) ([]byte, error) {
+	s := *p.Float32Slice()
+	for _, v := range s {
+		b = protowire.AppendVarint(b, f.wiretag)
+		b = protowire.AppendFixed32(b, math.Float32bits(v))
+	}
+	return b, nil
+}
+
+// consumeFloatSlice wire decodes a []float32 pointer as a repeated Float.
+func consumeFloatSlice(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, _ unmarshalOptions) (out unmarshalOutput, err error) {
+	sp := p.Float32Slice()
+	if wtyp == protowire.BytesType {
+		s := *sp
+		b, n := protowire.ConsumeBytes(b)
+		if n < 0 {
+			return out, protowire.ParseError(n)
+		}
+		for len(b) > 0 {
+			v, n := protowire.ConsumeFixed32(b)
+			if n < 0 {
+				return out, protowire.ParseError(n)
+			}
+			s = append(s, math.Float32frombits(v))
+			b = b[n:]
+		}
+		*sp = s
+		out.n = n
+		return out, nil
+	}
+	if wtyp != protowire.Fixed32Type {
+		return out, errUnknown
+	}
+	v, n := protowire.ConsumeFixed32(b)
+	if n < 0 {
+		return out, protowire.ParseError(n)
+	}
+	*sp = append(*sp, math.Float32frombits(v))
+	out.n = n
+	return out, nil
+}
+
+var coderFloatSlice = pointerCoderFuncs{
+	size:      sizeFloatSlice,
+	marshal:   appendFloatSlice,
+	unmarshal: consumeFloatSlice,
+	merge:     mergeFloat32Slice,
+}
+
+// sizeFloatPackedSlice returns the size of wire encoding a []float32 pointer as a packed repeated Float.
+func sizeFloatPackedSlice(p pointer, f *coderFieldInfo, _ marshalOptions) (size int) {
+	s := *p.Float32Slice()
+	if len(s) == 0 {
+		return 0
+	}
+	n := len(s) * protowire.SizeFixed32()
+	return f.tagsize + protowire.SizeBytes(n)
+}
+
+// appendFloatPackedSlice encodes a []float32 pointer as a packed repeated Float.
+func appendFloatPackedSlice(b []byte, p pointer, f *coderFieldInfo, _ marshalOptions) ([]byte, error) {
+	s := *p.Float32Slice()
+	if len(s) == 0 {
+		return b, nil
+	}
+	b = protowire.AppendVarint(b, f.wiretag)
+	n := len(s) * protowire.SizeFixed32()
+	b = protowire.AppendVarint(b, uint64(n))
+	for _, v := range s {
+		b = protowire.AppendFixed32(b, math.Float32bits(v))
+	}
+	return b, nil
+}
+
+var coderFloatPackedSlice = pointerCoderFuncs{
+	size:      sizeFloatPackedSlice,
+	marshal:   appendFloatPackedSlice,
+	unmarshal: consumeFloatSlice,
+	merge:     mergeFloat32Slice,
+}
+
+// sizeFloatValue returns the size of wire encoding a float32 value as a Float.
+func sizeFloatValue(v protoreflect.Value, tagsize int, _ marshalOptions) int {
+	return tagsize + protowire.SizeFixed32()
+}
+
+// appendFloatValue encodes a float32 value as a Float.
+func appendFloatValue(b []byte, v protoreflect.Value, wiretag uint64, _ marshalOptions) ([]byte, error) {
+	b = protowire.AppendVarint(b, wiretag)
+	b = protowire.AppendFixed32(b, math.Float32bits(float32(v.Float())))
+	return b, nil
+}
+
+// consumeFloatValue decodes a float32 value as a Float.
+func consumeFloatValue(b []byte, _ protoreflect.Value, _ protowire.Number, wtyp protowire.Type, _ unmarshalOptions) (_ protoreflect.Value, out unmarshalOutput, err error) {
+	if wtyp != protowire.Fixed32Type {
+		return protoreflect.Value{}, out, errUnknown
+	}
+	v, n := protowire.ConsumeFixed32(b)
+	if n < 0 {
+		return protoreflect.Value{}, out, protowire.ParseError(n)
+	}
+	out.n = n
+	return protoreflect.ValueOfFloat32(math.Float32frombits(uint32(v))), out, nil
+}
+
+var coderFloatValue = valueCoderFuncs{
+	size:      sizeFloatValue,
+	marshal:   appendFloatValue,
+	unmarshal: consumeFloatValue,
+	merge:     mergeScalarValue,
+}
+
+// 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 + protowire.SizeFixed32())
+	return size
+}
+
+// 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 = protowire.AppendVarint(b, wiretag)
+		b = protowire.AppendFixed32(b, math.Float32bits(float32(v.Float())))
+	}
+	return b, nil
+}
+
+// consumeFloatSliceValue wire decodes a []float32 value as a repeated Float.
+func consumeFloatSliceValue(b []byte, listv protoreflect.Value, _ protowire.Number, wtyp protowire.Type, _ unmarshalOptions) (_ protoreflect.Value, out unmarshalOutput, err error) {
+	list := listv.List()
+	if wtyp == protowire.BytesType {
+		b, n := protowire.ConsumeBytes(b)
+		if n < 0 {
+			return protoreflect.Value{}, out, protowire.ParseError(n)
+		}
+		for len(b) > 0 {
+			v, n := protowire.ConsumeFixed32(b)
+			if n < 0 {
+				return protoreflect.Value{}, out, protowire.ParseError(n)
+			}
+			list.Append(protoreflect.ValueOfFloat32(math.Float32frombits(uint32(v))))
+			b = b[n:]
+		}
+		out.n = n
+		return listv, out, nil
+	}
+	if wtyp != protowire.Fixed32Type {
+		return protoreflect.Value{}, out, errUnknown
+	}
+	v, n := protowire.ConsumeFixed32(b)
+	if n < 0 {
+		return protoreflect.Value{}, out, protowire.ParseError(n)
+	}
+	list.Append(protoreflect.ValueOfFloat32(math.Float32frombits(uint32(v))))
+	out.n = n
+	return listv, out, nil
+}
+
+var coderFloatSliceValue = valueCoderFuncs{
+	size:      sizeFloatSliceValue,
+	marshal:   appendFloatSliceValue,
+	unmarshal: consumeFloatSliceValue,
+	merge:     mergeListValue,
+}
+
+// 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()
+	llen := list.Len()
+	if llen == 0 {
+		return 0
+	}
+	n := llen * protowire.SizeFixed32()
+	return tagsize + protowire.SizeBytes(n)
+}
+
+// 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 = protowire.AppendVarint(b, wiretag)
+	n := llen * protowire.SizeFixed32()
+	b = protowire.AppendVarint(b, uint64(n))
+	for i := 0; i < llen; i++ {
+		v := list.Get(i)
+		b = protowire.AppendFixed32(b, math.Float32bits(float32(v.Float())))
+	}
+	return b, nil
+}
+
+var coderFloatPackedSliceValue = valueCoderFuncs{
+	size:      sizeFloatPackedSliceValue,
+	marshal:   appendFloatPackedSliceValue,
+	unmarshal: consumeFloatSliceValue,
+	merge:     mergeListValue,
+}
+
+// sizeSfixed64 returns the size of wire encoding a int64 pointer as a Sfixed64.
+func sizeSfixed64(p pointer, f *coderFieldInfo, _ marshalOptions) (size int) {
+
+	return f.tagsize + protowire.SizeFixed64()
+}
+
+// appendSfixed64 wire encodes a int64 pointer as a Sfixed64.
+func appendSfixed64(b []byte, p pointer, f *coderFieldInfo, _ marshalOptions) ([]byte, error) {
+	v := *p.Int64()
+	b = protowire.AppendVarint(b, f.wiretag)
+	b = protowire.AppendFixed64(b, uint64(v))
+	return b, nil
+}
+
+// consumeSfixed64 wire decodes a int64 pointer as a Sfixed64.
+func consumeSfixed64(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, _ unmarshalOptions) (out unmarshalOutput, err error) {
+	if wtyp != protowire.Fixed64Type {
+		return out, errUnknown
+	}
+	v, n := protowire.ConsumeFixed64(b)
+	if n < 0 {
+		return out, protowire.ParseError(n)
+	}
+	*p.Int64() = int64(v)
+	out.n = n
+	return out, nil
+}
+
+var coderSfixed64 = pointerCoderFuncs{
+	size:      sizeSfixed64,
+	marshal:   appendSfixed64,
+	unmarshal: consumeSfixed64,
+	merge:     mergeInt64,
+}
+
+// sizeSfixed64NoZero returns the size of wire encoding a int64 pointer as a Sfixed64.
+// The zero value is not encoded.
+func sizeSfixed64NoZero(p pointer, f *coderFieldInfo, _ marshalOptions) (size int) {
+	v := *p.Int64()
+	if v == 0 {
+		return 0
+	}
+	return f.tagsize + protowire.SizeFixed64()
+}
+
+// appendSfixed64NoZero wire encodes a int64 pointer as a Sfixed64.
+// The zero value is not encoded.
+func appendSfixed64NoZero(b []byte, p pointer, f *coderFieldInfo, _ marshalOptions) ([]byte, error) {
+	v := *p.Int64()
+	if v == 0 {
+		return b, nil
+	}
+	b = protowire.AppendVarint(b, f.wiretag)
+	b = protowire.AppendFixed64(b, uint64(v))
+	return b, nil
+}
+
+var coderSfixed64NoZero = pointerCoderFuncs{
+	size:      sizeSfixed64NoZero,
+	marshal:   appendSfixed64NoZero,
+	unmarshal: consumeSfixed64,
+	merge:     mergeInt64NoZero,
+}
+
+// sizeSfixed64Ptr returns the size of wire encoding a *int64 pointer as a Sfixed64.
+// It panics if the pointer is nil.
+func sizeSfixed64Ptr(p pointer, f *coderFieldInfo, _ marshalOptions) (size int) {
+	return f.tagsize + protowire.SizeFixed64()
+}
+
+// appendSfixed64Ptr wire encodes a *int64 pointer as a Sfixed64.
+// It panics if the pointer is nil.
+func appendSfixed64Ptr(b []byte, p pointer, f *coderFieldInfo, _ marshalOptions) ([]byte, error) {
+	v := **p.Int64Ptr()
+	b = protowire.AppendVarint(b, f.wiretag)
+	b = protowire.AppendFixed64(b, uint64(v))
+	return b, nil
+}
+
+// consumeSfixed64Ptr wire decodes a *int64 pointer as a Sfixed64.
+func consumeSfixed64Ptr(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, _ unmarshalOptions) (out unmarshalOutput, err error) {
+	if wtyp != protowire.Fixed64Type {
+		return out, errUnknown
+	}
+	v, n := protowire.ConsumeFixed64(b)
+	if n < 0 {
+		return out, protowire.ParseError(n)
+	}
+	vp := p.Int64Ptr()
+	if *vp == nil {
+		*vp = new(int64)
+	}
+	**vp = int64(v)
+	out.n = n
+	return out, nil
+}
+
+var coderSfixed64Ptr = pointerCoderFuncs{
+	size:      sizeSfixed64Ptr,
+	marshal:   appendSfixed64Ptr,
+	unmarshal: consumeSfixed64Ptr,
+	merge:     mergeInt64Ptr,
+}
+
+// sizeSfixed64Slice returns the size of wire encoding a []int64 pointer as a repeated Sfixed64.
+func sizeSfixed64Slice(p pointer, f *coderFieldInfo, _ marshalOptions) (size int) {
+	s := *p.Int64Slice()
+	size = len(s) * (f.tagsize + protowire.SizeFixed64())
+	return size
+}
+
+// appendSfixed64Slice encodes a []int64 pointer as a repeated Sfixed64.
+func appendSfixed64Slice(b []byte, p pointer, f *coderFieldInfo, _ marshalOptions) ([]byte, error) {
+	s := *p.Int64Slice()
+	for _, v := range s {
+		b = protowire.AppendVarint(b, f.wiretag)
+		b = protowire.AppendFixed64(b, uint64(v))
+	}
+	return b, nil
+}
+
+// consumeSfixed64Slice wire decodes a []int64 pointer as a repeated Sfixed64.
+func consumeSfixed64Slice(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, _ unmarshalOptions) (out unmarshalOutput, err error) {
+	sp := p.Int64Slice()
+	if wtyp == protowire.BytesType {
+		s := *sp
+		b, n := protowire.ConsumeBytes(b)
+		if n < 0 {
+			return out, protowire.ParseError(n)
+		}
+		for len(b) > 0 {
+			v, n := protowire.ConsumeFixed64(b)
+			if n < 0 {
+				return out, protowire.ParseError(n)
+			}
+			s = append(s, int64(v))
+			b = b[n:]
+		}
+		*sp = s
+		out.n = n
+		return out, nil
+	}
+	if wtyp != protowire.Fixed64Type {
+		return out, errUnknown
+	}
+	v, n := protowire.ConsumeFixed64(b)
+	if n < 0 {
+		return out, protowire.ParseError(n)
+	}
+	*sp = append(*sp, int64(v))
+	out.n = n
+	return out, nil
+}
+
+var coderSfixed64Slice = pointerCoderFuncs{
+	size:      sizeSfixed64Slice,
+	marshal:   appendSfixed64Slice,
+	unmarshal: consumeSfixed64Slice,
+	merge:     mergeInt64Slice,
+}
+
+// sizeSfixed64PackedSlice returns the size of wire encoding a []int64 pointer as a packed repeated Sfixed64.
+func sizeSfixed64PackedSlice(p pointer, f *coderFieldInfo, _ marshalOptions) (size int) {
+	s := *p.Int64Slice()
+	if len(s) == 0 {
+		return 0
+	}
+	n := len(s) * protowire.SizeFixed64()
+	return f.tagsize + protowire.SizeBytes(n)
+}
+
+// appendSfixed64PackedSlice encodes a []int64 pointer as a packed repeated Sfixed64.
+func appendSfixed64PackedSlice(b []byte, p pointer, f *coderFieldInfo, _ marshalOptions) ([]byte, error) {
+	s := *p.Int64Slice()
+	if len(s) == 0 {
+		return b, nil
+	}
+	b = protowire.AppendVarint(b, f.wiretag)
+	n := len(s) * protowire.SizeFixed64()
+	b = protowire.AppendVarint(b, uint64(n))
+	for _, v := range s {
+		b = protowire.AppendFixed64(b, uint64(v))
+	}
+	return b, nil
+}
+
+var coderSfixed64PackedSlice = pointerCoderFuncs{
+	size:      sizeSfixed64PackedSlice,
+	marshal:   appendSfixed64PackedSlice,
+	unmarshal: consumeSfixed64Slice,
+	merge:     mergeInt64Slice,
+}
+
+// sizeSfixed64Value returns the size of wire encoding a int64 value as a Sfixed64.
+func sizeSfixed64Value(v protoreflect.Value, tagsize int, _ marshalOptions) int {
+	return tagsize + protowire.SizeFixed64()
+}
+
+// appendSfixed64Value encodes a int64 value as a Sfixed64.
+func appendSfixed64Value(b []byte, v protoreflect.Value, wiretag uint64, _ marshalOptions) ([]byte, error) {
+	b = protowire.AppendVarint(b, wiretag)
+	b = protowire.AppendFixed64(b, uint64(v.Int()))
+	return b, nil
+}
+
+// consumeSfixed64Value decodes a int64 value as a Sfixed64.
+func consumeSfixed64Value(b []byte, _ protoreflect.Value, _ protowire.Number, wtyp protowire.Type, _ unmarshalOptions) (_ protoreflect.Value, out unmarshalOutput, err error) {
+	if wtyp != protowire.Fixed64Type {
+		return protoreflect.Value{}, out, errUnknown
+	}
+	v, n := protowire.ConsumeFixed64(b)
+	if n < 0 {
+		return protoreflect.Value{}, out, protowire.ParseError(n)
+	}
+	out.n = n
+	return protoreflect.ValueOfInt64(int64(v)), out, nil
+}
+
+var coderSfixed64Value = valueCoderFuncs{
+	size:      sizeSfixed64Value,
+	marshal:   appendSfixed64Value,
+	unmarshal: consumeSfixed64Value,
+	merge:     mergeScalarValue,
+}
+
+// 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 + protowire.SizeFixed64())
+	return size
+}
+
+// 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 = protowire.AppendVarint(b, wiretag)
+		b = protowire.AppendFixed64(b, uint64(v.Int()))
+	}
+	return b, nil
+}
+
+// consumeSfixed64SliceValue wire decodes a []int64 value as a repeated Sfixed64.
+func consumeSfixed64SliceValue(b []byte, listv protoreflect.Value, _ protowire.Number, wtyp protowire.Type, _ unmarshalOptions) (_ protoreflect.Value, out unmarshalOutput, err error) {
+	list := listv.List()
+	if wtyp == protowire.BytesType {
+		b, n := protowire.ConsumeBytes(b)
+		if n < 0 {
+			return protoreflect.Value{}, out, protowire.ParseError(n)
+		}
+		for len(b) > 0 {
+			v, n := protowire.ConsumeFixed64(b)
+			if n < 0 {
+				return protoreflect.Value{}, out, protowire.ParseError(n)
+			}
+			list.Append(protoreflect.ValueOfInt64(int64(v)))
+			b = b[n:]
+		}
+		out.n = n
+		return listv, out, nil
+	}
+	if wtyp != protowire.Fixed64Type {
+		return protoreflect.Value{}, out, errUnknown
+	}
+	v, n := protowire.ConsumeFixed64(b)
+	if n < 0 {
+		return protoreflect.Value{}, out, protowire.ParseError(n)
+	}
+	list.Append(protoreflect.ValueOfInt64(int64(v)))
+	out.n = n
+	return listv, out, nil
+}
+
+var coderSfixed64SliceValue = valueCoderFuncs{
+	size:      sizeSfixed64SliceValue,
+	marshal:   appendSfixed64SliceValue,
+	unmarshal: consumeSfixed64SliceValue,
+	merge:     mergeListValue,
+}
+
+// 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()
+	llen := list.Len()
+	if llen == 0 {
+		return 0
+	}
+	n := llen * protowire.SizeFixed64()
+	return tagsize + protowire.SizeBytes(n)
+}
+
+// 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 = protowire.AppendVarint(b, wiretag)
+	n := llen * protowire.SizeFixed64()
+	b = protowire.AppendVarint(b, uint64(n))
+	for i := 0; i < llen; i++ {
+		v := list.Get(i)
+		b = protowire.AppendFixed64(b, uint64(v.Int()))
+	}
+	return b, nil
+}
+
+var coderSfixed64PackedSliceValue = valueCoderFuncs{
+	size:      sizeSfixed64PackedSliceValue,
+	marshal:   appendSfixed64PackedSliceValue,
+	unmarshal: consumeSfixed64SliceValue,
+	merge:     mergeListValue,
+}
+
+// sizeFixed64 returns the size of wire encoding a uint64 pointer as a Fixed64.
+func sizeFixed64(p pointer, f *coderFieldInfo, _ marshalOptions) (size int) {
+
+	return f.tagsize + protowire.SizeFixed64()
+}
+
+// appendFixed64 wire encodes a uint64 pointer as a Fixed64.
+func appendFixed64(b []byte, p pointer, f *coderFieldInfo, _ marshalOptions) ([]byte, error) {
+	v := *p.Uint64()
+	b = protowire.AppendVarint(b, f.wiretag)
+	b = protowire.AppendFixed64(b, v)
+	return b, nil
+}
+
+// consumeFixed64 wire decodes a uint64 pointer as a Fixed64.
+func consumeFixed64(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, _ unmarshalOptions) (out unmarshalOutput, err error) {
+	if wtyp != protowire.Fixed64Type {
+		return out, errUnknown
+	}
+	v, n := protowire.ConsumeFixed64(b)
+	if n < 0 {
+		return out, protowire.ParseError(n)
+	}
+	*p.Uint64() = v
+	out.n = n
+	return out, nil
+}
+
+var coderFixed64 = pointerCoderFuncs{
+	size:      sizeFixed64,
+	marshal:   appendFixed64,
+	unmarshal: consumeFixed64,
+	merge:     mergeUint64,
+}
+
+// sizeFixed64NoZero returns the size of wire encoding a uint64 pointer as a Fixed64.
+// The zero value is not encoded.
+func sizeFixed64NoZero(p pointer, f *coderFieldInfo, _ marshalOptions) (size int) {
+	v := *p.Uint64()
+	if v == 0 {
+		return 0
+	}
+	return f.tagsize + protowire.SizeFixed64()
+}
+
+// appendFixed64NoZero wire encodes a uint64 pointer as a Fixed64.
+// The zero value is not encoded.
+func appendFixed64NoZero(b []byte, p pointer, f *coderFieldInfo, _ marshalOptions) ([]byte, error) {
+	v := *p.Uint64()
+	if v == 0 {
+		return b, nil
+	}
+	b = protowire.AppendVarint(b, f.wiretag)
+	b = protowire.AppendFixed64(b, v)
+	return b, nil
+}
+
+var coderFixed64NoZero = pointerCoderFuncs{
+	size:      sizeFixed64NoZero,
+	marshal:   appendFixed64NoZero,
+	unmarshal: consumeFixed64,
+	merge:     mergeUint64NoZero,
+}
+
+// sizeFixed64Ptr returns the size of wire encoding a *uint64 pointer as a Fixed64.
+// It panics if the pointer is nil.
+func sizeFixed64Ptr(p pointer, f *coderFieldInfo, _ marshalOptions) (size int) {
+	return f.tagsize + protowire.SizeFixed64()
+}
+
+// appendFixed64Ptr wire encodes a *uint64 pointer as a Fixed64.
+// It panics if the pointer is nil.
+func appendFixed64Ptr(b []byte, p pointer, f *coderFieldInfo, _ marshalOptions) ([]byte, error) {
+	v := **p.Uint64Ptr()
+	b = protowire.AppendVarint(b, f.wiretag)
+	b = protowire.AppendFixed64(b, v)
+	return b, nil
+}
+
+// consumeFixed64Ptr wire decodes a *uint64 pointer as a Fixed64.
+func consumeFixed64Ptr(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, _ unmarshalOptions) (out unmarshalOutput, err error) {
+	if wtyp != protowire.Fixed64Type {
+		return out, errUnknown
+	}
+	v, n := protowire.ConsumeFixed64(b)
+	if n < 0 {
+		return out, protowire.ParseError(n)
+	}
+	vp := p.Uint64Ptr()
+	if *vp == nil {
+		*vp = new(uint64)
+	}
+	**vp = v
+	out.n = n
+	return out, nil
+}
+
+var coderFixed64Ptr = pointerCoderFuncs{
+	size:      sizeFixed64Ptr,
+	marshal:   appendFixed64Ptr,
+	unmarshal: consumeFixed64Ptr,
+	merge:     mergeUint64Ptr,
+}
+
+// sizeFixed64Slice returns the size of wire encoding a []uint64 pointer as a repeated Fixed64.
+func sizeFixed64Slice(p pointer, f *coderFieldInfo, _ marshalOptions) (size int) {
+	s := *p.Uint64Slice()
+	size = len(s) * (f.tagsize + protowire.SizeFixed64())
+	return size
+}
+
+// appendFixed64Slice encodes a []uint64 pointer as a repeated Fixed64.
+func appendFixed64Slice(b []byte, p pointer, f *coderFieldInfo, _ marshalOptions) ([]byte, error) {
+	s := *p.Uint64Slice()
+	for _, v := range s {
+		b = protowire.AppendVarint(b, f.wiretag)
+		b = protowire.AppendFixed64(b, v)
+	}
+	return b, nil
+}
+
+// consumeFixed64Slice wire decodes a []uint64 pointer as a repeated Fixed64.
+func consumeFixed64Slice(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, _ unmarshalOptions) (out unmarshalOutput, err error) {
+	sp := p.Uint64Slice()
+	if wtyp == protowire.BytesType {
+		s := *sp
+		b, n := protowire.ConsumeBytes(b)
+		if n < 0 {
+			return out, protowire.ParseError(n)
+		}
+		for len(b) > 0 {
+			v, n := protowire.ConsumeFixed64(b)
+			if n < 0 {
+				return out, protowire.ParseError(n)
+			}
+			s = append(s, v)
+			b = b[n:]
+		}
+		*sp = s
+		out.n = n
+		return out, nil
+	}
+	if wtyp != protowire.Fixed64Type {
+		return out, errUnknown
+	}
+	v, n := protowire.ConsumeFixed64(b)
+	if n < 0 {
+		return out, protowire.ParseError(n)
+	}
+	*sp = append(*sp, v)
+	out.n = n
+	return out, nil
+}
+
+var coderFixed64Slice = pointerCoderFuncs{
+	size:      sizeFixed64Slice,
+	marshal:   appendFixed64Slice,
+	unmarshal: consumeFixed64Slice,
+	merge:     mergeUint64Slice,
+}
+
+// sizeFixed64PackedSlice returns the size of wire encoding a []uint64 pointer as a packed repeated Fixed64.
+func sizeFixed64PackedSlice(p pointer, f *coderFieldInfo, _ marshalOptions) (size int) {
+	s := *p.Uint64Slice()
+	if len(s) == 0 {
+		return 0
+	}
+	n := len(s) * protowire.SizeFixed64()
+	return f.tagsize + protowire.SizeBytes(n)
+}
+
+// appendFixed64PackedSlice encodes a []uint64 pointer as a packed repeated Fixed64.
+func appendFixed64PackedSlice(b []byte, p pointer, f *coderFieldInfo, _ marshalOptions) ([]byte, error) {
+	s := *p.Uint64Slice()
+	if len(s) == 0 {
+		return b, nil
+	}
+	b = protowire.AppendVarint(b, f.wiretag)
+	n := len(s) * protowire.SizeFixed64()
+	b = protowire.AppendVarint(b, uint64(n))
+	for _, v := range s {
+		b = protowire.AppendFixed64(b, v)
+	}
+	return b, nil
+}
+
+var coderFixed64PackedSlice = pointerCoderFuncs{
+	size:      sizeFixed64PackedSlice,
+	marshal:   appendFixed64PackedSlice,
+	unmarshal: consumeFixed64Slice,
+	merge:     mergeUint64Slice,
+}
+
+// sizeFixed64Value returns the size of wire encoding a uint64 value as a Fixed64.
+func sizeFixed64Value(v protoreflect.Value, tagsize int, _ marshalOptions) int {
+	return tagsize + protowire.SizeFixed64()
+}
+
+// appendFixed64Value encodes a uint64 value as a Fixed64.
+func appendFixed64Value(b []byte, v protoreflect.Value, wiretag uint64, _ marshalOptions) ([]byte, error) {
+	b = protowire.AppendVarint(b, wiretag)
+	b = protowire.AppendFixed64(b, v.Uint())
+	return b, nil
+}
+
+// consumeFixed64Value decodes a uint64 value as a Fixed64.
+func consumeFixed64Value(b []byte, _ protoreflect.Value, _ protowire.Number, wtyp protowire.Type, _ unmarshalOptions) (_ protoreflect.Value, out unmarshalOutput, err error) {
+	if wtyp != protowire.Fixed64Type {
+		return protoreflect.Value{}, out, errUnknown
+	}
+	v, n := protowire.ConsumeFixed64(b)
+	if n < 0 {
+		return protoreflect.Value{}, out, protowire.ParseError(n)
+	}
+	out.n = n
+	return protoreflect.ValueOfUint64(v), out, nil
+}
+
+var coderFixed64Value = valueCoderFuncs{
+	size:      sizeFixed64Value,
+	marshal:   appendFixed64Value,
+	unmarshal: consumeFixed64Value,
+	merge:     mergeScalarValue,
+}
+
+// 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 + protowire.SizeFixed64())
+	return size
+}
+
+// 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 = protowire.AppendVarint(b, wiretag)
+		b = protowire.AppendFixed64(b, v.Uint())
+	}
+	return b, nil
+}
+
+// consumeFixed64SliceValue wire decodes a []uint64 value as a repeated Fixed64.
+func consumeFixed64SliceValue(b []byte, listv protoreflect.Value, _ protowire.Number, wtyp protowire.Type, _ unmarshalOptions) (_ protoreflect.Value, out unmarshalOutput, err error) {
+	list := listv.List()
+	if wtyp == protowire.BytesType {
+		b, n := protowire.ConsumeBytes(b)
+		if n < 0 {
+			return protoreflect.Value{}, out, protowire.ParseError(n)
+		}
+		for len(b) > 0 {
+			v, n := protowire.ConsumeFixed64(b)
+			if n < 0 {
+				return protoreflect.Value{}, out, protowire.ParseError(n)
+			}
+			list.Append(protoreflect.ValueOfUint64(v))
+			b = b[n:]
+		}
+		out.n = n
+		return listv, out, nil
+	}
+	if wtyp != protowire.Fixed64Type {
+		return protoreflect.Value{}, out, errUnknown
+	}
+	v, n := protowire.ConsumeFixed64(b)
+	if n < 0 {
+		return protoreflect.Value{}, out, protowire.ParseError(n)
+	}
+	list.Append(protoreflect.ValueOfUint64(v))
+	out.n = n
+	return listv, out, nil
+}
+
+var coderFixed64SliceValue = valueCoderFuncs{
+	size:      sizeFixed64SliceValue,
+	marshal:   appendFixed64SliceValue,
+	unmarshal: consumeFixed64SliceValue,
+	merge:     mergeListValue,
+}
+
+// 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()
+	llen := list.Len()
+	if llen == 0 {
+		return 0
+	}
+	n := llen * protowire.SizeFixed64()
+	return tagsize + protowire.SizeBytes(n)
+}
+
+// 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 = protowire.AppendVarint(b, wiretag)
+	n := llen * protowire.SizeFixed64()
+	b = protowire.AppendVarint(b, uint64(n))
+	for i := 0; i < llen; i++ {
+		v := list.Get(i)
+		b = protowire.AppendFixed64(b, v.Uint())
+	}
+	return b, nil
+}
+
+var coderFixed64PackedSliceValue = valueCoderFuncs{
+	size:      sizeFixed64PackedSliceValue,
+	marshal:   appendFixed64PackedSliceValue,
+	unmarshal: consumeFixed64SliceValue,
+	merge:     mergeListValue,
+}
+
+// sizeDouble returns the size of wire encoding a float64 pointer as a Double.
+func sizeDouble(p pointer, f *coderFieldInfo, _ marshalOptions) (size int) {
+
+	return f.tagsize + protowire.SizeFixed64()
+}
+
+// appendDouble wire encodes a float64 pointer as a Double.
+func appendDouble(b []byte, p pointer, f *coderFieldInfo, _ marshalOptions) ([]byte, error) {
+	v := *p.Float64()
+	b = protowire.AppendVarint(b, f.wiretag)
+	b = protowire.AppendFixed64(b, math.Float64bits(v))
+	return b, nil
+}
+
+// consumeDouble wire decodes a float64 pointer as a Double.
+func consumeDouble(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, _ unmarshalOptions) (out unmarshalOutput, err error) {
+	if wtyp != protowire.Fixed64Type {
+		return out, errUnknown
+	}
+	v, n := protowire.ConsumeFixed64(b)
+	if n < 0 {
+		return out, protowire.ParseError(n)
+	}
+	*p.Float64() = math.Float64frombits(v)
+	out.n = n
+	return out, nil
+}
+
+var coderDouble = pointerCoderFuncs{
+	size:      sizeDouble,
+	marshal:   appendDouble,
+	unmarshal: consumeDouble,
+	merge:     mergeFloat64,
+}
+
+// sizeDoubleNoZero returns the size of wire encoding a float64 pointer as a Double.
+// The zero value is not encoded.
+func sizeDoubleNoZero(p pointer, f *coderFieldInfo, _ marshalOptions) (size int) {
+	v := *p.Float64()
+	if v == 0 && !math.Signbit(float64(v)) {
+		return 0
+	}
+	return f.tagsize + protowire.SizeFixed64()
+}
+
+// appendDoubleNoZero wire encodes a float64 pointer as a Double.
+// The zero value is not encoded.
+func appendDoubleNoZero(b []byte, p pointer, f *coderFieldInfo, _ marshalOptions) ([]byte, error) {
+	v := *p.Float64()
+	if v == 0 && !math.Signbit(float64(v)) {
+		return b, nil
+	}
+	b = protowire.AppendVarint(b, f.wiretag)
+	b = protowire.AppendFixed64(b, math.Float64bits(v))
+	return b, nil
+}
+
+var coderDoubleNoZero = pointerCoderFuncs{
+	size:      sizeDoubleNoZero,
+	marshal:   appendDoubleNoZero,
+	unmarshal: consumeDouble,
+	merge:     mergeFloat64NoZero,
+}
+
+// sizeDoublePtr returns the size of wire encoding a *float64 pointer as a Double.
+// It panics if the pointer is nil.
+func sizeDoublePtr(p pointer, f *coderFieldInfo, _ marshalOptions) (size int) {
+	return f.tagsize + protowire.SizeFixed64()
+}
+
+// appendDoublePtr wire encodes a *float64 pointer as a Double.
+// It panics if the pointer is nil.
+func appendDoublePtr(b []byte, p pointer, f *coderFieldInfo, _ marshalOptions) ([]byte, error) {
+	v := **p.Float64Ptr()
+	b = protowire.AppendVarint(b, f.wiretag)
+	b = protowire.AppendFixed64(b, math.Float64bits(v))
+	return b, nil
+}
+
+// consumeDoublePtr wire decodes a *float64 pointer as a Double.
+func consumeDoublePtr(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, _ unmarshalOptions) (out unmarshalOutput, err error) {
+	if wtyp != protowire.Fixed64Type {
+		return out, errUnknown
+	}
+	v, n := protowire.ConsumeFixed64(b)
+	if n < 0 {
+		return out, protowire.ParseError(n)
+	}
+	vp := p.Float64Ptr()
+	if *vp == nil {
+		*vp = new(float64)
+	}
+	**vp = math.Float64frombits(v)
+	out.n = n
+	return out, nil
+}
+
+var coderDoublePtr = pointerCoderFuncs{
+	size:      sizeDoublePtr,
+	marshal:   appendDoublePtr,
+	unmarshal: consumeDoublePtr,
+	merge:     mergeFloat64Ptr,
+}
+
+// sizeDoubleSlice returns the size of wire encoding a []float64 pointer as a repeated Double.
+func sizeDoubleSlice(p pointer, f *coderFieldInfo, _ marshalOptions) (size int) {
+	s := *p.Float64Slice()
+	size = len(s) * (f.tagsize + protowire.SizeFixed64())
+	return size
+}
+
+// appendDoubleSlice encodes a []float64 pointer as a repeated Double.
+func appendDoubleSlice(b []byte, p pointer, f *coderFieldInfo, _ marshalOptions) ([]byte, error) {
+	s := *p.Float64Slice()
+	for _, v := range s {
+		b = protowire.AppendVarint(b, f.wiretag)
+		b = protowire.AppendFixed64(b, math.Float64bits(v))
+	}
+	return b, nil
+}
+
+// consumeDoubleSlice wire decodes a []float64 pointer as a repeated Double.
+func consumeDoubleSlice(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, _ unmarshalOptions) (out unmarshalOutput, err error) {
+	sp := p.Float64Slice()
+	if wtyp == protowire.BytesType {
+		s := *sp
+		b, n := protowire.ConsumeBytes(b)
+		if n < 0 {
+			return out, protowire.ParseError(n)
+		}
+		for len(b) > 0 {
+			v, n := protowire.ConsumeFixed64(b)
+			if n < 0 {
+				return out, protowire.ParseError(n)
+			}
+			s = append(s, math.Float64frombits(v))
+			b = b[n:]
+		}
+		*sp = s
+		out.n = n
+		return out, nil
+	}
+	if wtyp != protowire.Fixed64Type {
+		return out, errUnknown
+	}
+	v, n := protowire.ConsumeFixed64(b)
+	if n < 0 {
+		return out, protowire.ParseError(n)
+	}
+	*sp = append(*sp, math.Float64frombits(v))
+	out.n = n
+	return out, nil
+}
+
+var coderDoubleSlice = pointerCoderFuncs{
+	size:      sizeDoubleSlice,
+	marshal:   appendDoubleSlice,
+	unmarshal: consumeDoubleSlice,
+	merge:     mergeFloat64Slice,
+}
+
+// sizeDoublePackedSlice returns the size of wire encoding a []float64 pointer as a packed repeated Double.
+func sizeDoublePackedSlice(p pointer, f *coderFieldInfo, _ marshalOptions) (size int) {
+	s := *p.Float64Slice()
+	if len(s) == 0 {
+		return 0
+	}
+	n := len(s) * protowire.SizeFixed64()
+	return f.tagsize + protowire.SizeBytes(n)
+}
+
+// appendDoublePackedSlice encodes a []float64 pointer as a packed repeated Double.
+func appendDoublePackedSlice(b []byte, p pointer, f *coderFieldInfo, _ marshalOptions) ([]byte, error) {
+	s := *p.Float64Slice()
+	if len(s) == 0 {
+		return b, nil
+	}
+	b = protowire.AppendVarint(b, f.wiretag)
+	n := len(s) * protowire.SizeFixed64()
+	b = protowire.AppendVarint(b, uint64(n))
+	for _, v := range s {
+		b = protowire.AppendFixed64(b, math.Float64bits(v))
+	}
+	return b, nil
+}
+
+var coderDoublePackedSlice = pointerCoderFuncs{
+	size:      sizeDoublePackedSlice,
+	marshal:   appendDoublePackedSlice,
+	unmarshal: consumeDoubleSlice,
+	merge:     mergeFloat64Slice,
+}
+
+// sizeDoubleValue returns the size of wire encoding a float64 value as a Double.
+func sizeDoubleValue(v protoreflect.Value, tagsize int, _ marshalOptions) int {
+	return tagsize + protowire.SizeFixed64()
+}
+
+// appendDoubleValue encodes a float64 value as a Double.
+func appendDoubleValue(b []byte, v protoreflect.Value, wiretag uint64, _ marshalOptions) ([]byte, error) {
+	b = protowire.AppendVarint(b, wiretag)
+	b = protowire.AppendFixed64(b, math.Float64bits(v.Float()))
+	return b, nil
+}
+
+// consumeDoubleValue decodes a float64 value as a Double.
+func consumeDoubleValue(b []byte, _ protoreflect.Value, _ protowire.Number, wtyp protowire.Type, _ unmarshalOptions) (_ protoreflect.Value, out unmarshalOutput, err error) {
+	if wtyp != protowire.Fixed64Type {
+		return protoreflect.Value{}, out, errUnknown
+	}
+	v, n := protowire.ConsumeFixed64(b)
+	if n < 0 {
+		return protoreflect.Value{}, out, protowire.ParseError(n)
+	}
+	out.n = n
+	return protoreflect.ValueOfFloat64(math.Float64frombits(v)), out, nil
+}
+
+var coderDoubleValue = valueCoderFuncs{
+	size:      sizeDoubleValue,
+	marshal:   appendDoubleValue,
+	unmarshal: consumeDoubleValue,
+	merge:     mergeScalarValue,
+}
+
+// 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 + protowire.SizeFixed64())
+	return size
+}
+
+// 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 = protowire.AppendVarint(b, wiretag)
+		b = protowire.AppendFixed64(b, math.Float64bits(v.Float()))
+	}
+	return b, nil
+}
+
+// consumeDoubleSliceValue wire decodes a []float64 value as a repeated Double.
+func consumeDoubleSliceValue(b []byte, listv protoreflect.Value, _ protowire.Number, wtyp protowire.Type, _ unmarshalOptions) (_ protoreflect.Value, out unmarshalOutput, err error) {
+	list := listv.List()
+	if wtyp == protowire.BytesType {
+		b, n := protowire.ConsumeBytes(b)
+		if n < 0 {
+			return protoreflect.Value{}, out, protowire.ParseError(n)
+		}
+		for len(b) > 0 {
+			v, n := protowire.ConsumeFixed64(b)
+			if n < 0 {
+				return protoreflect.Value{}, out, protowire.ParseError(n)
+			}
+			list.Append(protoreflect.ValueOfFloat64(math.Float64frombits(v)))
+			b = b[n:]
+		}
+		out.n = n
+		return listv, out, nil
+	}
+	if wtyp != protowire.Fixed64Type {
+		return protoreflect.Value{}, out, errUnknown
+	}
+	v, n := protowire.ConsumeFixed64(b)
+	if n < 0 {
+		return protoreflect.Value{}, out, protowire.ParseError(n)
+	}
+	list.Append(protoreflect.ValueOfFloat64(math.Float64frombits(v)))
+	out.n = n
+	return listv, out, nil
+}
+
+var coderDoubleSliceValue = valueCoderFuncs{
+	size:      sizeDoubleSliceValue,
+	marshal:   appendDoubleSliceValue,
+	unmarshal: consumeDoubleSliceValue,
+	merge:     mergeListValue,
+}
+
+// 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()
+	llen := list.Len()
+	if llen == 0 {
+		return 0
+	}
+	n := llen * protowire.SizeFixed64()
+	return tagsize + protowire.SizeBytes(n)
+}
+
+// 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 = protowire.AppendVarint(b, wiretag)
+	n := llen * protowire.SizeFixed64()
+	b = protowire.AppendVarint(b, uint64(n))
+	for i := 0; i < llen; i++ {
+		v := list.Get(i)
+		b = protowire.AppendFixed64(b, math.Float64bits(v.Float()))
+	}
+	return b, nil
+}
+
+var coderDoublePackedSliceValue = valueCoderFuncs{
+	size:      sizeDoublePackedSliceValue,
+	marshal:   appendDoublePackedSliceValue,
+	unmarshal: consumeDoubleSliceValue,
+	merge:     mergeListValue,
+}
+
+// sizeString returns the size of wire encoding a string pointer as a String.
+func sizeString(p pointer, f *coderFieldInfo, _ marshalOptions) (size int) {
+	v := *p.String()
+	return f.tagsize + protowire.SizeBytes(len(v))
+}
+
+// appendString wire encodes a string pointer as a String.
+func appendString(b []byte, p pointer, f *coderFieldInfo, _ marshalOptions) ([]byte, error) {
+	v := *p.String()
+	b = protowire.AppendVarint(b, f.wiretag)
+	b = protowire.AppendString(b, v)
+	return b, nil
+}
+
+// consumeString wire decodes a string pointer as a String.
+func consumeString(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, _ unmarshalOptions) (out unmarshalOutput, err error) {
+	if wtyp != protowire.BytesType {
+		return out, errUnknown
+	}
+	v, n := protowire.ConsumeString(b)
+	if n < 0 {
+		return out, protowire.ParseError(n)
+	}
+	*p.String() = v
+	out.n = n
+	return out, nil
+}
+
+var coderString = pointerCoderFuncs{
+	size:      sizeString,
+	marshal:   appendString,
+	unmarshal: consumeString,
+	merge:     mergeString,
+}
+
+// appendStringValidateUTF8 wire encodes a string pointer as a String.
+func appendStringValidateUTF8(b []byte, p pointer, f *coderFieldInfo, _ marshalOptions) ([]byte, error) {
+	v := *p.String()
+	b = protowire.AppendVarint(b, f.wiretag)
+	b = protowire.AppendString(b, v)
+	if !utf8.ValidString(v) {
+		return b, errInvalidUTF8{}
+	}
+	return b, nil
+}
+
+// consumeStringValidateUTF8 wire decodes a string pointer as a String.
+func consumeStringValidateUTF8(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, _ unmarshalOptions) (out unmarshalOutput, err error) {
+	if wtyp != protowire.BytesType {
+		return out, errUnknown
+	}
+	v, n := protowire.ConsumeString(b)
+	if n < 0 {
+		return out, protowire.ParseError(n)
+	}
+	if !utf8.ValidString(v) {
+		return out, errInvalidUTF8{}
+	}
+	*p.String() = v
+	out.n = n
+	return out, nil
+}
+
+var coderStringValidateUTF8 = pointerCoderFuncs{
+	size:      sizeString,
+	marshal:   appendStringValidateUTF8,
+	unmarshal: consumeStringValidateUTF8,
+	merge:     mergeString,
+}
+
+// sizeStringNoZero returns the size of wire encoding a string pointer as a String.
+// The zero value is not encoded.
+func sizeStringNoZero(p pointer, f *coderFieldInfo, _ marshalOptions) (size int) {
+	v := *p.String()
+	if len(v) == 0 {
+		return 0
+	}
+	return f.tagsize + protowire.SizeBytes(len(v))
+}
+
+// appendStringNoZero wire encodes a string pointer as a String.
+// The zero value is not encoded.
+func appendStringNoZero(b []byte, p pointer, f *coderFieldInfo, _ marshalOptions) ([]byte, error) {
+	v := *p.String()
+	if len(v) == 0 {
+		return b, nil
+	}
+	b = protowire.AppendVarint(b, f.wiretag)
+	b = protowire.AppendString(b, v)
+	return b, nil
+}
+
+var coderStringNoZero = pointerCoderFuncs{
+	size:      sizeStringNoZero,
+	marshal:   appendStringNoZero,
+	unmarshal: consumeString,
+	merge:     mergeStringNoZero,
+}
+
+// appendStringNoZeroValidateUTF8 wire encodes a string pointer as a String.
+// The zero value is not encoded.
+func appendStringNoZeroValidateUTF8(b []byte, p pointer, f *coderFieldInfo, _ marshalOptions) ([]byte, error) {
+	v := *p.String()
+	if len(v) == 0 {
+		return b, nil
+	}
+	b = protowire.AppendVarint(b, f.wiretag)
+	b = protowire.AppendString(b, v)
+	if !utf8.ValidString(v) {
+		return b, errInvalidUTF8{}
+	}
+	return b, nil
+}
+
+var coderStringNoZeroValidateUTF8 = pointerCoderFuncs{
+	size:      sizeStringNoZero,
+	marshal:   appendStringNoZeroValidateUTF8,
+	unmarshal: consumeStringValidateUTF8,
+	merge:     mergeStringNoZero,
+}
+
+// sizeStringPtr returns the size of wire encoding a *string pointer as a String.
+// It panics if the pointer is nil.
+func sizeStringPtr(p pointer, f *coderFieldInfo, _ marshalOptions) (size int) {
+	v := **p.StringPtr()
+	return f.tagsize + protowire.SizeBytes(len(v))
+}
+
+// appendStringPtr wire encodes a *string pointer as a String.
+// It panics if the pointer is nil.
+func appendStringPtr(b []byte, p pointer, f *coderFieldInfo, _ marshalOptions) ([]byte, error) {
+	v := **p.StringPtr()
+	b = protowire.AppendVarint(b, f.wiretag)
+	b = protowire.AppendString(b, v)
+	return b, nil
+}
+
+// consumeStringPtr wire decodes a *string pointer as a String.
+func consumeStringPtr(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, _ unmarshalOptions) (out unmarshalOutput, err error) {
+	if wtyp != protowire.BytesType {
+		return out, errUnknown
+	}
+	v, n := protowire.ConsumeString(b)
+	if n < 0 {
+		return out, protowire.ParseError(n)
+	}
+	vp := p.StringPtr()
+	if *vp == nil {
+		*vp = new(string)
+	}
+	**vp = v
+	out.n = n
+	return out, nil
+}
+
+var coderStringPtr = pointerCoderFuncs{
+	size:      sizeStringPtr,
+	marshal:   appendStringPtr,
+	unmarshal: consumeStringPtr,
+	merge:     mergeStringPtr,
+}
+
+// appendStringPtrValidateUTF8 wire encodes a *string pointer as a String.
+// It panics if the pointer is nil.
+func appendStringPtrValidateUTF8(b []byte, p pointer, f *coderFieldInfo, _ marshalOptions) ([]byte, error) {
+	v := **p.StringPtr()
+	b = protowire.AppendVarint(b, f.wiretag)
+	b = protowire.AppendString(b, v)
+	if !utf8.ValidString(v) {
+		return b, errInvalidUTF8{}
+	}
+	return b, nil
+}
+
+// consumeStringPtrValidateUTF8 wire decodes a *string pointer as a String.
+func consumeStringPtrValidateUTF8(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, _ unmarshalOptions) (out unmarshalOutput, err error) {
+	if wtyp != protowire.BytesType {
+		return out, errUnknown
+	}
+	v, n := protowire.ConsumeString(b)
+	if n < 0 {
+		return out, protowire.ParseError(n)
+	}
+	if !utf8.ValidString(v) {
+		return out, errInvalidUTF8{}
+	}
+	vp := p.StringPtr()
+	if *vp == nil {
+		*vp = new(string)
+	}
+	**vp = v
+	out.n = n
+	return out, nil
+}
+
+var coderStringPtrValidateUTF8 = pointerCoderFuncs{
+	size:      sizeStringPtr,
+	marshal:   appendStringPtrValidateUTF8,
+	unmarshal: consumeStringPtrValidateUTF8,
+	merge:     mergeStringPtr,
+}
+
+// sizeStringSlice returns the size of wire encoding a []string pointer as a repeated String.
+func sizeStringSlice(p pointer, f *coderFieldInfo, _ marshalOptions) (size int) {
+	s := *p.StringSlice()
+	for _, v := range s {
+		size += f.tagsize + protowire.SizeBytes(len(v))
+	}
+	return size
+}
+
+// appendStringSlice encodes a []string pointer as a repeated String.
+func appendStringSlice(b []byte, p pointer, f *coderFieldInfo, _ marshalOptions) ([]byte, error) {
+	s := *p.StringSlice()
+	for _, v := range s {
+		b = protowire.AppendVarint(b, f.wiretag)
+		b = protowire.AppendString(b, v)
+	}
+	return b, nil
+}
+
+// consumeStringSlice wire decodes a []string pointer as a repeated String.
+func consumeStringSlice(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, _ unmarshalOptions) (out unmarshalOutput, err error) {
+	sp := p.StringSlice()
+	if wtyp != protowire.BytesType {
+		return out, errUnknown
+	}
+	v, n := protowire.ConsumeString(b)
+	if n < 0 {
+		return out, protowire.ParseError(n)
+	}
+	*sp = append(*sp, v)
+	out.n = n
+	return out, nil
+}
+
+var coderStringSlice = pointerCoderFuncs{
+	size:      sizeStringSlice,
+	marshal:   appendStringSlice,
+	unmarshal: consumeStringSlice,
+	merge:     mergeStringSlice,
+}
+
+// appendStringSliceValidateUTF8 encodes a []string pointer as a repeated String.
+func appendStringSliceValidateUTF8(b []byte, p pointer, f *coderFieldInfo, _ marshalOptions) ([]byte, error) {
+	s := *p.StringSlice()
+	for _, v := range s {
+		b = protowire.AppendVarint(b, f.wiretag)
+		b = protowire.AppendString(b, v)
+		if !utf8.ValidString(v) {
+			return b, errInvalidUTF8{}
+		}
+	}
+	return b, nil
+}
+
+// consumeStringSliceValidateUTF8 wire decodes a []string pointer as a repeated String.
+func consumeStringSliceValidateUTF8(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, _ unmarshalOptions) (out unmarshalOutput, err error) {
+	sp := p.StringSlice()
+	if wtyp != protowire.BytesType {
+		return out, errUnknown
+	}
+	v, n := protowire.ConsumeString(b)
+	if n < 0 {
+		return out, protowire.ParseError(n)
+	}
+	if !utf8.ValidString(v) {
+		return out, errInvalidUTF8{}
+	}
+	*sp = append(*sp, v)
+	out.n = n
+	return out, nil
+}
+
+var coderStringSliceValidateUTF8 = pointerCoderFuncs{
+	size:      sizeStringSlice,
+	marshal:   appendStringSliceValidateUTF8,
+	unmarshal: consumeStringSliceValidateUTF8,
+	merge:     mergeStringSlice,
+}
+
+// sizeStringValue returns the size of wire encoding a string value as a String.
+func sizeStringValue(v protoreflect.Value, tagsize int, _ marshalOptions) int {
+	return tagsize + protowire.SizeBytes(len(v.String()))
+}
+
+// appendStringValue encodes a string value as a String.
+func appendStringValue(b []byte, v protoreflect.Value, wiretag uint64, _ marshalOptions) ([]byte, error) {
+	b = protowire.AppendVarint(b, wiretag)
+	b = protowire.AppendString(b, v.String())
+	return b, nil
+}
+
+// consumeStringValue decodes a string value as a String.
+func consumeStringValue(b []byte, _ protoreflect.Value, _ protowire.Number, wtyp protowire.Type, _ unmarshalOptions) (_ protoreflect.Value, out unmarshalOutput, err error) {
+	if wtyp != protowire.BytesType {
+		return protoreflect.Value{}, out, errUnknown
+	}
+	v, n := protowire.ConsumeString(b)
+	if n < 0 {
+		return protoreflect.Value{}, out, protowire.ParseError(n)
+	}
+	out.n = n
+	return protoreflect.ValueOfString(string(v)), out, nil
+}
+
+var coderStringValue = valueCoderFuncs{
+	size:      sizeStringValue,
+	marshal:   appendStringValue,
+	unmarshal: consumeStringValue,
+	merge:     mergeScalarValue,
+}
+
+// appendStringValueValidateUTF8 encodes a string value as a String.
+func appendStringValueValidateUTF8(b []byte, v protoreflect.Value, wiretag uint64, _ marshalOptions) ([]byte, error) {
+	b = protowire.AppendVarint(b, wiretag)
+	b = protowire.AppendString(b, v.String())
+	if !utf8.ValidString(v.String()) {
+		return b, errInvalidUTF8{}
+	}
+	return b, nil
+}
+
+// consumeStringValueValidateUTF8 decodes a string value as a String.
+func consumeStringValueValidateUTF8(b []byte, _ protoreflect.Value, _ protowire.Number, wtyp protowire.Type, _ unmarshalOptions) (_ protoreflect.Value, out unmarshalOutput, err error) {
+	if wtyp != protowire.BytesType {
+		return protoreflect.Value{}, out, errUnknown
+	}
+	v, n := protowire.ConsumeString(b)
+	if n < 0 {
+		return protoreflect.Value{}, out, protowire.ParseError(n)
+	}
+	if !utf8.ValidString(v) {
+		return protoreflect.Value{}, out, errInvalidUTF8{}
+	}
+	out.n = n
+	return protoreflect.ValueOfString(string(v)), out, nil
+}
+
+var coderStringValueValidateUTF8 = valueCoderFuncs{
+	size:      sizeStringValue,
+	marshal:   appendStringValueValidateUTF8,
+	unmarshal: consumeStringValueValidateUTF8,
+	merge:     mergeScalarValue,
+}
+
+// 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 + protowire.SizeBytes(len(v.String()))
+	}
+	return size
+}
+
+// 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 = protowire.AppendVarint(b, wiretag)
+		b = protowire.AppendString(b, v.String())
+	}
+	return b, nil
+}
+
+// consumeStringSliceValue wire decodes a []string value as a repeated String.
+func consumeStringSliceValue(b []byte, listv protoreflect.Value, _ protowire.Number, wtyp protowire.Type, _ unmarshalOptions) (_ protoreflect.Value, out unmarshalOutput, err error) {
+	list := listv.List()
+	if wtyp != protowire.BytesType {
+		return protoreflect.Value{}, out, errUnknown
+	}
+	v, n := protowire.ConsumeString(b)
+	if n < 0 {
+		return protoreflect.Value{}, out, protowire.ParseError(n)
+	}
+	list.Append(protoreflect.ValueOfString(string(v)))
+	out.n = n
+	return listv, out, nil
+}
+
+var coderStringSliceValue = valueCoderFuncs{
+	size:      sizeStringSliceValue,
+	marshal:   appendStringSliceValue,
+	unmarshal: consumeStringSliceValue,
+	merge:     mergeListValue,
+}
+
+// sizeBytes returns the size of wire encoding a []byte pointer as a Bytes.
+func sizeBytes(p pointer, f *coderFieldInfo, _ marshalOptions) (size int) {
+	v := *p.Bytes()
+	return f.tagsize + protowire.SizeBytes(len(v))
+}
+
+// appendBytes wire encodes a []byte pointer as a Bytes.
+func appendBytes(b []byte, p pointer, f *coderFieldInfo, _ marshalOptions) ([]byte, error) {
+	v := *p.Bytes()
+	b = protowire.AppendVarint(b, f.wiretag)
+	b = protowire.AppendBytes(b, v)
+	return b, nil
+}
+
+// consumeBytes wire decodes a []byte pointer as a Bytes.
+func consumeBytes(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, _ unmarshalOptions) (out unmarshalOutput, err error) {
+	if wtyp != protowire.BytesType {
+		return out, errUnknown
+	}
+	v, n := protowire.ConsumeBytes(b)
+	if n < 0 {
+		return out, protowire.ParseError(n)
+	}
+	*p.Bytes() = append(emptyBuf[:], v...)
+	out.n = n
+	return out, nil
+}
+
+var coderBytes = pointerCoderFuncs{
+	size:      sizeBytes,
+	marshal:   appendBytes,
+	unmarshal: consumeBytes,
+	merge:     mergeBytes,
+}
+
+// appendBytesValidateUTF8 wire encodes a []byte pointer as a Bytes.
+func appendBytesValidateUTF8(b []byte, p pointer, f *coderFieldInfo, _ marshalOptions) ([]byte, error) {
+	v := *p.Bytes()
+	b = protowire.AppendVarint(b, f.wiretag)
+	b = protowire.AppendBytes(b, v)
+	if !utf8.Valid(v) {
+		return b, errInvalidUTF8{}
+	}
+	return b, nil
+}
+
+// consumeBytesValidateUTF8 wire decodes a []byte pointer as a Bytes.
+func consumeBytesValidateUTF8(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, _ unmarshalOptions) (out unmarshalOutput, err error) {
+	if wtyp != protowire.BytesType {
+		return out, errUnknown
+	}
+	v, n := protowire.ConsumeBytes(b)
+	if n < 0 {
+		return out, protowire.ParseError(n)
+	}
+	if !utf8.Valid(v) {
+		return out, errInvalidUTF8{}
+	}
+	*p.Bytes() = append(emptyBuf[:], v...)
+	out.n = n
+	return out, nil
+}
+
+var coderBytesValidateUTF8 = pointerCoderFuncs{
+	size:      sizeBytes,
+	marshal:   appendBytesValidateUTF8,
+	unmarshal: consumeBytesValidateUTF8,
+	merge:     mergeBytes,
+}
+
+// sizeBytesNoZero returns the size of wire encoding a []byte pointer as a Bytes.
+// The zero value is not encoded.
+func sizeBytesNoZero(p pointer, f *coderFieldInfo, _ marshalOptions) (size int) {
+	v := *p.Bytes()
+	if len(v) == 0 {
+		return 0
+	}
+	return f.tagsize + protowire.SizeBytes(len(v))
+}
+
+// appendBytesNoZero wire encodes a []byte pointer as a Bytes.
+// The zero value is not encoded.
+func appendBytesNoZero(b []byte, p pointer, f *coderFieldInfo, _ marshalOptions) ([]byte, error) {
+	v := *p.Bytes()
+	if len(v) == 0 {
+		return b, nil
+	}
+	b = protowire.AppendVarint(b, f.wiretag)
+	b = protowire.AppendBytes(b, v)
+	return b, nil
+}
+
+// consumeBytesNoZero wire decodes a []byte pointer as a Bytes.
+// The zero value is not decoded.
+func consumeBytesNoZero(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, _ unmarshalOptions) (out unmarshalOutput, err error) {
+	if wtyp != protowire.BytesType {
+		return out, errUnknown
+	}
+	v, n := protowire.ConsumeBytes(b)
+	if n < 0 {
+		return out, protowire.ParseError(n)
+	}
+	*p.Bytes() = append(([]byte)(nil), v...)
+	out.n = n
+	return out, nil
+}
+
+var coderBytesNoZero = pointerCoderFuncs{
+	size:      sizeBytesNoZero,
+	marshal:   appendBytesNoZero,
+	unmarshal: consumeBytesNoZero,
+	merge:     mergeBytesNoZero,
+}
+
+// appendBytesNoZeroValidateUTF8 wire encodes a []byte pointer as a Bytes.
+// The zero value is not encoded.
+func appendBytesNoZeroValidateUTF8(b []byte, p pointer, f *coderFieldInfo, _ marshalOptions) ([]byte, error) {
+	v := *p.Bytes()
+	if len(v) == 0 {
+		return b, nil
+	}
+	b = protowire.AppendVarint(b, f.wiretag)
+	b = protowire.AppendBytes(b, v)
+	if !utf8.Valid(v) {
+		return b, errInvalidUTF8{}
+	}
+	return b, nil
+}
+
+// consumeBytesNoZeroValidateUTF8 wire decodes a []byte pointer as a Bytes.
+func consumeBytesNoZeroValidateUTF8(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, _ unmarshalOptions) (out unmarshalOutput, err error) {
+	if wtyp != protowire.BytesType {
+		return out, errUnknown
+	}
+	v, n := protowire.ConsumeBytes(b)
+	if n < 0 {
+		return out, protowire.ParseError(n)
+	}
+	if !utf8.Valid(v) {
+		return out, errInvalidUTF8{}
+	}
+	*p.Bytes() = append(([]byte)(nil), v...)
+	out.n = n
+	return out, nil
+}
+
+var coderBytesNoZeroValidateUTF8 = pointerCoderFuncs{
+	size:      sizeBytesNoZero,
+	marshal:   appendBytesNoZeroValidateUTF8,
+	unmarshal: consumeBytesNoZeroValidateUTF8,
+	merge:     mergeBytesNoZero,
+}
+
+// sizeBytesSlice returns the size of wire encoding a [][]byte pointer as a repeated Bytes.
+func sizeBytesSlice(p pointer, f *coderFieldInfo, _ marshalOptions) (size int) {
+	s := *p.BytesSlice()
+	for _, v := range s {
+		size += f.tagsize + protowire.SizeBytes(len(v))
+	}
+	return size
+}
+
+// appendBytesSlice encodes a [][]byte pointer as a repeated Bytes.
+func appendBytesSlice(b []byte, p pointer, f *coderFieldInfo, _ marshalOptions) ([]byte, error) {
+	s := *p.BytesSlice()
+	for _, v := range s {
+		b = protowire.AppendVarint(b, f.wiretag)
+		b = protowire.AppendBytes(b, v)
+	}
+	return b, nil
+}
+
+// consumeBytesSlice wire decodes a [][]byte pointer as a repeated Bytes.
+func consumeBytesSlice(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, _ unmarshalOptions) (out unmarshalOutput, err error) {
+	sp := p.BytesSlice()
+	if wtyp != protowire.BytesType {
+		return out, errUnknown
+	}
+	v, n := protowire.ConsumeBytes(b)
+	if n < 0 {
+		return out, protowire.ParseError(n)
+	}
+	*sp = append(*sp, append(emptyBuf[:], v...))
+	out.n = n
+	return out, nil
+}
+
+var coderBytesSlice = pointerCoderFuncs{
+	size:      sizeBytesSlice,
+	marshal:   appendBytesSlice,
+	unmarshal: consumeBytesSlice,
+	merge:     mergeBytesSlice,
+}
+
+// appendBytesSliceValidateUTF8 encodes a [][]byte pointer as a repeated Bytes.
+func appendBytesSliceValidateUTF8(b []byte, p pointer, f *coderFieldInfo, _ marshalOptions) ([]byte, error) {
+	s := *p.BytesSlice()
+	for _, v := range s {
+		b = protowire.AppendVarint(b, f.wiretag)
+		b = protowire.AppendBytes(b, v)
+		if !utf8.Valid(v) {
+			return b, errInvalidUTF8{}
+		}
+	}
+	return b, nil
+}
+
+// consumeBytesSliceValidateUTF8 wire decodes a [][]byte pointer as a repeated Bytes.
+func consumeBytesSliceValidateUTF8(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, _ unmarshalOptions) (out unmarshalOutput, err error) {
+	sp := p.BytesSlice()
+	if wtyp != protowire.BytesType {
+		return out, errUnknown
+	}
+	v, n := protowire.ConsumeBytes(b)
+	if n < 0 {
+		return out, protowire.ParseError(n)
+	}
+	if !utf8.Valid(v) {
+		return out, errInvalidUTF8{}
+	}
+	*sp = append(*sp, append(emptyBuf[:], v...))
+	out.n = n
+	return out, nil
+}
+
+var coderBytesSliceValidateUTF8 = pointerCoderFuncs{
+	size:      sizeBytesSlice,
+	marshal:   appendBytesSliceValidateUTF8,
+	unmarshal: consumeBytesSliceValidateUTF8,
+	merge:     mergeBytesSlice,
+}
+
+// sizeBytesValue returns the size of wire encoding a []byte value as a Bytes.
+func sizeBytesValue(v protoreflect.Value, tagsize int, _ marshalOptions) int {
+	return tagsize + protowire.SizeBytes(len(v.Bytes()))
+}
+
+// appendBytesValue encodes a []byte value as a Bytes.
+func appendBytesValue(b []byte, v protoreflect.Value, wiretag uint64, _ marshalOptions) ([]byte, error) {
+	b = protowire.AppendVarint(b, wiretag)
+	b = protowire.AppendBytes(b, v.Bytes())
+	return b, nil
+}
+
+// consumeBytesValue decodes a []byte value as a Bytes.
+func consumeBytesValue(b []byte, _ protoreflect.Value, _ protowire.Number, wtyp protowire.Type, _ unmarshalOptions) (_ protoreflect.Value, out unmarshalOutput, err error) {
+	if wtyp != protowire.BytesType {
+		return protoreflect.Value{}, out, errUnknown
+	}
+	v, n := protowire.ConsumeBytes(b)
+	if n < 0 {
+		return protoreflect.Value{}, out, protowire.ParseError(n)
+	}
+	out.n = n
+	return protoreflect.ValueOfBytes(append(emptyBuf[:], v...)), out, nil
+}
+
+var coderBytesValue = valueCoderFuncs{
+	size:      sizeBytesValue,
+	marshal:   appendBytesValue,
+	unmarshal: consumeBytesValue,
+	merge:     mergeBytesValue,
+}
+
+// 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 + protowire.SizeBytes(len(v.Bytes()))
+	}
+	return size
+}
+
+// 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 = protowire.AppendVarint(b, wiretag)
+		b = protowire.AppendBytes(b, v.Bytes())
+	}
+	return b, nil
+}
+
+// consumeBytesSliceValue wire decodes a [][]byte value as a repeated Bytes.
+func consumeBytesSliceValue(b []byte, listv protoreflect.Value, _ protowire.Number, wtyp protowire.Type, _ unmarshalOptions) (_ protoreflect.Value, out unmarshalOutput, err error) {
+	list := listv.List()
+	if wtyp != protowire.BytesType {
+		return protoreflect.Value{}, out, errUnknown
+	}
+	v, n := protowire.ConsumeBytes(b)
+	if n < 0 {
+		return protoreflect.Value{}, out, protowire.ParseError(n)
+	}
+	list.Append(protoreflect.ValueOfBytes(append(emptyBuf[:], v...)))
+	out.n = n
+	return listv, out, nil
+}
+
+var coderBytesSliceValue = valueCoderFuncs{
+	size:      sizeBytesSliceValue,
+	marshal:   appendBytesSliceValue,
+	unmarshal: consumeBytesSliceValue,
+	merge:     mergeBytesListValue,
+}
+
+// We append to an empty array rather than a nil []byte to get non-nil zero-length byte slices.
+var emptyBuf [0]byte
+
+var wireTypes = map[protoreflect.Kind]protowire.Type{
+	protoreflect.BoolKind:     protowire.VarintType,
+	protoreflect.EnumKind:     protowire.VarintType,
+	protoreflect.Int32Kind:    protowire.VarintType,
+	protoreflect.Sint32Kind:   protowire.VarintType,
+	protoreflect.Uint32Kind:   protowire.VarintType,
+	protoreflect.Int64Kind:    protowire.VarintType,
+	protoreflect.Sint64Kind:   protowire.VarintType,
+	protoreflect.Uint64Kind:   protowire.VarintType,
+	protoreflect.Sfixed32Kind: protowire.Fixed32Type,
+	protoreflect.Fixed32Kind:  protowire.Fixed32Type,
+	protoreflect.FloatKind:    protowire.Fixed32Type,
+	protoreflect.Sfixed64Kind: protowire.Fixed64Type,
+	protoreflect.Fixed64Kind:  protowire.Fixed64Type,
+	protoreflect.DoubleKind:   protowire.Fixed64Type,
+	protoreflect.StringKind:   protowire.BytesType,
+	protoreflect.BytesKind:    protowire.BytesType,
+	protoreflect.MessageKind:  protowire.BytesType,
+	protoreflect.GroupKind:    protowire.StartGroupType,
+}
diff --git a/vendor/google.golang.org/protobuf/internal/impl/codec_map.go b/vendor/google.golang.org/protobuf/internal/impl/codec_map.go
new file mode 100644
index 0000000..35a67c2
--- /dev/null
+++ b/vendor/google.golang.org/protobuf/internal/impl/codec_map.go
@@ -0,0 +1,388 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package impl
+
+import (
+	"errors"
+	"reflect"
+	"sort"
+
+	"google.golang.org/protobuf/encoding/protowire"
+	pref "google.golang.org/protobuf/reflect/protoreflect"
+)
+
+type mapInfo struct {
+	goType     reflect.Type
+	keyWiretag uint64
+	valWiretag uint64
+	keyFuncs   valueCoderFuncs
+	valFuncs   valueCoderFuncs
+	keyZero    pref.Value
+	keyKind    pref.Kind
+	conv       *mapConverter
+}
+
+func encoderFuncsForMap(fd pref.FieldDescriptor, ft reflect.Type) (valueMessage *MessageInfo, funcs pointerCoderFuncs) {
+	// TODO: Consider generating specialized map coders.
+	keyField := fd.MapKey()
+	valField := fd.MapValue()
+	keyWiretag := protowire.EncodeTag(1, wireTypes[keyField.Kind()])
+	valWiretag := protowire.EncodeTag(2, wireTypes[valField.Kind()])
+	keyFuncs := encoderFuncsForValue(keyField)
+	valFuncs := encoderFuncsForValue(valField)
+	conv := newMapConverter(ft, fd)
+
+	mapi := &mapInfo{
+		goType:     ft,
+		keyWiretag: keyWiretag,
+		valWiretag: valWiretag,
+		keyFuncs:   keyFuncs,
+		valFuncs:   valFuncs,
+		keyZero:    keyField.Default(),
+		keyKind:    keyField.Kind(),
+		conv:       conv,
+	}
+	if valField.Kind() == pref.MessageKind {
+		valueMessage = getMessageInfo(ft.Elem())
+	}
+
+	funcs = pointerCoderFuncs{
+		size: func(p pointer, f *coderFieldInfo, opts marshalOptions) int {
+			return sizeMap(p.AsValueOf(ft).Elem(), mapi, f, opts)
+		},
+		marshal: func(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
+			return appendMap(b, p.AsValueOf(ft).Elem(), mapi, f, opts)
+		},
+		unmarshal: func(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (unmarshalOutput, error) {
+			mp := p.AsValueOf(ft)
+			if mp.Elem().IsNil() {
+				mp.Elem().Set(reflect.MakeMap(mapi.goType))
+			}
+			if f.mi == nil {
+				return consumeMap(b, mp.Elem(), wtyp, mapi, f, opts)
+			} else {
+				return consumeMapOfMessage(b, mp.Elem(), wtyp, mapi, f, opts)
+			}
+		},
+	}
+	switch valField.Kind() {
+	case pref.MessageKind:
+		funcs.merge = mergeMapOfMessage
+	case pref.BytesKind:
+		funcs.merge = mergeMapOfBytes
+	default:
+		funcs.merge = mergeMap
+	}
+	if valFuncs.isInit != nil {
+		funcs.isInit = func(p pointer, f *coderFieldInfo) error {
+			return isInitMap(p.AsValueOf(ft).Elem(), mapi, f)
+		}
+	}
+	return valueMessage, funcs
+}
+
+const (
+	mapKeyTagSize = 1 // field 1, tag size 1.
+	mapValTagSize = 1 // field 2, tag size 2.
+)
+
+func sizeMap(mapv reflect.Value, mapi *mapInfo, f *coderFieldInfo, opts marshalOptions) int {
+	if mapv.Len() == 0 {
+		return 0
+	}
+	n := 0
+	iter := mapRange(mapv)
+	for iter.Next() {
+		key := mapi.conv.keyConv.PBValueOf(iter.Key()).MapKey()
+		keySize := mapi.keyFuncs.size(key.Value(), mapKeyTagSize, opts)
+		var valSize int
+		value := mapi.conv.valConv.PBValueOf(iter.Value())
+		if f.mi == nil {
+			valSize = mapi.valFuncs.size(value, mapValTagSize, opts)
+		} else {
+			p := pointerOfValue(iter.Value())
+			valSize += mapValTagSize
+			valSize += protowire.SizeBytes(f.mi.sizePointer(p, opts))
+		}
+		n += f.tagsize + protowire.SizeBytes(keySize+valSize)
+	}
+	return n
+}
+
+func consumeMap(b []byte, mapv reflect.Value, wtyp protowire.Type, mapi *mapInfo, f *coderFieldInfo, opts unmarshalOptions) (out unmarshalOutput, err error) {
+	if wtyp != protowire.BytesType {
+		return out, errUnknown
+	}
+	b, n := protowire.ConsumeBytes(b)
+	if n < 0 {
+		return out, protowire.ParseError(n)
+	}
+	var (
+		key = mapi.keyZero
+		val = mapi.conv.valConv.New()
+	)
+	for len(b) > 0 {
+		num, wtyp, n := protowire.ConsumeTag(b)
+		if n < 0 {
+			return out, protowire.ParseError(n)
+		}
+		if num > protowire.MaxValidNumber {
+			return out, errors.New("invalid field number")
+		}
+		b = b[n:]
+		err := errUnknown
+		switch num {
+		case 1:
+			var v pref.Value
+			var o unmarshalOutput
+			v, o, err = mapi.keyFuncs.unmarshal(b, key, num, wtyp, opts)
+			if err != nil {
+				break
+			}
+			key = v
+			n = o.n
+		case 2:
+			var v pref.Value
+			var o unmarshalOutput
+			v, o, err = mapi.valFuncs.unmarshal(b, val, num, wtyp, opts)
+			if err != nil {
+				break
+			}
+			val = v
+			n = o.n
+		}
+		if err == errUnknown {
+			n = protowire.ConsumeFieldValue(num, wtyp, b)
+			if n < 0 {
+				return out, protowire.ParseError(n)
+			}
+		} else if err != nil {
+			return out, err
+		}
+		b = b[n:]
+	}
+	mapv.SetMapIndex(mapi.conv.keyConv.GoValueOf(key), mapi.conv.valConv.GoValueOf(val))
+	out.n = n
+	return out, nil
+}
+
+func consumeMapOfMessage(b []byte, mapv reflect.Value, wtyp protowire.Type, mapi *mapInfo, f *coderFieldInfo, opts unmarshalOptions) (out unmarshalOutput, err error) {
+	if wtyp != protowire.BytesType {
+		return out, errUnknown
+	}
+	b, n := protowire.ConsumeBytes(b)
+	if n < 0 {
+		return out, protowire.ParseError(n)
+	}
+	var (
+		key = mapi.keyZero
+		val = reflect.New(f.mi.GoReflectType.Elem())
+	)
+	for len(b) > 0 {
+		num, wtyp, n := protowire.ConsumeTag(b)
+		if n < 0 {
+			return out, protowire.ParseError(n)
+		}
+		if num > protowire.MaxValidNumber {
+			return out, errors.New("invalid field number")
+		}
+		b = b[n:]
+		err := errUnknown
+		switch num {
+		case 1:
+			var v pref.Value
+			var o unmarshalOutput
+			v, o, err = mapi.keyFuncs.unmarshal(b, key, num, wtyp, opts)
+			if err != nil {
+				break
+			}
+			key = v
+			n = o.n
+		case 2:
+			if wtyp != protowire.BytesType {
+				break
+			}
+			var v []byte
+			v, n = protowire.ConsumeBytes(b)
+			if n < 0 {
+				return out, protowire.ParseError(n)
+			}
+			var o unmarshalOutput
+			o, err = f.mi.unmarshalPointer(v, pointerOfValue(val), 0, opts)
+			if o.initialized {
+				// Consider this map item initialized so long as we see
+				// an initialized value.
+				out.initialized = true
+			}
+		}
+		if err == errUnknown {
+			n = protowire.ConsumeFieldValue(num, wtyp, b)
+			if n < 0 {
+				return out, protowire.ParseError(n)
+			}
+		} else if err != nil {
+			return out, err
+		}
+		b = b[n:]
+	}
+	mapv.SetMapIndex(mapi.conv.keyConv.GoValueOf(key), val)
+	out.n = n
+	return out, nil
+}
+
+func appendMapItem(b []byte, keyrv, valrv reflect.Value, mapi *mapInfo, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
+	if f.mi == nil {
+		key := mapi.conv.keyConv.PBValueOf(keyrv).MapKey()
+		val := mapi.conv.valConv.PBValueOf(valrv)
+		size := 0
+		size += mapi.keyFuncs.size(key.Value(), mapKeyTagSize, opts)
+		size += mapi.valFuncs.size(val, mapValTagSize, opts)
+		b = protowire.AppendVarint(b, uint64(size))
+		b, err := mapi.keyFuncs.marshal(b, key.Value(), mapi.keyWiretag, opts)
+		if err != nil {
+			return nil, err
+		}
+		return mapi.valFuncs.marshal(b, val, mapi.valWiretag, opts)
+	} else {
+		key := mapi.conv.keyConv.PBValueOf(keyrv).MapKey()
+		val := pointerOfValue(valrv)
+		valSize := f.mi.sizePointer(val, opts)
+		size := 0
+		size += mapi.keyFuncs.size(key.Value(), mapKeyTagSize, opts)
+		size += mapValTagSize + protowire.SizeBytes(valSize)
+		b = protowire.AppendVarint(b, uint64(size))
+		b, err := mapi.keyFuncs.marshal(b, key.Value(), mapi.keyWiretag, opts)
+		if err != nil {
+			return nil, err
+		}
+		b = protowire.AppendVarint(b, mapi.valWiretag)
+		b = protowire.AppendVarint(b, uint64(valSize))
+		return f.mi.marshalAppendPointer(b, val, opts)
+	}
+}
+
+func appendMap(b []byte, mapv reflect.Value, mapi *mapInfo, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
+	if mapv.Len() == 0 {
+		return b, nil
+	}
+	if opts.Deterministic() {
+		return appendMapDeterministic(b, mapv, mapi, f, opts)
+	}
+	iter := mapRange(mapv)
+	for iter.Next() {
+		var err error
+		b = protowire.AppendVarint(b, f.wiretag)
+		b, err = appendMapItem(b, iter.Key(), iter.Value(), mapi, f, opts)
+		if err != nil {
+			return b, err
+		}
+	}
+	return b, nil
+}
+
+func appendMapDeterministic(b []byte, mapv reflect.Value, mapi *mapInfo, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
+	keys := mapv.MapKeys()
+	sort.Slice(keys, func(i, j int) bool {
+		switch keys[i].Kind() {
+		case reflect.Bool:
+			return !keys[i].Bool() && keys[j].Bool()
+		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+			return keys[i].Int() < keys[j].Int()
+		case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+			return keys[i].Uint() < keys[j].Uint()
+		case reflect.Float32, reflect.Float64:
+			return keys[i].Float() < keys[j].Float()
+		case reflect.String:
+			return keys[i].String() < keys[j].String()
+		default:
+			panic("invalid kind: " + keys[i].Kind().String())
+		}
+	})
+	for _, key := range keys {
+		var err error
+		b = protowire.AppendVarint(b, f.wiretag)
+		b, err = appendMapItem(b, key, mapv.MapIndex(key), mapi, f, opts)
+		if err != nil {
+			return b, err
+		}
+	}
+	return b, nil
+}
+
+func isInitMap(mapv reflect.Value, mapi *mapInfo, f *coderFieldInfo) error {
+	if mi := f.mi; mi != nil {
+		mi.init()
+		if !mi.needsInitCheck {
+			return nil
+		}
+		iter := mapRange(mapv)
+		for iter.Next() {
+			val := pointerOfValue(iter.Value())
+			if err := mi.checkInitializedPointer(val); err != nil {
+				return err
+			}
+		}
+	} else {
+		iter := mapRange(mapv)
+		for iter.Next() {
+			val := mapi.conv.valConv.PBValueOf(iter.Value())
+			if err := mapi.valFuncs.isInit(val); err != nil {
+				return err
+			}
+		}
+	}
+	return nil
+}
+
+func mergeMap(dst, src pointer, f *coderFieldInfo, opts mergeOptions) {
+	dstm := dst.AsValueOf(f.ft).Elem()
+	srcm := src.AsValueOf(f.ft).Elem()
+	if srcm.Len() == 0 {
+		return
+	}
+	if dstm.IsNil() {
+		dstm.Set(reflect.MakeMap(f.ft))
+	}
+	iter := mapRange(srcm)
+	for iter.Next() {
+		dstm.SetMapIndex(iter.Key(), iter.Value())
+	}
+}
+
+func mergeMapOfBytes(dst, src pointer, f *coderFieldInfo, opts mergeOptions) {
+	dstm := dst.AsValueOf(f.ft).Elem()
+	srcm := src.AsValueOf(f.ft).Elem()
+	if srcm.Len() == 0 {
+		return
+	}
+	if dstm.IsNil() {
+		dstm.Set(reflect.MakeMap(f.ft))
+	}
+	iter := mapRange(srcm)
+	for iter.Next() {
+		dstm.SetMapIndex(iter.Key(), reflect.ValueOf(append(emptyBuf[:], iter.Value().Bytes()...)))
+	}
+}
+
+func mergeMapOfMessage(dst, src pointer, f *coderFieldInfo, opts mergeOptions) {
+	dstm := dst.AsValueOf(f.ft).Elem()
+	srcm := src.AsValueOf(f.ft).Elem()
+	if srcm.Len() == 0 {
+		return
+	}
+	if dstm.IsNil() {
+		dstm.Set(reflect.MakeMap(f.ft))
+	}
+	iter := mapRange(srcm)
+	for iter.Next() {
+		val := reflect.New(f.ft.Elem().Elem())
+		if f.mi != nil {
+			f.mi.mergePointer(pointerOfValue(val), pointerOfValue(iter.Value()), opts)
+		} else {
+			opts.Merge(asMessage(val), asMessage(iter.Value()))
+		}
+		dstm.SetMapIndex(iter.Key(), val)
+	}
+}
diff --git a/vendor/google.golang.org/protobuf/internal/impl/codec_map_go111.go b/vendor/google.golang.org/protobuf/internal/impl/codec_map_go111.go
new file mode 100644
index 0000000..2706bb6
--- /dev/null
+++ b/vendor/google.golang.org/protobuf/internal/impl/codec_map_go111.go
@@ -0,0 +1,37 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build !go1.12
+
+package impl
+
+import "reflect"
+
+type mapIter struct {
+	v    reflect.Value
+	keys []reflect.Value
+}
+
+// mapRange provides a less-efficient equivalent to
+// the Go 1.12 reflect.Value.MapRange method.
+func mapRange(v reflect.Value) *mapIter {
+	return &mapIter{v: v}
+}
+
+func (i *mapIter) Next() bool {
+	if i.keys == nil {
+		i.keys = i.v.MapKeys()
+	} else {
+		i.keys = i.keys[1:]
+	}
+	return len(i.keys) > 0
+}
+
+func (i *mapIter) Key() reflect.Value {
+	return i.keys[0]
+}
+
+func (i *mapIter) Value() reflect.Value {
+	return i.v.MapIndex(i.keys[0])
+}
diff --git a/vendor/google.golang.org/protobuf/internal/impl/codec_map_go112.go b/vendor/google.golang.org/protobuf/internal/impl/codec_map_go112.go
new file mode 100644
index 0000000..1533ef6
--- /dev/null
+++ b/vendor/google.golang.org/protobuf/internal/impl/codec_map_go112.go
@@ -0,0 +1,11 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build go1.12
+
+package impl
+
+import "reflect"
+
+func mapRange(v reflect.Value) *reflect.MapIter { return v.MapRange() }
diff --git a/vendor/google.golang.org/protobuf/internal/impl/codec_message.go b/vendor/google.golang.org/protobuf/internal/impl/codec_message.go
new file mode 100644
index 0000000..0e176d5
--- /dev/null
+++ b/vendor/google.golang.org/protobuf/internal/impl/codec_message.go
@@ -0,0 +1,159 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package impl
+
+import (
+	"fmt"
+	"reflect"
+	"sort"
+
+	"google.golang.org/protobuf/encoding/protowire"
+	"google.golang.org/protobuf/internal/encoding/messageset"
+	"google.golang.org/protobuf/internal/fieldsort"
+	pref "google.golang.org/protobuf/reflect/protoreflect"
+	piface "google.golang.org/protobuf/runtime/protoiface"
+)
+
+// coderMessageInfo contains per-message information used by the fast-path functions.
+// This is a different type from MessageInfo to keep MessageInfo as general-purpose as
+// possible.
+type coderMessageInfo struct {
+	methods piface.Methods
+
+	orderedCoderFields []*coderFieldInfo
+	denseCoderFields   []*coderFieldInfo
+	coderFields        map[protowire.Number]*coderFieldInfo
+	sizecacheOffset    offset
+	unknownOffset      offset
+	extensionOffset    offset
+	needsInitCheck     bool
+	isMessageSet       bool
+	numRequiredFields  uint8
+}
+
+type coderFieldInfo struct {
+	funcs      pointerCoderFuncs // fast-path per-field functions
+	mi         *MessageInfo      // field's message
+	ft         reflect.Type
+	validation validationInfo   // information used by message validation
+	num        pref.FieldNumber // field number
+	offset     offset           // struct field offset
+	wiretag    uint64           // field tag (number + wire type)
+	tagsize    int              // size of the varint-encoded tag
+	isPointer  bool             // true if IsNil may be called on the struct field
+	isRequired bool             // true if field is required
+}
+
+func (mi *MessageInfo) makeCoderMethods(t reflect.Type, si structInfo) {
+	mi.sizecacheOffset = si.sizecacheOffset
+	mi.unknownOffset = si.unknownOffset
+	mi.extensionOffset = si.extensionOffset
+
+	mi.coderFields = make(map[protowire.Number]*coderFieldInfo)
+	fields := mi.Desc.Fields()
+	preallocFields := make([]coderFieldInfo, fields.Len())
+	for i := 0; i < fields.Len(); i++ {
+		fd := fields.Get(i)
+
+		fs := si.fieldsByNumber[fd.Number()]
+		isOneof := fd.ContainingOneof() != nil && !fd.ContainingOneof().IsSynthetic()
+		if isOneof {
+			fs = si.oneofsByName[fd.ContainingOneof().Name()]
+		}
+		ft := fs.Type
+		var wiretag uint64
+		if !fd.IsPacked() {
+			wiretag = protowire.EncodeTag(fd.Number(), wireTypes[fd.Kind()])
+		} else {
+			wiretag = protowire.EncodeTag(fd.Number(), protowire.BytesType)
+		}
+		var fieldOffset offset
+		var funcs pointerCoderFuncs
+		var childMessage *MessageInfo
+		switch {
+		case isOneof:
+			fieldOffset = offsetOf(fs, mi.Exporter)
+		case fd.IsWeak():
+			fieldOffset = si.weakOffset
+			funcs = makeWeakMessageFieldCoder(fd)
+		default:
+			fieldOffset = offsetOf(fs, mi.Exporter)
+			childMessage, funcs = fieldCoder(fd, ft)
+		}
+		cf := &preallocFields[i]
+		*cf = coderFieldInfo{
+			num:        fd.Number(),
+			offset:     fieldOffset,
+			wiretag:    wiretag,
+			ft:         ft,
+			tagsize:    protowire.SizeVarint(wiretag),
+			funcs:      funcs,
+			mi:         childMessage,
+			validation: newFieldValidationInfo(mi, si, fd, ft),
+			isPointer:  fd.Cardinality() == pref.Repeated || fd.HasPresence(),
+			isRequired: fd.Cardinality() == pref.Required,
+		}
+		mi.orderedCoderFields = append(mi.orderedCoderFields, cf)
+		mi.coderFields[cf.num] = cf
+	}
+	for i, oneofs := 0, mi.Desc.Oneofs(); i < oneofs.Len(); i++ {
+		if od := oneofs.Get(i); !od.IsSynthetic() {
+			mi.initOneofFieldCoders(od, si)
+		}
+	}
+	if messageset.IsMessageSet(mi.Desc) {
+		if !mi.extensionOffset.IsValid() {
+			panic(fmt.Sprintf("%v: MessageSet with no extensions field", mi.Desc.FullName()))
+		}
+		if !mi.unknownOffset.IsValid() {
+			panic(fmt.Sprintf("%v: MessageSet with no unknown field", mi.Desc.FullName()))
+		}
+		mi.isMessageSet = true
+	}
+	sort.Slice(mi.orderedCoderFields, func(i, j int) bool {
+		return mi.orderedCoderFields[i].num < mi.orderedCoderFields[j].num
+	})
+
+	var maxDense pref.FieldNumber
+	for _, cf := range mi.orderedCoderFields {
+		if cf.num >= 16 && cf.num >= 2*maxDense {
+			break
+		}
+		maxDense = cf.num
+	}
+	mi.denseCoderFields = make([]*coderFieldInfo, maxDense+1)
+	for _, cf := range mi.orderedCoderFields {
+		if int(cf.num) >= len(mi.denseCoderFields) {
+			break
+		}
+		mi.denseCoderFields[cf.num] = cf
+	}
+
+	// To preserve compatibility with historic wire output, marshal oneofs last.
+	if mi.Desc.Oneofs().Len() > 0 {
+		sort.Slice(mi.orderedCoderFields, func(i, j int) bool {
+			fi := fields.ByNumber(mi.orderedCoderFields[i].num)
+			fj := fields.ByNumber(mi.orderedCoderFields[j].num)
+			return fieldsort.Less(fi, fj)
+		})
+	}
+
+	mi.needsInitCheck = needsInitCheck(mi.Desc)
+	if mi.methods.Marshal == nil && mi.methods.Size == nil {
+		mi.methods.Flags |= piface.SupportMarshalDeterministic
+		mi.methods.Marshal = mi.marshal
+		mi.methods.Size = mi.size
+	}
+	if mi.methods.Unmarshal == nil {
+		mi.methods.Flags |= piface.SupportUnmarshalDiscardUnknown
+		mi.methods.Unmarshal = mi.unmarshal
+	}
+	if mi.methods.CheckInitialized == nil {
+		mi.methods.CheckInitialized = mi.checkInitialized
+	}
+	if mi.methods.Merge == nil {
+		mi.methods.Merge = mi.merge
+	}
+}
diff --git a/vendor/google.golang.org/protobuf/internal/impl/codec_messageset.go b/vendor/google.golang.org/protobuf/internal/impl/codec_messageset.go
new file mode 100644
index 0000000..cfb68e1
--- /dev/null
+++ b/vendor/google.golang.org/protobuf/internal/impl/codec_messageset.go
@@ -0,0 +1,120 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package impl
+
+import (
+	"sort"
+
+	"google.golang.org/protobuf/encoding/protowire"
+	"google.golang.org/protobuf/internal/encoding/messageset"
+	"google.golang.org/protobuf/internal/errors"
+	"google.golang.org/protobuf/internal/flags"
+)
+
+func sizeMessageSet(mi *MessageInfo, p pointer, opts marshalOptions) (size int) {
+	if !flags.ProtoLegacy {
+		return 0
+	}
+
+	ext := *p.Apply(mi.extensionOffset).Extensions()
+	for _, x := range ext {
+		xi := getExtensionFieldInfo(x.Type())
+		if xi.funcs.size == nil {
+			continue
+		}
+		num, _ := protowire.DecodeTag(xi.wiretag)
+		size += messageset.SizeField(num)
+		size += xi.funcs.size(x.Value(), protowire.SizeTag(messageset.FieldMessage), opts)
+	}
+
+	unknown := *p.Apply(mi.unknownOffset).Bytes()
+	size += messageset.SizeUnknown(unknown)
+
+	return size
+}
+
+func marshalMessageSet(mi *MessageInfo, b []byte, p pointer, opts marshalOptions) ([]byte, error) {
+	if !flags.ProtoLegacy {
+		return b, errors.New("no support for message_set_wire_format")
+	}
+
+	ext := *p.Apply(mi.extensionOffset).Extensions()
+	switch len(ext) {
+	case 0:
+	case 1:
+		// Fast-path for one extension: Don't bother sorting the keys.
+		for _, x := range ext {
+			var err error
+			b, err = marshalMessageSetField(mi, b, x, opts)
+			if err != nil {
+				return b, err
+			}
+		}
+	default:
+		// Sort the keys to provide a deterministic encoding.
+		// Not sure this is required, but the old code does it.
+		keys := make([]int, 0, len(ext))
+		for k := range ext {
+			keys = append(keys, int(k))
+		}
+		sort.Ints(keys)
+		for _, k := range keys {
+			var err error
+			b, err = marshalMessageSetField(mi, b, ext[int32(k)], opts)
+			if err != nil {
+				return b, err
+			}
+		}
+	}
+
+	unknown := *p.Apply(mi.unknownOffset).Bytes()
+	b, err := messageset.AppendUnknown(b, unknown)
+	if err != nil {
+		return b, err
+	}
+
+	return b, nil
+}
+
+func marshalMessageSetField(mi *MessageInfo, b []byte, x ExtensionField, opts marshalOptions) ([]byte, error) {
+	xi := getExtensionFieldInfo(x.Type())
+	num, _ := protowire.DecodeTag(xi.wiretag)
+	b = messageset.AppendFieldStart(b, num)
+	b, err := xi.funcs.marshal(b, x.Value(), protowire.EncodeTag(messageset.FieldMessage, protowire.BytesType), opts)
+	if err != nil {
+		return b, err
+	}
+	b = messageset.AppendFieldEnd(b)
+	return b, nil
+}
+
+func unmarshalMessageSet(mi *MessageInfo, b []byte, p pointer, opts unmarshalOptions) (out unmarshalOutput, err error) {
+	if !flags.ProtoLegacy {
+		return out, errors.New("no support for message_set_wire_format")
+	}
+
+	ep := p.Apply(mi.extensionOffset).Extensions()
+	if *ep == nil {
+		*ep = make(map[int32]ExtensionField)
+	}
+	ext := *ep
+	unknown := p.Apply(mi.unknownOffset).Bytes()
+	initialized := true
+	err = messageset.Unmarshal(b, true, func(num protowire.Number, v []byte) error {
+		o, err := mi.unmarshalExtension(v, num, protowire.BytesType, ext, opts)
+		if err == errUnknown {
+			*unknown = protowire.AppendTag(*unknown, num, protowire.BytesType)
+			*unknown = append(*unknown, v...)
+			return nil
+		}
+		if !o.initialized {
+			initialized = false
+		}
+		return err
+	})
+	out.n = len(b)
+	out.initialized = initialized
+	return out, err
+}
diff --git a/vendor/google.golang.org/protobuf/internal/impl/codec_reflect.go b/vendor/google.golang.org/protobuf/internal/impl/codec_reflect.go
new file mode 100644
index 0000000..86f7dc3
--- /dev/null
+++ b/vendor/google.golang.org/protobuf/internal/impl/codec_reflect.go
@@ -0,0 +1,209 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build purego appengine
+
+package impl
+
+import (
+	"reflect"
+
+	"google.golang.org/protobuf/encoding/protowire"
+)
+
+func sizeEnum(p pointer, f *coderFieldInfo, _ marshalOptions) (size int) {
+	v := p.v.Elem().Int()
+	return f.tagsize + protowire.SizeVarint(uint64(v))
+}
+
+func appendEnum(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
+	v := p.v.Elem().Int()
+	b = protowire.AppendVarint(b, f.wiretag)
+	b = protowire.AppendVarint(b, uint64(v))
+	return b, nil
+}
+
+func consumeEnum(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, _ unmarshalOptions) (out unmarshalOutput, err error) {
+	if wtyp != protowire.VarintType {
+		return out, errUnknown
+	}
+	v, n := protowire.ConsumeVarint(b)
+	if n < 0 {
+		return out, protowire.ParseError(n)
+	}
+	p.v.Elem().SetInt(int64(v))
+	out.n = n
+	return out, nil
+}
+
+func mergeEnum(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
+	dst.v.Elem().Set(src.v.Elem())
+}
+
+var coderEnum = pointerCoderFuncs{
+	size:      sizeEnum,
+	marshal:   appendEnum,
+	unmarshal: consumeEnum,
+	merge:     mergeEnum,
+}
+
+func sizeEnumNoZero(p pointer, f *coderFieldInfo, opts marshalOptions) (size int) {
+	if p.v.Elem().Int() == 0 {
+		return 0
+	}
+	return sizeEnum(p, f, opts)
+}
+
+func appendEnumNoZero(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
+	if p.v.Elem().Int() == 0 {
+		return b, nil
+	}
+	return appendEnum(b, p, f, opts)
+}
+
+func mergeEnumNoZero(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
+	if src.v.Elem().Int() != 0 {
+		dst.v.Elem().Set(src.v.Elem())
+	}
+}
+
+var coderEnumNoZero = pointerCoderFuncs{
+	size:      sizeEnumNoZero,
+	marshal:   appendEnumNoZero,
+	unmarshal: consumeEnum,
+	merge:     mergeEnumNoZero,
+}
+
+func sizeEnumPtr(p pointer, f *coderFieldInfo, opts marshalOptions) (size int) {
+	return sizeEnum(pointer{p.v.Elem()}, f, opts)
+}
+
+func appendEnumPtr(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
+	return appendEnum(b, pointer{p.v.Elem()}, f, opts)
+}
+
+func consumeEnumPtr(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (out unmarshalOutput, err error) {
+	if wtyp != protowire.VarintType {
+		return out, errUnknown
+	}
+	if p.v.Elem().IsNil() {
+		p.v.Elem().Set(reflect.New(p.v.Elem().Type().Elem()))
+	}
+	return consumeEnum(b, pointer{p.v.Elem()}, wtyp, f, opts)
+}
+
+func mergeEnumPtr(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
+	if !src.v.Elem().IsNil() {
+		v := reflect.New(dst.v.Type().Elem().Elem())
+		v.Elem().Set(src.v.Elem().Elem())
+		dst.v.Elem().Set(v)
+	}
+}
+
+var coderEnumPtr = pointerCoderFuncs{
+	size:      sizeEnumPtr,
+	marshal:   appendEnumPtr,
+	unmarshal: consumeEnumPtr,
+	merge:     mergeEnumPtr,
+}
+
+func sizeEnumSlice(p pointer, f *coderFieldInfo, opts marshalOptions) (size int) {
+	s := p.v.Elem()
+	for i, llen := 0, s.Len(); i < llen; i++ {
+		size += protowire.SizeVarint(uint64(s.Index(i).Int())) + f.tagsize
+	}
+	return size
+}
+
+func appendEnumSlice(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
+	s := p.v.Elem()
+	for i, llen := 0, s.Len(); i < llen; i++ {
+		b = protowire.AppendVarint(b, f.wiretag)
+		b = protowire.AppendVarint(b, uint64(s.Index(i).Int()))
+	}
+	return b, nil
+}
+
+func consumeEnumSlice(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (out unmarshalOutput, err error) {
+	s := p.v.Elem()
+	if wtyp == protowire.BytesType {
+		b, n := protowire.ConsumeBytes(b)
+		if n < 0 {
+			return out, protowire.ParseError(n)
+		}
+		for len(b) > 0 {
+			v, n := protowire.ConsumeVarint(b)
+			if n < 0 {
+				return out, protowire.ParseError(n)
+			}
+			rv := reflect.New(s.Type().Elem()).Elem()
+			rv.SetInt(int64(v))
+			s.Set(reflect.Append(s, rv))
+			b = b[n:]
+		}
+		out.n = n
+		return out, nil
+	}
+	if wtyp != protowire.VarintType {
+		return out, errUnknown
+	}
+	v, n := protowire.ConsumeVarint(b)
+	if n < 0 {
+		return out, protowire.ParseError(n)
+	}
+	rv := reflect.New(s.Type().Elem()).Elem()
+	rv.SetInt(int64(v))
+	s.Set(reflect.Append(s, rv))
+	out.n = n
+	return out, nil
+}
+
+func mergeEnumSlice(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
+	dst.v.Elem().Set(reflect.AppendSlice(dst.v.Elem(), src.v.Elem()))
+}
+
+var coderEnumSlice = pointerCoderFuncs{
+	size:      sizeEnumSlice,
+	marshal:   appendEnumSlice,
+	unmarshal: consumeEnumSlice,
+	merge:     mergeEnumSlice,
+}
+
+func sizeEnumPackedSlice(p pointer, f *coderFieldInfo, opts marshalOptions) (size int) {
+	s := p.v.Elem()
+	llen := s.Len()
+	if llen == 0 {
+		return 0
+	}
+	n := 0
+	for i := 0; i < llen; i++ {
+		n += protowire.SizeVarint(uint64(s.Index(i).Int()))
+	}
+	return f.tagsize + protowire.SizeBytes(n)
+}
+
+func appendEnumPackedSlice(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
+	s := p.v.Elem()
+	llen := s.Len()
+	if llen == 0 {
+		return b, nil
+	}
+	b = protowire.AppendVarint(b, f.wiretag)
+	n := 0
+	for i := 0; i < llen; i++ {
+		n += protowire.SizeVarint(uint64(s.Index(i).Int()))
+	}
+	b = protowire.AppendVarint(b, uint64(n))
+	for i := 0; i < llen; i++ {
+		b = protowire.AppendVarint(b, uint64(s.Index(i).Int()))
+	}
+	return b, nil
+}
+
+var coderEnumPackedSlice = pointerCoderFuncs{
+	size:      sizeEnumPackedSlice,
+	marshal:   appendEnumPackedSlice,
+	unmarshal: consumeEnumSlice,
+	merge:     mergeEnumSlice,
+}
diff --git a/vendor/google.golang.org/protobuf/internal/impl/codec_tables.go b/vendor/google.golang.org/protobuf/internal/impl/codec_tables.go
new file mode 100644
index 0000000..e899712
--- /dev/null
+++ b/vendor/google.golang.org/protobuf/internal/impl/codec_tables.go
@@ -0,0 +1,557 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package impl
+
+import (
+	"fmt"
+	"reflect"
+
+	"google.golang.org/protobuf/encoding/protowire"
+	"google.golang.org/protobuf/internal/strs"
+	pref "google.golang.org/protobuf/reflect/protoreflect"
+)
+
+// pointerCoderFuncs is a set of pointer encoding functions.
+type pointerCoderFuncs struct {
+	mi        *MessageInfo
+	size      func(p pointer, f *coderFieldInfo, opts marshalOptions) int
+	marshal   func(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error)
+	unmarshal func(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (unmarshalOutput, error)
+	isInit    func(p pointer, f *coderFieldInfo) error
+	merge     func(dst, src pointer, f *coderFieldInfo, opts mergeOptions)
+}
+
+// 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 protowire.Number, wtyp protowire.Type, opts unmarshalOptions) (pref.Value, unmarshalOutput, error)
+	isInit    func(v pref.Value) error
+	merge     func(dst, src pref.Value, opts mergeOptions) pref.Value
+}
+
+// fieldCoder returns pointer functions for a field, used for operating on
+// struct fields.
+func fieldCoder(fd pref.FieldDescriptor, ft reflect.Type) (*MessageInfo, pointerCoderFuncs) {
+	switch {
+	case fd.IsMap():
+		return encoderFuncsForMap(fd, ft)
+	case fd.Cardinality() == pref.Repeated && !fd.IsPacked():
+		// Repeated fields (not packed).
+		if ft.Kind() != reflect.Slice {
+			break
+		}
+		ft := ft.Elem()
+		switch fd.Kind() {
+		case pref.BoolKind:
+			if ft.Kind() == reflect.Bool {
+				return nil, coderBoolSlice
+			}
+		case pref.EnumKind:
+			if ft.Kind() == reflect.Int32 {
+				return nil, coderEnumSlice
+			}
+		case pref.Int32Kind:
+			if ft.Kind() == reflect.Int32 {
+				return nil, coderInt32Slice
+			}
+		case pref.Sint32Kind:
+			if ft.Kind() == reflect.Int32 {
+				return nil, coderSint32Slice
+			}
+		case pref.Uint32Kind:
+			if ft.Kind() == reflect.Uint32 {
+				return nil, coderUint32Slice
+			}
+		case pref.Int64Kind:
+			if ft.Kind() == reflect.Int64 {
+				return nil, coderInt64Slice
+			}
+		case pref.Sint64Kind:
+			if ft.Kind() == reflect.Int64 {
+				return nil, coderSint64Slice
+			}
+		case pref.Uint64Kind:
+			if ft.Kind() == reflect.Uint64 {
+				return nil, coderUint64Slice
+			}
+		case pref.Sfixed32Kind:
+			if ft.Kind() == reflect.Int32 {
+				return nil, coderSfixed32Slice
+			}
+		case pref.Fixed32Kind:
+			if ft.Kind() == reflect.Uint32 {
+				return nil, coderFixed32Slice
+			}
+		case pref.FloatKind:
+			if ft.Kind() == reflect.Float32 {
+				return nil, coderFloatSlice
+			}
+		case pref.Sfixed64Kind:
+			if ft.Kind() == reflect.Int64 {
+				return nil, coderSfixed64Slice
+			}
+		case pref.Fixed64Kind:
+			if ft.Kind() == reflect.Uint64 {
+				return nil, coderFixed64Slice
+			}
+		case pref.DoubleKind:
+			if ft.Kind() == reflect.Float64 {
+				return nil, coderDoubleSlice
+			}
+		case pref.StringKind:
+			if ft.Kind() == reflect.String && strs.EnforceUTF8(fd) {
+				return nil, coderStringSliceValidateUTF8
+			}
+			if ft.Kind() == reflect.String {
+				return nil, coderStringSlice
+			}
+			if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 && strs.EnforceUTF8(fd) {
+				return nil, coderBytesSliceValidateUTF8
+			}
+			if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 {
+				return nil, coderBytesSlice
+			}
+		case pref.BytesKind:
+			if ft.Kind() == reflect.String {
+				return nil, coderStringSlice
+			}
+			if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 {
+				return nil, coderBytesSlice
+			}
+		case pref.MessageKind:
+			return getMessageInfo(ft), makeMessageSliceFieldCoder(fd, ft)
+		case pref.GroupKind:
+			return getMessageInfo(ft), makeGroupSliceFieldCoder(fd, ft)
+		}
+	case fd.Cardinality() == pref.Repeated && fd.IsPacked():
+		// Packed repeated fields.
+		//
+		// Only repeated fields of primitive numeric types
+		// (Varint, Fixed32, or Fixed64 wire type) can be packed.
+		if ft.Kind() != reflect.Slice {
+			break
+		}
+		ft := ft.Elem()
+		switch fd.Kind() {
+		case pref.BoolKind:
+			if ft.Kind() == reflect.Bool {
+				return nil, coderBoolPackedSlice
+			}
+		case pref.EnumKind:
+			if ft.Kind() == reflect.Int32 {
+				return nil, coderEnumPackedSlice
+			}
+		case pref.Int32Kind:
+			if ft.Kind() == reflect.Int32 {
+				return nil, coderInt32PackedSlice
+			}
+		case pref.Sint32Kind:
+			if ft.Kind() == reflect.Int32 {
+				return nil, coderSint32PackedSlice
+			}
+		case pref.Uint32Kind:
+			if ft.Kind() == reflect.Uint32 {
+				return nil, coderUint32PackedSlice
+			}
+		case pref.Int64Kind:
+			if ft.Kind() == reflect.Int64 {
+				return nil, coderInt64PackedSlice
+			}
+		case pref.Sint64Kind:
+			if ft.Kind() == reflect.Int64 {
+				return nil, coderSint64PackedSlice
+			}
+		case pref.Uint64Kind:
+			if ft.Kind() == reflect.Uint64 {
+				return nil, coderUint64PackedSlice
+			}
+		case pref.Sfixed32Kind:
+			if ft.Kind() == reflect.Int32 {
+				return nil, coderSfixed32PackedSlice
+			}
+		case pref.Fixed32Kind:
+			if ft.Kind() == reflect.Uint32 {
+				return nil, coderFixed32PackedSlice
+			}
+		case pref.FloatKind:
+			if ft.Kind() == reflect.Float32 {
+				return nil, coderFloatPackedSlice
+			}
+		case pref.Sfixed64Kind:
+			if ft.Kind() == reflect.Int64 {
+				return nil, coderSfixed64PackedSlice
+			}
+		case pref.Fixed64Kind:
+			if ft.Kind() == reflect.Uint64 {
+				return nil, coderFixed64PackedSlice
+			}
+		case pref.DoubleKind:
+			if ft.Kind() == reflect.Float64 {
+				return nil, coderDoublePackedSlice
+			}
+		}
+	case fd.Kind() == pref.MessageKind:
+		return getMessageInfo(ft), makeMessageFieldCoder(fd, ft)
+	case fd.Kind() == pref.GroupKind:
+		return getMessageInfo(ft), makeGroupFieldCoder(fd, ft)
+	case fd.Syntax() == pref.Proto3 && fd.ContainingOneof() == nil:
+		// Populated oneof fields always encode even if set to the zero value,
+		// which normally are not encoded in proto3.
+		switch fd.Kind() {
+		case pref.BoolKind:
+			if ft.Kind() == reflect.Bool {
+				return nil, coderBoolNoZero
+			}
+		case pref.EnumKind:
+			if ft.Kind() == reflect.Int32 {
+				return nil, coderEnumNoZero
+			}
+		case pref.Int32Kind:
+			if ft.Kind() == reflect.Int32 {
+				return nil, coderInt32NoZero
+			}
+		case pref.Sint32Kind:
+			if ft.Kind() == reflect.Int32 {
+				return nil, coderSint32NoZero
+			}
+		case pref.Uint32Kind:
+			if ft.Kind() == reflect.Uint32 {
+				return nil, coderUint32NoZero
+			}
+		case pref.Int64Kind:
+			if ft.Kind() == reflect.Int64 {
+				return nil, coderInt64NoZero
+			}
+		case pref.Sint64Kind:
+			if ft.Kind() == reflect.Int64 {
+				return nil, coderSint64NoZero
+			}
+		case pref.Uint64Kind:
+			if ft.Kind() == reflect.Uint64 {
+				return nil, coderUint64NoZero
+			}
+		case pref.Sfixed32Kind:
+			if ft.Kind() == reflect.Int32 {
+				return nil, coderSfixed32NoZero
+			}
+		case pref.Fixed32Kind:
+			if ft.Kind() == reflect.Uint32 {
+				return nil, coderFixed32NoZero
+			}
+		case pref.FloatKind:
+			if ft.Kind() == reflect.Float32 {
+				return nil, coderFloatNoZero
+			}
+		case pref.Sfixed64Kind:
+			if ft.Kind() == reflect.Int64 {
+				return nil, coderSfixed64NoZero
+			}
+		case pref.Fixed64Kind:
+			if ft.Kind() == reflect.Uint64 {
+				return nil, coderFixed64NoZero
+			}
+		case pref.DoubleKind:
+			if ft.Kind() == reflect.Float64 {
+				return nil, coderDoubleNoZero
+			}
+		case pref.StringKind:
+			if ft.Kind() == reflect.String && strs.EnforceUTF8(fd) {
+				return nil, coderStringNoZeroValidateUTF8
+			}
+			if ft.Kind() == reflect.String {
+				return nil, coderStringNoZero
+			}
+			if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 && strs.EnforceUTF8(fd) {
+				return nil, coderBytesNoZeroValidateUTF8
+			}
+			if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 {
+				return nil, coderBytesNoZero
+			}
+		case pref.BytesKind:
+			if ft.Kind() == reflect.String {
+				return nil, coderStringNoZero
+			}
+			if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 {
+				return nil, coderBytesNoZero
+			}
+		}
+	case ft.Kind() == reflect.Ptr:
+		ft := ft.Elem()
+		switch fd.Kind() {
+		case pref.BoolKind:
+			if ft.Kind() == reflect.Bool {
+				return nil, coderBoolPtr
+			}
+		case pref.EnumKind:
+			if ft.Kind() == reflect.Int32 {
+				return nil, coderEnumPtr
+			}
+		case pref.Int32Kind:
+			if ft.Kind() == reflect.Int32 {
+				return nil, coderInt32Ptr
+			}
+		case pref.Sint32Kind:
+			if ft.Kind() == reflect.Int32 {
+				return nil, coderSint32Ptr
+			}
+		case pref.Uint32Kind:
+			if ft.Kind() == reflect.Uint32 {
+				return nil, coderUint32Ptr
+			}
+		case pref.Int64Kind:
+			if ft.Kind() == reflect.Int64 {
+				return nil, coderInt64Ptr
+			}
+		case pref.Sint64Kind:
+			if ft.Kind() == reflect.Int64 {
+				return nil, coderSint64Ptr
+			}
+		case pref.Uint64Kind:
+			if ft.Kind() == reflect.Uint64 {
+				return nil, coderUint64Ptr
+			}
+		case pref.Sfixed32Kind:
+			if ft.Kind() == reflect.Int32 {
+				return nil, coderSfixed32Ptr
+			}
+		case pref.Fixed32Kind:
+			if ft.Kind() == reflect.Uint32 {
+				return nil, coderFixed32Ptr
+			}
+		case pref.FloatKind:
+			if ft.Kind() == reflect.Float32 {
+				return nil, coderFloatPtr
+			}
+		case pref.Sfixed64Kind:
+			if ft.Kind() == reflect.Int64 {
+				return nil, coderSfixed64Ptr
+			}
+		case pref.Fixed64Kind:
+			if ft.Kind() == reflect.Uint64 {
+				return nil, coderFixed64Ptr
+			}
+		case pref.DoubleKind:
+			if ft.Kind() == reflect.Float64 {
+				return nil, coderDoublePtr
+			}
+		case pref.StringKind:
+			if ft.Kind() == reflect.String && strs.EnforceUTF8(fd) {
+				return nil, coderStringPtrValidateUTF8
+			}
+			if ft.Kind() == reflect.String {
+				return nil, coderStringPtr
+			}
+		case pref.BytesKind:
+			if ft.Kind() == reflect.String {
+				return nil, coderStringPtr
+			}
+		}
+	default:
+		switch fd.Kind() {
+		case pref.BoolKind:
+			if ft.Kind() == reflect.Bool {
+				return nil, coderBool
+			}
+		case pref.EnumKind:
+			if ft.Kind() == reflect.Int32 {
+				return nil, coderEnum
+			}
+		case pref.Int32Kind:
+			if ft.Kind() == reflect.Int32 {
+				return nil, coderInt32
+			}
+		case pref.Sint32Kind:
+			if ft.Kind() == reflect.Int32 {
+				return nil, coderSint32
+			}
+		case pref.Uint32Kind:
+			if ft.Kind() == reflect.Uint32 {
+				return nil, coderUint32
+			}
+		case pref.Int64Kind:
+			if ft.Kind() == reflect.Int64 {
+				return nil, coderInt64
+			}
+		case pref.Sint64Kind:
+			if ft.Kind() == reflect.Int64 {
+				return nil, coderSint64
+			}
+		case pref.Uint64Kind:
+			if ft.Kind() == reflect.Uint64 {
+				return nil, coderUint64
+			}
+		case pref.Sfixed32Kind:
+			if ft.Kind() == reflect.Int32 {
+				return nil, coderSfixed32
+			}
+		case pref.Fixed32Kind:
+			if ft.Kind() == reflect.Uint32 {
+				return nil, coderFixed32
+			}
+		case pref.FloatKind:
+			if ft.Kind() == reflect.Float32 {
+				return nil, coderFloat
+			}
+		case pref.Sfixed64Kind:
+			if ft.Kind() == reflect.Int64 {
+				return nil, coderSfixed64
+			}
+		case pref.Fixed64Kind:
+			if ft.Kind() == reflect.Uint64 {
+				return nil, coderFixed64
+			}
+		case pref.DoubleKind:
+			if ft.Kind() == reflect.Float64 {
+				return nil, coderDouble
+			}
+		case pref.StringKind:
+			if ft.Kind() == reflect.String && strs.EnforceUTF8(fd) {
+				return nil, coderStringValidateUTF8
+			}
+			if ft.Kind() == reflect.String {
+				return nil, coderString
+			}
+			if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 && strs.EnforceUTF8(fd) {
+				return nil, coderBytesValidateUTF8
+			}
+			if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 {
+				return nil, coderBytes
+			}
+		case pref.BytesKind:
+			if ft.Kind() == reflect.String {
+				return nil, coderString
+			}
+			if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 {
+				return nil, coderBytes
+			}
+		}
+	}
+	panic(fmt.Sprintf("invalid type: no encoder for %v %v %v/%v", fd.FullName(), fd.Cardinality(), fd.Kind(), ft))
+}
+
+// encoderFuncsForValue returns value functions for a field, used for
+// extension values and map encoding.
+func encoderFuncsForValue(fd pref.FieldDescriptor) valueCoderFuncs {
+	switch {
+	case fd.Cardinality() == pref.Repeated && !fd.IsPacked():
+		switch fd.Kind() {
+		case pref.BoolKind:
+			return coderBoolSliceValue
+		case pref.EnumKind:
+			return coderEnumSliceValue
+		case pref.Int32Kind:
+			return coderInt32SliceValue
+		case pref.Sint32Kind:
+			return coderSint32SliceValue
+		case pref.Uint32Kind:
+			return coderUint32SliceValue
+		case pref.Int64Kind:
+			return coderInt64SliceValue
+		case pref.Sint64Kind:
+			return coderSint64SliceValue
+		case pref.Uint64Kind:
+			return coderUint64SliceValue
+		case pref.Sfixed32Kind:
+			return coderSfixed32SliceValue
+		case pref.Fixed32Kind:
+			return coderFixed32SliceValue
+		case pref.FloatKind:
+			return coderFloatSliceValue
+		case pref.Sfixed64Kind:
+			return coderSfixed64SliceValue
+		case pref.Fixed64Kind:
+			return coderFixed64SliceValue
+		case pref.DoubleKind:
+			return coderDoubleSliceValue
+		case pref.StringKind:
+			// We don't have a UTF-8 validating coder for repeated string fields.
+			// Value coders are used for extensions and maps.
+			// Extensions are never proto3, and maps never contain lists.
+			return coderStringSliceValue
+		case pref.BytesKind:
+			return coderBytesSliceValue
+		case pref.MessageKind:
+			return coderMessageSliceValue
+		case pref.GroupKind:
+			return coderGroupSliceValue
+		}
+	case fd.Cardinality() == pref.Repeated && fd.IsPacked():
+		switch fd.Kind() {
+		case pref.BoolKind:
+			return coderBoolPackedSliceValue
+		case pref.EnumKind:
+			return coderEnumPackedSliceValue
+		case pref.Int32Kind:
+			return coderInt32PackedSliceValue
+		case pref.Sint32Kind:
+			return coderSint32PackedSliceValue
+		case pref.Uint32Kind:
+			return coderUint32PackedSliceValue
+		case pref.Int64Kind:
+			return coderInt64PackedSliceValue
+		case pref.Sint64Kind:
+			return coderSint64PackedSliceValue
+		case pref.Uint64Kind:
+			return coderUint64PackedSliceValue
+		case pref.Sfixed32Kind:
+			return coderSfixed32PackedSliceValue
+		case pref.Fixed32Kind:
+			return coderFixed32PackedSliceValue
+		case pref.FloatKind:
+			return coderFloatPackedSliceValue
+		case pref.Sfixed64Kind:
+			return coderSfixed64PackedSliceValue
+		case pref.Fixed64Kind:
+			return coderFixed64PackedSliceValue
+		case pref.DoubleKind:
+			return coderDoublePackedSliceValue
+		}
+	default:
+		switch fd.Kind() {
+		default:
+		case pref.BoolKind:
+			return coderBoolValue
+		case pref.EnumKind:
+			return coderEnumValue
+		case pref.Int32Kind:
+			return coderInt32Value
+		case pref.Sint32Kind:
+			return coderSint32Value
+		case pref.Uint32Kind:
+			return coderUint32Value
+		case pref.Int64Kind:
+			return coderInt64Value
+		case pref.Sint64Kind:
+			return coderSint64Value
+		case pref.Uint64Kind:
+			return coderUint64Value
+		case pref.Sfixed32Kind:
+			return coderSfixed32Value
+		case pref.Fixed32Kind:
+			return coderFixed32Value
+		case pref.FloatKind:
+			return coderFloatValue
+		case pref.Sfixed64Kind:
+			return coderSfixed64Value
+		case pref.Fixed64Kind:
+			return coderFixed64Value
+		case pref.DoubleKind:
+			return coderDoubleValue
+		case pref.StringKind:
+			if strs.EnforceUTF8(fd) {
+				return coderStringValueValidateUTF8
+			}
+			return coderStringValue
+		case pref.BytesKind:
+			return coderBytesValue
+		case pref.MessageKind:
+			return coderMessageValue
+		case pref.GroupKind:
+			return coderGroupValue
+		}
+	}
+	panic(fmt.Sprintf("invalid field: no encoder for %v %v %v", fd.FullName(), fd.Cardinality(), fd.Kind()))
+}
diff --git a/vendor/google.golang.org/protobuf/internal/impl/codec_unsafe.go b/vendor/google.golang.org/protobuf/internal/impl/codec_unsafe.go
new file mode 100644
index 0000000..e118af1
--- /dev/null
+++ b/vendor/google.golang.org/protobuf/internal/impl/codec_unsafe.go
@@ -0,0 +1,17 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build !purego,!appengine
+
+package impl
+
+// When using unsafe pointers, we can just treat enum values as int32s.
+
+var (
+	coderEnumNoZero      = coderInt32NoZero
+	coderEnum            = coderInt32
+	coderEnumPtr         = coderInt32Ptr
+	coderEnumSlice       = coderInt32Slice
+	coderEnumPackedSlice = coderInt32PackedSlice
+)
diff --git a/vendor/google.golang.org/protobuf/internal/impl/convert.go b/vendor/google.golang.org/protobuf/internal/impl/convert.go
new file mode 100644
index 0000000..36a90df
--- /dev/null
+++ b/vendor/google.golang.org/protobuf/internal/impl/convert.go
@@ -0,0 +1,467 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package impl
+
+import (
+	"fmt"
+	"reflect"
+
+	pref "google.golang.org/protobuf/reflect/protoreflect"
+)
+
+// unwrapper unwraps the value to the underlying value.
+// This is implemented by List and Map.
+type unwrapper interface {
+	protoUnwrap() interface{}
+}
+
+// A Converter coverts to/from Go reflect.Value types and protobuf protoreflect.Value types.
+type Converter interface {
+	// PBValueOf converts a reflect.Value to a protoreflect.Value.
+	PBValueOf(reflect.Value) pref.Value
+
+	// GoValueOf converts a protoreflect.Value to a reflect.Value.
+	GoValueOf(pref.Value) reflect.Value
+
+	// IsValidPB returns whether a protoreflect.Value is compatible with this type.
+	IsValidPB(pref.Value) bool
+
+	// IsValidGo returns whether a reflect.Value is compatible with this type.
+	IsValidGo(reflect.Value) bool
+
+	// New returns a new field value.
+	// For scalars, it returns the default value of the field.
+	// For composite types, it returns a new mutable value.
+	New() pref.Value
+
+	// Zero returns a new field value.
+	// For scalars, it returns the default value of the field.
+	// For composite types, it returns an immutable, empty value.
+	Zero() pref.Value
+}
+
+// NewConverter matches a Go type with a protobuf field and returns a Converter
+// that converts between the two. Enums must be a named int32 kind that
+// implements protoreflect.Enum, and messages must be pointer to a named
+// struct type that implements protoreflect.ProtoMessage.
+//
+// This matcher deliberately supports a wider range of Go types than what
+// protoc-gen-go historically generated to be able to automatically wrap some
+// v1 messages generated by other forks of protoc-gen-go.
+func NewConverter(t reflect.Type, fd pref.FieldDescriptor) Converter {
+	switch {
+	case fd.IsList():
+		return newListConverter(t, fd)
+	case fd.IsMap():
+		return newMapConverter(t, fd)
+	default:
+		return newSingularConverter(t, fd)
+	}
+	panic(fmt.Sprintf("invalid Go type %v for field %v", t, fd.FullName()))
+}
+
+var (
+	boolType    = reflect.TypeOf(bool(false))
+	int32Type   = reflect.TypeOf(int32(0))
+	int64Type   = reflect.TypeOf(int64(0))
+	uint32Type  = reflect.TypeOf(uint32(0))
+	uint64Type  = reflect.TypeOf(uint64(0))
+	float32Type = reflect.TypeOf(float32(0))
+	float64Type = reflect.TypeOf(float64(0))
+	stringType  = reflect.TypeOf(string(""))
+	bytesType   = reflect.TypeOf([]byte(nil))
+	byteType    = reflect.TypeOf(byte(0))
+)
+
+var (
+	boolZero    = pref.ValueOfBool(false)
+	int32Zero   = pref.ValueOfInt32(0)
+	int64Zero   = pref.ValueOfInt64(0)
+	uint32Zero  = pref.ValueOfUint32(0)
+	uint64Zero  = pref.ValueOfUint64(0)
+	float32Zero = pref.ValueOfFloat32(0)
+	float64Zero = pref.ValueOfFloat64(0)
+	stringZero  = pref.ValueOfString("")
+	bytesZero   = pref.ValueOfBytes(nil)
+)
+
+func newSingularConverter(t reflect.Type, fd pref.FieldDescriptor) Converter {
+	defVal := func(fd pref.FieldDescriptor, zero pref.Value) pref.Value {
+		if fd.Cardinality() == pref.Repeated {
+			// Default isn't defined for repeated fields.
+			return zero
+		}
+		return fd.Default()
+	}
+	switch fd.Kind() {
+	case pref.BoolKind:
+		if t.Kind() == reflect.Bool {
+			return &boolConverter{t, defVal(fd, boolZero)}
+		}
+	case pref.Int32Kind, pref.Sint32Kind, pref.Sfixed32Kind:
+		if t.Kind() == reflect.Int32 {
+			return &int32Converter{t, defVal(fd, int32Zero)}
+		}
+	case pref.Int64Kind, pref.Sint64Kind, pref.Sfixed64Kind:
+		if t.Kind() == reflect.Int64 {
+			return &int64Converter{t, defVal(fd, int64Zero)}
+		}
+	case pref.Uint32Kind, pref.Fixed32Kind:
+		if t.Kind() == reflect.Uint32 {
+			return &uint32Converter{t, defVal(fd, uint32Zero)}
+		}
+	case pref.Uint64Kind, pref.Fixed64Kind:
+		if t.Kind() == reflect.Uint64 {
+			return &uint64Converter{t, defVal(fd, uint64Zero)}
+		}
+	case pref.FloatKind:
+		if t.Kind() == reflect.Float32 {
+			return &float32Converter{t, defVal(fd, float32Zero)}
+		}
+	case pref.DoubleKind:
+		if t.Kind() == reflect.Float64 {
+			return &float64Converter{t, defVal(fd, float64Zero)}
+		}
+	case pref.StringKind:
+		if t.Kind() == reflect.String || (t.Kind() == reflect.Slice && t.Elem() == byteType) {
+			return &stringConverter{t, defVal(fd, stringZero)}
+		}
+	case pref.BytesKind:
+		if t.Kind() == reflect.String || (t.Kind() == reflect.Slice && t.Elem() == byteType) {
+			return &bytesConverter{t, defVal(fd, bytesZero)}
+		}
+	case pref.EnumKind:
+		// Handle enums, which must be a named int32 type.
+		if t.Kind() == reflect.Int32 {
+			return newEnumConverter(t, fd)
+		}
+	case pref.MessageKind, pref.GroupKind:
+		return newMessageConverter(t)
+	}
+	panic(fmt.Sprintf("invalid Go type %v for field %v", t, fd.FullName()))
+}
+
+type boolConverter struct {
+	goType reflect.Type
+	def    pref.Value
+}
+
+func (c *boolConverter) PBValueOf(v reflect.Value) pref.Value {
+	if v.Type() != c.goType {
+		panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType))
+	}
+	return pref.ValueOfBool(v.Bool())
+}
+func (c *boolConverter) GoValueOf(v pref.Value) reflect.Value {
+	return reflect.ValueOf(v.Bool()).Convert(c.goType)
+}
+func (c *boolConverter) IsValidPB(v pref.Value) bool {
+	_, ok := v.Interface().(bool)
+	return ok
+}
+func (c *boolConverter) IsValidGo(v reflect.Value) bool {
+	return v.IsValid() && v.Type() == c.goType
+}
+func (c *boolConverter) New() pref.Value  { return c.def }
+func (c *boolConverter) Zero() pref.Value { return c.def }
+
+type int32Converter struct {
+	goType reflect.Type
+	def    pref.Value
+}
+
+func (c *int32Converter) PBValueOf(v reflect.Value) pref.Value {
+	if v.Type() != c.goType {
+		panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType))
+	}
+	return pref.ValueOfInt32(int32(v.Int()))
+}
+func (c *int32Converter) GoValueOf(v pref.Value) reflect.Value {
+	return reflect.ValueOf(int32(v.Int())).Convert(c.goType)
+}
+func (c *int32Converter) IsValidPB(v pref.Value) bool {
+	_, ok := v.Interface().(int32)
+	return ok
+}
+func (c *int32Converter) IsValidGo(v reflect.Value) bool {
+	return v.IsValid() && v.Type() == c.goType
+}
+func (c *int32Converter) New() pref.Value  { return c.def }
+func (c *int32Converter) Zero() pref.Value { return c.def }
+
+type int64Converter struct {
+	goType reflect.Type
+	def    pref.Value
+}
+
+func (c *int64Converter) PBValueOf(v reflect.Value) pref.Value {
+	if v.Type() != c.goType {
+		panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType))
+	}
+	return pref.ValueOfInt64(int64(v.Int()))
+}
+func (c *int64Converter) GoValueOf(v pref.Value) reflect.Value {
+	return reflect.ValueOf(int64(v.Int())).Convert(c.goType)
+}
+func (c *int64Converter) IsValidPB(v pref.Value) bool {
+	_, ok := v.Interface().(int64)
+	return ok
+}
+func (c *int64Converter) IsValidGo(v reflect.Value) bool {
+	return v.IsValid() && v.Type() == c.goType
+}
+func (c *int64Converter) New() pref.Value  { return c.def }
+func (c *int64Converter) Zero() pref.Value { return c.def }
+
+type uint32Converter struct {
+	goType reflect.Type
+	def    pref.Value
+}
+
+func (c *uint32Converter) PBValueOf(v reflect.Value) pref.Value {
+	if v.Type() != c.goType {
+		panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType))
+	}
+	return pref.ValueOfUint32(uint32(v.Uint()))
+}
+func (c *uint32Converter) GoValueOf(v pref.Value) reflect.Value {
+	return reflect.ValueOf(uint32(v.Uint())).Convert(c.goType)
+}
+func (c *uint32Converter) IsValidPB(v pref.Value) bool {
+	_, ok := v.Interface().(uint32)
+	return ok
+}
+func (c *uint32Converter) IsValidGo(v reflect.Value) bool {
+	return v.IsValid() && v.Type() == c.goType
+}
+func (c *uint32Converter) New() pref.Value  { return c.def }
+func (c *uint32Converter) Zero() pref.Value { return c.def }
+
+type uint64Converter struct {
+	goType reflect.Type
+	def    pref.Value
+}
+
+func (c *uint64Converter) PBValueOf(v reflect.Value) pref.Value {
+	if v.Type() != c.goType {
+		panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType))
+	}
+	return pref.ValueOfUint64(uint64(v.Uint()))
+}
+func (c *uint64Converter) GoValueOf(v pref.Value) reflect.Value {
+	return reflect.ValueOf(uint64(v.Uint())).Convert(c.goType)
+}
+func (c *uint64Converter) IsValidPB(v pref.Value) bool {
+	_, ok := v.Interface().(uint64)
+	return ok
+}
+func (c *uint64Converter) IsValidGo(v reflect.Value) bool {
+	return v.IsValid() && v.Type() == c.goType
+}
+func (c *uint64Converter) New() pref.Value  { return c.def }
+func (c *uint64Converter) Zero() pref.Value { return c.def }
+
+type float32Converter struct {
+	goType reflect.Type
+	def    pref.Value
+}
+
+func (c *float32Converter) PBValueOf(v reflect.Value) pref.Value {
+	if v.Type() != c.goType {
+		panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType))
+	}
+	return pref.ValueOfFloat32(float32(v.Float()))
+}
+func (c *float32Converter) GoValueOf(v pref.Value) reflect.Value {
+	return reflect.ValueOf(float32(v.Float())).Convert(c.goType)
+}
+func (c *float32Converter) IsValidPB(v pref.Value) bool {
+	_, ok := v.Interface().(float32)
+	return ok
+}
+func (c *float32Converter) IsValidGo(v reflect.Value) bool {
+	return v.IsValid() && v.Type() == c.goType
+}
+func (c *float32Converter) New() pref.Value  { return c.def }
+func (c *float32Converter) Zero() pref.Value { return c.def }
+
+type float64Converter struct {
+	goType reflect.Type
+	def    pref.Value
+}
+
+func (c *float64Converter) PBValueOf(v reflect.Value) pref.Value {
+	if v.Type() != c.goType {
+		panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType))
+	}
+	return pref.ValueOfFloat64(float64(v.Float()))
+}
+func (c *float64Converter) GoValueOf(v pref.Value) reflect.Value {
+	return reflect.ValueOf(float64(v.Float())).Convert(c.goType)
+}
+func (c *float64Converter) IsValidPB(v pref.Value) bool {
+	_, ok := v.Interface().(float64)
+	return ok
+}
+func (c *float64Converter) IsValidGo(v reflect.Value) bool {
+	return v.IsValid() && v.Type() == c.goType
+}
+func (c *float64Converter) New() pref.Value  { return c.def }
+func (c *float64Converter) Zero() pref.Value { return c.def }
+
+type stringConverter struct {
+	goType reflect.Type
+	def    pref.Value
+}
+
+func (c *stringConverter) PBValueOf(v reflect.Value) pref.Value {
+	if v.Type() != c.goType {
+		panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType))
+	}
+	return pref.ValueOfString(v.Convert(stringType).String())
+}
+func (c *stringConverter) GoValueOf(v pref.Value) reflect.Value {
+	// pref.Value.String never panics, so we go through an interface
+	// conversion here to check the type.
+	s := v.Interface().(string)
+	if c.goType.Kind() == reflect.Slice && s == "" {
+		return reflect.Zero(c.goType) // ensure empty string is []byte(nil)
+	}
+	return reflect.ValueOf(s).Convert(c.goType)
+}
+func (c *stringConverter) IsValidPB(v pref.Value) bool {
+	_, ok := v.Interface().(string)
+	return ok
+}
+func (c *stringConverter) IsValidGo(v reflect.Value) bool {
+	return v.IsValid() && v.Type() == c.goType
+}
+func (c *stringConverter) New() pref.Value  { return c.def }
+func (c *stringConverter) Zero() pref.Value { return c.def }
+
+type bytesConverter struct {
+	goType reflect.Type
+	def    pref.Value
+}
+
+func (c *bytesConverter) PBValueOf(v reflect.Value) pref.Value {
+	if v.Type() != c.goType {
+		panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType))
+	}
+	if c.goType.Kind() == reflect.String && v.Len() == 0 {
+		return pref.ValueOfBytes(nil) // ensure empty string is []byte(nil)
+	}
+	return pref.ValueOfBytes(v.Convert(bytesType).Bytes())
+}
+func (c *bytesConverter) GoValueOf(v pref.Value) reflect.Value {
+	return reflect.ValueOf(v.Bytes()).Convert(c.goType)
+}
+func (c *bytesConverter) IsValidPB(v pref.Value) bool {
+	_, ok := v.Interface().([]byte)
+	return ok
+}
+func (c *bytesConverter) IsValidGo(v reflect.Value) bool {
+	return v.IsValid() && v.Type() == c.goType
+}
+func (c *bytesConverter) New() pref.Value  { return c.def }
+func (c *bytesConverter) Zero() pref.Value { return c.def }
+
+type enumConverter struct {
+	goType reflect.Type
+	def    pref.Value
+}
+
+func newEnumConverter(goType reflect.Type, fd pref.FieldDescriptor) Converter {
+	var def pref.Value
+	if fd.Cardinality() == pref.Repeated {
+		def = pref.ValueOfEnum(fd.Enum().Values().Get(0).Number())
+	} else {
+		def = fd.Default()
+	}
+	return &enumConverter{goType, def}
+}
+
+func (c *enumConverter) PBValueOf(v reflect.Value) pref.Value {
+	if v.Type() != c.goType {
+		panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType))
+	}
+	return pref.ValueOfEnum(pref.EnumNumber(v.Int()))
+}
+
+func (c *enumConverter) GoValueOf(v pref.Value) reflect.Value {
+	return reflect.ValueOf(v.Enum()).Convert(c.goType)
+}
+
+func (c *enumConverter) IsValidPB(v pref.Value) bool {
+	_, ok := v.Interface().(pref.EnumNumber)
+	return ok
+}
+
+func (c *enumConverter) IsValidGo(v reflect.Value) bool {
+	return v.IsValid() && v.Type() == c.goType
+}
+
+func (c *enumConverter) New() pref.Value {
+	return c.def
+}
+
+func (c *enumConverter) Zero() pref.Value {
+	return c.def
+}
+
+type messageConverter struct {
+	goType reflect.Type
+}
+
+func newMessageConverter(goType reflect.Type) Converter {
+	return &messageConverter{goType}
+}
+
+func (c *messageConverter) PBValueOf(v reflect.Value) pref.Value {
+	if v.Type() != c.goType {
+		panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType))
+	}
+	if m, ok := v.Interface().(pref.ProtoMessage); ok {
+		return pref.ValueOfMessage(m.ProtoReflect())
+	}
+	return pref.ValueOfMessage(legacyWrapMessage(v))
+}
+
+func (c *messageConverter) GoValueOf(v pref.Value) reflect.Value {
+	m := v.Message()
+	var rv reflect.Value
+	if u, ok := m.(unwrapper); ok {
+		rv = reflect.ValueOf(u.protoUnwrap())
+	} else {
+		rv = reflect.ValueOf(m.Interface())
+	}
+	if rv.Type() != c.goType {
+		panic(fmt.Sprintf("invalid type: got %v, want %v", rv.Type(), c.goType))
+	}
+	return rv
+}
+
+func (c *messageConverter) IsValidPB(v pref.Value) bool {
+	m := v.Message()
+	var rv reflect.Value
+	if u, ok := m.(unwrapper); ok {
+		rv = reflect.ValueOf(u.protoUnwrap())
+	} else {
+		rv = reflect.ValueOf(m.Interface())
+	}
+	return rv.Type() == c.goType
+}
+
+func (c *messageConverter) IsValidGo(v reflect.Value) bool {
+	return v.IsValid() && v.Type() == c.goType
+}
+
+func (c *messageConverter) New() pref.Value {
+	return c.PBValueOf(reflect.New(c.goType.Elem()))
+}
+
+func (c *messageConverter) Zero() pref.Value {
+	return c.PBValueOf(reflect.Zero(c.goType))
+}
diff --git a/vendor/google.golang.org/protobuf/internal/impl/convert_list.go b/vendor/google.golang.org/protobuf/internal/impl/convert_list.go
new file mode 100644
index 0000000..6fccab5
--- /dev/null
+++ b/vendor/google.golang.org/protobuf/internal/impl/convert_list.go
@@ -0,0 +1,141 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package impl
+
+import (
+	"fmt"
+	"reflect"
+
+	pref "google.golang.org/protobuf/reflect/protoreflect"
+)
+
+func newListConverter(t reflect.Type, fd pref.FieldDescriptor) Converter {
+	switch {
+	case t.Kind() == reflect.Ptr && t.Elem().Kind() == reflect.Slice:
+		return &listPtrConverter{t, newSingularConverter(t.Elem().Elem(), fd)}
+	case t.Kind() == reflect.Slice:
+		return &listConverter{t, newSingularConverter(t.Elem(), fd)}
+	}
+	panic(fmt.Sprintf("invalid Go type %v for field %v", t, fd.FullName()))
+}
+
+type listConverter struct {
+	goType reflect.Type // []T
+	c      Converter
+}
+
+func (c *listConverter) PBValueOf(v reflect.Value) pref.Value {
+	if v.Type() != c.goType {
+		panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType))
+	}
+	pv := reflect.New(c.goType)
+	pv.Elem().Set(v)
+	return pref.ValueOfList(&listReflect{pv, c.c})
+}
+
+func (c *listConverter) GoValueOf(v pref.Value) reflect.Value {
+	rv := v.List().(*listReflect).v
+	if rv.IsNil() {
+		return reflect.Zero(c.goType)
+	}
+	return rv.Elem()
+}
+
+func (c *listConverter) IsValidPB(v pref.Value) bool {
+	list, ok := v.Interface().(*listReflect)
+	if !ok {
+		return false
+	}
+	return list.v.Type().Elem() == c.goType
+}
+
+func (c *listConverter) IsValidGo(v reflect.Value) bool {
+	return v.IsValid() && v.Type() == c.goType
+}
+
+func (c *listConverter) New() pref.Value {
+	return pref.ValueOfList(&listReflect{reflect.New(c.goType), c.c})
+}
+
+func (c *listConverter) Zero() pref.Value {
+	return pref.ValueOfList(&listReflect{reflect.Zero(reflect.PtrTo(c.goType)), c.c})
+}
+
+type listPtrConverter struct {
+	goType reflect.Type // *[]T
+	c      Converter
+}
+
+func (c *listPtrConverter) PBValueOf(v reflect.Value) pref.Value {
+	if v.Type() != c.goType {
+		panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType))
+	}
+	return pref.ValueOfList(&listReflect{v, c.c})
+}
+
+func (c *listPtrConverter) GoValueOf(v pref.Value) reflect.Value {
+	return v.List().(*listReflect).v
+}
+
+func (c *listPtrConverter) IsValidPB(v pref.Value) bool {
+	list, ok := v.Interface().(*listReflect)
+	if !ok {
+		return false
+	}
+	return list.v.Type() == c.goType
+}
+
+func (c *listPtrConverter) IsValidGo(v reflect.Value) bool {
+	return v.IsValid() && v.Type() == c.goType
+}
+
+func (c *listPtrConverter) New() pref.Value {
+	return c.PBValueOf(reflect.New(c.goType.Elem()))
+}
+
+func (c *listPtrConverter) Zero() pref.Value {
+	return c.PBValueOf(reflect.Zero(c.goType))
+}
+
+type listReflect struct {
+	v    reflect.Value // *[]T
+	conv Converter
+}
+
+func (ls *listReflect) Len() int {
+	if ls.v.IsNil() {
+		return 0
+	}
+	return ls.v.Elem().Len()
+}
+func (ls *listReflect) Get(i int) pref.Value {
+	return ls.conv.PBValueOf(ls.v.Elem().Index(i))
+}
+func (ls *listReflect) Set(i int, v pref.Value) {
+	ls.v.Elem().Index(i).Set(ls.conv.GoValueOf(v))
+}
+func (ls *listReflect) Append(v pref.Value) {
+	ls.v.Elem().Set(reflect.Append(ls.v.Elem(), ls.conv.GoValueOf(v)))
+}
+func (ls *listReflect) AppendMutable() pref.Value {
+	if _, ok := ls.conv.(*messageConverter); !ok {
+		panic("invalid AppendMutable on list with non-message type")
+	}
+	v := ls.NewElement()
+	ls.Append(v)
+	return v
+}
+func (ls *listReflect) Truncate(i int) {
+	ls.v.Elem().Set(ls.v.Elem().Slice(0, i))
+}
+func (ls *listReflect) NewElement() pref.Value {
+	return ls.conv.New()
+}
+func (ls *listReflect) IsValid() bool {
+	return !ls.v.IsNil()
+}
+func (ls *listReflect) protoUnwrap() interface{} {
+	return ls.v.Interface()
+}
diff --git a/vendor/google.golang.org/protobuf/internal/impl/convert_map.go b/vendor/google.golang.org/protobuf/internal/impl/convert_map.go
new file mode 100644
index 0000000..de06b25
--- /dev/null
+++ b/vendor/google.golang.org/protobuf/internal/impl/convert_map.go
@@ -0,0 +1,121 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package impl
+
+import (
+	"fmt"
+	"reflect"
+
+	pref "google.golang.org/protobuf/reflect/protoreflect"
+)
+
+type mapConverter struct {
+	goType           reflect.Type // map[K]V
+	keyConv, valConv Converter
+}
+
+func newMapConverter(t reflect.Type, fd pref.FieldDescriptor) *mapConverter {
+	if t.Kind() != reflect.Map {
+		panic(fmt.Sprintf("invalid Go type %v for field %v", t, fd.FullName()))
+	}
+	return &mapConverter{
+		goType:  t,
+		keyConv: newSingularConverter(t.Key(), fd.MapKey()),
+		valConv: newSingularConverter(t.Elem(), fd.MapValue()),
+	}
+}
+
+func (c *mapConverter) PBValueOf(v reflect.Value) pref.Value {
+	if v.Type() != c.goType {
+		panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType))
+	}
+	return pref.ValueOfMap(&mapReflect{v, c.keyConv, c.valConv})
+}
+
+func (c *mapConverter) GoValueOf(v pref.Value) reflect.Value {
+	return v.Map().(*mapReflect).v
+}
+
+func (c *mapConverter) IsValidPB(v pref.Value) bool {
+	mapv, ok := v.Interface().(*mapReflect)
+	if !ok {
+		return false
+	}
+	return mapv.v.Type() == c.goType
+}
+
+func (c *mapConverter) IsValidGo(v reflect.Value) bool {
+	return v.IsValid() && v.Type() == c.goType
+}
+
+func (c *mapConverter) New() pref.Value {
+	return c.PBValueOf(reflect.MakeMap(c.goType))
+}
+
+func (c *mapConverter) Zero() pref.Value {
+	return c.PBValueOf(reflect.Zero(c.goType))
+}
+
+type mapReflect struct {
+	v       reflect.Value // map[K]V
+	keyConv Converter
+	valConv Converter
+}
+
+func (ms *mapReflect) Len() int {
+	return ms.v.Len()
+}
+func (ms *mapReflect) Has(k pref.MapKey) bool {
+	rk := ms.keyConv.GoValueOf(k.Value())
+	rv := ms.v.MapIndex(rk)
+	return rv.IsValid()
+}
+func (ms *mapReflect) Get(k pref.MapKey) pref.Value {
+	rk := ms.keyConv.GoValueOf(k.Value())
+	rv := ms.v.MapIndex(rk)
+	if !rv.IsValid() {
+		return pref.Value{}
+	}
+	return ms.valConv.PBValueOf(rv)
+}
+func (ms *mapReflect) Set(k pref.MapKey, v pref.Value) {
+	rk := ms.keyConv.GoValueOf(k.Value())
+	rv := ms.valConv.GoValueOf(v)
+	ms.v.SetMapIndex(rk, rv)
+}
+func (ms *mapReflect) Clear(k pref.MapKey) {
+	rk := ms.keyConv.GoValueOf(k.Value())
+	ms.v.SetMapIndex(rk, reflect.Value{})
+}
+func (ms *mapReflect) Mutable(k pref.MapKey) pref.Value {
+	if _, ok := ms.valConv.(*messageConverter); !ok {
+		panic("invalid Mutable on map with non-message value type")
+	}
+	v := ms.Get(k)
+	if !v.IsValid() {
+		v = ms.NewValue()
+		ms.Set(k, v)
+	}
+	return v
+}
+func (ms *mapReflect) Range(f func(pref.MapKey, pref.Value) bool) {
+	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
+		}
+	}
+}
+func (ms *mapReflect) NewValue() pref.Value {
+	return ms.valConv.New()
+}
+func (ms *mapReflect) IsValid() bool {
+	return !ms.v.IsNil()
+}
+func (ms *mapReflect) protoUnwrap() interface{} {
+	return ms.v.Interface()
+}
diff --git a/vendor/google.golang.org/protobuf/internal/impl/decode.go b/vendor/google.golang.org/protobuf/internal/impl/decode.go
new file mode 100644
index 0000000..85ba1d3
--- /dev/null
+++ b/vendor/google.golang.org/protobuf/internal/impl/decode.go
@@ -0,0 +1,274 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package impl
+
+import (
+	"math/bits"
+
+	"google.golang.org/protobuf/encoding/protowire"
+	"google.golang.org/protobuf/internal/errors"
+	"google.golang.org/protobuf/internal/flags"
+	"google.golang.org/protobuf/proto"
+	"google.golang.org/protobuf/reflect/protoreflect"
+	preg "google.golang.org/protobuf/reflect/protoregistry"
+	"google.golang.org/protobuf/runtime/protoiface"
+	piface "google.golang.org/protobuf/runtime/protoiface"
+)
+
+type unmarshalOptions struct {
+	flags    protoiface.UnmarshalInputFlags
+	resolver interface {
+		FindExtensionByName(field protoreflect.FullName) (protoreflect.ExtensionType, error)
+		FindExtensionByNumber(message protoreflect.FullName, field protoreflect.FieldNumber) (protoreflect.ExtensionType, error)
+	}
+}
+
+func (o unmarshalOptions) Options() proto.UnmarshalOptions {
+	return proto.UnmarshalOptions{
+		Merge:          true,
+		AllowPartial:   true,
+		DiscardUnknown: o.DiscardUnknown(),
+		Resolver:       o.resolver,
+	}
+}
+
+func (o unmarshalOptions) DiscardUnknown() bool { return o.flags&piface.UnmarshalDiscardUnknown != 0 }
+
+func (o unmarshalOptions) IsDefault() bool {
+	return o.flags == 0 && o.resolver == preg.GlobalTypes
+}
+
+var lazyUnmarshalOptions = unmarshalOptions{
+	resolver: preg.GlobalTypes,
+}
+
+type unmarshalOutput struct {
+	n           int // number of bytes consumed
+	initialized bool
+}
+
+// unmarshal is protoreflect.Methods.Unmarshal.
+func (mi *MessageInfo) unmarshal(in piface.UnmarshalInput) (piface.UnmarshalOutput, error) {
+	var p pointer
+	if ms, ok := in.Message.(*messageState); ok {
+		p = ms.pointer()
+	} else {
+		p = in.Message.(*messageReflectWrapper).pointer()
+	}
+	out, err := mi.unmarshalPointer(in.Buf, p, 0, unmarshalOptions{
+		flags:    in.Flags,
+		resolver: in.Resolver,
+	})
+	var flags piface.UnmarshalOutputFlags
+	if out.initialized {
+		flags |= piface.UnmarshalInitialized
+	}
+	return piface.UnmarshalOutput{
+		Flags: flags,
+	}, err
+}
+
+// errUnknown is returned during unmarshaling to indicate a parse error that
+// should result in a field being placed in the unknown fields section (for example,
+// when the wire type doesn't match) as opposed to the entire unmarshal operation
+// failing (for example, when a field extends past the available input).
+//
+// This is a sentinel error which should never be visible to the user.
+var errUnknown = errors.New("unknown")
+
+func (mi *MessageInfo) unmarshalPointer(b []byte, p pointer, groupTag protowire.Number, opts unmarshalOptions) (out unmarshalOutput, err error) {
+	mi.init()
+	if flags.ProtoLegacy && mi.isMessageSet {
+		return unmarshalMessageSet(mi, b, p, opts)
+	}
+	initialized := true
+	var requiredMask uint64
+	var exts *map[int32]ExtensionField
+	start := len(b)
+	for len(b) > 0 {
+		// Parse the tag (field number and wire type).
+		var tag uint64
+		if b[0] < 0x80 {
+			tag = uint64(b[0])
+			b = b[1:]
+		} else if len(b) >= 2 && b[1] < 128 {
+			tag = uint64(b[0]&0x7f) + uint64(b[1])<<7
+			b = b[2:]
+		} else {
+			var n int
+			tag, n = protowire.ConsumeVarint(b)
+			if n < 0 {
+				return out, protowire.ParseError(n)
+			}
+			b = b[n:]
+		}
+		var num protowire.Number
+		if n := tag >> 3; n < uint64(protowire.MinValidNumber) || n > uint64(protowire.MaxValidNumber) {
+			return out, errors.New("invalid field number")
+		} else {
+			num = protowire.Number(n)
+		}
+		wtyp := protowire.Type(tag & 7)
+
+		if wtyp == protowire.EndGroupType {
+			if num != groupTag {
+				return out, errors.New("mismatching end group marker")
+			}
+			groupTag = 0
+			break
+		}
+
+		var f *coderFieldInfo
+		if int(num) < len(mi.denseCoderFields) {
+			f = mi.denseCoderFields[num]
+		} else {
+			f = mi.coderFields[num]
+		}
+		var n int
+		err := errUnknown
+		switch {
+		case f != nil:
+			if f.funcs.unmarshal == nil {
+				break
+			}
+			var o unmarshalOutput
+			o, err = f.funcs.unmarshal(b, p.Apply(f.offset), wtyp, f, opts)
+			n = o.n
+			if err != nil {
+				break
+			}
+			requiredMask |= f.validation.requiredBit
+			if f.funcs.isInit != nil && !o.initialized {
+				initialized = false
+			}
+		default:
+			// Possible extension.
+			if exts == nil && mi.extensionOffset.IsValid() {
+				exts = p.Apply(mi.extensionOffset).Extensions()
+				if *exts == nil {
+					*exts = make(map[int32]ExtensionField)
+				}
+			}
+			if exts == nil {
+				break
+			}
+			var o unmarshalOutput
+			o, err = mi.unmarshalExtension(b, num, wtyp, *exts, opts)
+			if err != nil {
+				break
+			}
+			n = o.n
+			if !o.initialized {
+				initialized = false
+			}
+		}
+		if err != nil {
+			if err != errUnknown {
+				return out, err
+			}
+			n = protowire.ConsumeFieldValue(num, wtyp, b)
+			if n < 0 {
+				return out, protowire.ParseError(n)
+			}
+			if !opts.DiscardUnknown() && mi.unknownOffset.IsValid() {
+				u := p.Apply(mi.unknownOffset).Bytes()
+				*u = protowire.AppendTag(*u, num, wtyp)
+				*u = append(*u, b[:n]...)
+			}
+		}
+		b = b[n:]
+	}
+	if groupTag != 0 {
+		return out, errors.New("missing end group marker")
+	}
+	if mi.numRequiredFields > 0 && bits.OnesCount64(requiredMask) != int(mi.numRequiredFields) {
+		initialized = false
+	}
+	if initialized {
+		out.initialized = true
+	}
+	out.n = start - len(b)
+	return out, nil
+}
+
+func (mi *MessageInfo) unmarshalExtension(b []byte, num protowire.Number, wtyp protowire.Type, exts map[int32]ExtensionField, opts unmarshalOptions) (out unmarshalOutput, err error) {
+	x := exts[int32(num)]
+	xt := x.Type()
+	if xt == nil {
+		var err error
+		xt, err = opts.resolver.FindExtensionByNumber(mi.Desc.FullName(), num)
+		if err != nil {
+			if err == preg.NotFound {
+				return out, errUnknown
+			}
+			return out, errors.New("%v: unable to resolve extension %v: %v", mi.Desc.FullName(), num, err)
+		}
+	}
+	xi := getExtensionFieldInfo(xt)
+	if xi.funcs.unmarshal == nil {
+		return out, errUnknown
+	}
+	if flags.LazyUnmarshalExtensions {
+		if opts.IsDefault() && x.canLazy(xt) {
+			out, valid := skipExtension(b, xi, num, wtyp, opts)
+			switch valid {
+			case ValidationValid:
+				if out.initialized {
+					x.appendLazyBytes(xt, xi, num, wtyp, b[:out.n])
+					exts[int32(num)] = x
+					return out, nil
+				}
+			case ValidationInvalid:
+				return out, errors.New("invalid wire format")
+			case ValidationUnknown:
+			}
+		}
+	}
+	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.New()
+	}
+	v, out, err := xi.funcs.unmarshal(b, ival, num, wtyp, opts)
+	if err != nil {
+		return out, err
+	}
+	if xi.funcs.isInit == nil {
+		out.initialized = true
+	}
+	x.Set(xt, v)
+	exts[int32(num)] = x
+	return out, nil
+}
+
+func skipExtension(b []byte, xi *extensionFieldInfo, num protowire.Number, wtyp protowire.Type, opts unmarshalOptions) (out unmarshalOutput, _ ValidationStatus) {
+	if xi.validation.mi == nil {
+		return out, ValidationUnknown
+	}
+	xi.validation.mi.init()
+	switch xi.validation.typ {
+	case validationTypeMessage:
+		if wtyp != protowire.BytesType {
+			return out, ValidationUnknown
+		}
+		v, n := protowire.ConsumeBytes(b)
+		if n < 0 {
+			return out, ValidationUnknown
+		}
+		out, st := xi.validation.mi.validate(v, 0, opts)
+		out.n = n
+		return out, st
+	case validationTypeGroup:
+		if wtyp != protowire.StartGroupType {
+			return out, ValidationUnknown
+		}
+		out, st := xi.validation.mi.validate(b, num, opts)
+		return out, st
+	default:
+		return out, ValidationUnknown
+	}
+}
diff --git a/vendor/google.golang.org/protobuf/internal/impl/encode.go b/vendor/google.golang.org/protobuf/internal/impl/encode.go
new file mode 100644
index 0000000..8c8a794
--- /dev/null
+++ b/vendor/google.golang.org/protobuf/internal/impl/encode.go
@@ -0,0 +1,199 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package impl
+
+import (
+	"math"
+	"sort"
+	"sync/atomic"
+
+	"google.golang.org/protobuf/internal/flags"
+	proto "google.golang.org/protobuf/proto"
+	piface "google.golang.org/protobuf/runtime/protoiface"
+)
+
+type marshalOptions struct {
+	flags piface.MarshalInputFlags
+}
+
+func (o marshalOptions) Options() proto.MarshalOptions {
+	return proto.MarshalOptions{
+		AllowPartial:  true,
+		Deterministic: o.Deterministic(),
+		UseCachedSize: o.UseCachedSize(),
+	}
+}
+
+func (o marshalOptions) Deterministic() bool { return o.flags&piface.MarshalDeterministic != 0 }
+func (o marshalOptions) UseCachedSize() bool { return o.flags&piface.MarshalUseCachedSize != 0 }
+
+// size is protoreflect.Methods.Size.
+func (mi *MessageInfo) size(in piface.SizeInput) piface.SizeOutput {
+	var p pointer
+	if ms, ok := in.Message.(*messageState); ok {
+		p = ms.pointer()
+	} else {
+		p = in.Message.(*messageReflectWrapper).pointer()
+	}
+	size := mi.sizePointer(p, marshalOptions{
+		flags: in.Flags,
+	})
+	return piface.SizeOutput{Size: size}
+}
+
+func (mi *MessageInfo) sizePointer(p pointer, opts marshalOptions) (size int) {
+	mi.init()
+	if p.IsNil() {
+		return 0
+	}
+	if opts.UseCachedSize() && mi.sizecacheOffset.IsValid() {
+		if size := atomic.LoadInt32(p.Apply(mi.sizecacheOffset).Int32()); size >= 0 {
+			return int(size)
+		}
+	}
+	return mi.sizePointerSlow(p, opts)
+}
+
+func (mi *MessageInfo) sizePointerSlow(p pointer, opts marshalOptions) (size int) {
+	if flags.ProtoLegacy && mi.isMessageSet {
+		size = sizeMessageSet(mi, p, opts)
+		if mi.sizecacheOffset.IsValid() {
+			atomic.StoreInt32(p.Apply(mi.sizecacheOffset).Int32(), int32(size))
+		}
+		return size
+	}
+	if mi.extensionOffset.IsValid() {
+		e := p.Apply(mi.extensionOffset).Extensions()
+		size += mi.sizeExtensions(e, opts)
+	}
+	for _, f := range mi.orderedCoderFields {
+		if f.funcs.size == nil {
+			continue
+		}
+		fptr := p.Apply(f.offset)
+		if f.isPointer && fptr.Elem().IsNil() {
+			continue
+		}
+		size += f.funcs.size(fptr, f, opts)
+	}
+	if mi.unknownOffset.IsValid() {
+		u := *p.Apply(mi.unknownOffset).Bytes()
+		size += len(u)
+	}
+	if mi.sizecacheOffset.IsValid() {
+		if size > math.MaxInt32 {
+			// The size is too large for the int32 sizecache field.
+			// We will need to recompute the size when encoding;
+			// unfortunately expensive, but better than invalid output.
+			atomic.StoreInt32(p.Apply(mi.sizecacheOffset).Int32(), -1)
+		} else {
+			atomic.StoreInt32(p.Apply(mi.sizecacheOffset).Int32(), int32(size))
+		}
+	}
+	return size
+}
+
+// marshal is protoreflect.Methods.Marshal.
+func (mi *MessageInfo) marshal(in piface.MarshalInput) (out piface.MarshalOutput, err error) {
+	var p pointer
+	if ms, ok := in.Message.(*messageState); ok {
+		p = ms.pointer()
+	} else {
+		p = in.Message.(*messageReflectWrapper).pointer()
+	}
+	b, err := mi.marshalAppendPointer(in.Buf, p, marshalOptions{
+		flags: in.Flags,
+	})
+	return piface.MarshalOutput{Buf: b}, err
+}
+
+func (mi *MessageInfo) marshalAppendPointer(b []byte, p pointer, opts marshalOptions) ([]byte, error) {
+	mi.init()
+	if p.IsNil() {
+		return b, nil
+	}
+	if flags.ProtoLegacy && mi.isMessageSet {
+		return marshalMessageSet(mi, b, p, opts)
+	}
+	var err error
+	// The old marshaler encodes extensions at beginning.
+	if mi.extensionOffset.IsValid() {
+		e := p.Apply(mi.extensionOffset).Extensions()
+		// TODO: Special handling for MessageSet?
+		b, err = mi.appendExtensions(b, e, opts)
+		if err != nil {
+			return b, err
+		}
+	}
+	for _, f := range mi.orderedCoderFields {
+		if f.funcs.marshal == nil {
+			continue
+		}
+		fptr := p.Apply(f.offset)
+		if f.isPointer && fptr.Elem().IsNil() {
+			continue
+		}
+		b, err = f.funcs.marshal(b, fptr, f, opts)
+		if err != nil {
+			return b, err
+		}
+	}
+	if mi.unknownOffset.IsValid() && !mi.isMessageSet {
+		u := *p.Apply(mi.unknownOffset).Bytes()
+		b = append(b, u...)
+	}
+	return b, nil
+}
+
+func (mi *MessageInfo) sizeExtensions(ext *map[int32]ExtensionField, opts marshalOptions) (n int) {
+	if ext == nil {
+		return 0
+	}
+	for _, x := range *ext {
+		xi := getExtensionFieldInfo(x.Type())
+		if xi.funcs.size == nil {
+			continue
+		}
+		n += xi.funcs.size(x.Value(), xi.tagsize, opts)
+	}
+	return n
+}
+
+func (mi *MessageInfo) appendExtensions(b []byte, ext *map[int32]ExtensionField, opts marshalOptions) ([]byte, error) {
+	if ext == nil {
+		return b, nil
+	}
+
+	switch len(*ext) {
+	case 0:
+		return b, nil
+	case 1:
+		// Fast-path for one extension: Don't bother sorting the keys.
+		var err error
+		for _, x := range *ext {
+			xi := getExtensionFieldInfo(x.Type())
+			b, err = xi.funcs.marshal(b, x.Value(), xi.wiretag, opts)
+		}
+		return b, err
+	default:
+		// Sort the keys to provide a deterministic encoding.
+		// Not sure this is required, but the old code does it.
+		keys := make([]int, 0, len(*ext))
+		for k := range *ext {
+			keys = append(keys, int(k))
+		}
+		sort.Ints(keys)
+		var err error
+		for _, k := range keys {
+			x := (*ext)[int32(k)]
+			xi := getExtensionFieldInfo(x.Type())
+			b, err = xi.funcs.marshal(b, x.Value(), xi.wiretag, opts)
+			if err != nil {
+				return b, err
+			}
+		}
+		return b, nil
+	}
+}
diff --git a/vendor/google.golang.org/protobuf/internal/impl/enum.go b/vendor/google.golang.org/protobuf/internal/impl/enum.go
new file mode 100644
index 0000000..8c1eab4
--- /dev/null
+++ b/vendor/google.golang.org/protobuf/internal/impl/enum.go
@@ -0,0 +1,21 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package impl
+
+import (
+	"reflect"
+
+	pref "google.golang.org/protobuf/reflect/protoreflect"
+)
+
+type EnumInfo struct {
+	GoReflectType reflect.Type // int32 kind
+	Desc          pref.EnumDescriptor
+}
+
+func (t *EnumInfo) New(n pref.EnumNumber) pref.Enum {
+	return reflect.ValueOf(n).Convert(t.GoReflectType).Interface().(pref.Enum)
+}
+func (t *EnumInfo) Descriptor() pref.EnumDescriptor { return t.Desc }
diff --git a/vendor/google.golang.org/protobuf/internal/impl/extension.go b/vendor/google.golang.org/protobuf/internal/impl/extension.go
new file mode 100644
index 0000000..e904fd9
--- /dev/null
+++ b/vendor/google.golang.org/protobuf/internal/impl/extension.go
@@ -0,0 +1,156 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package impl
+
+import (
+	"reflect"
+	"sync"
+	"sync/atomic"
+
+	pref "google.golang.org/protobuf/reflect/protoreflect"
+	piface "google.golang.org/protobuf/runtime/protoiface"
+)
+
+// ExtensionInfo implements ExtensionType.
+//
+// This type contains a number of exported fields for legacy compatibility.
+// The only non-deprecated use of this type is through the methods of the
+// ExtensionType interface.
+type ExtensionInfo struct {
+	// An ExtensionInfo may exist in several stages of initialization.
+	//
+	// extensionInfoUninitialized: Some or all of the legacy exported
+	// fields may be set, but none of the unexported fields have been
+	// initialized. This is the starting state for an ExtensionInfo
+	// in legacy generated code.
+	//
+	// extensionInfoDescInit: The desc field is set, but other unexported fields
+	// may not be initialized. Legacy exported fields may or may not be set.
+	// This is the starting state for an ExtensionInfo in newly generated code.
+	//
+	// extensionInfoFullInit: The ExtensionInfo is fully initialized.
+	// This state is only entered after lazy initialization is complete.
+	init uint32
+	mu   sync.Mutex
+
+	goType reflect.Type
+	desc   extensionTypeDescriptor
+	conv   Converter
+	info   *extensionFieldInfo // for fast-path method implementations
+
+	// ExtendedType is a typed nil-pointer to the parent message type that
+	// is being extended. It is possible for this to be unpopulated in v2
+	// since the message may no longer implement the MessageV1 interface.
+	//
+	// Deprecated: Use the ExtendedType method instead.
+	ExtendedType piface.MessageV1
+
+	// ExtensionType is the zero value of the extension type.
+	//
+	// For historical reasons, reflect.TypeOf(ExtensionType) and the
+	// type returned by InterfaceOf may not be identical.
+	//
+	// Deprecated: Use InterfaceOf(xt.Zero()) instead.
+	ExtensionType interface{}
+
+	// Field is the field number of the extension.
+	//
+	// Deprecated: Use the Descriptor().Number method instead.
+	Field int32
+
+	// Name is the fully qualified name of extension.
+	//
+	// Deprecated: Use the Descriptor().FullName method instead.
+	Name string
+
+	// Tag is the protobuf struct tag used in the v1 API.
+	//
+	// Deprecated: Do not use.
+	Tag string
+
+	// Filename is the proto filename in which the extension is defined.
+	//
+	// Deprecated: Use Descriptor().ParentFile().Path() instead.
+	Filename string
+}
+
+// Stages of initialization: See the ExtensionInfo.init field.
+const (
+	extensionInfoUninitialized = 0
+	extensionInfoDescInit      = 1
+	extensionInfoFullInit      = 2
+)
+
+func InitExtensionInfo(xi *ExtensionInfo, xd pref.ExtensionDescriptor, goType reflect.Type) {
+	xi.goType = goType
+	xi.desc = extensionTypeDescriptor{xd, xi}
+	xi.init = extensionInfoDescInit
+}
+
+func (xi *ExtensionInfo) New() pref.Value {
+	return xi.lazyInit().New()
+}
+func (xi *ExtensionInfo) Zero() pref.Value {
+	return xi.lazyInit().Zero()
+}
+func (xi *ExtensionInfo) ValueOf(v interface{}) pref.Value {
+	return xi.lazyInit().PBValueOf(reflect.ValueOf(v))
+}
+func (xi *ExtensionInfo) InterfaceOf(v pref.Value) interface{} {
+	return xi.lazyInit().GoValueOf(v).Interface()
+}
+func (xi *ExtensionInfo) IsValidValue(v pref.Value) bool {
+	return xi.lazyInit().IsValidPB(v)
+}
+func (xi *ExtensionInfo) IsValidInterface(v interface{}) bool {
+	return xi.lazyInit().IsValidGo(reflect.ValueOf(v))
+}
+func (xi *ExtensionInfo) TypeDescriptor() pref.ExtensionTypeDescriptor {
+	if atomic.LoadUint32(&xi.init) < extensionInfoDescInit {
+		xi.lazyInitSlow()
+	}
+	return &xi.desc
+}
+
+func (xi *ExtensionInfo) lazyInit() Converter {
+	if atomic.LoadUint32(&xi.init) < extensionInfoFullInit {
+		xi.lazyInitSlow()
+	}
+	return xi.conv
+}
+
+func (xi *ExtensionInfo) lazyInitSlow() {
+	xi.mu.Lock()
+	defer xi.mu.Unlock()
+
+	if xi.init == extensionInfoFullInit {
+		return
+	}
+	defer atomic.StoreUint32(&xi.init, extensionInfoFullInit)
+
+	if xi.desc.ExtensionDescriptor == nil {
+		xi.initFromLegacy()
+	}
+	if !xi.desc.ExtensionDescriptor.IsPlaceholder() {
+		if xi.ExtensionType == nil {
+			xi.initToLegacy()
+		}
+		xi.conv = NewConverter(xi.goType, xi.desc.ExtensionDescriptor)
+		xi.info = makeExtensionFieldInfo(xi.desc.ExtensionDescriptor)
+		xi.info.validation = newValidationInfo(xi.desc.ExtensionDescriptor, xi.goType)
+	}
+}
+
+type extensionTypeDescriptor struct {
+	pref.ExtensionDescriptor
+	xi *ExtensionInfo
+}
+
+func (xtd *extensionTypeDescriptor) Type() pref.ExtensionType {
+	return xtd.xi
+}
+func (xtd *extensionTypeDescriptor) Descriptor() pref.ExtensionDescriptor {
+	return xtd.ExtensionDescriptor
+}
diff --git a/vendor/google.golang.org/protobuf/internal/impl/legacy_enum.go b/vendor/google.golang.org/protobuf/internal/impl/legacy_enum.go
new file mode 100644
index 0000000..f7d7ffb
--- /dev/null
+++ b/vendor/google.golang.org/protobuf/internal/impl/legacy_enum.go
@@ -0,0 +1,219 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package impl
+
+import (
+	"fmt"
+	"reflect"
+	"strings"
+	"sync"
+
+	"google.golang.org/protobuf/internal/filedesc"
+	"google.golang.org/protobuf/internal/strs"
+	"google.golang.org/protobuf/reflect/protoreflect"
+	pref "google.golang.org/protobuf/reflect/protoreflect"
+)
+
+// legacyEnumName returns the name of enums used in legacy code.
+// It is neither the protobuf full name nor the qualified Go name,
+// but rather an odd hybrid of both.
+func legacyEnumName(ed pref.EnumDescriptor) string {
+	var protoPkg string
+	enumName := string(ed.FullName())
+	if fd := ed.ParentFile(); fd != nil {
+		protoPkg = string(fd.Package())
+		enumName = strings.TrimPrefix(enumName, protoPkg+".")
+	}
+	if protoPkg == "" {
+		return strs.GoCamelCase(enumName)
+	}
+	return protoPkg + "." + strs.GoCamelCase(enumName)
+}
+
+// legacyWrapEnum wraps v as a protoreflect.Enum,
+// where v must be a int32 kind and not implement the v2 API already.
+func legacyWrapEnum(v reflect.Value) pref.Enum {
+	et := legacyLoadEnumType(v.Type())
+	return et.New(pref.EnumNumber(v.Int()))
+}
+
+var legacyEnumTypeCache sync.Map // map[reflect.Type]protoreflect.EnumType
+
+// legacyLoadEnumType dynamically loads a protoreflect.EnumType for t,
+// where t must be an int32 kind and not implement the v2 API already.
+func legacyLoadEnumType(t reflect.Type) pref.EnumType {
+	// Fast-path: check if a EnumType is cached for this concrete type.
+	if et, ok := legacyEnumTypeCache.Load(t); ok {
+		return et.(pref.EnumType)
+	}
+
+	// Slow-path: derive enum descriptor and initialize EnumType.
+	var et pref.EnumType
+	ed := LegacyLoadEnumDesc(t)
+	et = &legacyEnumType{
+		desc:   ed,
+		goType: t,
+	}
+	if et, ok := legacyEnumTypeCache.LoadOrStore(t, et); ok {
+		return et.(pref.EnumType)
+	}
+	return et
+}
+
+type legacyEnumType struct {
+	desc   pref.EnumDescriptor
+	goType reflect.Type
+	m      sync.Map // map[protoreflect.EnumNumber]proto.Enum
+}
+
+func (t *legacyEnumType) New(n pref.EnumNumber) pref.Enum {
+	if e, ok := t.m.Load(n); ok {
+		return e.(pref.Enum)
+	}
+	e := &legacyEnumWrapper{num: n, pbTyp: t, goTyp: t.goType}
+	t.m.Store(n, e)
+	return e
+}
+func (t *legacyEnumType) Descriptor() pref.EnumDescriptor {
+	return t.desc
+}
+
+type legacyEnumWrapper struct {
+	num   pref.EnumNumber
+	pbTyp pref.EnumType
+	goTyp reflect.Type
+}
+
+func (e *legacyEnumWrapper) Descriptor() pref.EnumDescriptor {
+	return e.pbTyp.Descriptor()
+}
+func (e *legacyEnumWrapper) Type() pref.EnumType {
+	return e.pbTyp
+}
+func (e *legacyEnumWrapper) Number() pref.EnumNumber {
+	return e.num
+}
+func (e *legacyEnumWrapper) ProtoReflect() pref.Enum {
+	return e
+}
+func (e *legacyEnumWrapper) protoUnwrap() interface{} {
+	v := reflect.New(e.goTyp).Elem()
+	v.SetInt(int64(e.num))
+	return v.Interface()
+}
+
+var (
+	_ pref.Enum = (*legacyEnumWrapper)(nil)
+	_ unwrapper = (*legacyEnumWrapper)(nil)
+)
+
+var legacyEnumDescCache sync.Map // map[reflect.Type]protoreflect.EnumDescriptor
+
+// LegacyLoadEnumDesc returns an EnumDescriptor derived from the Go type,
+// which must be an int32 kind and not implement the v2 API already.
+//
+// This is exported for testing purposes.
+func LegacyLoadEnumDesc(t reflect.Type) pref.EnumDescriptor {
+	// Fast-path: check if an EnumDescriptor is cached for this concrete type.
+	if ed, ok := legacyEnumDescCache.Load(t); ok {
+		return ed.(pref.EnumDescriptor)
+	}
+
+	// Slow-path: initialize EnumDescriptor from the raw descriptor.
+	ev := reflect.Zero(t).Interface()
+	if _, ok := ev.(pref.Enum); ok {
+		panic(fmt.Sprintf("%v already implements proto.Enum", t))
+	}
+	edV1, ok := ev.(enumV1)
+	if !ok {
+		return aberrantLoadEnumDesc(t)
+	}
+	b, idxs := edV1.EnumDescriptor()
+
+	var ed pref.EnumDescriptor
+	if len(idxs) == 1 {
+		ed = legacyLoadFileDesc(b).Enums().Get(idxs[0])
+	} else {
+		md := legacyLoadFileDesc(b).Messages().Get(idxs[0])
+		for _, i := range idxs[1 : len(idxs)-1] {
+			md = md.Messages().Get(i)
+		}
+		ed = md.Enums().Get(idxs[len(idxs)-1])
+	}
+	if ed, ok := legacyEnumDescCache.LoadOrStore(t, ed); ok {
+		return ed.(protoreflect.EnumDescriptor)
+	}
+	return ed
+}
+
+var aberrantEnumDescCache sync.Map // map[reflect.Type]protoreflect.EnumDescriptor
+
+// aberrantLoadEnumDesc returns an EnumDescriptor derived from the Go type,
+// which must not implement protoreflect.Enum or enumV1.
+//
+// If the type does not implement enumV1, then there is no reliable
+// way to derive the original protobuf type information.
+// We are unable to use the global enum registry since it is
+// unfortunately keyed by the protobuf full name, which we also do not know.
+// Thus, this produces some bogus enum descriptor based on the Go type name.
+func aberrantLoadEnumDesc(t reflect.Type) pref.EnumDescriptor {
+	// Fast-path: check if an EnumDescriptor is cached for this concrete type.
+	if ed, ok := aberrantEnumDescCache.Load(t); ok {
+		return ed.(pref.EnumDescriptor)
+	}
+
+	// Slow-path: construct a bogus, but unique EnumDescriptor.
+	ed := &filedesc.Enum{L2: new(filedesc.EnumL2)}
+	ed.L0.FullName = AberrantDeriveFullName(t) // e.g., github_com.user.repo.MyEnum
+	ed.L0.ParentFile = filedesc.SurrogateProto3
+	ed.L2.Values.List = append(ed.L2.Values.List, filedesc.EnumValue{})
+
+	// TODO: Use the presence of a UnmarshalJSON method to determine proto2?
+
+	vd := &ed.L2.Values.List[0]
+	vd.L0.FullName = ed.L0.FullName + "_UNKNOWN" // e.g., github_com.user.repo.MyEnum_UNKNOWN
+	vd.L0.ParentFile = ed.L0.ParentFile
+	vd.L0.Parent = ed
+
+	// TODO: We could use the String method to obtain some enum value names by
+	// starting at 0 and print the enum until it produces invalid identifiers.
+	// An exhaustive query is clearly impractical, but can be best-effort.
+
+	if ed, ok := aberrantEnumDescCache.LoadOrStore(t, ed); ok {
+		return ed.(pref.EnumDescriptor)
+	}
+	return ed
+}
+
+// AberrantDeriveFullName derives a fully qualified protobuf name for the given Go type
+// The provided name is not guaranteed to be stable nor universally unique.
+// It should be sufficiently unique within a program.
+//
+// This is exported for testing purposes.
+func AberrantDeriveFullName(t reflect.Type) pref.FullName {
+	sanitize := func(r rune) rune {
+		switch {
+		case r == '/':
+			return '.'
+		case 'a' <= r && r <= 'z', 'A' <= r && r <= 'Z', '0' <= r && r <= '9':
+			return r
+		default:
+			return '_'
+		}
+	}
+	prefix := strings.Map(sanitize, t.PkgPath())
+	suffix := strings.Map(sanitize, t.Name())
+	if suffix == "" {
+		suffix = fmt.Sprintf("UnknownX%X", reflect.ValueOf(t).Pointer())
+	}
+
+	ss := append(strings.Split(prefix, "."), suffix)
+	for i, s := range ss {
+		if s == "" || ('0' <= s[0] && s[0] <= '9') {
+			ss[i] = "x" + s
+		}
+	}
+	return pref.FullName(strings.Join(ss, "."))
+}
diff --git a/vendor/google.golang.org/protobuf/internal/impl/legacy_export.go b/vendor/google.golang.org/protobuf/internal/impl/legacy_export.go
new file mode 100644
index 0000000..c3d741c
--- /dev/null
+++ b/vendor/google.golang.org/protobuf/internal/impl/legacy_export.go
@@ -0,0 +1,92 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package impl
+
+import (
+	"encoding/binary"
+	"encoding/json"
+	"hash/crc32"
+	"math"
+	"reflect"
+
+	"google.golang.org/protobuf/internal/errors"
+	pref "google.golang.org/protobuf/reflect/protoreflect"
+	piface "google.golang.org/protobuf/runtime/protoiface"
+)
+
+// These functions exist to support exported APIs in generated protobufs.
+// While these are deprecated, they cannot be removed for compatibility reasons.
+
+// LegacyEnumName returns the name of enums used in legacy code.
+func (Export) LegacyEnumName(ed pref.EnumDescriptor) string {
+	return legacyEnumName(ed)
+}
+
+// LegacyMessageTypeOf returns the protoreflect.MessageType for m,
+// with name used as the message name if necessary.
+func (Export) LegacyMessageTypeOf(m piface.MessageV1, name pref.FullName) pref.MessageType {
+	if mv := (Export{}).protoMessageV2Of(m); mv != nil {
+		return mv.ProtoReflect().Type()
+	}
+	return legacyLoadMessageInfo(reflect.TypeOf(m), name)
+}
+
+// UnmarshalJSONEnum unmarshals an enum from a JSON-encoded input.
+// The input can either be a string representing the enum value by name,
+// or a number representing the enum number itself.
+func (Export) UnmarshalJSONEnum(ed pref.EnumDescriptor, b []byte) (pref.EnumNumber, error) {
+	if b[0] == '"' {
+		var name pref.Name
+		if err := json.Unmarshal(b, &name); err != nil {
+			return 0, errors.New("invalid input for enum %v: %s", ed.FullName(), b)
+		}
+		ev := ed.Values().ByName(name)
+		if ev == nil {
+			return 0, errors.New("invalid value for enum %v: %s", ed.FullName(), name)
+		}
+		return ev.Number(), nil
+	} else {
+		var num pref.EnumNumber
+		if err := json.Unmarshal(b, &num); err != nil {
+			return 0, errors.New("invalid input for enum %v: %s", ed.FullName(), b)
+		}
+		return num, nil
+	}
+}
+
+// CompressGZIP compresses the input as a GZIP-encoded file.
+// The current implementation does no compression.
+func (Export) CompressGZIP(in []byte) (out []byte) {
+	// RFC 1952, section 2.3.1.
+	var gzipHeader = [10]byte{0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff}
+
+	// RFC 1951, section 3.2.4.
+	var blockHeader [5]byte
+	const maxBlockSize = math.MaxUint16
+	numBlocks := 1 + len(in)/maxBlockSize
+
+	// RFC 1952, section 2.3.1.
+	var gzipFooter [8]byte
+	binary.LittleEndian.PutUint32(gzipFooter[0:4], crc32.ChecksumIEEE(in))
+	binary.LittleEndian.PutUint32(gzipFooter[4:8], uint32(len(in)))
+
+	// Encode the input without compression using raw DEFLATE blocks.
+	out = make([]byte, 0, len(gzipHeader)+len(blockHeader)*numBlocks+len(in)+len(gzipFooter))
+	out = append(out, gzipHeader[:]...)
+	for blockHeader[0] == 0 {
+		blockSize := maxBlockSize
+		if blockSize > len(in) {
+			blockHeader[0] = 0x01 // final bit per RFC 1951, section 3.2.3.
+			blockSize = len(in)
+		}
+		binary.LittleEndian.PutUint16(blockHeader[1:3], uint16(blockSize)^0x0000)
+		binary.LittleEndian.PutUint16(blockHeader[3:5], uint16(blockSize)^0xffff)
+		out = append(out, blockHeader[:]...)
+		out = append(out, in[:blockSize]...)
+		in = in[blockSize:]
+	}
+	out = append(out, gzipFooter[:]...)
+	return out
+}
diff --git a/vendor/google.golang.org/protobuf/internal/impl/legacy_extension.go b/vendor/google.golang.org/protobuf/internal/impl/legacy_extension.go
new file mode 100644
index 0000000..61757ce
--- /dev/null
+++ b/vendor/google.golang.org/protobuf/internal/impl/legacy_extension.go
@@ -0,0 +1,175 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package impl
+
+import (
+	"reflect"
+
+	"google.golang.org/protobuf/internal/descopts"
+	"google.golang.org/protobuf/internal/encoding/messageset"
+	ptag "google.golang.org/protobuf/internal/encoding/tag"
+	"google.golang.org/protobuf/internal/filedesc"
+	"google.golang.org/protobuf/internal/pragma"
+	pref "google.golang.org/protobuf/reflect/protoreflect"
+	preg "google.golang.org/protobuf/reflect/protoregistry"
+	piface "google.golang.org/protobuf/runtime/protoiface"
+)
+
+func (xi *ExtensionInfo) initToLegacy() {
+	xd := xi.desc
+	var parent piface.MessageV1
+	messageName := xd.ContainingMessage().FullName()
+	if mt, _ := preg.GlobalTypes.FindMessageByName(messageName); mt != nil {
+		// Create a new parent message and unwrap it if possible.
+		mv := mt.New().Interface()
+		t := reflect.TypeOf(mv)
+		if mv, ok := mv.(unwrapper); ok {
+			t = reflect.TypeOf(mv.protoUnwrap())
+		}
+
+		// Check whether the message implements the legacy v1 Message interface.
+		mz := reflect.Zero(t).Interface()
+		if mz, ok := mz.(piface.MessageV1); ok {
+			parent = mz
+		}
+	}
+
+	// Determine the v1 extension type, which is unfortunately not the same as
+	// the v2 ExtensionType.GoType.
+	extType := xi.goType
+	switch extType.Kind() {
+	case reflect.Bool, reflect.Int32, reflect.Int64, reflect.Uint32, reflect.Uint64, reflect.Float32, reflect.Float64, reflect.String:
+		extType = reflect.PtrTo(extType) // T -> *T for singular scalar fields
+	}
+
+	// Reconstruct the legacy enum full name.
+	var enumName string
+	if xd.Kind() == pref.EnumKind {
+		enumName = legacyEnumName(xd.Enum())
+	}
+
+	// Derive the proto file that the extension was declared within.
+	var filename string
+	if fd := xd.ParentFile(); fd != nil {
+		filename = fd.Path()
+	}
+
+	// For MessageSet extensions, the name used is the parent message.
+	name := xd.FullName()
+	if messageset.IsMessageSetExtension(xd) {
+		name = name.Parent()
+	}
+
+	xi.ExtendedType = parent
+	xi.ExtensionType = reflect.Zero(extType).Interface()
+	xi.Field = int32(xd.Number())
+	xi.Name = string(name)
+	xi.Tag = ptag.Marshal(xd, enumName)
+	xi.Filename = filename
+}
+
+// initFromLegacy initializes an ExtensionInfo from
+// the contents of the deprecated exported fields of the type.
+func (xi *ExtensionInfo) initFromLegacy() {
+	// The v1 API returns "type incomplete" descriptors where only the
+	// field number is specified. In such a case, use a placeholder.
+	if xi.ExtendedType == nil || xi.ExtensionType == nil {
+		xd := placeholderExtension{
+			name:   pref.FullName(xi.Name),
+			number: pref.FieldNumber(xi.Field),
+		}
+		xi.desc = extensionTypeDescriptor{xd, xi}
+		return
+	}
+
+	// Resolve enum or message dependencies.
+	var ed pref.EnumDescriptor
+	var md pref.MessageDescriptor
+	t := reflect.TypeOf(xi.ExtensionType)
+	isOptional := t.Kind() == reflect.Ptr && t.Elem().Kind() != reflect.Struct
+	isRepeated := t.Kind() == reflect.Slice && t.Elem().Kind() != reflect.Uint8
+	if isOptional || isRepeated {
+		t = t.Elem()
+	}
+	switch v := reflect.Zero(t).Interface().(type) {
+	case pref.Enum:
+		ed = v.Descriptor()
+	case enumV1:
+		ed = LegacyLoadEnumDesc(t)
+	case pref.ProtoMessage:
+		md = v.ProtoReflect().Descriptor()
+	case messageV1:
+		md = LegacyLoadMessageDesc(t)
+	}
+
+	// Derive basic field information from the struct tag.
+	var evs pref.EnumValueDescriptors
+	if ed != nil {
+		evs = ed.Values()
+	}
+	fd := ptag.Unmarshal(xi.Tag, t, evs).(*filedesc.Field)
+
+	// Construct a v2 ExtensionType.
+	xd := &filedesc.Extension{L2: new(filedesc.ExtensionL2)}
+	xd.L0.ParentFile = filedesc.SurrogateProto2
+	xd.L0.FullName = pref.FullName(xi.Name)
+	xd.L1.Number = pref.FieldNumber(xi.Field)
+	xd.L1.Cardinality = fd.L1.Cardinality
+	xd.L1.Kind = fd.L1.Kind
+	xd.L2.IsPacked = fd.L1.IsPacked
+	xd.L2.Default = fd.L1.Default
+	xd.L1.Extendee = Export{}.MessageDescriptorOf(xi.ExtendedType)
+	xd.L2.Enum = ed
+	xd.L2.Message = md
+
+	// Derive real extension field name for MessageSets.
+	if messageset.IsMessageSet(xd.L1.Extendee) && md.FullName() == xd.L0.FullName {
+		xd.L0.FullName = xd.L0.FullName.Append(messageset.ExtensionName)
+	}
+
+	tt := reflect.TypeOf(xi.ExtensionType)
+	if isOptional {
+		tt = tt.Elem()
+	}
+	xi.goType = tt
+	xi.desc = extensionTypeDescriptor{xd, xi}
+}
+
+type placeholderExtension struct {
+	name   pref.FullName
+	number pref.FieldNumber
+}
+
+func (x placeholderExtension) ParentFile() pref.FileDescriptor            { return nil }
+func (x placeholderExtension) Parent() pref.Descriptor                    { return nil }
+func (x placeholderExtension) Index() int                                 { return 0 }
+func (x placeholderExtension) Syntax() pref.Syntax                        { return 0 }
+func (x placeholderExtension) Name() pref.Name                            { return x.name.Name() }
+func (x placeholderExtension) FullName() pref.FullName                    { return x.name }
+func (x placeholderExtension) IsPlaceholder() bool                        { return true }
+func (x placeholderExtension) Options() pref.ProtoMessage                 { return descopts.Field }
+func (x placeholderExtension) Number() pref.FieldNumber                   { return x.number }
+func (x placeholderExtension) Cardinality() pref.Cardinality              { return 0 }
+func (x placeholderExtension) Kind() pref.Kind                            { return 0 }
+func (x placeholderExtension) HasJSONName() bool                          { return false }
+func (x placeholderExtension) JSONName() string                           { return "" }
+func (x placeholderExtension) HasPresence() bool                          { return false }
+func (x placeholderExtension) HasOptionalKeyword() bool                   { return false }
+func (x placeholderExtension) IsExtension() bool                          { return true }
+func (x placeholderExtension) IsWeak() bool                               { return false }
+func (x placeholderExtension) IsPacked() bool                             { return false }
+func (x placeholderExtension) IsList() bool                               { return false }
+func (x placeholderExtension) IsMap() bool                                { return false }
+func (x placeholderExtension) MapKey() pref.FieldDescriptor               { return nil }
+func (x placeholderExtension) MapValue() pref.FieldDescriptor             { return nil }
+func (x placeholderExtension) HasDefault() bool                           { return false }
+func (x placeholderExtension) Default() pref.Value                        { return pref.Value{} }
+func (x placeholderExtension) DefaultEnumValue() pref.EnumValueDescriptor { return nil }
+func (x placeholderExtension) ContainingOneof() pref.OneofDescriptor      { return nil }
+func (x placeholderExtension) ContainingMessage() pref.MessageDescriptor  { return nil }
+func (x placeholderExtension) Enum() pref.EnumDescriptor                  { return nil }
+func (x placeholderExtension) Message() pref.MessageDescriptor            { return nil }
+func (x placeholderExtension) ProtoType(pref.FieldDescriptor)             { return }
+func (x placeholderExtension) ProtoInternal(pragma.DoNotImplement)        { return }
diff --git a/vendor/google.golang.org/protobuf/internal/impl/legacy_file.go b/vendor/google.golang.org/protobuf/internal/impl/legacy_file.go
new file mode 100644
index 0000000..9ab0910
--- /dev/null
+++ b/vendor/google.golang.org/protobuf/internal/impl/legacy_file.go
@@ -0,0 +1,81 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package impl
+
+import (
+	"bytes"
+	"compress/gzip"
+	"io/ioutil"
+	"sync"
+
+	"google.golang.org/protobuf/internal/filedesc"
+	"google.golang.org/protobuf/reflect/protoreflect"
+	"google.golang.org/protobuf/reflect/protoregistry"
+)
+
+// Every enum and message type generated by protoc-gen-go since commit 2fc053c5
+// on February 25th, 2016 has had a method to get the raw descriptor.
+// Types that were not generated by protoc-gen-go or were generated prior
+// to that version are not supported.
+//
+// The []byte returned is the encoded form of a FileDescriptorProto message
+// compressed using GZIP. The []int is the path from the top-level file
+// to the specific message or enum declaration.
+type (
+	enumV1 interface {
+		EnumDescriptor() ([]byte, []int)
+	}
+	messageV1 interface {
+		Descriptor() ([]byte, []int)
+	}
+)
+
+var legacyFileDescCache sync.Map // map[*byte]protoreflect.FileDescriptor
+
+// legacyLoadFileDesc unmarshals b as a compressed FileDescriptorProto message.
+//
+// This assumes that b is immutable and that b does not refer to part of a
+// concatenated series of GZIP files (which would require shenanigans that
+// rely on the concatenation properties of both protobufs and GZIP).
+// File descriptors generated by protoc-gen-go do not rely on that property.
+func legacyLoadFileDesc(b []byte) protoreflect.FileDescriptor {
+	// Fast-path: check whether we already have a cached file descriptor.
+	if fd, ok := legacyFileDescCache.Load(&b[0]); ok {
+		return fd.(protoreflect.FileDescriptor)
+	}
+
+	// Slow-path: decompress and unmarshal the file descriptor proto.
+	zr, err := gzip.NewReader(bytes.NewReader(b))
+	if err != nil {
+		panic(err)
+	}
+	b2, err := ioutil.ReadAll(zr)
+	if err != nil {
+		panic(err)
+	}
+
+	fd := filedesc.Builder{
+		RawDescriptor: b2,
+		FileRegistry:  resolverOnly{protoregistry.GlobalFiles}, // do not register back to global registry
+	}.Build().File
+	if fd, ok := legacyFileDescCache.LoadOrStore(&b[0], fd); ok {
+		return fd.(protoreflect.FileDescriptor)
+	}
+	return fd
+}
+
+type resolverOnly struct {
+	reg *protoregistry.Files
+}
+
+func (r resolverOnly) FindFileByPath(path string) (protoreflect.FileDescriptor, error) {
+	return r.reg.FindFileByPath(path)
+}
+func (r resolverOnly) FindDescriptorByName(name protoreflect.FullName) (protoreflect.Descriptor, error) {
+	return r.reg.FindDescriptorByName(name)
+}
+func (resolverOnly) RegisterFile(protoreflect.FileDescriptor) error {
+	return nil
+}
diff --git a/vendor/google.golang.org/protobuf/internal/impl/legacy_message.go b/vendor/google.golang.org/protobuf/internal/impl/legacy_message.go
new file mode 100644
index 0000000..06c68e1
--- /dev/null
+++ b/vendor/google.golang.org/protobuf/internal/impl/legacy_message.go
@@ -0,0 +1,502 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package impl
+
+import (
+	"fmt"
+	"reflect"
+	"strings"
+	"sync"
+
+	"google.golang.org/protobuf/internal/descopts"
+	ptag "google.golang.org/protobuf/internal/encoding/tag"
+	"google.golang.org/protobuf/internal/errors"
+	"google.golang.org/protobuf/internal/filedesc"
+	"google.golang.org/protobuf/internal/strs"
+	"google.golang.org/protobuf/reflect/protoreflect"
+	pref "google.golang.org/protobuf/reflect/protoreflect"
+	"google.golang.org/protobuf/runtime/protoiface"
+	piface "google.golang.org/protobuf/runtime/protoiface"
+)
+
+// legacyWrapMessage wraps v as a protoreflect.Message,
+// where v must be a *struct kind and not implement the v2 API already.
+func legacyWrapMessage(v reflect.Value) pref.Message {
+	typ := v.Type()
+	if typ.Kind() != reflect.Ptr || typ.Elem().Kind() != reflect.Struct {
+		return aberrantMessage{v: v}
+	}
+	mt := legacyLoadMessageInfo(typ, "")
+	return mt.MessageOf(v.Interface())
+}
+
+var legacyMessageTypeCache sync.Map // map[reflect.Type]*MessageInfo
+
+// legacyLoadMessageInfo dynamically loads a *MessageInfo for t,
+// where t must be a *struct kind and not implement the v2 API already.
+// The provided name is used if it cannot be determined from the message.
+func legacyLoadMessageInfo(t reflect.Type, name pref.FullName) *MessageInfo {
+	// Fast-path: check if a MessageInfo is cached for this concrete type.
+	if mt, ok := legacyMessageTypeCache.Load(t); ok {
+		return mt.(*MessageInfo)
+	}
+
+	// Slow-path: derive message descriptor and initialize MessageInfo.
+	mi := &MessageInfo{
+		Desc:          legacyLoadMessageDesc(t, name),
+		GoReflectType: t,
+	}
+
+	v := reflect.Zero(t).Interface()
+	if _, ok := v.(legacyMarshaler); ok {
+		mi.methods.Marshal = legacyMarshal
+
+		// We have no way to tell whether the type's Marshal method
+		// supports deterministic serialization or not, but this
+		// preserves the v1 implementation's behavior of always
+		// calling Marshal methods when present.
+		mi.methods.Flags |= piface.SupportMarshalDeterministic
+	}
+	if _, ok := v.(legacyUnmarshaler); ok {
+		mi.methods.Unmarshal = legacyUnmarshal
+	}
+	if _, ok := v.(legacyMerger); ok {
+		mi.methods.Merge = legacyMerge
+	}
+
+	if mi, ok := legacyMessageTypeCache.LoadOrStore(t, mi); ok {
+		return mi.(*MessageInfo)
+	}
+	return mi
+}
+
+var legacyMessageDescCache sync.Map // map[reflect.Type]protoreflect.MessageDescriptor
+
+// LegacyLoadMessageDesc returns an MessageDescriptor derived from the Go type,
+// which must be a *struct kind and not implement the v2 API already.
+//
+// This is exported for testing purposes.
+func LegacyLoadMessageDesc(t reflect.Type) pref.MessageDescriptor {
+	return legacyLoadMessageDesc(t, "")
+}
+func legacyLoadMessageDesc(t reflect.Type, name pref.FullName) pref.MessageDescriptor {
+	// Fast-path: check if a MessageDescriptor is cached for this concrete type.
+	if mi, ok := legacyMessageDescCache.Load(t); ok {
+		return mi.(pref.MessageDescriptor)
+	}
+
+	// Slow-path: initialize MessageDescriptor from the raw descriptor.
+	mv := reflect.Zero(t).Interface()
+	if _, ok := mv.(pref.ProtoMessage); ok {
+		panic(fmt.Sprintf("%v already implements proto.Message", t))
+	}
+	mdV1, ok := mv.(messageV1)
+	if !ok {
+		return aberrantLoadMessageDesc(t, name)
+	}
+
+	// If this is a dynamic message type where there isn't a 1-1 mapping between
+	// Go and protobuf types, calling the Descriptor method on the zero value of
+	// the message type isn't likely to work. If it panics, swallow the panic and
+	// continue as if the Descriptor method wasn't present.
+	b, idxs := func() ([]byte, []int) {
+		defer func() {
+			recover()
+		}()
+		return mdV1.Descriptor()
+	}()
+	if b == nil {
+		return aberrantLoadMessageDesc(t, name)
+	}
+
+	// If the Go type has no fields, then this might be a proto3 empty message
+	// from before the size cache was added. If there are any fields, check to
+	// see that at least one of them looks like something we generated.
+	if nfield := t.Elem().NumField(); nfield > 0 {
+		hasProtoField := false
+		for i := 0; i < nfield; i++ {
+			f := t.Elem().Field(i)
+			if f.Tag.Get("protobuf") != "" || f.Tag.Get("protobuf_oneof") != "" || strings.HasPrefix(f.Name, "XXX_") {
+				hasProtoField = true
+				break
+			}
+		}
+		if !hasProtoField {
+			return aberrantLoadMessageDesc(t, name)
+		}
+	}
+
+	md := legacyLoadFileDesc(b).Messages().Get(idxs[0])
+	for _, i := range idxs[1:] {
+		md = md.Messages().Get(i)
+	}
+	if name != "" && md.FullName() != name {
+		panic(fmt.Sprintf("mismatching message name: got %v, want %v", md.FullName(), name))
+	}
+	if md, ok := legacyMessageDescCache.LoadOrStore(t, md); ok {
+		return md.(protoreflect.MessageDescriptor)
+	}
+	return md
+}
+
+var (
+	aberrantMessageDescLock  sync.Mutex
+	aberrantMessageDescCache map[reflect.Type]protoreflect.MessageDescriptor
+)
+
+// aberrantLoadMessageDesc returns an MessageDescriptor derived from the Go type,
+// which must not implement protoreflect.ProtoMessage or messageV1.
+//
+// This is a best-effort derivation of the message descriptor using the protobuf
+// tags on the struct fields.
+func aberrantLoadMessageDesc(t reflect.Type, name pref.FullName) pref.MessageDescriptor {
+	aberrantMessageDescLock.Lock()
+	defer aberrantMessageDescLock.Unlock()
+	if aberrantMessageDescCache == nil {
+		aberrantMessageDescCache = make(map[reflect.Type]protoreflect.MessageDescriptor)
+	}
+	return aberrantLoadMessageDescReentrant(t, name)
+}
+func aberrantLoadMessageDescReentrant(t reflect.Type, name pref.FullName) pref.MessageDescriptor {
+	// Fast-path: check if an MessageDescriptor is cached for this concrete type.
+	if md, ok := aberrantMessageDescCache[t]; ok {
+		return md
+	}
+
+	// Slow-path: construct a descriptor from the Go struct type (best-effort).
+	// Cache the MessageDescriptor early on so that we can resolve internal
+	// cyclic references.
+	md := &filedesc.Message{L2: new(filedesc.MessageL2)}
+	md.L0.FullName = aberrantDeriveMessageName(t, name)
+	md.L0.ParentFile = filedesc.SurrogateProto2
+	aberrantMessageDescCache[t] = md
+
+	if t.Kind() != reflect.Ptr || t.Elem().Kind() != reflect.Struct {
+		return md
+	}
+
+	// Try to determine if the message is using proto3 by checking scalars.
+	for i := 0; i < t.Elem().NumField(); i++ {
+		f := t.Elem().Field(i)
+		if tag := f.Tag.Get("protobuf"); tag != "" {
+			switch f.Type.Kind() {
+			case reflect.Bool, reflect.Int32, reflect.Int64, reflect.Uint32, reflect.Uint64, reflect.Float32, reflect.Float64, reflect.String:
+				md.L0.ParentFile = filedesc.SurrogateProto3
+			}
+			for _, s := range strings.Split(tag, ",") {
+				if s == "proto3" {
+					md.L0.ParentFile = filedesc.SurrogateProto3
+				}
+			}
+		}
+	}
+
+	// Obtain a list of oneof wrapper types.
+	var oneofWrappers []reflect.Type
+	for _, method := range []string{"XXX_OneofFuncs", "XXX_OneofWrappers"} {
+		if fn, ok := t.MethodByName(method); ok {
+			for _, v := range fn.Func.Call([]reflect.Value{reflect.Zero(fn.Type.In(0))}) {
+				if vs, ok := v.Interface().([]interface{}); ok {
+					for _, v := range vs {
+						oneofWrappers = append(oneofWrappers, reflect.TypeOf(v))
+					}
+				}
+			}
+		}
+	}
+
+	// Obtain a list of the extension ranges.
+	if fn, ok := t.MethodByName("ExtensionRangeArray"); ok {
+		vs := fn.Func.Call([]reflect.Value{reflect.Zero(fn.Type.In(0))})[0]
+		for i := 0; i < vs.Len(); i++ {
+			v := vs.Index(i)
+			md.L2.ExtensionRanges.List = append(md.L2.ExtensionRanges.List, [2]pref.FieldNumber{
+				pref.FieldNumber(v.FieldByName("Start").Int()),
+				pref.FieldNumber(v.FieldByName("End").Int() + 1),
+			})
+			md.L2.ExtensionRangeOptions = append(md.L2.ExtensionRangeOptions, nil)
+		}
+	}
+
+	// Derive the message fields by inspecting the struct fields.
+	for i := 0; i < t.Elem().NumField(); i++ {
+		f := t.Elem().Field(i)
+		if tag := f.Tag.Get("protobuf"); tag != "" {
+			tagKey := f.Tag.Get("protobuf_key")
+			tagVal := f.Tag.Get("protobuf_val")
+			aberrantAppendField(md, f.Type, tag, tagKey, tagVal)
+		}
+		if tag := f.Tag.Get("protobuf_oneof"); tag != "" {
+			n := len(md.L2.Oneofs.List)
+			md.L2.Oneofs.List = append(md.L2.Oneofs.List, filedesc.Oneof{})
+			od := &md.L2.Oneofs.List[n]
+			od.L0.FullName = md.FullName().Append(pref.Name(tag))
+			od.L0.ParentFile = md.L0.ParentFile
+			od.L0.Parent = md
+			od.L0.Index = n
+
+			for _, t := range oneofWrappers {
+				if t.Implements(f.Type) {
+					f := t.Elem().Field(0)
+					if tag := f.Tag.Get("protobuf"); tag != "" {
+						aberrantAppendField(md, f.Type, tag, "", "")
+						fd := &md.L2.Fields.List[len(md.L2.Fields.List)-1]
+						fd.L1.ContainingOneof = od
+						od.L1.Fields.List = append(od.L1.Fields.List, fd)
+					}
+				}
+			}
+		}
+	}
+
+	return md
+}
+
+func aberrantDeriveMessageName(t reflect.Type, name pref.FullName) pref.FullName {
+	if name.IsValid() {
+		return name
+	}
+	func() {
+		defer func() { recover() }() // swallow possible nil panics
+		if m, ok := reflect.Zero(t).Interface().(interface{ XXX_MessageName() string }); ok {
+			name = pref.FullName(m.XXX_MessageName())
+		}
+	}()
+	if name.IsValid() {
+		return name
+	}
+	if t.Kind() == reflect.Ptr {
+		t = t.Elem()
+	}
+	return AberrantDeriveFullName(t)
+}
+
+func aberrantAppendField(md *filedesc.Message, goType reflect.Type, tag, tagKey, tagVal string) {
+	t := goType
+	isOptional := t.Kind() == reflect.Ptr && t.Elem().Kind() != reflect.Struct
+	isRepeated := t.Kind() == reflect.Slice && t.Elem().Kind() != reflect.Uint8
+	if isOptional || isRepeated {
+		t = t.Elem()
+	}
+	fd := ptag.Unmarshal(tag, t, placeholderEnumValues{}).(*filedesc.Field)
+
+	// Append field descriptor to the message.
+	n := len(md.L2.Fields.List)
+	md.L2.Fields.List = append(md.L2.Fields.List, *fd)
+	fd = &md.L2.Fields.List[n]
+	fd.L0.FullName = md.FullName().Append(fd.Name())
+	fd.L0.ParentFile = md.L0.ParentFile
+	fd.L0.Parent = md
+	fd.L0.Index = n
+
+	if fd.L1.IsWeak || fd.L1.HasPacked {
+		fd.L1.Options = func() pref.ProtoMessage {
+			opts := descopts.Field.ProtoReflect().New()
+			if fd.L1.IsWeak {
+				opts.Set(opts.Descriptor().Fields().ByName("weak"), protoreflect.ValueOfBool(true))
+			}
+			if fd.L1.HasPacked {
+				opts.Set(opts.Descriptor().Fields().ByName("packed"), protoreflect.ValueOfBool(fd.L1.IsPacked))
+			}
+			return opts.Interface()
+		}
+	}
+
+	// Populate Enum and Message.
+	if fd.Enum() == nil && fd.Kind() == pref.EnumKind {
+		switch v := reflect.Zero(t).Interface().(type) {
+		case pref.Enum:
+			fd.L1.Enum = v.Descriptor()
+		default:
+			fd.L1.Enum = LegacyLoadEnumDesc(t)
+		}
+	}
+	if fd.Message() == nil && (fd.Kind() == pref.MessageKind || fd.Kind() == pref.GroupKind) {
+		switch v := reflect.Zero(t).Interface().(type) {
+		case pref.ProtoMessage:
+			fd.L1.Message = v.ProtoReflect().Descriptor()
+		case messageV1:
+			fd.L1.Message = LegacyLoadMessageDesc(t)
+		default:
+			if t.Kind() == reflect.Map {
+				n := len(md.L1.Messages.List)
+				md.L1.Messages.List = append(md.L1.Messages.List, filedesc.Message{L2: new(filedesc.MessageL2)})
+				md2 := &md.L1.Messages.List[n]
+				md2.L0.FullName = md.FullName().Append(pref.Name(strs.MapEntryName(string(fd.Name()))))
+				md2.L0.ParentFile = md.L0.ParentFile
+				md2.L0.Parent = md
+				md2.L0.Index = n
+
+				md2.L1.IsMapEntry = true
+				md2.L2.Options = func() pref.ProtoMessage {
+					opts := descopts.Message.ProtoReflect().New()
+					opts.Set(opts.Descriptor().Fields().ByName("map_entry"), protoreflect.ValueOfBool(true))
+					return opts.Interface()
+				}
+
+				aberrantAppendField(md2, t.Key(), tagKey, "", "")
+				aberrantAppendField(md2, t.Elem(), tagVal, "", "")
+
+				fd.L1.Message = md2
+				break
+			}
+			fd.L1.Message = aberrantLoadMessageDescReentrant(t, "")
+		}
+	}
+}
+
+type placeholderEnumValues struct {
+	protoreflect.EnumValueDescriptors
+}
+
+func (placeholderEnumValues) ByNumber(n pref.EnumNumber) pref.EnumValueDescriptor {
+	return filedesc.PlaceholderEnumValue(pref.FullName(fmt.Sprintf("UNKNOWN_%d", n)))
+}
+
+// legacyMarshaler is the proto.Marshaler interface superseded by protoiface.Methoder.
+type legacyMarshaler interface {
+	Marshal() ([]byte, error)
+}
+
+// legacyUnmarshaler is the proto.Unmarshaler interface superseded by protoiface.Methoder.
+type legacyUnmarshaler interface {
+	Unmarshal([]byte) error
+}
+
+// legacyMerger is the proto.Merger interface superseded by protoiface.Methoder.
+type legacyMerger interface {
+	Merge(protoiface.MessageV1)
+}
+
+var legacyProtoMethods = &piface.Methods{
+	Marshal:   legacyMarshal,
+	Unmarshal: legacyUnmarshal,
+	Merge:     legacyMerge,
+
+	// We have no way to tell whether the type's Marshal method
+	// supports deterministic serialization or not, but this
+	// preserves the v1 implementation's behavior of always
+	// calling Marshal methods when present.
+	Flags: piface.SupportMarshalDeterministic,
+}
+
+func legacyMarshal(in piface.MarshalInput) (piface.MarshalOutput, error) {
+	v := in.Message.(unwrapper).protoUnwrap()
+	marshaler, ok := v.(legacyMarshaler)
+	if !ok {
+		return piface.MarshalOutput{}, errors.New("%T does not implement Marshal", v)
+	}
+	out, err := marshaler.Marshal()
+	if in.Buf != nil {
+		out = append(in.Buf, out...)
+	}
+	return piface.MarshalOutput{
+		Buf: out,
+	}, err
+}
+
+func legacyUnmarshal(in piface.UnmarshalInput) (piface.UnmarshalOutput, error) {
+	v := in.Message.(unwrapper).protoUnwrap()
+	unmarshaler, ok := v.(legacyUnmarshaler)
+	if !ok {
+		return piface.UnmarshalOutput{}, errors.New("%T does not implement Marshal", v)
+	}
+	return piface.UnmarshalOutput{}, unmarshaler.Unmarshal(in.Buf)
+}
+
+func legacyMerge(in piface.MergeInput) piface.MergeOutput {
+	dstv := in.Destination.(unwrapper).protoUnwrap()
+	merger, ok := dstv.(legacyMerger)
+	if !ok {
+		return piface.MergeOutput{}
+	}
+	merger.Merge(Export{}.ProtoMessageV1Of(in.Source))
+	return piface.MergeOutput{Flags: piface.MergeComplete}
+}
+
+// aberrantMessageType implements MessageType for all types other than pointer-to-struct.
+type aberrantMessageType struct {
+	t reflect.Type
+}
+
+func (mt aberrantMessageType) New() pref.Message {
+	return aberrantMessage{reflect.Zero(mt.t)}
+}
+func (mt aberrantMessageType) Zero() pref.Message {
+	return aberrantMessage{reflect.Zero(mt.t)}
+}
+func (mt aberrantMessageType) GoType() reflect.Type {
+	return mt.t
+}
+func (mt aberrantMessageType) Descriptor() pref.MessageDescriptor {
+	return LegacyLoadMessageDesc(mt.t)
+}
+
+// aberrantMessage implements Message for all types other than pointer-to-struct.
+//
+// When the underlying type implements legacyMarshaler or legacyUnmarshaler,
+// the aberrant Message can be marshaled or unmarshaled. Otherwise, there is
+// not much that can be done with values of this type.
+type aberrantMessage struct {
+	v reflect.Value
+}
+
+func (m aberrantMessage) ProtoReflect() pref.Message {
+	return m
+}
+
+func (m aberrantMessage) Descriptor() pref.MessageDescriptor {
+	return LegacyLoadMessageDesc(m.v.Type())
+}
+func (m aberrantMessage) Type() pref.MessageType {
+	return aberrantMessageType{m.v.Type()}
+}
+func (m aberrantMessage) New() pref.Message {
+	return aberrantMessage{reflect.Zero(m.v.Type())}
+}
+func (m aberrantMessage) Interface() pref.ProtoMessage {
+	return m
+}
+func (m aberrantMessage) Range(f func(pref.FieldDescriptor, pref.Value) bool) {
+}
+func (m aberrantMessage) Has(pref.FieldDescriptor) bool {
+	panic("invalid field descriptor")
+}
+func (m aberrantMessage) Clear(pref.FieldDescriptor) {
+	panic("invalid field descriptor")
+}
+func (m aberrantMessage) Get(pref.FieldDescriptor) pref.Value {
+	panic("invalid field descriptor")
+}
+func (m aberrantMessage) Set(pref.FieldDescriptor, pref.Value) {
+	panic("invalid field descriptor")
+}
+func (m aberrantMessage) Mutable(pref.FieldDescriptor) pref.Value {
+	panic("invalid field descriptor")
+}
+func (m aberrantMessage) NewField(pref.FieldDescriptor) pref.Value {
+	panic("invalid field descriptor")
+}
+func (m aberrantMessage) WhichOneof(pref.OneofDescriptor) pref.FieldDescriptor {
+	panic("invalid oneof descriptor")
+}
+func (m aberrantMessage) GetUnknown() pref.RawFields {
+	return nil
+}
+func (m aberrantMessage) SetUnknown(pref.RawFields) {
+	// SetUnknown discards its input on messages which don't support unknown field storage.
+}
+func (m aberrantMessage) IsValid() bool {
+	// An invalid message is a read-only, empty message. Since we don't know anything
+	// about the alleged contents of this message, we can't say with confidence that
+	// it is invalid in this sense. Therefore, report it as valid.
+	return true
+}
+func (m aberrantMessage) ProtoMethods() *piface.Methods {
+	return legacyProtoMethods
+}
+func (m aberrantMessage) protoUnwrap() interface{} {
+	return m.v.Interface()
+}
diff --git a/vendor/google.golang.org/protobuf/internal/impl/merge.go b/vendor/google.golang.org/protobuf/internal/impl/merge.go
new file mode 100644
index 0000000..cdc4267
--- /dev/null
+++ b/vendor/google.golang.org/protobuf/internal/impl/merge.go
@@ -0,0 +1,176 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package impl
+
+import (
+	"fmt"
+	"reflect"
+
+	"google.golang.org/protobuf/proto"
+	pref "google.golang.org/protobuf/reflect/protoreflect"
+	piface "google.golang.org/protobuf/runtime/protoiface"
+)
+
+type mergeOptions struct{}
+
+func (o mergeOptions) Merge(dst, src proto.Message) {
+	proto.Merge(dst, src)
+}
+
+// merge is protoreflect.Methods.Merge.
+func (mi *MessageInfo) merge(in piface.MergeInput) piface.MergeOutput {
+	dp, ok := mi.getPointer(in.Destination)
+	if !ok {
+		return piface.MergeOutput{}
+	}
+	sp, ok := mi.getPointer(in.Source)
+	if !ok {
+		return piface.MergeOutput{}
+	}
+	mi.mergePointer(dp, sp, mergeOptions{})
+	return piface.MergeOutput{Flags: piface.MergeComplete}
+}
+
+func (mi *MessageInfo) mergePointer(dst, src pointer, opts mergeOptions) {
+	mi.init()
+	if dst.IsNil() {
+		panic(fmt.Sprintf("invalid value: merging into nil message"))
+	}
+	if src.IsNil() {
+		return
+	}
+	for _, f := range mi.orderedCoderFields {
+		if f.funcs.merge == nil {
+			continue
+		}
+		sfptr := src.Apply(f.offset)
+		if f.isPointer && sfptr.Elem().IsNil() {
+			continue
+		}
+		f.funcs.merge(dst.Apply(f.offset), sfptr, f, opts)
+	}
+	if mi.extensionOffset.IsValid() {
+		sext := src.Apply(mi.extensionOffset).Extensions()
+		dext := dst.Apply(mi.extensionOffset).Extensions()
+		if *dext == nil {
+			*dext = make(map[int32]ExtensionField)
+		}
+		for num, sx := range *sext {
+			xt := sx.Type()
+			xi := getExtensionFieldInfo(xt)
+			if xi.funcs.merge == nil {
+				continue
+			}
+			dx := (*dext)[num]
+			var dv pref.Value
+			if dx.Type() == sx.Type() {
+				dv = dx.Value()
+			}
+			if !dv.IsValid() && xi.unmarshalNeedsValue {
+				dv = xt.New()
+			}
+			dv = xi.funcs.merge(dv, sx.Value(), opts)
+			dx.Set(sx.Type(), dv)
+			(*dext)[num] = dx
+		}
+	}
+	if mi.unknownOffset.IsValid() {
+		du := dst.Apply(mi.unknownOffset).Bytes()
+		su := src.Apply(mi.unknownOffset).Bytes()
+		if len(*su) > 0 {
+			*du = append(*du, *su...)
+		}
+	}
+}
+
+func mergeScalarValue(dst, src pref.Value, opts mergeOptions) pref.Value {
+	return src
+}
+
+func mergeBytesValue(dst, src pref.Value, opts mergeOptions) pref.Value {
+	return pref.ValueOfBytes(append(emptyBuf[:], src.Bytes()...))
+}
+
+func mergeListValue(dst, src pref.Value, opts mergeOptions) pref.Value {
+	dstl := dst.List()
+	srcl := src.List()
+	for i, llen := 0, srcl.Len(); i < llen; i++ {
+		dstl.Append(srcl.Get(i))
+	}
+	return dst
+}
+
+func mergeBytesListValue(dst, src pref.Value, opts mergeOptions) pref.Value {
+	dstl := dst.List()
+	srcl := src.List()
+	for i, llen := 0, srcl.Len(); i < llen; i++ {
+		sb := srcl.Get(i).Bytes()
+		db := append(emptyBuf[:], sb...)
+		dstl.Append(pref.ValueOfBytes(db))
+	}
+	return dst
+}
+
+func mergeMessageListValue(dst, src pref.Value, opts mergeOptions) pref.Value {
+	dstl := dst.List()
+	srcl := src.List()
+	for i, llen := 0, srcl.Len(); i < llen; i++ {
+		sm := srcl.Get(i).Message()
+		dm := proto.Clone(sm.Interface()).ProtoReflect()
+		dstl.Append(pref.ValueOfMessage(dm))
+	}
+	return dst
+}
+
+func mergeMessageValue(dst, src pref.Value, opts mergeOptions) pref.Value {
+	opts.Merge(dst.Message().Interface(), src.Message().Interface())
+	return dst
+}
+
+func mergeMessage(dst, src pointer, f *coderFieldInfo, opts mergeOptions) {
+	if f.mi != nil {
+		if dst.Elem().IsNil() {
+			dst.SetPointer(pointerOfValue(reflect.New(f.mi.GoReflectType.Elem())))
+		}
+		f.mi.mergePointer(dst.Elem(), src.Elem(), opts)
+	} else {
+		dm := dst.AsValueOf(f.ft).Elem()
+		sm := src.AsValueOf(f.ft).Elem()
+		if dm.IsNil() {
+			dm.Set(reflect.New(f.ft.Elem()))
+		}
+		opts.Merge(asMessage(dm), asMessage(sm))
+	}
+}
+
+func mergeMessageSlice(dst, src pointer, f *coderFieldInfo, opts mergeOptions) {
+	for _, sp := range src.PointerSlice() {
+		dm := reflect.New(f.ft.Elem().Elem())
+		if f.mi != nil {
+			f.mi.mergePointer(pointerOfValue(dm), sp, opts)
+		} else {
+			opts.Merge(asMessage(dm), asMessage(sp.AsValueOf(f.ft.Elem().Elem())))
+		}
+		dst.AppendPointerSlice(pointerOfValue(dm))
+	}
+}
+
+func mergeBytes(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
+	*dst.Bytes() = append(emptyBuf[:], *src.Bytes()...)
+}
+
+func mergeBytesNoZero(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
+	v := *src.Bytes()
+	if len(v) > 0 {
+		*dst.Bytes() = append(emptyBuf[:], v...)
+	}
+}
+
+func mergeBytesSlice(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
+	ds := dst.BytesSlice()
+	for _, v := range *src.BytesSlice() {
+		*ds = append(*ds, append(emptyBuf[:], v...))
+	}
+}
diff --git a/vendor/google.golang.org/protobuf/internal/impl/merge_gen.go b/vendor/google.golang.org/protobuf/internal/impl/merge_gen.go
new file mode 100644
index 0000000..8816c27
--- /dev/null
+++ b/vendor/google.golang.org/protobuf/internal/impl/merge_gen.go
@@ -0,0 +1,209 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Code generated by generate-types. DO NOT EDIT.
+
+package impl
+
+import ()
+
+func mergeBool(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
+	*dst.Bool() = *src.Bool()
+}
+
+func mergeBoolNoZero(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
+	v := *src.Bool()
+	if v != false {
+		*dst.Bool() = v
+	}
+}
+
+func mergeBoolPtr(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
+	p := *src.BoolPtr()
+	if p != nil {
+		v := *p
+		*dst.BoolPtr() = &v
+	}
+}
+
+func mergeBoolSlice(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
+	ds := dst.BoolSlice()
+	ss := src.BoolSlice()
+	*ds = append(*ds, *ss...)
+}
+
+func mergeInt32(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
+	*dst.Int32() = *src.Int32()
+}
+
+func mergeInt32NoZero(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
+	v := *src.Int32()
+	if v != 0 {
+		*dst.Int32() = v
+	}
+}
+
+func mergeInt32Ptr(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
+	p := *src.Int32Ptr()
+	if p != nil {
+		v := *p
+		*dst.Int32Ptr() = &v
+	}
+}
+
+func mergeInt32Slice(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
+	ds := dst.Int32Slice()
+	ss := src.Int32Slice()
+	*ds = append(*ds, *ss...)
+}
+
+func mergeUint32(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
+	*dst.Uint32() = *src.Uint32()
+}
+
+func mergeUint32NoZero(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
+	v := *src.Uint32()
+	if v != 0 {
+		*dst.Uint32() = v
+	}
+}
+
+func mergeUint32Ptr(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
+	p := *src.Uint32Ptr()
+	if p != nil {
+		v := *p
+		*dst.Uint32Ptr() = &v
+	}
+}
+
+func mergeUint32Slice(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
+	ds := dst.Uint32Slice()
+	ss := src.Uint32Slice()
+	*ds = append(*ds, *ss...)
+}
+
+func mergeInt64(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
+	*dst.Int64() = *src.Int64()
+}
+
+func mergeInt64NoZero(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
+	v := *src.Int64()
+	if v != 0 {
+		*dst.Int64() = v
+	}
+}
+
+func mergeInt64Ptr(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
+	p := *src.Int64Ptr()
+	if p != nil {
+		v := *p
+		*dst.Int64Ptr() = &v
+	}
+}
+
+func mergeInt64Slice(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
+	ds := dst.Int64Slice()
+	ss := src.Int64Slice()
+	*ds = append(*ds, *ss...)
+}
+
+func mergeUint64(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
+	*dst.Uint64() = *src.Uint64()
+}
+
+func mergeUint64NoZero(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
+	v := *src.Uint64()
+	if v != 0 {
+		*dst.Uint64() = v
+	}
+}
+
+func mergeUint64Ptr(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
+	p := *src.Uint64Ptr()
+	if p != nil {
+		v := *p
+		*dst.Uint64Ptr() = &v
+	}
+}
+
+func mergeUint64Slice(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
+	ds := dst.Uint64Slice()
+	ss := src.Uint64Slice()
+	*ds = append(*ds, *ss...)
+}
+
+func mergeFloat32(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
+	*dst.Float32() = *src.Float32()
+}
+
+func mergeFloat32NoZero(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
+	v := *src.Float32()
+	if v != 0 {
+		*dst.Float32() = v
+	}
+}
+
+func mergeFloat32Ptr(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
+	p := *src.Float32Ptr()
+	if p != nil {
+		v := *p
+		*dst.Float32Ptr() = &v
+	}
+}
+
+func mergeFloat32Slice(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
+	ds := dst.Float32Slice()
+	ss := src.Float32Slice()
+	*ds = append(*ds, *ss...)
+}
+
+func mergeFloat64(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
+	*dst.Float64() = *src.Float64()
+}
+
+func mergeFloat64NoZero(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
+	v := *src.Float64()
+	if v != 0 {
+		*dst.Float64() = v
+	}
+}
+
+func mergeFloat64Ptr(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
+	p := *src.Float64Ptr()
+	if p != nil {
+		v := *p
+		*dst.Float64Ptr() = &v
+	}
+}
+
+func mergeFloat64Slice(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
+	ds := dst.Float64Slice()
+	ss := src.Float64Slice()
+	*ds = append(*ds, *ss...)
+}
+
+func mergeString(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
+	*dst.String() = *src.String()
+}
+
+func mergeStringNoZero(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
+	v := *src.String()
+	if v != "" {
+		*dst.String() = v
+	}
+}
+
+func mergeStringPtr(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
+	p := *src.StringPtr()
+	if p != nil {
+		v := *p
+		*dst.StringPtr() = &v
+	}
+}
+
+func mergeStringSlice(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
+	ds := dst.StringSlice()
+	ss := src.StringSlice()
+	*ds = append(*ds, *ss...)
+}
diff --git a/vendor/google.golang.org/protobuf/internal/impl/message.go b/vendor/google.golang.org/protobuf/internal/impl/message.go
new file mode 100644
index 0000000..7dd994b
--- /dev/null
+++ b/vendor/google.golang.org/protobuf/internal/impl/message.go
@@ -0,0 +1,215 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package impl
+
+import (
+	"fmt"
+	"reflect"
+	"strconv"
+	"strings"
+	"sync"
+	"sync/atomic"
+
+	"google.golang.org/protobuf/internal/genname"
+	"google.golang.org/protobuf/reflect/protoreflect"
+	pref "google.golang.org/protobuf/reflect/protoreflect"
+)
+
+// MessageInfo provides protobuf related functionality for a given Go type
+// that represents a message. A given instance of MessageInfo is tied to
+// exactly one Go type, which must be a pointer to a struct type.
+//
+// The exported fields must be populated before any methods are called
+// and cannot be mutated after set.
+type MessageInfo struct {
+	// GoReflectType is the underlying message Go type and must be populated.
+	GoReflectType reflect.Type // pointer to struct
+
+	// Desc is the underlying message descriptor type and must be populated.
+	Desc pref.MessageDescriptor
+
+	// Exporter must be provided in a purego environment in order to provide
+	// access to unexported fields.
+	Exporter exporter
+
+	// OneofWrappers is list of pointers to oneof wrapper struct types.
+	OneofWrappers []interface{}
+
+	initMu   sync.Mutex // protects all unexported fields
+	initDone uint32
+
+	reflectMessageInfo // for reflection implementation
+	coderMessageInfo   // for fast-path method implementations
+}
+
+// exporter is a function that returns a reference to the ith field of v,
+// where v is a pointer to a struct. It returns nil if it does not support
+// exporting the requested field (e.g., already exported).
+type exporter func(v interface{}, i int) interface{}
+
+// getMessageInfo returns the MessageInfo for any message type that
+// is generated by our implementation of protoc-gen-go (for v2 and on).
+// If it is unable to obtain a MessageInfo, it returns nil.
+func getMessageInfo(mt reflect.Type) *MessageInfo {
+	m, ok := reflect.Zero(mt).Interface().(pref.ProtoMessage)
+	if !ok {
+		return nil
+	}
+	mr, ok := m.ProtoReflect().(interface{ ProtoMessageInfo() *MessageInfo })
+	if !ok {
+		return nil
+	}
+	return mr.ProtoMessageInfo()
+}
+
+func (mi *MessageInfo) init() {
+	// This function is called in the hot path. Inline the sync.Once logic,
+	// since allocating a closure for Once.Do is expensive.
+	// Keep init small to ensure that it can be inlined.
+	if atomic.LoadUint32(&mi.initDone) == 0 {
+		mi.initOnce()
+	}
+}
+
+func (mi *MessageInfo) initOnce() {
+	mi.initMu.Lock()
+	defer mi.initMu.Unlock()
+	if mi.initDone == 1 {
+		return
+	}
+
+	t := mi.GoReflectType
+	if t.Kind() != reflect.Ptr && t.Elem().Kind() != reflect.Struct {
+		panic(fmt.Sprintf("got %v, want *struct kind", t))
+	}
+	t = t.Elem()
+
+	si := mi.makeStructInfo(t)
+	mi.makeReflectFuncs(t, si)
+	mi.makeCoderMethods(t, si)
+
+	atomic.StoreUint32(&mi.initDone, 1)
+}
+
+// getPointer returns the pointer for a message, which should be of
+// the type of the MessageInfo. If the message is of a different type,
+// it returns ok==false.
+func (mi *MessageInfo) getPointer(m pref.Message) (p pointer, ok bool) {
+	switch m := m.(type) {
+	case *messageState:
+		return m.pointer(), m.messageInfo() == mi
+	case *messageReflectWrapper:
+		return m.pointer(), m.messageInfo() == mi
+	}
+	return pointer{}, false
+}
+
+type (
+	SizeCache       = int32
+	WeakFields      = map[int32]protoreflect.ProtoMessage
+	UnknownFields   = []byte
+	ExtensionFields = map[int32]ExtensionField
+)
+
+var (
+	sizecacheType       = reflect.TypeOf(SizeCache(0))
+	weakFieldsType      = reflect.TypeOf(WeakFields(nil))
+	unknownFieldsType   = reflect.TypeOf(UnknownFields(nil))
+	extensionFieldsType = reflect.TypeOf(ExtensionFields(nil))
+)
+
+type structInfo struct {
+	sizecacheOffset offset
+	weakOffset      offset
+	unknownOffset   offset
+	extensionOffset offset
+
+	fieldsByNumber        map[pref.FieldNumber]reflect.StructField
+	oneofsByName          map[pref.Name]reflect.StructField
+	oneofWrappersByType   map[reflect.Type]pref.FieldNumber
+	oneofWrappersByNumber map[pref.FieldNumber]reflect.Type
+}
+
+func (mi *MessageInfo) makeStructInfo(t reflect.Type) structInfo {
+	si := structInfo{
+		sizecacheOffset: invalidOffset,
+		weakOffset:      invalidOffset,
+		unknownOffset:   invalidOffset,
+		extensionOffset: invalidOffset,
+
+		fieldsByNumber:        map[pref.FieldNumber]reflect.StructField{},
+		oneofsByName:          map[pref.Name]reflect.StructField{},
+		oneofWrappersByType:   map[reflect.Type]pref.FieldNumber{},
+		oneofWrappersByNumber: map[pref.FieldNumber]reflect.Type{},
+	}
+
+fieldLoop:
+	for i := 0; i < t.NumField(); i++ {
+		switch f := t.Field(i); f.Name {
+		case genname.SizeCache, genname.SizeCacheA:
+			if f.Type == sizecacheType {
+				si.sizecacheOffset = offsetOf(f, mi.Exporter)
+			}
+		case genname.WeakFields, genname.WeakFieldsA:
+			if f.Type == weakFieldsType {
+				si.weakOffset = offsetOf(f, mi.Exporter)
+			}
+		case genname.UnknownFields, genname.UnknownFieldsA:
+			if f.Type == unknownFieldsType {
+				si.unknownOffset = offsetOf(f, mi.Exporter)
+			}
+		case genname.ExtensionFields, genname.ExtensionFieldsA, genname.ExtensionFieldsB:
+			if f.Type == extensionFieldsType {
+				si.extensionOffset = offsetOf(f, mi.Exporter)
+			}
+		default:
+			for _, s := range strings.Split(f.Tag.Get("protobuf"), ",") {
+				if len(s) > 0 && strings.Trim(s, "0123456789") == "" {
+					n, _ := strconv.ParseUint(s, 10, 64)
+					si.fieldsByNumber[pref.FieldNumber(n)] = f
+					continue fieldLoop
+				}
+			}
+			if s := f.Tag.Get("protobuf_oneof"); len(s) > 0 {
+				si.oneofsByName[pref.Name(s)] = f
+				continue fieldLoop
+			}
+		}
+	}
+
+	// Derive a mapping of oneof wrappers to fields.
+	oneofWrappers := mi.OneofWrappers
+	for _, method := range []string{"XXX_OneofFuncs", "XXX_OneofWrappers"} {
+		if fn, ok := reflect.PtrTo(t).MethodByName(method); ok {
+			for _, v := range fn.Func.Call([]reflect.Value{reflect.Zero(fn.Type.In(0))}) {
+				if vs, ok := v.Interface().([]interface{}); ok {
+					oneofWrappers = vs
+				}
+			}
+		}
+	}
+	for _, v := range oneofWrappers {
+		tf := reflect.TypeOf(v).Elem()
+		f := tf.Field(0)
+		for _, s := range strings.Split(f.Tag.Get("protobuf"), ",") {
+			if len(s) > 0 && strings.Trim(s, "0123456789") == "" {
+				n, _ := strconv.ParseUint(s, 10, 64)
+				si.oneofWrappersByType[tf] = pref.FieldNumber(n)
+				si.oneofWrappersByNumber[pref.FieldNumber(n)] = tf
+				break
+			}
+		}
+	}
+
+	return si
+}
+
+func (mi *MessageInfo) New() protoreflect.Message {
+	return mi.MessageOf(reflect.New(mi.GoReflectType.Elem()).Interface())
+}
+func (mi *MessageInfo) Zero() protoreflect.Message {
+	return mi.MessageOf(reflect.Zero(mi.GoReflectType).Interface())
+}
+func (mi *MessageInfo) Descriptor() protoreflect.MessageDescriptor { return mi.Desc }
diff --git a/vendor/google.golang.org/protobuf/internal/impl/message_reflect.go b/vendor/google.golang.org/protobuf/internal/impl/message_reflect.go
new file mode 100644
index 0000000..0f4b8db
--- /dev/null
+++ b/vendor/google.golang.org/protobuf/internal/impl/message_reflect.go
@@ -0,0 +1,364 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package impl
+
+import (
+	"fmt"
+	"reflect"
+
+	"google.golang.org/protobuf/internal/pragma"
+	pref "google.golang.org/protobuf/reflect/protoreflect"
+)
+
+type reflectMessageInfo struct {
+	fields map[pref.FieldNumber]*fieldInfo
+	oneofs map[pref.Name]*oneofInfo
+
+	// denseFields is a subset of fields where:
+	//	0 < fieldDesc.Number() < len(denseFields)
+	// It provides faster access to the fieldInfo, but may be incomplete.
+	denseFields []*fieldInfo
+
+	// rangeInfos is a list of all fields (not belonging to a oneof) and oneofs.
+	rangeInfos []interface{} // either *fieldInfo or *oneofInfo
+
+	getUnknown   func(pointer) pref.RawFields
+	setUnknown   func(pointer, pref.RawFields)
+	extensionMap func(pointer) *extensionMap
+
+	nilMessage atomicNilMessage
+}
+
+// makeReflectFuncs generates the set of functions to support reflection.
+func (mi *MessageInfo) makeReflectFuncs(t reflect.Type, si structInfo) {
+	mi.makeKnownFieldsFunc(si)
+	mi.makeUnknownFieldsFunc(t, si)
+	mi.makeExtensionFieldsFunc(t, si)
+}
+
+// makeKnownFieldsFunc generates functions for operations that can be performed
+// on each protobuf message field. It takes in a reflect.Type representing the
+// Go struct and matches message fields with struct fields.
+//
+// This code assumes that the struct is well-formed and panics if there are
+// any discrepancies.
+func (mi *MessageInfo) makeKnownFieldsFunc(si structInfo) {
+	mi.fields = map[pref.FieldNumber]*fieldInfo{}
+	md := mi.Desc
+	fds := md.Fields()
+	for i := 0; i < fds.Len(); i++ {
+		fd := fds.Get(i)
+		fs := si.fieldsByNumber[fd.Number()]
+		var fi fieldInfo
+		switch {
+		case fd.ContainingOneof() != nil && !fd.ContainingOneof().IsSynthetic():
+			fi = fieldInfoForOneof(fd, si.oneofsByName[fd.ContainingOneof().Name()], mi.Exporter, si.oneofWrappersByNumber[fd.Number()])
+		case fd.IsMap():
+			fi = fieldInfoForMap(fd, fs, mi.Exporter)
+		case fd.IsList():
+			fi = fieldInfoForList(fd, fs, mi.Exporter)
+		case fd.IsWeak():
+			fi = fieldInfoForWeakMessage(fd, si.weakOffset)
+		case fd.Kind() == pref.MessageKind || fd.Kind() == pref.GroupKind:
+			fi = fieldInfoForMessage(fd, fs, mi.Exporter)
+		default:
+			fi = fieldInfoForScalar(fd, fs, mi.Exporter)
+		}
+		mi.fields[fd.Number()] = &fi
+	}
+
+	mi.oneofs = map[pref.Name]*oneofInfo{}
+	for i := 0; i < md.Oneofs().Len(); i++ {
+		od := md.Oneofs().Get(i)
+		mi.oneofs[od.Name()] = makeOneofInfo(od, si, mi.Exporter)
+	}
+
+	mi.denseFields = make([]*fieldInfo, fds.Len()*2)
+	for i := 0; i < fds.Len(); i++ {
+		if fd := fds.Get(i); int(fd.Number()) < len(mi.denseFields) {
+			mi.denseFields[fd.Number()] = mi.fields[fd.Number()]
+		}
+	}
+
+	for i := 0; i < fds.Len(); {
+		fd := fds.Get(i)
+		if od := fd.ContainingOneof(); od != nil && !od.IsSynthetic() {
+			mi.rangeInfos = append(mi.rangeInfos, mi.oneofs[od.Name()])
+			i += od.Fields().Len()
+		} else {
+			mi.rangeInfos = append(mi.rangeInfos, mi.fields[fd.Number()])
+			i++
+		}
+	}
+}
+
+func (mi *MessageInfo) makeUnknownFieldsFunc(t reflect.Type, si structInfo) {
+	mi.getUnknown = func(pointer) pref.RawFields { return nil }
+	mi.setUnknown = func(pointer, pref.RawFields) { return }
+	if si.unknownOffset.IsValid() {
+		mi.getUnknown = func(p pointer) pref.RawFields {
+			if p.IsNil() {
+				return nil
+			}
+			rv := p.Apply(si.unknownOffset).AsValueOf(unknownFieldsType)
+			return pref.RawFields(*rv.Interface().(*[]byte))
+		}
+		mi.setUnknown = func(p pointer, b pref.RawFields) {
+			if p.IsNil() {
+				panic("invalid SetUnknown on nil Message")
+			}
+			rv := p.Apply(si.unknownOffset).AsValueOf(unknownFieldsType)
+			*rv.Interface().(*[]byte) = []byte(b)
+		}
+	} else {
+		mi.getUnknown = func(pointer) pref.RawFields {
+			return nil
+		}
+		mi.setUnknown = func(p pointer, _ pref.RawFields) {
+			if p.IsNil() {
+				panic("invalid SetUnknown on nil Message")
+			}
+		}
+	}
+}
+
+func (mi *MessageInfo) makeExtensionFieldsFunc(t reflect.Type, si structInfo) {
+	if si.extensionOffset.IsValid() {
+		mi.extensionMap = func(p pointer) *extensionMap {
+			if p.IsNil() {
+				return (*extensionMap)(nil)
+			}
+			v := p.Apply(si.extensionOffset).AsValueOf(extensionFieldsType)
+			return (*extensionMap)(v.Interface().(*map[int32]ExtensionField))
+		}
+	} else {
+		mi.extensionMap = func(pointer) *extensionMap {
+			return (*extensionMap)(nil)
+		}
+	}
+}
+
+type extensionMap map[int32]ExtensionField
+
+func (m *extensionMap) Range(f func(pref.FieldDescriptor, pref.Value) bool) {
+	if m != nil {
+		for _, x := range *m {
+			xd := x.Type().TypeDescriptor()
+			v := x.Value()
+			if xd.IsList() && v.List().Len() == 0 {
+				continue
+			}
+			if !f(xd, v) {
+				return
+			}
+		}
+	}
+}
+func (m *extensionMap) Has(xt pref.ExtensionType) (ok bool) {
+	if m == nil {
+		return false
+	}
+	xd := xt.TypeDescriptor()
+	x, ok := (*m)[int32(xd.Number())]
+	if !ok {
+		return false
+	}
+	switch {
+	case xd.IsList():
+		return x.Value().List().Len() > 0
+	case xd.IsMap():
+		return x.Value().Map().Len() > 0
+	case xd.Message() != nil:
+		return x.Value().Message().IsValid()
+	}
+	return true
+}
+func (m *extensionMap) Clear(xt pref.ExtensionType) {
+	delete(*m, int32(xt.TypeDescriptor().Number()))
+}
+func (m *extensionMap) Get(xt pref.ExtensionType) pref.Value {
+	xd := xt.TypeDescriptor()
+	if m != nil {
+		if x, ok := (*m)[int32(xd.Number())]; ok {
+			return x.Value()
+		}
+	}
+	return xt.Zero()
+}
+func (m *extensionMap) Set(xt pref.ExtensionType, v pref.Value) {
+	xd := xt.TypeDescriptor()
+	isValid := true
+	switch {
+	case !xt.IsValidValue(v):
+		isValid = false
+	case xd.IsList():
+		isValid = v.List().IsValid()
+	case xd.IsMap():
+		isValid = v.Map().IsValid()
+	case xd.Message() != nil:
+		isValid = v.Message().IsValid()
+	}
+	if !isValid {
+		panic(fmt.Sprintf("%v: assigning invalid value", xt.TypeDescriptor().FullName()))
+	}
+
+	if *m == nil {
+		*m = make(map[int32]ExtensionField)
+	}
+	var x ExtensionField
+	x.Set(xt, v)
+	(*m)[int32(xd.Number())] = x
+}
+func (m *extensionMap) Mutable(xt pref.ExtensionType) pref.Value {
+	xd := xt.TypeDescriptor()
+	if xd.Kind() != pref.MessageKind && xd.Kind() != pref.GroupKind && !xd.IsList() && !xd.IsMap() {
+		panic("invalid Mutable on field with non-composite type")
+	}
+	if x, ok := (*m)[int32(xd.Number())]; ok {
+		return x.Value()
+	}
+	v := xt.New()
+	m.Set(xt, v)
+	return v
+}
+
+// MessageState is a data structure that is nested as the first field in a
+// concrete message. It provides a way to implement the ProtoReflect method
+// in an allocation-free way without needing to have a shadow Go type generated
+// for every message type. This technique only works using unsafe.
+//
+//
+// Example generated code:
+//
+//	type M struct {
+//		state protoimpl.MessageState
+//
+//		Field1 int32
+//		Field2 string
+//		Field3 *BarMessage
+//		...
+//	}
+//
+//	func (m *M) ProtoReflect() protoreflect.Message {
+//		mi := &file_fizz_buzz_proto_msgInfos[5]
+//		if protoimpl.UnsafeEnabled && m != nil {
+//			ms := protoimpl.X.MessageStateOf(Pointer(m))
+//			if ms.LoadMessageInfo() == nil {
+//				ms.StoreMessageInfo(mi)
+//			}
+//			return ms
+//		}
+//		return mi.MessageOf(m)
+//	}
+//
+// The MessageState type holds a *MessageInfo, which must be atomically set to
+// the message info associated with a given message instance.
+// By unsafely converting a *M into a *MessageState, the MessageState object
+// has access to all the information needed to implement protobuf reflection.
+// It has access to the message info as its first field, and a pointer to the
+// MessageState is identical to a pointer to the concrete message value.
+//
+//
+// Requirements:
+//	• The type M must implement protoreflect.ProtoMessage.
+//	• The address of m must not be nil.
+//	• The address of m and the address of m.state must be equal,
+//	even though they are different Go types.
+type MessageState struct {
+	pragma.NoUnkeyedLiterals
+	pragma.DoNotCompare
+	pragma.DoNotCopy
+
+	atomicMessageInfo *MessageInfo
+}
+
+type messageState MessageState
+
+var (
+	_ pref.Message = (*messageState)(nil)
+	_ unwrapper    = (*messageState)(nil)
+)
+
+// messageDataType is a tuple of a pointer to the message data and
+// a pointer to the message type. It is a generalized way of providing a
+// reflective view over a message instance. The disadvantage of this approach
+// is the need to allocate this tuple of 16B.
+type messageDataType struct {
+	p  pointer
+	mi *MessageInfo
+}
+
+type (
+	messageReflectWrapper messageDataType
+	messageIfaceWrapper   messageDataType
+)
+
+var (
+	_ pref.Message      = (*messageReflectWrapper)(nil)
+	_ unwrapper         = (*messageReflectWrapper)(nil)
+	_ pref.ProtoMessage = (*messageIfaceWrapper)(nil)
+	_ unwrapper         = (*messageIfaceWrapper)(nil)
+)
+
+// MessageOf returns a reflective view over a message. The input must be a
+// pointer to a named Go struct. If the provided type has a ProtoReflect method,
+// it must be implemented by calling this method.
+func (mi *MessageInfo) MessageOf(m interface{}) pref.Message {
+	// TODO: Switch the input to be an opaque Pointer.
+	if reflect.TypeOf(m) != mi.GoReflectType {
+		panic(fmt.Sprintf("type mismatch: got %T, want %v", m, mi.GoReflectType))
+	}
+	p := pointerOfIface(m)
+	if p.IsNil() {
+		return mi.nilMessage.Init(mi)
+	}
+	return &messageReflectWrapper{p, mi}
+}
+
+func (m *messageReflectWrapper) pointer() pointer          { return m.p }
+func (m *messageReflectWrapper) messageInfo() *MessageInfo { return m.mi }
+
+func (m *messageIfaceWrapper) ProtoReflect() pref.Message {
+	return (*messageReflectWrapper)(m)
+}
+func (m *messageIfaceWrapper) protoUnwrap() interface{} {
+	return m.p.AsIfaceOf(m.mi.GoReflectType.Elem())
+}
+
+// checkField verifies that the provided field descriptor is valid.
+// Exactly one of the returned values is populated.
+func (mi *MessageInfo) checkField(fd pref.FieldDescriptor) (*fieldInfo, pref.ExtensionType) {
+	var fi *fieldInfo
+	if n := fd.Number(); 0 < n && int(n) < len(mi.denseFields) {
+		fi = mi.denseFields[n]
+	} else {
+		fi = mi.fields[n]
+	}
+	if fi != nil {
+		if fi.fieldDesc != fd {
+			if got, want := fd.FullName(), fi.fieldDesc.FullName(); got != want {
+				panic(fmt.Sprintf("mismatching field: got %v, want %v", got, want))
+			}
+			panic(fmt.Sprintf("mismatching field: %v", fd.FullName()))
+		}
+		return fi, nil
+	}
+
+	if fd.IsExtension() {
+		if got, want := fd.ContainingMessage().FullName(), mi.Desc.FullName(); got != want {
+			// TODO: Should this be exact containing message descriptor match?
+			panic(fmt.Sprintf("extension %v has mismatching containing message: got %v, want %v", fd.FullName(), got, want))
+		}
+		if !mi.Desc.ExtensionRanges().Has(fd.Number()) {
+			panic(fmt.Sprintf("extension %v extends %v outside the extension range", fd.FullName(), mi.Desc.FullName()))
+		}
+		xtd, ok := fd.(pref.ExtensionTypeDescriptor)
+		if !ok {
+			panic(fmt.Sprintf("extension %v does not implement protoreflect.ExtensionTypeDescriptor", fd.FullName()))
+		}
+		return nil, xtd.Type()
+	}
+	panic(fmt.Sprintf("field %v is invalid", fd.FullName()))
+}
diff --git a/vendor/google.golang.org/protobuf/internal/impl/message_reflect_field.go b/vendor/google.golang.org/protobuf/internal/impl/message_reflect_field.go
new file mode 100644
index 0000000..23124a8
--- /dev/null
+++ b/vendor/google.golang.org/protobuf/internal/impl/message_reflect_field.go
@@ -0,0 +1,466 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package impl
+
+import (
+	"fmt"
+	"math"
+	"reflect"
+	"sync"
+
+	"google.golang.org/protobuf/internal/flags"
+	pref "google.golang.org/protobuf/reflect/protoreflect"
+	preg "google.golang.org/protobuf/reflect/protoregistry"
+)
+
+type fieldInfo struct {
+	fieldDesc pref.FieldDescriptor
+
+	// These fields are used for protobuf reflection support.
+	has        func(pointer) bool
+	clear      func(pointer)
+	get        func(pointer) pref.Value
+	set        func(pointer, pref.Value)
+	mutable    func(pointer) pref.Value
+	newMessage func() pref.Message
+	newField   func() pref.Value
+}
+
+func fieldInfoForOneof(fd pref.FieldDescriptor, fs reflect.StructField, x exporter, ot reflect.Type) fieldInfo {
+	ft := fs.Type
+	if ft.Kind() != reflect.Interface {
+		panic(fmt.Sprintf("field %v has invalid type: got %v, want interface kind", fd.FullName(), ft))
+	}
+	if ot.Kind() != reflect.Struct {
+		panic(fmt.Sprintf("field %v has invalid type: got %v, want struct kind", fd.FullName(), ot))
+	}
+	if !reflect.PtrTo(ot).Implements(ft) {
+		panic(fmt.Sprintf("field %v has invalid type: %v does not implement %v", fd.FullName(), ot, ft))
+	}
+	conv := NewConverter(ot.Field(0).Type, fd)
+	isMessage := fd.Message() != nil
+
+	// TODO: Implement unsafe fast path?
+	fieldOffset := offsetOf(fs, x)
+	return fieldInfo{
+		// NOTE: The logic below intentionally assumes that oneof fields are
+		// well-formatted. That is, the oneof interface never contains a
+		// typed nil pointer to one of the wrapper structs.
+
+		fieldDesc: fd,
+		has: func(p pointer) bool {
+			if p.IsNil() {
+				return false
+			}
+			rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
+			if rv.IsNil() || rv.Elem().Type().Elem() != ot || rv.Elem().IsNil() {
+				return false
+			}
+			return true
+		},
+		clear: func(p pointer) {
+			rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
+			if rv.IsNil() || rv.Elem().Type().Elem() != ot {
+				// NOTE: We intentionally don't check for rv.Elem().IsNil()
+				// so that (*OneofWrapperType)(nil) gets cleared to nil.
+				return
+			}
+			rv.Set(reflect.Zero(rv.Type()))
+		},
+		get: func(p pointer) pref.Value {
+			if p.IsNil() {
+				return conv.Zero()
+			}
+			rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
+			if rv.IsNil() || rv.Elem().Type().Elem() != ot || rv.Elem().IsNil() {
+				return conv.Zero()
+			}
+			rv = rv.Elem().Elem().Field(0)
+			return conv.PBValueOf(rv)
+		},
+		set: func(p pointer, v pref.Value) {
+			rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
+			if rv.IsNil() || rv.Elem().Type().Elem() != ot || rv.Elem().IsNil() {
+				rv.Set(reflect.New(ot))
+			}
+			rv = rv.Elem().Elem().Field(0)
+			rv.Set(conv.GoValueOf(v))
+		},
+		mutable: func(p pointer) pref.Value {
+			if !isMessage {
+				panic(fmt.Sprintf("field %v with invalid Mutable call on field with non-composite type", fd.FullName()))
+			}
+			rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
+			if rv.IsNil() || rv.Elem().Type().Elem() != ot || rv.Elem().IsNil() {
+				rv.Set(reflect.New(ot))
+			}
+			rv = rv.Elem().Elem().Field(0)
+			if rv.IsNil() {
+				rv.Set(conv.GoValueOf(pref.ValueOfMessage(conv.New().Message())))
+			}
+			return conv.PBValueOf(rv)
+		},
+		newMessage: func() pref.Message {
+			return conv.New().Message()
+		},
+		newField: func() pref.Value {
+			return conv.New()
+		},
+	}
+}
+
+func fieldInfoForMap(fd pref.FieldDescriptor, fs reflect.StructField, x exporter) fieldInfo {
+	ft := fs.Type
+	if ft.Kind() != reflect.Map {
+		panic(fmt.Sprintf("field %v has invalid type: got %v, want map kind", fd.FullName(), ft))
+	}
+	conv := NewConverter(ft, fd)
+
+	// TODO: Implement unsafe fast path?
+	fieldOffset := offsetOf(fs, x)
+	return fieldInfo{
+		fieldDesc: fd,
+		has: func(p pointer) bool {
+			if p.IsNil() {
+				return false
+			}
+			rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
+			return rv.Len() > 0
+		},
+		clear: func(p pointer) {
+			rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
+			rv.Set(reflect.Zero(rv.Type()))
+		},
+		get: func(p pointer) pref.Value {
+			if p.IsNil() {
+				return conv.Zero()
+			}
+			rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
+			if rv.Len() == 0 {
+				return conv.Zero()
+			}
+			return conv.PBValueOf(rv)
+		},
+		set: func(p pointer, v pref.Value) {
+			rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
+			pv := conv.GoValueOf(v)
+			if pv.IsNil() {
+				panic(fmt.Sprintf("map field %v cannot be set with read-only value", fd.FullName()))
+			}
+			rv.Set(pv)
+		},
+		mutable: func(p pointer) pref.Value {
+			v := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
+			if v.IsNil() {
+				v.Set(reflect.MakeMap(fs.Type))
+			}
+			return conv.PBValueOf(v)
+		},
+		newField: func() pref.Value {
+			return conv.New()
+		},
+	}
+}
+
+func fieldInfoForList(fd pref.FieldDescriptor, fs reflect.StructField, x exporter) fieldInfo {
+	ft := fs.Type
+	if ft.Kind() != reflect.Slice {
+		panic(fmt.Sprintf("field %v has invalid type: got %v, want slice kind", fd.FullName(), ft))
+	}
+	conv := NewConverter(reflect.PtrTo(ft), fd)
+
+	// TODO: Implement unsafe fast path?
+	fieldOffset := offsetOf(fs, x)
+	return fieldInfo{
+		fieldDesc: fd,
+		has: func(p pointer) bool {
+			if p.IsNil() {
+				return false
+			}
+			rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
+			return rv.Len() > 0
+		},
+		clear: func(p pointer) {
+			rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
+			rv.Set(reflect.Zero(rv.Type()))
+		},
+		get: func(p pointer) pref.Value {
+			if p.IsNil() {
+				return conv.Zero()
+			}
+			rv := p.Apply(fieldOffset).AsValueOf(fs.Type)
+			if rv.Elem().Len() == 0 {
+				return conv.Zero()
+			}
+			return conv.PBValueOf(rv)
+		},
+		set: func(p pointer, v pref.Value) {
+			rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
+			pv := conv.GoValueOf(v)
+			if pv.IsNil() {
+				panic(fmt.Sprintf("list field %v cannot be set with read-only value", fd.FullName()))
+			}
+			rv.Set(pv.Elem())
+		},
+		mutable: func(p pointer) pref.Value {
+			v := p.Apply(fieldOffset).AsValueOf(fs.Type)
+			return conv.PBValueOf(v)
+		},
+		newField: func() pref.Value {
+			return conv.New()
+		},
+	}
+}
+
+var (
+	nilBytes   = reflect.ValueOf([]byte(nil))
+	emptyBytes = reflect.ValueOf([]byte{})
+)
+
+func fieldInfoForScalar(fd pref.FieldDescriptor, fs reflect.StructField, x exporter) fieldInfo {
+	ft := fs.Type
+	nullable := fd.HasPresence()
+	isBytes := ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8
+	if nullable {
+		if ft.Kind() != reflect.Ptr && ft.Kind() != reflect.Slice {
+			panic(fmt.Sprintf("field %v has invalid type: got %v, want pointer", fd.FullName(), ft))
+		}
+		if ft.Kind() == reflect.Ptr {
+			ft = ft.Elem()
+		}
+	}
+	conv := NewConverter(ft, fd)
+
+	// TODO: Implement unsafe fast path?
+	fieldOffset := offsetOf(fs, x)
+	return fieldInfo{
+		fieldDesc: fd,
+		has: func(p pointer) bool {
+			if p.IsNil() {
+				return false
+			}
+			rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
+			if nullable {
+				return !rv.IsNil()
+			}
+			switch rv.Kind() {
+			case reflect.Bool:
+				return rv.Bool()
+			case reflect.Int32, reflect.Int64:
+				return rv.Int() != 0
+			case reflect.Uint32, reflect.Uint64:
+				return rv.Uint() != 0
+			case reflect.Float32, reflect.Float64:
+				return rv.Float() != 0 || math.Signbit(rv.Float())
+			case reflect.String, reflect.Slice:
+				return rv.Len() > 0
+			default:
+				panic(fmt.Sprintf("field %v has invalid type: %v", fd.FullName(), rv.Type())) // should never happen
+			}
+		},
+		clear: func(p pointer) {
+			rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
+			rv.Set(reflect.Zero(rv.Type()))
+		},
+		get: func(p pointer) pref.Value {
+			if p.IsNil() {
+				return conv.Zero()
+			}
+			rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
+			if nullable {
+				if rv.IsNil() {
+					return conv.Zero()
+				}
+				if rv.Kind() == reflect.Ptr {
+					rv = rv.Elem()
+				}
+			}
+			return conv.PBValueOf(rv)
+		},
+		set: func(p pointer, v pref.Value) {
+			rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
+			if nullable && rv.Kind() == reflect.Ptr {
+				if rv.IsNil() {
+					rv.Set(reflect.New(ft))
+				}
+				rv = rv.Elem()
+			}
+			rv.Set(conv.GoValueOf(v))
+			if isBytes && rv.Len() == 0 {
+				if nullable {
+					rv.Set(emptyBytes) // preserve presence
+				} else {
+					rv.Set(nilBytes) // do not preserve presence
+				}
+			}
+		},
+		newField: func() pref.Value {
+			return conv.New()
+		},
+	}
+}
+
+func fieldInfoForWeakMessage(fd pref.FieldDescriptor, weakOffset offset) fieldInfo {
+	if !flags.ProtoLegacy {
+		panic("no support for proto1 weak fields")
+	}
+
+	var once sync.Once
+	var messageType pref.MessageType
+	lazyInit := func() {
+		once.Do(func() {
+			messageName := fd.Message().FullName()
+			messageType, _ = preg.GlobalTypes.FindMessageByName(messageName)
+			if messageType == nil {
+				panic(fmt.Sprintf("weak message %v for field %v is not linked in", messageName, fd.FullName()))
+			}
+		})
+	}
+
+	num := fd.Number()
+	return fieldInfo{
+		fieldDesc: fd,
+		has: func(p pointer) bool {
+			if p.IsNil() {
+				return false
+			}
+			_, ok := p.Apply(weakOffset).WeakFields().get(num)
+			return ok
+		},
+		clear: func(p pointer) {
+			p.Apply(weakOffset).WeakFields().clear(num)
+		},
+		get: func(p pointer) pref.Value {
+			lazyInit()
+			if p.IsNil() {
+				return pref.ValueOfMessage(messageType.Zero())
+			}
+			m, ok := p.Apply(weakOffset).WeakFields().get(num)
+			if !ok {
+				return pref.ValueOfMessage(messageType.Zero())
+			}
+			return pref.ValueOfMessage(m.ProtoReflect())
+		},
+		set: func(p pointer, v pref.Value) {
+			lazyInit()
+			m := v.Message()
+			if m.Descriptor() != messageType.Descriptor() {
+				if got, want := m.Descriptor().FullName(), messageType.Descriptor().FullName(); got != want {
+					panic(fmt.Sprintf("field %v has mismatching message descriptor: got %v, want %v", fd.FullName(), got, want))
+				}
+				panic(fmt.Sprintf("field %v has mismatching message descriptor: %v", fd.FullName(), m.Descriptor().FullName()))
+			}
+			p.Apply(weakOffset).WeakFields().set(num, m.Interface())
+		},
+		mutable: func(p pointer) pref.Value {
+			lazyInit()
+			fs := p.Apply(weakOffset).WeakFields()
+			m, ok := fs.get(num)
+			if !ok {
+				m = messageType.New().Interface()
+				fs.set(num, m)
+			}
+			return pref.ValueOfMessage(m.ProtoReflect())
+		},
+		newMessage: func() pref.Message {
+			lazyInit()
+			return messageType.New()
+		},
+		newField: func() pref.Value {
+			lazyInit()
+			return pref.ValueOfMessage(messageType.New())
+		},
+	}
+}
+
+func fieldInfoForMessage(fd pref.FieldDescriptor, fs reflect.StructField, x exporter) fieldInfo {
+	ft := fs.Type
+	conv := NewConverter(ft, fd)
+
+	// TODO: Implement unsafe fast path?
+	fieldOffset := offsetOf(fs, x)
+	return fieldInfo{
+		fieldDesc: fd,
+		has: func(p pointer) bool {
+			if p.IsNil() {
+				return false
+			}
+			rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
+			return !rv.IsNil()
+		},
+		clear: func(p pointer) {
+			rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
+			rv.Set(reflect.Zero(rv.Type()))
+		},
+		get: func(p pointer) pref.Value {
+			if p.IsNil() {
+				return conv.Zero()
+			}
+			rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
+			return conv.PBValueOf(rv)
+		},
+		set: func(p pointer, v pref.Value) {
+			rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
+			rv.Set(conv.GoValueOf(v))
+			if rv.IsNil() {
+				panic(fmt.Sprintf("field %v has invalid nil pointer", fd.FullName()))
+			}
+		},
+		mutable: func(p pointer) pref.Value {
+			rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
+			if rv.IsNil() {
+				rv.Set(conv.GoValueOf(conv.New()))
+			}
+			return conv.PBValueOf(rv)
+		},
+		newMessage: func() pref.Message {
+			return conv.New().Message()
+		},
+		newField: func() pref.Value {
+			return conv.New()
+		},
+	}
+}
+
+type oneofInfo struct {
+	oneofDesc pref.OneofDescriptor
+	which     func(pointer) pref.FieldNumber
+}
+
+func makeOneofInfo(od pref.OneofDescriptor, si structInfo, x exporter) *oneofInfo {
+	oi := &oneofInfo{oneofDesc: od}
+	if od.IsSynthetic() {
+		fs := si.fieldsByNumber[od.Fields().Get(0).Number()]
+		fieldOffset := offsetOf(fs, x)
+		oi.which = func(p pointer) pref.FieldNumber {
+			if p.IsNil() {
+				return 0
+			}
+			rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
+			if rv.IsNil() { // valid on either *T or []byte
+				return 0
+			}
+			return od.Fields().Get(0).Number()
+		}
+	} else {
+		fs := si.oneofsByName[od.Name()]
+		fieldOffset := offsetOf(fs, x)
+		oi.which = func(p pointer) pref.FieldNumber {
+			if p.IsNil() {
+				return 0
+			}
+			rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
+			if rv.IsNil() {
+				return 0
+			}
+			rv = rv.Elem()
+			if rv.IsNil() {
+				return 0
+			}
+			return si.oneofWrappersByType[rv.Type().Elem()]
+		}
+	}
+	return oi
+}
diff --git a/vendor/google.golang.org/protobuf/internal/impl/message_reflect_gen.go b/vendor/google.golang.org/protobuf/internal/impl/message_reflect_gen.go
new file mode 100644
index 0000000..741d6e5
--- /dev/null
+++ b/vendor/google.golang.org/protobuf/internal/impl/message_reflect_gen.go
@@ -0,0 +1,249 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Code generated by generate-types. DO NOT EDIT.
+
+package impl
+
+import (
+	"google.golang.org/protobuf/reflect/protoreflect"
+	"google.golang.org/protobuf/runtime/protoiface"
+)
+
+func (m *messageState) Descriptor() protoreflect.MessageDescriptor {
+	return m.messageInfo().Desc
+}
+func (m *messageState) Type() protoreflect.MessageType {
+	return m.messageInfo()
+}
+func (m *messageState) New() protoreflect.Message {
+	return m.messageInfo().New()
+}
+func (m *messageState) Interface() protoreflect.ProtoMessage {
+	return m.protoUnwrap().(protoreflect.ProtoMessage)
+}
+func (m *messageState) protoUnwrap() interface{} {
+	return m.pointer().AsIfaceOf(m.messageInfo().GoReflectType.Elem())
+}
+func (m *messageState) ProtoMethods() *protoiface.Methods {
+	m.messageInfo().init()
+	return &m.messageInfo().methods
+}
+
+// ProtoMessageInfo is a pseudo-internal API for allowing the v1 code
+// to be able to retrieve a v2 MessageInfo struct.
+//
+// WARNING: This method is exempt from the compatibility promise and
+// may be removed in the future without warning.
+func (m *messageState) ProtoMessageInfo() *MessageInfo {
+	return m.messageInfo()
+}
+
+func (m *messageState) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) {
+	m.messageInfo().init()
+	for _, ri := range m.messageInfo().rangeInfos {
+		switch ri := ri.(type) {
+		case *fieldInfo:
+			if ri.has(m.pointer()) {
+				if !f(ri.fieldDesc, ri.get(m.pointer())) {
+					return
+				}
+			}
+		case *oneofInfo:
+			if n := ri.which(m.pointer()); n > 0 {
+				fi := m.messageInfo().fields[n]
+				if !f(fi.fieldDesc, fi.get(m.pointer())) {
+					return
+				}
+			}
+		}
+	}
+	m.messageInfo().extensionMap(m.pointer()).Range(f)
+}
+func (m *messageState) Has(fd protoreflect.FieldDescriptor) bool {
+	m.messageInfo().init()
+	if fi, xt := m.messageInfo().checkField(fd); fi != nil {
+		return fi.has(m.pointer())
+	} else {
+		return m.messageInfo().extensionMap(m.pointer()).Has(xt)
+	}
+}
+func (m *messageState) Clear(fd protoreflect.FieldDescriptor) {
+	m.messageInfo().init()
+	if fi, xt := m.messageInfo().checkField(fd); fi != nil {
+		fi.clear(m.pointer())
+	} else {
+		m.messageInfo().extensionMap(m.pointer()).Clear(xt)
+	}
+}
+func (m *messageState) Get(fd protoreflect.FieldDescriptor) protoreflect.Value {
+	m.messageInfo().init()
+	if fi, xt := m.messageInfo().checkField(fd); fi != nil {
+		return fi.get(m.pointer())
+	} else {
+		return m.messageInfo().extensionMap(m.pointer()).Get(xt)
+	}
+}
+func (m *messageState) Set(fd protoreflect.FieldDescriptor, v protoreflect.Value) {
+	m.messageInfo().init()
+	if fi, xt := m.messageInfo().checkField(fd); fi != nil {
+		fi.set(m.pointer(), v)
+	} else {
+		m.messageInfo().extensionMap(m.pointer()).Set(xt, v)
+	}
+}
+func (m *messageState) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value {
+	m.messageInfo().init()
+	if fi, xt := m.messageInfo().checkField(fd); fi != nil {
+		return fi.mutable(m.pointer())
+	} else {
+		return m.messageInfo().extensionMap(m.pointer()).Mutable(xt)
+	}
+}
+func (m *messageState) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value {
+	m.messageInfo().init()
+	if fi, xt := m.messageInfo().checkField(fd); fi != nil {
+		return fi.newField()
+	} else {
+		return xt.New()
+	}
+}
+func (m *messageState) WhichOneof(od protoreflect.OneofDescriptor) protoreflect.FieldDescriptor {
+	m.messageInfo().init()
+	if oi := m.messageInfo().oneofs[od.Name()]; oi != nil && oi.oneofDesc == od {
+		return od.Fields().ByNumber(oi.which(m.pointer()))
+	}
+	panic("invalid oneof descriptor " + string(od.FullName()) + " for message " + string(m.Descriptor().FullName()))
+}
+func (m *messageState) GetUnknown() protoreflect.RawFields {
+	m.messageInfo().init()
+	return m.messageInfo().getUnknown(m.pointer())
+}
+func (m *messageState) SetUnknown(b protoreflect.RawFields) {
+	m.messageInfo().init()
+	m.messageInfo().setUnknown(m.pointer(), b)
+}
+func (m *messageState) IsValid() bool {
+	return !m.pointer().IsNil()
+}
+
+func (m *messageReflectWrapper) Descriptor() protoreflect.MessageDescriptor {
+	return m.messageInfo().Desc
+}
+func (m *messageReflectWrapper) Type() protoreflect.MessageType {
+	return m.messageInfo()
+}
+func (m *messageReflectWrapper) New() protoreflect.Message {
+	return m.messageInfo().New()
+}
+func (m *messageReflectWrapper) Interface() protoreflect.ProtoMessage {
+	if m, ok := m.protoUnwrap().(protoreflect.ProtoMessage); ok {
+		return m
+	}
+	return (*messageIfaceWrapper)(m)
+}
+func (m *messageReflectWrapper) protoUnwrap() interface{} {
+	return m.pointer().AsIfaceOf(m.messageInfo().GoReflectType.Elem())
+}
+func (m *messageReflectWrapper) ProtoMethods() *protoiface.Methods {
+	m.messageInfo().init()
+	return &m.messageInfo().methods
+}
+
+// ProtoMessageInfo is a pseudo-internal API for allowing the v1 code
+// to be able to retrieve a v2 MessageInfo struct.
+//
+// WARNING: This method is exempt from the compatibility promise and
+// may be removed in the future without warning.
+func (m *messageReflectWrapper) ProtoMessageInfo() *MessageInfo {
+	return m.messageInfo()
+}
+
+func (m *messageReflectWrapper) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) {
+	m.messageInfo().init()
+	for _, ri := range m.messageInfo().rangeInfos {
+		switch ri := ri.(type) {
+		case *fieldInfo:
+			if ri.has(m.pointer()) {
+				if !f(ri.fieldDesc, ri.get(m.pointer())) {
+					return
+				}
+			}
+		case *oneofInfo:
+			if n := ri.which(m.pointer()); n > 0 {
+				fi := m.messageInfo().fields[n]
+				if !f(fi.fieldDesc, fi.get(m.pointer())) {
+					return
+				}
+			}
+		}
+	}
+	m.messageInfo().extensionMap(m.pointer()).Range(f)
+}
+func (m *messageReflectWrapper) Has(fd protoreflect.FieldDescriptor) bool {
+	m.messageInfo().init()
+	if fi, xt := m.messageInfo().checkField(fd); fi != nil {
+		return fi.has(m.pointer())
+	} else {
+		return m.messageInfo().extensionMap(m.pointer()).Has(xt)
+	}
+}
+func (m *messageReflectWrapper) Clear(fd protoreflect.FieldDescriptor) {
+	m.messageInfo().init()
+	if fi, xt := m.messageInfo().checkField(fd); fi != nil {
+		fi.clear(m.pointer())
+	} else {
+		m.messageInfo().extensionMap(m.pointer()).Clear(xt)
+	}
+}
+func (m *messageReflectWrapper) Get(fd protoreflect.FieldDescriptor) protoreflect.Value {
+	m.messageInfo().init()
+	if fi, xt := m.messageInfo().checkField(fd); fi != nil {
+		return fi.get(m.pointer())
+	} else {
+		return m.messageInfo().extensionMap(m.pointer()).Get(xt)
+	}
+}
+func (m *messageReflectWrapper) Set(fd protoreflect.FieldDescriptor, v protoreflect.Value) {
+	m.messageInfo().init()
+	if fi, xt := m.messageInfo().checkField(fd); fi != nil {
+		fi.set(m.pointer(), v)
+	} else {
+		m.messageInfo().extensionMap(m.pointer()).Set(xt, v)
+	}
+}
+func (m *messageReflectWrapper) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value {
+	m.messageInfo().init()
+	if fi, xt := m.messageInfo().checkField(fd); fi != nil {
+		return fi.mutable(m.pointer())
+	} else {
+		return m.messageInfo().extensionMap(m.pointer()).Mutable(xt)
+	}
+}
+func (m *messageReflectWrapper) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value {
+	m.messageInfo().init()
+	if fi, xt := m.messageInfo().checkField(fd); fi != nil {
+		return fi.newField()
+	} else {
+		return xt.New()
+	}
+}
+func (m *messageReflectWrapper) WhichOneof(od protoreflect.OneofDescriptor) protoreflect.FieldDescriptor {
+	m.messageInfo().init()
+	if oi := m.messageInfo().oneofs[od.Name()]; oi != nil && oi.oneofDesc == od {
+		return od.Fields().ByNumber(oi.which(m.pointer()))
+	}
+	panic("invalid oneof descriptor " + string(od.FullName()) + " for message " + string(m.Descriptor().FullName()))
+}
+func (m *messageReflectWrapper) GetUnknown() protoreflect.RawFields {
+	m.messageInfo().init()
+	return m.messageInfo().getUnknown(m.pointer())
+}
+func (m *messageReflectWrapper) SetUnknown(b protoreflect.RawFields) {
+	m.messageInfo().init()
+	m.messageInfo().setUnknown(m.pointer(), b)
+}
+func (m *messageReflectWrapper) IsValid() bool {
+	return !m.pointer().IsNil()
+}
diff --git a/vendor/google.golang.org/protobuf/internal/impl/pointer_reflect.go b/vendor/google.golang.org/protobuf/internal/impl/pointer_reflect.go
new file mode 100644
index 0000000..67b4ede
--- /dev/null
+++ b/vendor/google.golang.org/protobuf/internal/impl/pointer_reflect.go
@@ -0,0 +1,177 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build purego appengine
+
+package impl
+
+import (
+	"fmt"
+	"reflect"
+	"sync"
+)
+
+const UnsafeEnabled = false
+
+// Pointer is an opaque pointer type.
+type Pointer interface{}
+
+// offset represents the offset to a struct field, accessible from a pointer.
+// The offset is the field index into a struct.
+type offset struct {
+	index  int
+	export exporter
+}
+
+// offsetOf returns a field offset for the struct field.
+func offsetOf(f reflect.StructField, x exporter) offset {
+	if len(f.Index) != 1 {
+		panic("embedded structs are not supported")
+	}
+	if f.PkgPath == "" {
+		return offset{index: f.Index[0]} // field is already exported
+	}
+	if x == nil {
+		panic("exporter must be provided for unexported field")
+	}
+	return offset{index: f.Index[0], export: x}
+}
+
+// IsValid reports whether the offset is valid.
+func (f offset) IsValid() bool { return f.index >= 0 }
+
+// invalidOffset is an invalid field offset.
+var invalidOffset = offset{index: -1}
+
+// zeroOffset is a noop when calling pointer.Apply.
+var zeroOffset = offset{index: 0}
+
+// pointer is an abstract representation of a pointer to a struct or field.
+type pointer struct{ v reflect.Value }
+
+// pointerOf returns p as a pointer.
+func pointerOf(p Pointer) pointer {
+	return pointerOfIface(p)
+}
+
+// pointerOfValue returns v as a pointer.
+func pointerOfValue(v reflect.Value) pointer {
+	return pointer{v: v}
+}
+
+// pointerOfIface returns the pointer portion of an interface.
+func pointerOfIface(v interface{}) pointer {
+	return pointer{v: reflect.ValueOf(v)}
+}
+
+// IsNil reports whether the pointer is nil.
+func (p pointer) IsNil() bool {
+	return p.v.IsNil()
+}
+
+// Apply adds an offset to the pointer to derive a new pointer
+// to a specified field. The current pointer must be pointing at a struct.
+func (p pointer) Apply(f offset) pointer {
+	if f.export != nil {
+		if v := reflect.ValueOf(f.export(p.v.Interface(), f.index)); v.IsValid() {
+			return pointer{v: v}
+		}
+	}
+	return pointer{v: p.v.Elem().Field(f.index).Addr()}
+}
+
+// AsValueOf treats p as a pointer to an object of type t and returns the value.
+// It is equivalent to reflect.ValueOf(p.AsIfaceOf(t))
+func (p pointer) AsValueOf(t reflect.Type) reflect.Value {
+	if got := p.v.Type().Elem(); got != t {
+		panic(fmt.Sprintf("invalid type: got %v, want %v", got, t))
+	}
+	return p.v
+}
+
+// AsIfaceOf treats p as a pointer to an object of type t and returns the value.
+// It is equivalent to p.AsValueOf(t).Interface()
+func (p pointer) AsIfaceOf(t reflect.Type) interface{} {
+	return p.AsValueOf(t).Interface()
+}
+
+func (p pointer) Bool() *bool              { return p.v.Interface().(*bool) }
+func (p pointer) BoolPtr() **bool          { return p.v.Interface().(**bool) }
+func (p pointer) BoolSlice() *[]bool       { return p.v.Interface().(*[]bool) }
+func (p pointer) Int32() *int32            { return p.v.Interface().(*int32) }
+func (p pointer) Int32Ptr() **int32        { return p.v.Interface().(**int32) }
+func (p pointer) Int32Slice() *[]int32     { return p.v.Interface().(*[]int32) }
+func (p pointer) Int64() *int64            { return p.v.Interface().(*int64) }
+func (p pointer) Int64Ptr() **int64        { return p.v.Interface().(**int64) }
+func (p pointer) Int64Slice() *[]int64     { return p.v.Interface().(*[]int64) }
+func (p pointer) Uint32() *uint32          { return p.v.Interface().(*uint32) }
+func (p pointer) Uint32Ptr() **uint32      { return p.v.Interface().(**uint32) }
+func (p pointer) Uint32Slice() *[]uint32   { return p.v.Interface().(*[]uint32) }
+func (p pointer) Uint64() *uint64          { return p.v.Interface().(*uint64) }
+func (p pointer) Uint64Ptr() **uint64      { return p.v.Interface().(**uint64) }
+func (p pointer) Uint64Slice() *[]uint64   { return p.v.Interface().(*[]uint64) }
+func (p pointer) Float32() *float32        { return p.v.Interface().(*float32) }
+func (p pointer) Float32Ptr() **float32    { return p.v.Interface().(**float32) }
+func (p pointer) Float32Slice() *[]float32 { return p.v.Interface().(*[]float32) }
+func (p pointer) Float64() *float64        { return p.v.Interface().(*float64) }
+func (p pointer) Float64Ptr() **float64    { return p.v.Interface().(**float64) }
+func (p pointer) Float64Slice() *[]float64 { return p.v.Interface().(*[]float64) }
+func (p pointer) String() *string          { return p.v.Interface().(*string) }
+func (p pointer) StringPtr() **string      { return p.v.Interface().(**string) }
+func (p pointer) StringSlice() *[]string   { return p.v.Interface().(*[]string) }
+func (p pointer) Bytes() *[]byte           { return p.v.Interface().(*[]byte) }
+func (p pointer) BytesSlice() *[][]byte    { return p.v.Interface().(*[][]byte) }
+func (p pointer) WeakFields() *weakFields  { return (*weakFields)(p.v.Interface().(*WeakFields)) }
+func (p pointer) Extensions() *map[int32]ExtensionField {
+	return p.v.Interface().(*map[int32]ExtensionField)
+}
+
+func (p pointer) Elem() pointer {
+	return pointer{v: p.v.Elem()}
+}
+
+// PointerSlice copies []*T from p as a new []pointer.
+// This behavior differs from the implementation in pointer_unsafe.go.
+func (p pointer) PointerSlice() []pointer {
+	// TODO: reconsider this
+	if p.v.IsNil() {
+		return nil
+	}
+	n := p.v.Elem().Len()
+	s := make([]pointer, n)
+	for i := 0; i < n; i++ {
+		s[i] = pointer{v: p.v.Elem().Index(i)}
+	}
+	return s
+}
+
+// AppendPointerSlice appends v to p, which must be a []*T.
+func (p pointer) AppendPointerSlice(v pointer) {
+	sp := p.v.Elem()
+	sp.Set(reflect.Append(sp, v.v))
+}
+
+// SetPointer sets *p to v.
+func (p pointer) SetPointer(v pointer) {
+	p.v.Elem().Set(v.v)
+}
+
+func (Export) MessageStateOf(p Pointer) *messageState     { panic("not supported") }
+func (ms *messageState) pointer() pointer                 { panic("not supported") }
+func (ms *messageState) messageInfo() *MessageInfo        { panic("not supported") }
+func (ms *messageState) LoadMessageInfo() *MessageInfo    { panic("not supported") }
+func (ms *messageState) StoreMessageInfo(mi *MessageInfo) { panic("not supported") }
+
+type atomicNilMessage struct {
+	once sync.Once
+	m    messageReflectWrapper
+}
+
+func (m *atomicNilMessage) Init(mi *MessageInfo) *messageReflectWrapper {
+	m.once.Do(func() {
+		m.m.p = pointerOfIface(reflect.Zero(mi.GoReflectType).Interface())
+		m.m.mi = mi
+	})
+	return &m.m
+}
diff --git a/vendor/google.golang.org/protobuf/internal/impl/pointer_unsafe.go b/vendor/google.golang.org/protobuf/internal/impl/pointer_unsafe.go
new file mode 100644
index 0000000..088aa85
--- /dev/null
+++ b/vendor/google.golang.org/protobuf/internal/impl/pointer_unsafe.go
@@ -0,0 +1,173 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build !purego,!appengine
+
+package impl
+
+import (
+	"reflect"
+	"sync/atomic"
+	"unsafe"
+)
+
+const UnsafeEnabled = true
+
+// Pointer is an opaque pointer type.
+type Pointer unsafe.Pointer
+
+// offset represents the offset to a struct field, accessible from a pointer.
+// The offset is the byte offset to the field from the start of the struct.
+type offset uintptr
+
+// offsetOf returns a field offset for the struct field.
+func offsetOf(f reflect.StructField, x exporter) offset {
+	return offset(f.Offset)
+}
+
+// IsValid reports whether the offset is valid.
+func (f offset) IsValid() bool { return f != invalidOffset }
+
+// invalidOffset is an invalid field offset.
+var invalidOffset = ^offset(0)
+
+// zeroOffset is a noop when calling pointer.Apply.
+var zeroOffset = offset(0)
+
+// pointer is a pointer to a message struct or field.
+type pointer struct{ p unsafe.Pointer }
+
+// pointerOf returns p as a pointer.
+func pointerOf(p Pointer) pointer {
+	return pointer{p: unsafe.Pointer(p)}
+}
+
+// pointerOfValue returns v as a pointer.
+func pointerOfValue(v reflect.Value) pointer {
+	return pointer{p: unsafe.Pointer(v.Pointer())}
+}
+
+// pointerOfIface returns the pointer portion of an interface.
+func pointerOfIface(v interface{}) pointer {
+	type ifaceHeader struct {
+		Type unsafe.Pointer
+		Data unsafe.Pointer
+	}
+	return pointer{p: (*ifaceHeader)(unsafe.Pointer(&v)).Data}
+}
+
+// IsNil reports whether the pointer is nil.
+func (p pointer) IsNil() bool {
+	return p.p == nil
+}
+
+// Apply adds an offset to the pointer to derive a new pointer
+// to a specified field. The pointer must be valid and pointing at a struct.
+func (p pointer) Apply(f offset) pointer {
+	if p.IsNil() {
+		panic("invalid nil pointer")
+	}
+	return pointer{p: unsafe.Pointer(uintptr(p.p) + uintptr(f))}
+}
+
+// AsValueOf treats p as a pointer to an object of type t and returns the value.
+// It is equivalent to reflect.ValueOf(p.AsIfaceOf(t))
+func (p pointer) AsValueOf(t reflect.Type) reflect.Value {
+	return reflect.NewAt(t, p.p)
+}
+
+// AsIfaceOf treats p as a pointer to an object of type t and returns the value.
+// It is equivalent to p.AsValueOf(t).Interface()
+func (p pointer) AsIfaceOf(t reflect.Type) interface{} {
+	// TODO: Use tricky unsafe magic to directly create ifaceHeader.
+	return p.AsValueOf(t).Interface()
+}
+
+func (p pointer) Bool() *bool                           { return (*bool)(p.p) }
+func (p pointer) BoolPtr() **bool                       { return (**bool)(p.p) }
+func (p pointer) BoolSlice() *[]bool                    { return (*[]bool)(p.p) }
+func (p pointer) Int32() *int32                         { return (*int32)(p.p) }
+func (p pointer) Int32Ptr() **int32                     { return (**int32)(p.p) }
+func (p pointer) Int32Slice() *[]int32                  { return (*[]int32)(p.p) }
+func (p pointer) Int64() *int64                         { return (*int64)(p.p) }
+func (p pointer) Int64Ptr() **int64                     { return (**int64)(p.p) }
+func (p pointer) Int64Slice() *[]int64                  { return (*[]int64)(p.p) }
+func (p pointer) Uint32() *uint32                       { return (*uint32)(p.p) }
+func (p pointer) Uint32Ptr() **uint32                   { return (**uint32)(p.p) }
+func (p pointer) Uint32Slice() *[]uint32                { return (*[]uint32)(p.p) }
+func (p pointer) Uint64() *uint64                       { return (*uint64)(p.p) }
+func (p pointer) Uint64Ptr() **uint64                   { return (**uint64)(p.p) }
+func (p pointer) Uint64Slice() *[]uint64                { return (*[]uint64)(p.p) }
+func (p pointer) Float32() *float32                     { return (*float32)(p.p) }
+func (p pointer) Float32Ptr() **float32                 { return (**float32)(p.p) }
+func (p pointer) Float32Slice() *[]float32              { return (*[]float32)(p.p) }
+func (p pointer) Float64() *float64                     { return (*float64)(p.p) }
+func (p pointer) Float64Ptr() **float64                 { return (**float64)(p.p) }
+func (p pointer) Float64Slice() *[]float64              { return (*[]float64)(p.p) }
+func (p pointer) String() *string                       { return (*string)(p.p) }
+func (p pointer) StringPtr() **string                   { return (**string)(p.p) }
+func (p pointer) StringSlice() *[]string                { return (*[]string)(p.p) }
+func (p pointer) Bytes() *[]byte                        { return (*[]byte)(p.p) }
+func (p pointer) BytesSlice() *[][]byte                 { return (*[][]byte)(p.p) }
+func (p pointer) WeakFields() *weakFields               { return (*weakFields)(p.p) }
+func (p pointer) Extensions() *map[int32]ExtensionField { return (*map[int32]ExtensionField)(p.p) }
+
+func (p pointer) Elem() pointer {
+	return pointer{p: *(*unsafe.Pointer)(p.p)}
+}
+
+// PointerSlice loads []*T from p as a []pointer.
+// The value returned is aliased with the original slice.
+// This behavior differs from the implementation in pointer_reflect.go.
+func (p pointer) PointerSlice() []pointer {
+	// Super-tricky - p should point to a []*T where T is a
+	// message type. We load it as []pointer.
+	return *(*[]pointer)(p.p)
+}
+
+// AppendPointerSlice appends v to p, which must be a []*T.
+func (p pointer) AppendPointerSlice(v pointer) {
+	*(*[]pointer)(p.p) = append(*(*[]pointer)(p.p), v)
+}
+
+// SetPointer sets *p to v.
+func (p pointer) SetPointer(v pointer) {
+	*(*unsafe.Pointer)(p.p) = (unsafe.Pointer)(v.p)
+}
+
+// Static check that MessageState does not exceed the size of a pointer.
+const _ = uint(unsafe.Sizeof(unsafe.Pointer(nil)) - unsafe.Sizeof(MessageState{}))
+
+func (Export) MessageStateOf(p Pointer) *messageState {
+	// Super-tricky - see documentation on MessageState.
+	return (*messageState)(unsafe.Pointer(p))
+}
+func (ms *messageState) pointer() pointer {
+	// Super-tricky - see documentation on MessageState.
+	return pointer{p: unsafe.Pointer(ms)}
+}
+func (ms *messageState) messageInfo() *MessageInfo {
+	mi := ms.LoadMessageInfo()
+	if mi == nil {
+		panic("invalid nil message info; this suggests memory corruption due to a race or shallow copy on the message struct")
+	}
+	return mi
+}
+func (ms *messageState) LoadMessageInfo() *MessageInfo {
+	return (*MessageInfo)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(&ms.atomicMessageInfo))))
+}
+func (ms *messageState) StoreMessageInfo(mi *MessageInfo) {
+	atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(&ms.atomicMessageInfo)), unsafe.Pointer(mi))
+}
+
+type atomicNilMessage struct{ p unsafe.Pointer } // p is a *messageReflectWrapper
+
+func (m *atomicNilMessage) Init(mi *MessageInfo) *messageReflectWrapper {
+	if p := atomic.LoadPointer(&m.p); p != nil {
+		return (*messageReflectWrapper)(p)
+	}
+	w := &messageReflectWrapper{mi: mi}
+	atomic.CompareAndSwapPointer(&m.p, nil, (unsafe.Pointer)(w))
+	return (*messageReflectWrapper)(atomic.LoadPointer(&m.p))
+}
diff --git a/vendor/google.golang.org/protobuf/internal/impl/validate.go b/vendor/google.golang.org/protobuf/internal/impl/validate.go
new file mode 100644
index 0000000..57de9cc
--- /dev/null
+++ b/vendor/google.golang.org/protobuf/internal/impl/validate.go
@@ -0,0 +1,575 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package impl
+
+import (
+	"fmt"
+	"math"
+	"math/bits"
+	"reflect"
+	"unicode/utf8"
+
+	"google.golang.org/protobuf/encoding/protowire"
+	"google.golang.org/protobuf/internal/encoding/messageset"
+	"google.golang.org/protobuf/internal/flags"
+	"google.golang.org/protobuf/internal/strs"
+	pref "google.golang.org/protobuf/reflect/protoreflect"
+	preg "google.golang.org/protobuf/reflect/protoregistry"
+	piface "google.golang.org/protobuf/runtime/protoiface"
+)
+
+// ValidationStatus is the result of validating the wire-format encoding of a message.
+type ValidationStatus int
+
+const (
+	// ValidationUnknown indicates that unmarshaling the message might succeed or fail.
+	// The validator was unable to render a judgement.
+	//
+	// The only causes of this status are an aberrant message type appearing somewhere
+	// in the message or a failure in the extension resolver.
+	ValidationUnknown ValidationStatus = iota + 1
+
+	// ValidationInvalid indicates that unmarshaling the message will fail.
+	ValidationInvalid
+
+	// ValidationValid indicates that unmarshaling the message will succeed.
+	ValidationValid
+)
+
+func (v ValidationStatus) String() string {
+	switch v {
+	case ValidationUnknown:
+		return "ValidationUnknown"
+	case ValidationInvalid:
+		return "ValidationInvalid"
+	case ValidationValid:
+		return "ValidationValid"
+	default:
+		return fmt.Sprintf("ValidationStatus(%d)", int(v))
+	}
+}
+
+// Validate determines whether the contents of the buffer are a valid wire encoding
+// of the message type.
+//
+// This function is exposed for testing.
+func Validate(mt pref.MessageType, in piface.UnmarshalInput) (out piface.UnmarshalOutput, _ ValidationStatus) {
+	mi, ok := mt.(*MessageInfo)
+	if !ok {
+		return out, ValidationUnknown
+	}
+	if in.Resolver == nil {
+		in.Resolver = preg.GlobalTypes
+	}
+	o, st := mi.validate(in.Buf, 0, unmarshalOptions{
+		flags:    in.Flags,
+		resolver: in.Resolver,
+	})
+	if o.initialized {
+		out.Flags |= piface.UnmarshalInitialized
+	}
+	return out, st
+}
+
+type validationInfo struct {
+	mi               *MessageInfo
+	typ              validationType
+	keyType, valType validationType
+
+	// For non-required fields, requiredBit is 0.
+	//
+	// For required fields, requiredBit's nth bit is set, where n is a
+	// unique index in the range [0, MessageInfo.numRequiredFields).
+	//
+	// If there are more than 64 required fields, requiredBit is 0.
+	requiredBit uint64
+}
+
+type validationType uint8
+
+const (
+	validationTypeOther validationType = iota
+	validationTypeMessage
+	validationTypeGroup
+	validationTypeMap
+	validationTypeRepeatedVarint
+	validationTypeRepeatedFixed32
+	validationTypeRepeatedFixed64
+	validationTypeVarint
+	validationTypeFixed32
+	validationTypeFixed64
+	validationTypeBytes
+	validationTypeUTF8String
+	validationTypeMessageSetItem
+)
+
+func newFieldValidationInfo(mi *MessageInfo, si structInfo, fd pref.FieldDescriptor, ft reflect.Type) validationInfo {
+	var vi validationInfo
+	switch {
+	case fd.ContainingOneof() != nil && !fd.ContainingOneof().IsSynthetic():
+		switch fd.Kind() {
+		case pref.MessageKind:
+			vi.typ = validationTypeMessage
+			if ot, ok := si.oneofWrappersByNumber[fd.Number()]; ok {
+				vi.mi = getMessageInfo(ot.Field(0).Type)
+			}
+		case pref.GroupKind:
+			vi.typ = validationTypeGroup
+			if ot, ok := si.oneofWrappersByNumber[fd.Number()]; ok {
+				vi.mi = getMessageInfo(ot.Field(0).Type)
+			}
+		case pref.StringKind:
+			if strs.EnforceUTF8(fd) {
+				vi.typ = validationTypeUTF8String
+			}
+		}
+	default:
+		vi = newValidationInfo(fd, ft)
+	}
+	if fd.Cardinality() == pref.Required {
+		// Avoid overflow. The required field check is done with a 64-bit mask, with
+		// any message containing more than 64 required fields always reported as
+		// potentially uninitialized, so it is not important to get a precise count
+		// of the required fields past 64.
+		if mi.numRequiredFields < math.MaxUint8 {
+			mi.numRequiredFields++
+			vi.requiredBit = 1 << (mi.numRequiredFields - 1)
+		}
+	}
+	return vi
+}
+
+func newValidationInfo(fd pref.FieldDescriptor, ft reflect.Type) validationInfo {
+	var vi validationInfo
+	switch {
+	case fd.IsList():
+		switch fd.Kind() {
+		case pref.MessageKind:
+			vi.typ = validationTypeMessage
+			if ft.Kind() == reflect.Slice {
+				vi.mi = getMessageInfo(ft.Elem())
+			}
+		case pref.GroupKind:
+			vi.typ = validationTypeGroup
+			if ft.Kind() == reflect.Slice {
+				vi.mi = getMessageInfo(ft.Elem())
+			}
+		case pref.StringKind:
+			vi.typ = validationTypeBytes
+			if strs.EnforceUTF8(fd) {
+				vi.typ = validationTypeUTF8String
+			}
+		default:
+			switch wireTypes[fd.Kind()] {
+			case protowire.VarintType:
+				vi.typ = validationTypeRepeatedVarint
+			case protowire.Fixed32Type:
+				vi.typ = validationTypeRepeatedFixed32
+			case protowire.Fixed64Type:
+				vi.typ = validationTypeRepeatedFixed64
+			}
+		}
+	case fd.IsMap():
+		vi.typ = validationTypeMap
+		switch fd.MapKey().Kind() {
+		case pref.StringKind:
+			if strs.EnforceUTF8(fd) {
+				vi.keyType = validationTypeUTF8String
+			}
+		}
+		switch fd.MapValue().Kind() {
+		case pref.MessageKind:
+			vi.valType = validationTypeMessage
+			if ft.Kind() == reflect.Map {
+				vi.mi = getMessageInfo(ft.Elem())
+			}
+		case pref.StringKind:
+			if strs.EnforceUTF8(fd) {
+				vi.valType = validationTypeUTF8String
+			}
+		}
+	default:
+		switch fd.Kind() {
+		case pref.MessageKind:
+			vi.typ = validationTypeMessage
+			if !fd.IsWeak() {
+				vi.mi = getMessageInfo(ft)
+			}
+		case pref.GroupKind:
+			vi.typ = validationTypeGroup
+			vi.mi = getMessageInfo(ft)
+		case pref.StringKind:
+			vi.typ = validationTypeBytes
+			if strs.EnforceUTF8(fd) {
+				vi.typ = validationTypeUTF8String
+			}
+		default:
+			switch wireTypes[fd.Kind()] {
+			case protowire.VarintType:
+				vi.typ = validationTypeVarint
+			case protowire.Fixed32Type:
+				vi.typ = validationTypeFixed32
+			case protowire.Fixed64Type:
+				vi.typ = validationTypeFixed64
+			case protowire.BytesType:
+				vi.typ = validationTypeBytes
+			}
+		}
+	}
+	return vi
+}
+
+func (mi *MessageInfo) validate(b []byte, groupTag protowire.Number, opts unmarshalOptions) (out unmarshalOutput, result ValidationStatus) {
+	mi.init()
+	type validationState struct {
+		typ              validationType
+		keyType, valType validationType
+		endGroup         protowire.Number
+		mi               *MessageInfo
+		tail             []byte
+		requiredMask     uint64
+	}
+
+	// Pre-allocate some slots to avoid repeated slice reallocation.
+	states := make([]validationState, 0, 16)
+	states = append(states, validationState{
+		typ: validationTypeMessage,
+		mi:  mi,
+	})
+	if groupTag > 0 {
+		states[0].typ = validationTypeGroup
+		states[0].endGroup = groupTag
+	}
+	initialized := true
+	start := len(b)
+State:
+	for len(states) > 0 {
+		st := &states[len(states)-1]
+		for len(b) > 0 {
+			// Parse the tag (field number and wire type).
+			var tag uint64
+			if b[0] < 0x80 {
+				tag = uint64(b[0])
+				b = b[1:]
+			} else if len(b) >= 2 && b[1] < 128 {
+				tag = uint64(b[0]&0x7f) + uint64(b[1])<<7
+				b = b[2:]
+			} else {
+				var n int
+				tag, n = protowire.ConsumeVarint(b)
+				if n < 0 {
+					return out, ValidationInvalid
+				}
+				b = b[n:]
+			}
+			var num protowire.Number
+			if n := tag >> 3; n < uint64(protowire.MinValidNumber) || n > uint64(protowire.MaxValidNumber) {
+				return out, ValidationInvalid
+			} else {
+				num = protowire.Number(n)
+			}
+			wtyp := protowire.Type(tag & 7)
+
+			if wtyp == protowire.EndGroupType {
+				if st.endGroup == num {
+					goto PopState
+				}
+				return out, ValidationInvalid
+			}
+			var vi validationInfo
+			switch {
+			case st.typ == validationTypeMap:
+				switch num {
+				case 1:
+					vi.typ = st.keyType
+				case 2:
+					vi.typ = st.valType
+					vi.mi = st.mi
+					vi.requiredBit = 1
+				}
+			case flags.ProtoLegacy && st.mi.isMessageSet:
+				switch num {
+				case messageset.FieldItem:
+					vi.typ = validationTypeMessageSetItem
+				}
+			default:
+				var f *coderFieldInfo
+				if int(num) < len(st.mi.denseCoderFields) {
+					f = st.mi.denseCoderFields[num]
+				} else {
+					f = st.mi.coderFields[num]
+				}
+				if f != nil {
+					vi = f.validation
+					if vi.typ == validationTypeMessage && vi.mi == nil {
+						// Probable weak field.
+						//
+						// TODO: Consider storing the results of this lookup somewhere
+						// rather than recomputing it on every validation.
+						fd := st.mi.Desc.Fields().ByNumber(num)
+						if fd == nil || !fd.IsWeak() {
+							break
+						}
+						messageName := fd.Message().FullName()
+						messageType, err := preg.GlobalTypes.FindMessageByName(messageName)
+						switch err {
+						case nil:
+							vi.mi, _ = messageType.(*MessageInfo)
+						case preg.NotFound:
+							vi.typ = validationTypeBytes
+						default:
+							return out, ValidationUnknown
+						}
+					}
+					break
+				}
+				// Possible extension field.
+				//
+				// TODO: We should return ValidationUnknown when:
+				//   1. The resolver is not frozen. (More extensions may be added to it.)
+				//   2. The resolver returns preg.NotFound.
+				// In this case, a type added to the resolver in the future could cause
+				// unmarshaling to begin failing. Supporting this requires some way to
+				// determine if the resolver is frozen.
+				xt, err := opts.resolver.FindExtensionByNumber(st.mi.Desc.FullName(), num)
+				if err != nil && err != preg.NotFound {
+					return out, ValidationUnknown
+				}
+				if err == nil {
+					vi = getExtensionFieldInfo(xt).validation
+				}
+			}
+			if vi.requiredBit != 0 {
+				// Check that the field has a compatible wire type.
+				// We only need to consider non-repeated field types,
+				// since repeated fields (and maps) can never be required.
+				ok := false
+				switch vi.typ {
+				case validationTypeVarint:
+					ok = wtyp == protowire.VarintType
+				case validationTypeFixed32:
+					ok = wtyp == protowire.Fixed32Type
+				case validationTypeFixed64:
+					ok = wtyp == protowire.Fixed64Type
+				case validationTypeBytes, validationTypeUTF8String, validationTypeMessage:
+					ok = wtyp == protowire.BytesType
+				case validationTypeGroup:
+					ok = wtyp == protowire.StartGroupType
+				}
+				if ok {
+					st.requiredMask |= vi.requiredBit
+				}
+			}
+
+			switch wtyp {
+			case protowire.VarintType:
+				if len(b) >= 10 {
+					switch {
+					case b[0] < 0x80:
+						b = b[1:]
+					case b[1] < 0x80:
+						b = b[2:]
+					case b[2] < 0x80:
+						b = b[3:]
+					case b[3] < 0x80:
+						b = b[4:]
+					case b[4] < 0x80:
+						b = b[5:]
+					case b[5] < 0x80:
+						b = b[6:]
+					case b[6] < 0x80:
+						b = b[7:]
+					case b[7] < 0x80:
+						b = b[8:]
+					case b[8] < 0x80:
+						b = b[9:]
+					case b[9] < 0x80 && b[9] < 2:
+						b = b[10:]
+					default:
+						return out, ValidationInvalid
+					}
+				} else {
+					switch {
+					case len(b) > 0 && b[0] < 0x80:
+						b = b[1:]
+					case len(b) > 1 && b[1] < 0x80:
+						b = b[2:]
+					case len(b) > 2 && b[2] < 0x80:
+						b = b[3:]
+					case len(b) > 3 && b[3] < 0x80:
+						b = b[4:]
+					case len(b) > 4 && b[4] < 0x80:
+						b = b[5:]
+					case len(b) > 5 && b[5] < 0x80:
+						b = b[6:]
+					case len(b) > 6 && b[6] < 0x80:
+						b = b[7:]
+					case len(b) > 7 && b[7] < 0x80:
+						b = b[8:]
+					case len(b) > 8 && b[8] < 0x80:
+						b = b[9:]
+					case len(b) > 9 && b[9] < 2:
+						b = b[10:]
+					default:
+						return out, ValidationInvalid
+					}
+				}
+				continue State
+			case protowire.BytesType:
+				var size uint64
+				if len(b) >= 1 && b[0] < 0x80 {
+					size = uint64(b[0])
+					b = b[1:]
+				} else if len(b) >= 2 && b[1] < 128 {
+					size = uint64(b[0]&0x7f) + uint64(b[1])<<7
+					b = b[2:]
+				} else {
+					var n int
+					size, n = protowire.ConsumeVarint(b)
+					if n < 0 {
+						return out, ValidationInvalid
+					}
+					b = b[n:]
+				}
+				if size > uint64(len(b)) {
+					return out, ValidationInvalid
+				}
+				v := b[:size]
+				b = b[size:]
+				switch vi.typ {
+				case validationTypeMessage:
+					if vi.mi == nil {
+						return out, ValidationUnknown
+					}
+					vi.mi.init()
+					fallthrough
+				case validationTypeMap:
+					if vi.mi != nil {
+						vi.mi.init()
+					}
+					states = append(states, validationState{
+						typ:     vi.typ,
+						keyType: vi.keyType,
+						valType: vi.valType,
+						mi:      vi.mi,
+						tail:    b,
+					})
+					b = v
+					continue State
+				case validationTypeRepeatedVarint:
+					// Packed field.
+					for len(v) > 0 {
+						_, n := protowire.ConsumeVarint(v)
+						if n < 0 {
+							return out, ValidationInvalid
+						}
+						v = v[n:]
+					}
+				case validationTypeRepeatedFixed32:
+					// Packed field.
+					if len(v)%4 != 0 {
+						return out, ValidationInvalid
+					}
+				case validationTypeRepeatedFixed64:
+					// Packed field.
+					if len(v)%8 != 0 {
+						return out, ValidationInvalid
+					}
+				case validationTypeUTF8String:
+					if !utf8.Valid(v) {
+						return out, ValidationInvalid
+					}
+				}
+			case protowire.Fixed32Type:
+				if len(b) < 4 {
+					return out, ValidationInvalid
+				}
+				b = b[4:]
+			case protowire.Fixed64Type:
+				if len(b) < 8 {
+					return out, ValidationInvalid
+				}
+				b = b[8:]
+			case protowire.StartGroupType:
+				switch {
+				case vi.typ == validationTypeGroup:
+					if vi.mi == nil {
+						return out, ValidationUnknown
+					}
+					vi.mi.init()
+					states = append(states, validationState{
+						typ:      validationTypeGroup,
+						mi:       vi.mi,
+						endGroup: num,
+					})
+					continue State
+				case flags.ProtoLegacy && vi.typ == validationTypeMessageSetItem:
+					typeid, v, n, err := messageset.ConsumeFieldValue(b, false)
+					if err != nil {
+						return out, ValidationInvalid
+					}
+					xt, err := opts.resolver.FindExtensionByNumber(st.mi.Desc.FullName(), typeid)
+					switch {
+					case err == preg.NotFound:
+						b = b[n:]
+					case err != nil:
+						return out, ValidationUnknown
+					default:
+						xvi := getExtensionFieldInfo(xt).validation
+						if xvi.mi != nil {
+							xvi.mi.init()
+						}
+						states = append(states, validationState{
+							typ:  xvi.typ,
+							mi:   xvi.mi,
+							tail: b[n:],
+						})
+						b = v
+						continue State
+					}
+				default:
+					n := protowire.ConsumeFieldValue(num, wtyp, b)
+					if n < 0 {
+						return out, ValidationInvalid
+					}
+					b = b[n:]
+				}
+			default:
+				return out, ValidationInvalid
+			}
+		}
+		if st.endGroup != 0 {
+			return out, ValidationInvalid
+		}
+		if len(b) != 0 {
+			return out, ValidationInvalid
+		}
+		b = st.tail
+	PopState:
+		numRequiredFields := 0
+		switch st.typ {
+		case validationTypeMessage, validationTypeGroup:
+			numRequiredFields = int(st.mi.numRequiredFields)
+		case validationTypeMap:
+			// If this is a map field with a message value that contains
+			// required fields, require that the value be present.
+			if st.mi != nil && st.mi.numRequiredFields > 0 {
+				numRequiredFields = 1
+			}
+		}
+		// If there are more than 64 required fields, this check will
+		// always fail and we will report that the message is potentially
+		// uninitialized.
+		if numRequiredFields > 0 && bits.OnesCount64(st.requiredMask) != numRequiredFields {
+			initialized = false
+		}
+		states = states[:len(states)-1]
+	}
+	out.n = start - len(b)
+	if initialized {
+		out.initialized = true
+	}
+	return out, ValidationValid
+}
diff --git a/vendor/google.golang.org/protobuf/internal/impl/weak.go b/vendor/google.golang.org/protobuf/internal/impl/weak.go
new file mode 100644
index 0000000..009cbef
--- /dev/null
+++ b/vendor/google.golang.org/protobuf/internal/impl/weak.go
@@ -0,0 +1,74 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package impl
+
+import (
+	"fmt"
+
+	pref "google.golang.org/protobuf/reflect/protoreflect"
+	"google.golang.org/protobuf/reflect/protoregistry"
+)
+
+// weakFields adds methods to the exported WeakFields type for internal use.
+//
+// The exported type is an alias to an unnamed type, so methods can't be
+// defined directly on it.
+type weakFields WeakFields
+
+func (w weakFields) get(num pref.FieldNumber) (pref.ProtoMessage, bool) {
+	m, ok := w[int32(num)]
+	return m, ok
+}
+
+func (w *weakFields) set(num pref.FieldNumber, m pref.ProtoMessage) {
+	if *w == nil {
+		*w = make(weakFields)
+	}
+	(*w)[int32(num)] = m
+}
+
+func (w *weakFields) clear(num pref.FieldNumber) {
+	delete(*w, int32(num))
+}
+
+func (Export) HasWeak(w WeakFields, num pref.FieldNumber) bool {
+	_, ok := w[int32(num)]
+	return ok
+}
+
+func (Export) ClearWeak(w *WeakFields, num pref.FieldNumber) {
+	delete(*w, int32(num))
+}
+
+func (Export) GetWeak(w WeakFields, num pref.FieldNumber, name pref.FullName) pref.ProtoMessage {
+	if m, ok := w[int32(num)]; ok {
+		return m
+	}
+	mt, _ := protoregistry.GlobalTypes.FindMessageByName(name)
+	if mt == nil {
+		panic(fmt.Sprintf("message %v for weak field is not linked in", name))
+	}
+	return mt.Zero().Interface()
+}
+
+func (Export) SetWeak(w *WeakFields, num pref.FieldNumber, name pref.FullName, m pref.ProtoMessage) {
+	if m != nil {
+		mt, _ := protoregistry.GlobalTypes.FindMessageByName(name)
+		if mt == nil {
+			panic(fmt.Sprintf("message %v for weak field is not linked in", name))
+		}
+		if mt != m.ProtoReflect().Type() {
+			panic(fmt.Sprintf("invalid message type for weak field: got %T, want %T", m, mt.Zero().Interface()))
+		}
+	}
+	if m == nil || !m.ProtoReflect().IsValid() {
+		delete(*w, int32(num))
+		return
+	}
+	if *w == nil {
+		*w = make(weakFields)
+	}
+	(*w)[int32(num)] = m
+}
