diff --git a/demo_test/vendor/google.golang.org/protobuf/AUTHORS b/demo_test/vendor/google.golang.org/protobuf/AUTHORS
new file mode 100644
index 0000000..2b00ddb
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/AUTHORS
@@ -0,0 +1,3 @@
+# This source code refers to The Go Authors for copyright purposes.
+# The master list of authors is in the main Go distribution,
+# visible at https://tip.golang.org/AUTHORS.
diff --git a/demo_test/vendor/google.golang.org/protobuf/CONTRIBUTORS b/demo_test/vendor/google.golang.org/protobuf/CONTRIBUTORS
new file mode 100644
index 0000000..1fbd3e9
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/CONTRIBUTORS
@@ -0,0 +1,3 @@
+# This source code was written by the Go contributors.
+# The master list of contributors is in the main Go distribution,
+# visible at https://tip.golang.org/CONTRIBUTORS.
diff --git a/demo_test/vendor/google.golang.org/protobuf/LICENSE b/demo_test/vendor/google.golang.org/protobuf/LICENSE
new file mode 100644
index 0000000..49ea0f9
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/LICENSE
@@ -0,0 +1,27 @@
+Copyright (c) 2018 The Go Authors. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+   * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+   * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+   * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/demo_test/vendor/google.golang.org/protobuf/PATENTS b/demo_test/vendor/google.golang.org/protobuf/PATENTS
new file mode 100644
index 0000000..7330990
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/PATENTS
@@ -0,0 +1,22 @@
+Additional IP Rights Grant (Patents)
+
+"This implementation" means the copyrightable works distributed by
+Google as part of the Go project.
+
+Google hereby grants to You a perpetual, worldwide, non-exclusive,
+no-charge, royalty-free, irrevocable (except as stated in this section)
+patent license to make, have made, use, offer to sell, sell, import,
+transfer and otherwise run, modify and propagate the contents of this
+implementation of Go, where such license applies only to those patent
+claims, both currently owned or controlled by Google and acquired in
+the future, licensable by Google that are necessarily infringed by this
+implementation of Go.  This grant does not include claims that would be
+infringed only as a consequence of further modification of this
+implementation.  If you or your agent or exclusive licensee institute or
+order or agree to the institution of patent litigation against any
+entity (including a cross-claim or counterclaim in a lawsuit) alleging
+that this implementation of Go or any code incorporated within this
+implementation of Go constitutes direct or contributory patent
+infringement, or inducement of patent infringement, then any patent
+rights granted to you under this License for this implementation of Go
+shall terminate as of the date such litigation is filed.
diff --git a/demo_test/vendor/google.golang.org/protobuf/encoding/prototext/decode.go b/demo_test/vendor/google.golang.org/protobuf/encoding/prototext/decode.go
new file mode 100644
index 0000000..cde2c20
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/encoding/prototext/decode.go
@@ -0,0 +1,788 @@
+// 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 prototext
+
+import (
+	"fmt"
+	"strings"
+	"unicode/utf8"
+
+	"google.golang.org/protobuf/internal/encoding/messageset"
+	"google.golang.org/protobuf/internal/encoding/text"
+	"google.golang.org/protobuf/internal/errors"
+	"google.golang.org/protobuf/internal/fieldnum"
+	"google.golang.org/protobuf/internal/flags"
+	"google.golang.org/protobuf/internal/pragma"
+	"google.golang.org/protobuf/internal/set"
+	"google.golang.org/protobuf/proto"
+	pref "google.golang.org/protobuf/reflect/protoreflect"
+	"google.golang.org/protobuf/reflect/protoregistry"
+)
+
+// Unmarshal reads the given []byte into the given proto.Message.
+func Unmarshal(b []byte, m proto.Message) error {
+	return UnmarshalOptions{}.Unmarshal(b, m)
+}
+
+// UnmarshalOptions is a configurable textproto format unmarshaler.
+type UnmarshalOptions struct {
+	pragma.NoUnkeyedLiterals
+
+	// AllowPartial accepts input for messages that will result in missing
+	// required fields. If AllowPartial is false (the default), Unmarshal will
+	// return error if there are any missing required fields.
+	AllowPartial bool
+
+	// DiscardUnknown specifies whether to ignore unknown fields when parsing.
+	// An unknown field is any field whose field name or field number does not
+	// resolve to any known or extension field in the message.
+	// By default, unmarshal rejects unknown fields as an error.
+	DiscardUnknown bool
+
+	// Resolver is used for looking up types when unmarshaling
+	// google.protobuf.Any messages or extension fields.
+	// If nil, this defaults to using protoregistry.GlobalTypes.
+	Resolver interface {
+		protoregistry.MessageTypeResolver
+		protoregistry.ExtensionTypeResolver
+	}
+}
+
+// Unmarshal reads the given []byte and populates the given proto.Message using options in
+// UnmarshalOptions object.
+func (o UnmarshalOptions) Unmarshal(b []byte, m proto.Message) error {
+	proto.Reset(m)
+
+	if o.Resolver == nil {
+		o.Resolver = protoregistry.GlobalTypes
+	}
+
+	dec := decoder{text.NewDecoder(b), o}
+	if err := dec.unmarshalMessage(m.ProtoReflect(), false); err != nil {
+		return err
+	}
+	if o.AllowPartial {
+		return nil
+	}
+	return proto.CheckInitialized(m)
+}
+
+type decoder struct {
+	*text.Decoder
+	opts UnmarshalOptions
+}
+
+// newError returns an error object with position info.
+func (d decoder) newError(pos int, f string, x ...interface{}) error {
+	line, column := d.Position(pos)
+	head := fmt.Sprintf("(line %d:%d): ", line, column)
+	return errors.New(head+f, x...)
+}
+
+// unexpectedTokenError returns a syntax error for the given unexpected token.
+func (d decoder) unexpectedTokenError(tok text.Token) error {
+	return d.syntaxError(tok.Pos(), "unexpected token: %s", tok.RawString())
+}
+
+// syntaxError returns a syntax error for given position.
+func (d decoder) syntaxError(pos int, f string, x ...interface{}) error {
+	line, column := d.Position(pos)
+	head := fmt.Sprintf("syntax error (line %d:%d): ", line, column)
+	return errors.New(head+f, x...)
+}
+
+// unmarshalMessage unmarshals into the given protoreflect.Message.
+func (d decoder) unmarshalMessage(m pref.Message, checkDelims bool) error {
+	messageDesc := m.Descriptor()
+	if !flags.ProtoLegacy && messageset.IsMessageSet(messageDesc) {
+		return errors.New("no support for proto1 MessageSets")
+	}
+
+	if messageDesc.FullName() == "google.protobuf.Any" {
+		return d.unmarshalAny(m, checkDelims)
+	}
+
+	if checkDelims {
+		tok, err := d.Read()
+		if err != nil {
+			return err
+		}
+
+		if tok.Kind() != text.MessageOpen {
+			return d.unexpectedTokenError(tok)
+		}
+	}
+
+	var seenNums set.Ints
+	var seenOneofs set.Ints
+	fieldDescs := messageDesc.Fields()
+
+	for {
+		// Read field name.
+		tok, err := d.Read()
+		if err != nil {
+			return err
+		}
+		switch typ := tok.Kind(); typ {
+		case text.Name:
+			// Continue below.
+		case text.EOF:
+			if checkDelims {
+				return text.ErrUnexpectedEOF
+			}
+			return nil
+		default:
+			if checkDelims && typ == text.MessageClose {
+				return nil
+			}
+			return d.unexpectedTokenError(tok)
+		}
+
+		// Resolve the field descriptor.
+		var name pref.Name
+		var fd pref.FieldDescriptor
+		var xt pref.ExtensionType
+		var xtErr error
+		var isFieldNumberName bool
+
+		switch tok.NameKind() {
+		case text.IdentName:
+			name = pref.Name(tok.IdentName())
+			fd = fieldDescs.ByName(name)
+			if fd == nil {
+				// The proto name of a group field is in all lowercase,
+				// while the textproto field name is the group message name.
+				gd := fieldDescs.ByName(pref.Name(strings.ToLower(string(name))))
+				if gd != nil && gd.Kind() == pref.GroupKind && gd.Message().Name() == name {
+					fd = gd
+				}
+			} else if fd.Kind() == pref.GroupKind && fd.Message().Name() != name {
+				fd = nil // reset since field name is actually the message name
+			}
+
+		case text.TypeName:
+			// Handle extensions only. This code path is not for Any.
+			xt, xtErr = d.findExtension(pref.FullName(tok.TypeName()))
+
+		case text.FieldNumber:
+			isFieldNumberName = true
+			num := pref.FieldNumber(tok.FieldNumber())
+			if !num.IsValid() {
+				return d.newError(tok.Pos(), "invalid field number: %d", num)
+			}
+			fd = fieldDescs.ByNumber(num)
+			if fd == nil {
+				xt, xtErr = d.opts.Resolver.FindExtensionByNumber(messageDesc.FullName(), num)
+			}
+		}
+
+		if xt != nil {
+			fd = xt.TypeDescriptor()
+			if !messageDesc.ExtensionRanges().Has(fd.Number()) || fd.ContainingMessage().FullName() != messageDesc.FullName() {
+				return d.newError(tok.Pos(), "message %v cannot be extended by %v", messageDesc.FullName(), fd.FullName())
+			}
+		} else if xtErr != nil && xtErr != protoregistry.NotFound {
+			return d.newError(tok.Pos(), "unable to resolve [%s]: %v", tok.RawString(), xtErr)
+		}
+		if flags.ProtoLegacy {
+			if fd != nil && fd.IsWeak() && fd.Message().IsPlaceholder() {
+				fd = nil // reset since the weak reference is not linked in
+			}
+		}
+
+		// Handle unknown fields.
+		if fd == nil {
+			if d.opts.DiscardUnknown || messageDesc.ReservedNames().Has(name) {
+				d.skipValue()
+				continue
+			}
+			return d.newError(tok.Pos(), "unknown field: %v", tok.RawString())
+		}
+
+		// Handle fields identified by field number.
+		if isFieldNumberName {
+			// TODO: Add an option to permit parsing field numbers.
+			//
+			// This requires careful thought as the MarshalOptions.EmitUnknown
+			// option allows formatting unknown fields as the field number and the
+			// best-effort textual representation of the field value.  In that case,
+			// it may not be possible to unmarshal the value from a parser that does
+			// have information about the unknown field.
+			return d.newError(tok.Pos(), "cannot specify field by number: %v", tok.RawString())
+		}
+
+		switch {
+		case fd.IsList():
+			kind := fd.Kind()
+			if kind != pref.MessageKind && kind != pref.GroupKind && !tok.HasSeparator() {
+				return d.syntaxError(tok.Pos(), "missing field separator :")
+			}
+
+			list := m.Mutable(fd).List()
+			if err := d.unmarshalList(fd, list); err != nil {
+				return err
+			}
+
+		case fd.IsMap():
+			mmap := m.Mutable(fd).Map()
+			if err := d.unmarshalMap(fd, mmap); err != nil {
+				return err
+			}
+
+		default:
+			kind := fd.Kind()
+			if kind != pref.MessageKind && kind != pref.GroupKind && !tok.HasSeparator() {
+				return d.syntaxError(tok.Pos(), "missing field separator :")
+			}
+
+			// If field is a oneof, check if it has already been set.
+			if od := fd.ContainingOneof(); od != nil {
+				idx := uint64(od.Index())
+				if seenOneofs.Has(idx) {
+					return d.newError(tok.Pos(), "error parsing %q, oneof %v is already set", tok.RawString(), od.FullName())
+				}
+				seenOneofs.Set(idx)
+			}
+
+			num := uint64(fd.Number())
+			if seenNums.Has(num) {
+				return d.newError(tok.Pos(), "non-repeated field %q is repeated", tok.RawString())
+			}
+
+			if err := d.unmarshalSingular(fd, m); err != nil {
+				return err
+			}
+			seenNums.Set(num)
+		}
+	}
+
+	return nil
+}
+
+// findExtension returns protoreflect.ExtensionType from the Resolver if found.
+func (d decoder) findExtension(xtName pref.FullName) (pref.ExtensionType, error) {
+	xt, err := d.opts.Resolver.FindExtensionByName(xtName)
+	if err == nil {
+		return xt, nil
+	}
+	return messageset.FindMessageSetExtension(d.opts.Resolver, xtName)
+}
+
+// unmarshalSingular unmarshals a non-repeated field value specified by the
+// given FieldDescriptor.
+func (d decoder) unmarshalSingular(fd pref.FieldDescriptor, m pref.Message) error {
+	var val pref.Value
+	var err error
+	switch fd.Kind() {
+	case pref.MessageKind, pref.GroupKind:
+		val = m.NewField(fd)
+		err = d.unmarshalMessage(val.Message(), true)
+	default:
+		val, err = d.unmarshalScalar(fd)
+	}
+	if err == nil {
+		m.Set(fd, val)
+	}
+	return err
+}
+
+// unmarshalScalar unmarshals a scalar/enum protoreflect.Value specified by the
+// given FieldDescriptor.
+func (d decoder) unmarshalScalar(fd pref.FieldDescriptor) (pref.Value, error) {
+	tok, err := d.Read()
+	if err != nil {
+		return pref.Value{}, err
+	}
+
+	if tok.Kind() != text.Scalar {
+		return pref.Value{}, d.unexpectedTokenError(tok)
+	}
+
+	kind := fd.Kind()
+	switch kind {
+	case pref.BoolKind:
+		if b, ok := tok.Bool(); ok {
+			return pref.ValueOfBool(b), nil
+		}
+
+	case pref.Int32Kind, pref.Sint32Kind, pref.Sfixed32Kind:
+		if n, ok := tok.Int32(); ok {
+			return pref.ValueOfInt32(n), nil
+		}
+
+	case pref.Int64Kind, pref.Sint64Kind, pref.Sfixed64Kind:
+		if n, ok := tok.Int64(); ok {
+			return pref.ValueOfInt64(n), nil
+		}
+
+	case pref.Uint32Kind, pref.Fixed32Kind:
+		if n, ok := tok.Uint32(); ok {
+			return pref.ValueOfUint32(n), nil
+		}
+
+	case pref.Uint64Kind, pref.Fixed64Kind:
+		if n, ok := tok.Uint64(); ok {
+			return pref.ValueOfUint64(n), nil
+		}
+
+	case pref.FloatKind:
+		if n, ok := tok.Float32(); ok {
+			return pref.ValueOfFloat32(n), nil
+		}
+
+	case pref.DoubleKind:
+		if n, ok := tok.Float64(); ok {
+			return pref.ValueOfFloat64(n), nil
+		}
+
+	case pref.StringKind:
+		if s, ok := tok.String(); ok {
+			if utf8.ValidString(s) {
+				return pref.ValueOfString(s), nil
+			}
+			return pref.Value{}, d.newError(tok.Pos(), "contains invalid UTF-8")
+		}
+
+	case pref.BytesKind:
+		if b, ok := tok.String(); ok {
+			return pref.ValueOfBytes([]byte(b)), nil
+		}
+
+	case pref.EnumKind:
+		if lit, ok := tok.Enum(); ok {
+			// Lookup EnumNumber based on name.
+			if enumVal := fd.Enum().Values().ByName(pref.Name(lit)); enumVal != nil {
+				return pref.ValueOfEnum(enumVal.Number()), nil
+			}
+		}
+		if num, ok := tok.Int32(); ok {
+			return pref.ValueOfEnum(pref.EnumNumber(num)), nil
+		}
+
+	default:
+		panic(fmt.Sprintf("invalid scalar kind %v", kind))
+	}
+
+	return pref.Value{}, d.newError(tok.Pos(), "invalid value for %v type: %v", kind, tok.RawString())
+}
+
+// unmarshalList unmarshals into given protoreflect.List. A list value can
+// either be in [] syntax or simply just a single scalar/message value.
+func (d decoder) unmarshalList(fd pref.FieldDescriptor, list pref.List) error {
+	tok, err := d.Peek()
+	if err != nil {
+		return err
+	}
+
+	switch fd.Kind() {
+	case pref.MessageKind, pref.GroupKind:
+		switch tok.Kind() {
+		case text.ListOpen:
+			d.Read()
+			for {
+				tok, err := d.Peek()
+				if err != nil {
+					return err
+				}
+
+				switch tok.Kind() {
+				case text.ListClose:
+					d.Read()
+					return nil
+				case text.MessageOpen:
+					pval := list.NewElement()
+					if err := d.unmarshalMessage(pval.Message(), true); err != nil {
+						return err
+					}
+					list.Append(pval)
+				default:
+					return d.unexpectedTokenError(tok)
+				}
+			}
+
+		case text.MessageOpen:
+			pval := list.NewElement()
+			if err := d.unmarshalMessage(pval.Message(), true); err != nil {
+				return err
+			}
+			list.Append(pval)
+			return nil
+		}
+
+	default:
+		switch tok.Kind() {
+		case text.ListOpen:
+			d.Read()
+			for {
+				tok, err := d.Peek()
+				if err != nil {
+					return err
+				}
+
+				switch tok.Kind() {
+				case text.ListClose:
+					d.Read()
+					return nil
+				case text.Scalar:
+					pval, err := d.unmarshalScalar(fd)
+					if err != nil {
+						return err
+					}
+					list.Append(pval)
+				default:
+					return d.unexpectedTokenError(tok)
+				}
+			}
+
+		case text.Scalar:
+			pval, err := d.unmarshalScalar(fd)
+			if err != nil {
+				return err
+			}
+			list.Append(pval)
+			return nil
+		}
+	}
+
+	return d.unexpectedTokenError(tok)
+}
+
+// unmarshalMap unmarshals into given protoreflect.Map. A map value is a
+// textproto message containing {key: <kvalue>, value: <mvalue>}.
+func (d decoder) unmarshalMap(fd pref.FieldDescriptor, mmap pref.Map) error {
+	// Determine ahead whether map entry is a scalar type or a message type in
+	// order to call the appropriate unmarshalMapValue func inside
+	// unmarshalMapEntry.
+	var unmarshalMapValue func() (pref.Value, error)
+	switch fd.MapValue().Kind() {
+	case pref.MessageKind, pref.GroupKind:
+		unmarshalMapValue = func() (pref.Value, error) {
+			pval := mmap.NewValue()
+			if err := d.unmarshalMessage(pval.Message(), true); err != nil {
+				return pref.Value{}, err
+			}
+			return pval, nil
+		}
+	default:
+		unmarshalMapValue = func() (pref.Value, error) {
+			return d.unmarshalScalar(fd.MapValue())
+		}
+	}
+
+	tok, err := d.Read()
+	if err != nil {
+		return err
+	}
+	switch tok.Kind() {
+	case text.MessageOpen:
+		return d.unmarshalMapEntry(fd, mmap, unmarshalMapValue)
+
+	case text.ListOpen:
+		for {
+			tok, err := d.Read()
+			if err != nil {
+				return err
+			}
+			switch tok.Kind() {
+			case text.ListClose:
+				return nil
+			case text.MessageOpen:
+				if err := d.unmarshalMapEntry(fd, mmap, unmarshalMapValue); err != nil {
+					return err
+				}
+			default:
+				return d.unexpectedTokenError(tok)
+			}
+		}
+
+	default:
+		return d.unexpectedTokenError(tok)
+	}
+}
+
+// unmarshalMap unmarshals into given protoreflect.Map. A map value is a
+// textproto message containing {key: <kvalue>, value: <mvalue>}.
+func (d decoder) unmarshalMapEntry(fd pref.FieldDescriptor, mmap pref.Map, unmarshalMapValue func() (pref.Value, error)) error {
+	var key pref.MapKey
+	var pval pref.Value
+Loop:
+	for {
+		// Read field name.
+		tok, err := d.Read()
+		if err != nil {
+			return err
+		}
+		switch tok.Kind() {
+		case text.Name:
+			if tok.NameKind() != text.IdentName {
+				if !d.opts.DiscardUnknown {
+					return d.newError(tok.Pos(), "unknown map entry field %q", tok.RawString())
+				}
+				d.skipValue()
+				continue Loop
+			}
+			// Continue below.
+		case text.MessageClose:
+			break Loop
+		default:
+			return d.unexpectedTokenError(tok)
+		}
+
+		name := tok.IdentName()
+		switch name {
+		case "key":
+			if !tok.HasSeparator() {
+				return d.syntaxError(tok.Pos(), "missing field separator :")
+			}
+			if key.IsValid() {
+				return d.newError(tok.Pos(), `map entry "key" cannot be repeated`)
+			}
+			val, err := d.unmarshalScalar(fd.MapKey())
+			if err != nil {
+				return err
+			}
+			key = val.MapKey()
+
+		case "value":
+			if kind := fd.MapValue().Kind(); (kind != pref.MessageKind) && (kind != pref.GroupKind) {
+				if !tok.HasSeparator() {
+					return d.syntaxError(tok.Pos(), "missing field separator :")
+				}
+			}
+			if pval.IsValid() {
+				return d.newError(tok.Pos(), `map entry "value" cannot be repeated`)
+			}
+			pval, err = unmarshalMapValue()
+			if err != nil {
+				return err
+			}
+
+		default:
+			if !d.opts.DiscardUnknown {
+				return d.newError(tok.Pos(), "unknown map entry field %q", name)
+			}
+			d.skipValue()
+		}
+	}
+
+	if !key.IsValid() {
+		key = fd.MapKey().Default().MapKey()
+	}
+	if !pval.IsValid() {
+		switch fd.MapValue().Kind() {
+		case pref.MessageKind, pref.GroupKind:
+			// If value field is not set for message/group types, construct an
+			// empty one as default.
+			pval = mmap.NewValue()
+		default:
+			pval = fd.MapValue().Default()
+		}
+	}
+	mmap.Set(key, pval)
+	return nil
+}
+
+// unmarshalAny unmarshals an Any textproto. It can either be in expanded form
+// or non-expanded form.
+func (d decoder) unmarshalAny(m pref.Message, checkDelims bool) error {
+	var typeURL string
+	var bValue []byte
+
+	// hasFields tracks which valid fields have been seen in the loop below in
+	// order to flag an error if there are duplicates or conflicts. It may
+	// contain the strings "type_url", "value" and "expanded".  The literal
+	// "expanded" is used to indicate that the expanded form has been
+	// encountered already.
+	hasFields := map[string]bool{}
+
+	if checkDelims {
+		tok, err := d.Read()
+		if err != nil {
+			return err
+		}
+
+		if tok.Kind() != text.MessageOpen {
+			return d.unexpectedTokenError(tok)
+		}
+	}
+
+Loop:
+	for {
+		// Read field name. Can only have 3 possible field names, i.e. type_url,
+		// value and type URL name inside [].
+		tok, err := d.Read()
+		if err != nil {
+			return err
+		}
+		if typ := tok.Kind(); typ != text.Name {
+			if checkDelims {
+				if typ == text.MessageClose {
+					break Loop
+				}
+			} else if typ == text.EOF {
+				break Loop
+			}
+			return d.unexpectedTokenError(tok)
+		}
+
+		switch tok.NameKind() {
+		case text.IdentName:
+			// Both type_url and value fields require field separator :.
+			if !tok.HasSeparator() {
+				return d.syntaxError(tok.Pos(), "missing field separator :")
+			}
+
+			switch tok.IdentName() {
+			case "type_url":
+				if hasFields["type_url"] {
+					return d.newError(tok.Pos(), "duplicate Any type_url field")
+				}
+				if hasFields["expanded"] {
+					return d.newError(tok.Pos(), "conflict with [%s] field", typeURL)
+				}
+				tok, err := d.Read()
+				if err != nil {
+					return err
+				}
+				var ok bool
+				typeURL, ok = tok.String()
+				if !ok {
+					return d.newError(tok.Pos(), "invalid Any type_url: %v", tok.RawString())
+				}
+				hasFields["type_url"] = true
+
+			case "value":
+				if hasFields["value"] {
+					return d.newError(tok.Pos(), "duplicate Any value field")
+				}
+				if hasFields["expanded"] {
+					return d.newError(tok.Pos(), "conflict with [%s] field", typeURL)
+				}
+				tok, err := d.Read()
+				if err != nil {
+					return err
+				}
+				s, ok := tok.String()
+				if !ok {
+					return d.newError(tok.Pos(), "invalid Any value: %v", tok.RawString())
+				}
+				bValue = []byte(s)
+				hasFields["value"] = true
+
+			default:
+				if !d.opts.DiscardUnknown {
+					return d.newError(tok.Pos(), "invalid field name %q in google.protobuf.Any message", tok.RawString())
+				}
+			}
+
+		case text.TypeName:
+			if hasFields["expanded"] {
+				return d.newError(tok.Pos(), "cannot have more than one type")
+			}
+			if hasFields["type_url"] {
+				return d.newError(tok.Pos(), "conflict with type_url field")
+			}
+			typeURL = tok.TypeName()
+			var err error
+			bValue, err = d.unmarshalExpandedAny(typeURL, tok.Pos())
+			if err != nil {
+				return err
+			}
+			hasFields["expanded"] = true
+
+		default:
+			if !d.opts.DiscardUnknown {
+				return d.newError(tok.Pos(), "invalid field name %q in google.protobuf.Any message", tok.RawString())
+			}
+		}
+	}
+
+	fds := m.Descriptor().Fields()
+	if len(typeURL) > 0 {
+		m.Set(fds.ByNumber(fieldnum.Any_TypeUrl), pref.ValueOfString(typeURL))
+	}
+	if len(bValue) > 0 {
+		m.Set(fds.ByNumber(fieldnum.Any_Value), pref.ValueOfBytes(bValue))
+	}
+	return nil
+}
+
+func (d decoder) unmarshalExpandedAny(typeURL string, pos int) ([]byte, error) {
+	mt, err := d.opts.Resolver.FindMessageByURL(typeURL)
+	if err != nil {
+		return nil, d.newError(pos, "unable to resolve message [%v]: %v", typeURL, err)
+	}
+	// Create new message for the embedded message type and unmarshal the value
+	// field into it.
+	m := mt.New()
+	if err := d.unmarshalMessage(m, true); err != nil {
+		return nil, err
+	}
+	// Serialize the embedded message and return the resulting bytes.
+	b, err := proto.MarshalOptions{
+		AllowPartial:  true, // Never check required fields inside an Any.
+		Deterministic: true,
+	}.Marshal(m.Interface())
+	if err != nil {
+		return nil, d.newError(pos, "error in marshaling message into Any.value: %v", err)
+	}
+	return b, nil
+}
+
+// skipValue makes the decoder parse a field value in order to advance the read
+// to the next field. It relies on Read returning an error if the types are not
+// in valid sequence.
+func (d decoder) skipValue() error {
+	tok, err := d.Read()
+	if err != nil {
+		return err
+	}
+	// Only need to continue reading for messages and lists.
+	switch tok.Kind() {
+	case text.MessageOpen:
+		return d.skipMessageValue()
+
+	case text.ListOpen:
+		for {
+			tok, err := d.Read()
+			if err != nil {
+				return err
+			}
+			switch tok.Kind() {
+			case text.ListClose:
+				return nil
+			case text.MessageOpen:
+				return d.skipMessageValue()
+			default:
+				// Skip items. This will not validate whether skipped values are
+				// of the same type or not, same behavior as C++
+				// TextFormat::Parser::AllowUnknownField(true) version 3.8.0.
+				if err := d.skipValue(); err != nil {
+					return err
+				}
+			}
+		}
+	}
+	return nil
+}
+
+// skipMessageValue makes the decoder parse and skip over all fields in a
+// message. It assumes that the previous read type is MessageOpen.
+func (d decoder) skipMessageValue() error {
+	for {
+		tok, err := d.Read()
+		if err != nil {
+			return err
+		}
+		switch tok.Kind() {
+		case text.MessageClose:
+			return nil
+		case text.Name:
+			if err := d.skipValue(); err != nil {
+				return err
+			}
+		}
+	}
+}
diff --git a/demo_test/vendor/google.golang.org/protobuf/encoding/prototext/doc.go b/demo_test/vendor/google.golang.org/protobuf/encoding/prototext/doc.go
new file mode 100644
index 0000000..162b4f9
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/encoding/prototext/doc.go
@@ -0,0 +1,7 @@
+// 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 prototext marshals and unmarshals protocol buffer messages as the
+// textproto format.
+package prototext
diff --git a/demo_test/vendor/google.golang.org/protobuf/encoding/prototext/encode.go b/demo_test/vendor/google.golang.org/protobuf/encoding/prototext/encode.go
new file mode 100644
index 0000000..83b65a6
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/encoding/prototext/encode.go
@@ -0,0 +1,410 @@
+// 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 prototext
+
+import (
+	"fmt"
+	"sort"
+	"strconv"
+	"unicode/utf8"
+
+	"google.golang.org/protobuf/encoding/protowire"
+	"google.golang.org/protobuf/internal/encoding/messageset"
+	"google.golang.org/protobuf/internal/encoding/text"
+	"google.golang.org/protobuf/internal/errors"
+	"google.golang.org/protobuf/internal/fieldnum"
+	"google.golang.org/protobuf/internal/flags"
+	"google.golang.org/protobuf/internal/mapsort"
+	"google.golang.org/protobuf/internal/pragma"
+	"google.golang.org/protobuf/proto"
+	pref "google.golang.org/protobuf/reflect/protoreflect"
+	"google.golang.org/protobuf/reflect/protoregistry"
+)
+
+const defaultIndent = "  "
+
+// Format formats the message as a multiline string.
+// This function is only intended for human consumption and ignores errors.
+// Do not depend on the output being stable. It may change over time across
+// different versions of the program.
+func Format(m proto.Message) string {
+	return MarshalOptions{Multiline: true}.Format(m)
+}
+
+// Marshal writes the given proto.Message in textproto format using default
+// options. Do not depend on the output being stable. It may change over time
+// across different versions of the program.
+func Marshal(m proto.Message) ([]byte, error) {
+	return MarshalOptions{}.Marshal(m)
+}
+
+// MarshalOptions is a configurable text format marshaler.
+type MarshalOptions struct {
+	pragma.NoUnkeyedLiterals
+
+	// Multiline specifies whether the marshaler should format the output in
+	// indented-form with every textual element on a new line.
+	// If Indent is an empty string, then an arbitrary indent is chosen.
+	Multiline bool
+
+	// Indent specifies the set of indentation characters to use in a multiline
+	// formatted output such that every entry is preceded by Indent and
+	// terminated by a newline. If non-empty, then Multiline is treated as true.
+	// Indent can only be composed of space or tab characters.
+	Indent string
+
+	// AllowPartial allows messages that have missing required fields to marshal
+	// without returning an error. If AllowPartial is false (the default),
+	// Marshal will return error if there are any missing required fields.
+	AllowPartial bool
+
+	// EmitUnknown specifies whether to emit unknown fields in the output.
+	// If specified, the unmarshaler may be unable to parse the output.
+	// The default is to exclude unknown fields.
+	EmitUnknown bool
+
+	// Resolver is used for looking up types when expanding google.protobuf.Any
+	// messages. If nil, this defaults to using protoregistry.GlobalTypes.
+	Resolver interface {
+		protoregistry.ExtensionTypeResolver
+		protoregistry.MessageTypeResolver
+	}
+}
+
+// Format formats the message as a string.
+// This method is only intended for human consumption and ignores errors.
+// Do not depend on the output being stable. It may change over time across
+// different versions of the program.
+func (o MarshalOptions) Format(m proto.Message) string {
+	if m == nil || !m.ProtoReflect().IsValid() {
+		return "<nil>" // invalid syntax, but okay since this is for debugging
+	}
+	o.AllowPartial = true
+	o.EmitUnknown = true
+	b, _ := o.Marshal(m)
+	return string(b)
+}
+
+// Marshal writes the given proto.Message in textproto format using options in
+// MarshalOptions object. Do not depend on the output being stable. It may
+// change over time across different versions of the program.
+func (o MarshalOptions) Marshal(m proto.Message) ([]byte, error) {
+	const outputASCII = false
+	var delims = [2]byte{'{', '}'}
+
+	if o.Multiline && o.Indent == "" {
+		o.Indent = defaultIndent
+	}
+	if o.Resolver == nil {
+		o.Resolver = protoregistry.GlobalTypes
+	}
+
+	internalEnc, err := text.NewEncoder(o.Indent, delims, outputASCII)
+	if err != nil {
+		return nil, err
+	}
+
+	enc := encoder{internalEnc, o}
+	err = enc.marshalMessage(m.ProtoReflect(), false)
+	if err != nil {
+		return nil, err
+	}
+	out := enc.Bytes()
+	if len(o.Indent) > 0 && len(out) > 0 {
+		out = append(out, '\n')
+	}
+	if o.AllowPartial {
+		return out, nil
+	}
+	return out, proto.CheckInitialized(m)
+}
+
+type encoder struct {
+	*text.Encoder
+	opts MarshalOptions
+}
+
+// marshalMessage marshals the given protoreflect.Message.
+func (e encoder) marshalMessage(m pref.Message, inclDelims bool) error {
+	messageDesc := m.Descriptor()
+	if !flags.ProtoLegacy && messageset.IsMessageSet(messageDesc) {
+		return errors.New("no support for proto1 MessageSets")
+	}
+
+	if inclDelims {
+		e.StartMessage()
+		defer e.EndMessage()
+	}
+
+	// Handle Any expansion.
+	if messageDesc.FullName() == "google.protobuf.Any" {
+		if e.marshalAny(m) {
+			return nil
+		}
+		// If unable to expand, continue on to marshal Any as a regular message.
+	}
+
+	// Marshal known fields.
+	fieldDescs := messageDesc.Fields()
+	size := fieldDescs.Len()
+	for i := 0; i < size; {
+		fd := fieldDescs.Get(i)
+		if od := fd.ContainingOneof(); od != nil {
+			fd = m.WhichOneof(od)
+			i += od.Fields().Len()
+		} else {
+			i++
+		}
+
+		if fd == nil || !m.Has(fd) {
+			continue
+		}
+
+		name := fd.Name()
+		// Use type name for group field name.
+		if fd.Kind() == pref.GroupKind {
+			name = fd.Message().Name()
+		}
+		val := m.Get(fd)
+		if err := e.marshalField(string(name), val, fd); err != nil {
+			return err
+		}
+	}
+
+	// Marshal extensions.
+	if err := e.marshalExtensions(m); err != nil {
+		return err
+	}
+
+	// Marshal unknown fields.
+	if e.opts.EmitUnknown {
+		e.marshalUnknown(m.GetUnknown())
+	}
+
+	return nil
+}
+
+// marshalField marshals the given field with protoreflect.Value.
+func (e encoder) marshalField(name string, val pref.Value, fd pref.FieldDescriptor) error {
+	switch {
+	case fd.IsList():
+		return e.marshalList(name, val.List(), fd)
+	case fd.IsMap():
+		return e.marshalMap(name, val.Map(), fd)
+	default:
+		e.WriteName(name)
+		return e.marshalSingular(val, fd)
+	}
+}
+
+// marshalSingular marshals the given non-repeated field value. This includes
+// all scalar types, enums, messages, and groups.
+func (e encoder) marshalSingular(val pref.Value, fd pref.FieldDescriptor) error {
+	kind := fd.Kind()
+	switch kind {
+	case pref.BoolKind:
+		e.WriteBool(val.Bool())
+
+	case pref.StringKind:
+		s := val.String()
+		if !utf8.ValidString(s) {
+			return errors.InvalidUTF8(string(fd.FullName()))
+		}
+		e.WriteString(s)
+
+	case pref.Int32Kind, pref.Int64Kind,
+		pref.Sint32Kind, pref.Sint64Kind,
+		pref.Sfixed32Kind, pref.Sfixed64Kind:
+		e.WriteInt(val.Int())
+
+	case pref.Uint32Kind, pref.Uint64Kind,
+		pref.Fixed32Kind, pref.Fixed64Kind:
+		e.WriteUint(val.Uint())
+
+	case pref.FloatKind:
+		// Encoder.WriteFloat handles the special numbers NaN and infinites.
+		e.WriteFloat(val.Float(), 32)
+
+	case pref.DoubleKind:
+		// Encoder.WriteFloat handles the special numbers NaN and infinites.
+		e.WriteFloat(val.Float(), 64)
+
+	case pref.BytesKind:
+		e.WriteString(string(val.Bytes()))
+
+	case pref.EnumKind:
+		num := val.Enum()
+		if desc := fd.Enum().Values().ByNumber(num); desc != nil {
+			e.WriteLiteral(string(desc.Name()))
+		} else {
+			// Use numeric value if there is no enum description.
+			e.WriteInt(int64(num))
+		}
+
+	case pref.MessageKind, pref.GroupKind:
+		return e.marshalMessage(val.Message(), true)
+
+	default:
+		panic(fmt.Sprintf("%v has unknown kind: %v", fd.FullName(), kind))
+	}
+	return nil
+}
+
+// marshalList marshals the given protoreflect.List as multiple name-value fields.
+func (e encoder) marshalList(name string, list pref.List, fd pref.FieldDescriptor) error {
+	size := list.Len()
+	for i := 0; i < size; i++ {
+		e.WriteName(name)
+		if err := e.marshalSingular(list.Get(i), fd); err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+// marshalMap marshals the given protoreflect.Map as multiple name-value fields.
+func (e encoder) marshalMap(name string, mmap pref.Map, fd pref.FieldDescriptor) error {
+	var err error
+	mapsort.Range(mmap, fd.MapKey().Kind(), func(key pref.MapKey, val pref.Value) bool {
+		e.WriteName(name)
+		e.StartMessage()
+		defer e.EndMessage()
+
+		e.WriteName("key")
+		err = e.marshalSingular(key.Value(), fd.MapKey())
+		if err != nil {
+			return false
+		}
+
+		e.WriteName("value")
+		err = e.marshalSingular(val, fd.MapValue())
+		if err != nil {
+			return false
+		}
+		return true
+	})
+	return err
+}
+
+// marshalExtensions marshals extension fields.
+func (e encoder) marshalExtensions(m pref.Message) error {
+	type entry struct {
+		key   string
+		value pref.Value
+		desc  pref.FieldDescriptor
+	}
+
+	// Get a sorted list based on field key first.
+	var entries []entry
+	m.Range(func(fd pref.FieldDescriptor, v pref.Value) bool {
+		if !fd.IsExtension() {
+			return true
+		}
+		// For MessageSet extensions, the name used is the parent message.
+		name := fd.FullName()
+		if messageset.IsMessageSetExtension(fd) {
+			name = name.Parent()
+		}
+		entries = append(entries, entry{
+			key:   string(name),
+			value: v,
+			desc:  fd,
+		})
+		return true
+	})
+	// Sort extensions lexicographically.
+	sort.Slice(entries, func(i, j int) bool {
+		return entries[i].key < entries[j].key
+	})
+
+	// Write out sorted list.
+	for _, entry := range entries {
+		// Extension field name is the proto field name enclosed in [].
+		name := "[" + entry.key + "]"
+		if err := e.marshalField(name, entry.value, entry.desc); err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+// marshalUnknown parses the given []byte and marshals fields out.
+// This function assumes proper encoding in the given []byte.
+func (e encoder) marshalUnknown(b []byte) {
+	const dec = 10
+	const hex = 16
+	for len(b) > 0 {
+		num, wtype, n := protowire.ConsumeTag(b)
+		b = b[n:]
+		e.WriteName(strconv.FormatInt(int64(num), dec))
+
+		switch wtype {
+		case protowire.VarintType:
+			var v uint64
+			v, n = protowire.ConsumeVarint(b)
+			e.WriteUint(v)
+		case protowire.Fixed32Type:
+			var v uint32
+			v, n = protowire.ConsumeFixed32(b)
+			e.WriteLiteral("0x" + strconv.FormatUint(uint64(v), hex))
+		case protowire.Fixed64Type:
+			var v uint64
+			v, n = protowire.ConsumeFixed64(b)
+			e.WriteLiteral("0x" + strconv.FormatUint(v, hex))
+		case protowire.BytesType:
+			var v []byte
+			v, n = protowire.ConsumeBytes(b)
+			e.WriteString(string(v))
+		case protowire.StartGroupType:
+			e.StartMessage()
+			var v []byte
+			v, n = protowire.ConsumeGroup(num, b)
+			e.marshalUnknown(v)
+			e.EndMessage()
+		default:
+			panic(fmt.Sprintf("prototext: error parsing unknown field wire type: %v", wtype))
+		}
+
+		b = b[n:]
+	}
+}
+
+// marshalAny marshals the given google.protobuf.Any message in expanded form.
+// It returns true if it was able to marshal, else false.
+func (e encoder) marshalAny(any pref.Message) bool {
+	// Construct the embedded message.
+	fds := any.Descriptor().Fields()
+	fdType := fds.ByNumber(fieldnum.Any_TypeUrl)
+	typeURL := any.Get(fdType).String()
+	mt, err := e.opts.Resolver.FindMessageByURL(typeURL)
+	if err != nil {
+		return false
+	}
+	m := mt.New().Interface()
+
+	// Unmarshal bytes into embedded message.
+	fdValue := fds.ByNumber(fieldnum.Any_Value)
+	value := any.Get(fdValue)
+	err = proto.UnmarshalOptions{
+		AllowPartial: true,
+		Resolver:     e.opts.Resolver,
+	}.Unmarshal(value.Bytes(), m)
+	if err != nil {
+		return false
+	}
+
+	// Get current encoder position. If marshaling fails, reset encoder output
+	// back to this position.
+	pos := e.Snapshot()
+
+	// Field name is the proto field name enclosed in [].
+	e.WriteName("[" + typeURL + "]")
+	err = e.marshalMessage(m.ProtoReflect(), true)
+	if err != nil {
+		e.Reset(pos)
+		return false
+	}
+	return true
+}
diff --git a/demo_test/vendor/google.golang.org/protobuf/encoding/protowire/wire.go b/demo_test/vendor/google.golang.org/protobuf/encoding/protowire/wire.go
new file mode 100644
index 0000000..a427f8b
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/encoding/protowire/wire.go
@@ -0,0 +1,538 @@
+// 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 protowire parses and formats the raw wire encoding.
+// See https://developers.google.com/protocol-buffers/docs/encoding.
+//
+// For marshaling and unmarshaling entire protobuf messages,
+// use the "google.golang.org/protobuf/proto" package instead.
+package protowire
+
+import (
+	"io"
+	"math"
+	"math/bits"
+
+	"google.golang.org/protobuf/internal/errors"
+)
+
+// Number represents the field number.
+type Number int32
+
+const (
+	MinValidNumber      Number = 1
+	FirstReservedNumber Number = 19000
+	LastReservedNumber  Number = 19999
+	MaxValidNumber      Number = 1<<29 - 1
+)
+
+// IsValid reports whether the field number is semantically valid.
+//
+// Note that while numbers within the reserved range are semantically invalid,
+// they are syntactically valid in the wire format.
+// Implementations may treat records with reserved field numbers as unknown.
+func (n Number) IsValid() bool {
+	return MinValidNumber <= n && n < FirstReservedNumber || LastReservedNumber < n && n <= MaxValidNumber
+}
+
+// Type represents the wire type.
+type Type int8
+
+const (
+	VarintType     Type = 0
+	Fixed32Type    Type = 5
+	Fixed64Type    Type = 1
+	BytesType      Type = 2
+	StartGroupType Type = 3
+	EndGroupType   Type = 4
+)
+
+const (
+	_ = -iota
+	errCodeTruncated
+	errCodeFieldNumber
+	errCodeOverflow
+	errCodeReserved
+	errCodeEndGroup
+)
+
+var (
+	errFieldNumber = errors.New("invalid field number")
+	errOverflow    = errors.New("variable length integer overflow")
+	errReserved    = errors.New("cannot parse reserved wire type")
+	errEndGroup    = errors.New("mismatching end group marker")
+	errParse       = errors.New("parse error")
+)
+
+// ParseError converts an error code into an error value.
+// This returns nil if n is a non-negative number.
+func ParseError(n int) error {
+	if n >= 0 {
+		return nil
+	}
+	switch n {
+	case errCodeTruncated:
+		return io.ErrUnexpectedEOF
+	case errCodeFieldNumber:
+		return errFieldNumber
+	case errCodeOverflow:
+		return errOverflow
+	case errCodeReserved:
+		return errReserved
+	case errCodeEndGroup:
+		return errEndGroup
+	default:
+		return errParse
+	}
+}
+
+// ConsumeField parses an entire field record (both tag and value) and returns
+// the field number, the wire type, and the total length.
+// This returns a negative length upon an error (see ParseError).
+//
+// The total length includes the tag header and the end group marker (if the
+// field is a group).
+func ConsumeField(b []byte) (Number, Type, int) {
+	num, typ, n := ConsumeTag(b)
+	if n < 0 {
+		return 0, 0, n // forward error code
+	}
+	m := ConsumeFieldValue(num, typ, b[n:])
+	if m < 0 {
+		return 0, 0, m // forward error code
+	}
+	return num, typ, n + m
+}
+
+// ConsumeFieldValue parses a field value and returns its length.
+// This assumes that the field Number and wire Type have already been parsed.
+// This returns a negative length upon an error (see ParseError).
+//
+// When parsing a group, the length includes the end group marker and
+// the end group is verified to match the starting field number.
+func ConsumeFieldValue(num Number, typ Type, b []byte) (n int) {
+	switch typ {
+	case VarintType:
+		_, n = ConsumeVarint(b)
+		return n
+	case Fixed32Type:
+		_, n = ConsumeFixed32(b)
+		return n
+	case Fixed64Type:
+		_, n = ConsumeFixed64(b)
+		return n
+	case BytesType:
+		_, n = ConsumeBytes(b)
+		return n
+	case StartGroupType:
+		n0 := len(b)
+		for {
+			num2, typ2, n := ConsumeTag(b)
+			if n < 0 {
+				return n // forward error code
+			}
+			b = b[n:]
+			if typ2 == EndGroupType {
+				if num != num2 {
+					return errCodeEndGroup
+				}
+				return n0 - len(b)
+			}
+
+			n = ConsumeFieldValue(num2, typ2, b)
+			if n < 0 {
+				return n // forward error code
+			}
+			b = b[n:]
+		}
+	case EndGroupType:
+		return errCodeEndGroup
+	default:
+		return errCodeReserved
+	}
+}
+
+// AppendTag encodes num and typ as a varint-encoded tag and appends it to b.
+func AppendTag(b []byte, num Number, typ Type) []byte {
+	return AppendVarint(b, EncodeTag(num, typ))
+}
+
+// ConsumeTag parses b as a varint-encoded tag, reporting its length.
+// This returns a negative length upon an error (see ParseError).
+func ConsumeTag(b []byte) (Number, Type, int) {
+	v, n := ConsumeVarint(b)
+	if n < 0 {
+		return 0, 0, n // forward error code
+	}
+	num, typ := DecodeTag(v)
+	if num < MinValidNumber {
+		return 0, 0, errCodeFieldNumber
+	}
+	return num, typ, n
+}
+
+func SizeTag(num Number) int {
+	return SizeVarint(EncodeTag(num, 0)) // wire type has no effect on size
+}
+
+// AppendVarint appends v to b as a varint-encoded uint64.
+func AppendVarint(b []byte, v uint64) []byte {
+	switch {
+	case v < 1<<7:
+		b = append(b, byte(v))
+	case v < 1<<14:
+		b = append(b,
+			byte((v>>0)&0x7f|0x80),
+			byte(v>>7))
+	case v < 1<<21:
+		b = append(b,
+			byte((v>>0)&0x7f|0x80),
+			byte((v>>7)&0x7f|0x80),
+			byte(v>>14))
+	case v < 1<<28:
+		b = append(b,
+			byte((v>>0)&0x7f|0x80),
+			byte((v>>7)&0x7f|0x80),
+			byte((v>>14)&0x7f|0x80),
+			byte(v>>21))
+	case v < 1<<35:
+		b = append(b,
+			byte((v>>0)&0x7f|0x80),
+			byte((v>>7)&0x7f|0x80),
+			byte((v>>14)&0x7f|0x80),
+			byte((v>>21)&0x7f|0x80),
+			byte(v>>28))
+	case v < 1<<42:
+		b = append(b,
+			byte((v>>0)&0x7f|0x80),
+			byte((v>>7)&0x7f|0x80),
+			byte((v>>14)&0x7f|0x80),
+			byte((v>>21)&0x7f|0x80),
+			byte((v>>28)&0x7f|0x80),
+			byte(v>>35))
+	case v < 1<<49:
+		b = append(b,
+			byte((v>>0)&0x7f|0x80),
+			byte((v>>7)&0x7f|0x80),
+			byte((v>>14)&0x7f|0x80),
+			byte((v>>21)&0x7f|0x80),
+			byte((v>>28)&0x7f|0x80),
+			byte((v>>35)&0x7f|0x80),
+			byte(v>>42))
+	case v < 1<<56:
+		b = append(b,
+			byte((v>>0)&0x7f|0x80),
+			byte((v>>7)&0x7f|0x80),
+			byte((v>>14)&0x7f|0x80),
+			byte((v>>21)&0x7f|0x80),
+			byte((v>>28)&0x7f|0x80),
+			byte((v>>35)&0x7f|0x80),
+			byte((v>>42)&0x7f|0x80),
+			byte(v>>49))
+	case v < 1<<63:
+		b = append(b,
+			byte((v>>0)&0x7f|0x80),
+			byte((v>>7)&0x7f|0x80),
+			byte((v>>14)&0x7f|0x80),
+			byte((v>>21)&0x7f|0x80),
+			byte((v>>28)&0x7f|0x80),
+			byte((v>>35)&0x7f|0x80),
+			byte((v>>42)&0x7f|0x80),
+			byte((v>>49)&0x7f|0x80),
+			byte(v>>56))
+	default:
+		b = append(b,
+			byte((v>>0)&0x7f|0x80),
+			byte((v>>7)&0x7f|0x80),
+			byte((v>>14)&0x7f|0x80),
+			byte((v>>21)&0x7f|0x80),
+			byte((v>>28)&0x7f|0x80),
+			byte((v>>35)&0x7f|0x80),
+			byte((v>>42)&0x7f|0x80),
+			byte((v>>49)&0x7f|0x80),
+			byte((v>>56)&0x7f|0x80),
+			1)
+	}
+	return b
+}
+
+// ConsumeVarint parses b as a varint-encoded uint64, reporting its length.
+// This returns a negative length upon an error (see ParseError).
+func ConsumeVarint(b []byte) (v uint64, n int) {
+	var y uint64
+	if len(b) <= 0 {
+		return 0, errCodeTruncated
+	}
+	v = uint64(b[0])
+	if v < 0x80 {
+		return v, 1
+	}
+	v -= 0x80
+
+	if len(b) <= 1 {
+		return 0, errCodeTruncated
+	}
+	y = uint64(b[1])
+	v += y << 7
+	if y < 0x80 {
+		return v, 2
+	}
+	v -= 0x80 << 7
+
+	if len(b) <= 2 {
+		return 0, errCodeTruncated
+	}
+	y = uint64(b[2])
+	v += y << 14
+	if y < 0x80 {
+		return v, 3
+	}
+	v -= 0x80 << 14
+
+	if len(b) <= 3 {
+		return 0, errCodeTruncated
+	}
+	y = uint64(b[3])
+	v += y << 21
+	if y < 0x80 {
+		return v, 4
+	}
+	v -= 0x80 << 21
+
+	if len(b) <= 4 {
+		return 0, errCodeTruncated
+	}
+	y = uint64(b[4])
+	v += y << 28
+	if y < 0x80 {
+		return v, 5
+	}
+	v -= 0x80 << 28
+
+	if len(b) <= 5 {
+		return 0, errCodeTruncated
+	}
+	y = uint64(b[5])
+	v += y << 35
+	if y < 0x80 {
+		return v, 6
+	}
+	v -= 0x80 << 35
+
+	if len(b) <= 6 {
+		return 0, errCodeTruncated
+	}
+	y = uint64(b[6])
+	v += y << 42
+	if y < 0x80 {
+		return v, 7
+	}
+	v -= 0x80 << 42
+
+	if len(b) <= 7 {
+		return 0, errCodeTruncated
+	}
+	y = uint64(b[7])
+	v += y << 49
+	if y < 0x80 {
+		return v, 8
+	}
+	v -= 0x80 << 49
+
+	if len(b) <= 8 {
+		return 0, errCodeTruncated
+	}
+	y = uint64(b[8])
+	v += y << 56
+	if y < 0x80 {
+		return v, 9
+	}
+	v -= 0x80 << 56
+
+	if len(b) <= 9 {
+		return 0, errCodeTruncated
+	}
+	y = uint64(b[9])
+	v += y << 63
+	if y < 2 {
+		return v, 10
+	}
+	return 0, errCodeOverflow
+}
+
+// SizeVarint returns the encoded size of a varint.
+// The size is guaranteed to be within 1 and 10, inclusive.
+func SizeVarint(v uint64) int {
+	// This computes 1 + (bits.Len64(v)-1)/7.
+	// 9/64 is a good enough approximation of 1/7
+	return int(9*uint32(bits.Len64(v))+64) / 64
+}
+
+// AppendFixed32 appends v to b as a little-endian uint32.
+func AppendFixed32(b []byte, v uint32) []byte {
+	return append(b,
+		byte(v>>0),
+		byte(v>>8),
+		byte(v>>16),
+		byte(v>>24))
+}
+
+// ConsumeFixed32 parses b as a little-endian uint32, reporting its length.
+// This returns a negative length upon an error (see ParseError).
+func ConsumeFixed32(b []byte) (v uint32, n int) {
+	if len(b) < 4 {
+		return 0, errCodeTruncated
+	}
+	v = uint32(b[0])<<0 | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24
+	return v, 4
+}
+
+// SizeFixed32 returns the encoded size of a fixed32; which is always 4.
+func SizeFixed32() int {
+	return 4
+}
+
+// AppendFixed64 appends v to b as a little-endian uint64.
+func AppendFixed64(b []byte, v uint64) []byte {
+	return append(b,
+		byte(v>>0),
+		byte(v>>8),
+		byte(v>>16),
+		byte(v>>24),
+		byte(v>>32),
+		byte(v>>40),
+		byte(v>>48),
+		byte(v>>56))
+}
+
+// ConsumeFixed64 parses b as a little-endian uint64, reporting its length.
+// This returns a negative length upon an error (see ParseError).
+func ConsumeFixed64(b []byte) (v uint64, n int) {
+	if len(b) < 8 {
+		return 0, errCodeTruncated
+	}
+	v = uint64(b[0])<<0 | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56
+	return v, 8
+}
+
+// SizeFixed64 returns the encoded size of a fixed64; which is always 8.
+func SizeFixed64() int {
+	return 8
+}
+
+// AppendBytes appends v to b as a length-prefixed bytes value.
+func AppendBytes(b []byte, v []byte) []byte {
+	return append(AppendVarint(b, uint64(len(v))), v...)
+}
+
+// ConsumeBytes parses b as a length-prefixed bytes value, reporting its length.
+// This returns a negative length upon an error (see ParseError).
+func ConsumeBytes(b []byte) (v []byte, n int) {
+	m, n := ConsumeVarint(b)
+	if n < 0 {
+		return nil, n // forward error code
+	}
+	if m > uint64(len(b[n:])) {
+		return nil, errCodeTruncated
+	}
+	return b[n:][:m], n + int(m)
+}
+
+// SizeBytes returns the encoded size of a length-prefixed bytes value,
+// given only the length.
+func SizeBytes(n int) int {
+	return SizeVarint(uint64(n)) + n
+}
+
+// AppendString appends v to b as a length-prefixed bytes value.
+func AppendString(b []byte, v string) []byte {
+	return append(AppendVarint(b, uint64(len(v))), v...)
+}
+
+// ConsumeString parses b as a length-prefixed bytes value, reporting its length.
+// This returns a negative length upon an error (see ParseError).
+func ConsumeString(b []byte) (v string, n int) {
+	bb, n := ConsumeBytes(b)
+	return string(bb), n
+}
+
+// AppendGroup appends v to b as group value, with a trailing end group marker.
+// The value v must not contain the end marker.
+func AppendGroup(b []byte, num Number, v []byte) []byte {
+	return AppendVarint(append(b, v...), EncodeTag(num, EndGroupType))
+}
+
+// ConsumeGroup parses b as a group value until the trailing end group marker,
+// and verifies that the end marker matches the provided num. The value v
+// does not contain the end marker, while the length does contain the end marker.
+// This returns a negative length upon an error (see ParseError).
+func ConsumeGroup(num Number, b []byte) (v []byte, n int) {
+	n = ConsumeFieldValue(num, StartGroupType, b)
+	if n < 0 {
+		return nil, n // forward error code
+	}
+	b = b[:n]
+
+	// Truncate off end group marker, but need to handle denormalized varints.
+	// Assuming end marker is never 0 (which is always the case since
+	// EndGroupType is non-zero), we can truncate all trailing bytes where the
+	// lower 7 bits are all zero (implying that the varint is denormalized).
+	for len(b) > 0 && b[len(b)-1]&0x7f == 0 {
+		b = b[:len(b)-1]
+	}
+	b = b[:len(b)-SizeTag(num)]
+	return b, n
+}
+
+// SizeGroup returns the encoded size of a group, given only the length.
+func SizeGroup(num Number, n int) int {
+	return n + SizeTag(num)
+}
+
+// DecodeTag decodes the field Number and wire Type from its unified form.
+// The Number is -1 if the decoded field number overflows int32.
+// Other than overflow, this does not check for field number validity.
+func DecodeTag(x uint64) (Number, Type) {
+	// NOTE: MessageSet allows for larger field numbers than normal.
+	if x>>3 > uint64(math.MaxInt32) {
+		return -1, 0
+	}
+	return Number(x >> 3), Type(x & 7)
+}
+
+// EncodeTag encodes the field Number and wire Type into its unified form.
+func EncodeTag(num Number, typ Type) uint64 {
+	return uint64(num)<<3 | uint64(typ&7)
+}
+
+// DecodeZigZag decodes a zig-zag-encoded uint64 as an int64.
+//	Input:  {…,  5,  3,  1,  0,  2,  4,  6, …}
+//	Output: {…, -3, -2, -1,  0, +1, +2, +3, …}
+func DecodeZigZag(x uint64) int64 {
+	return int64(x>>1) ^ int64(x)<<63>>63
+}
+
+// EncodeZigZag encodes an int64 as a zig-zag-encoded uint64.
+//	Input:  {…, -3, -2, -1,  0, +1, +2, +3, …}
+//	Output: {…,  5,  3,  1,  0,  2,  4,  6, …}
+func EncodeZigZag(x int64) uint64 {
+	return uint64(x<<1) ^ uint64(x>>63)
+}
+
+// DecodeBool decodes a uint64 as a bool.
+//	Input:  {    0,    1,    2, …}
+//	Output: {false, true, true, …}
+func DecodeBool(x uint64) bool {
+	return x != 0
+}
+
+// EncodeBool encodes a bool as a uint64.
+//	Input:  {false, true}
+//	Output: {    0,    1}
+func EncodeBool(x bool) uint64 {
+	if x {
+		return 1
+	}
+	return 0
+}
diff --git a/demo_test/vendor/google.golang.org/protobuf/internal/descfmt/stringer.go b/demo_test/vendor/google.golang.org/protobuf/internal/descfmt/stringer.go
new file mode 100644
index 0000000..4cb8d6d
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/internal/descfmt/stringer.go
@@ -0,0 +1,316 @@
+// 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 descfmt provides functionality to format descriptors.
+package descfmt
+
+import (
+	"fmt"
+	"io"
+	"reflect"
+	"strconv"
+	"strings"
+
+	"google.golang.org/protobuf/internal/detrand"
+	"google.golang.org/protobuf/internal/pragma"
+	pref "google.golang.org/protobuf/reflect/protoreflect"
+)
+
+type list interface {
+	Len() int
+	pragma.DoNotImplement
+}
+
+func FormatList(s fmt.State, r rune, vs list) {
+	io.WriteString(s, formatListOpt(vs, true, r == 'v' && (s.Flag('+') || s.Flag('#'))))
+}
+func formatListOpt(vs list, isRoot, allowMulti bool) string {
+	start, end := "[", "]"
+	if isRoot {
+		var name string
+		switch vs.(type) {
+		case pref.Names:
+			name = "Names"
+		case pref.FieldNumbers:
+			name = "FieldNumbers"
+		case pref.FieldRanges:
+			name = "FieldRanges"
+		case pref.EnumRanges:
+			name = "EnumRanges"
+		case pref.FileImports:
+			name = "FileImports"
+		case pref.Descriptor:
+			name = reflect.ValueOf(vs).MethodByName("Get").Type().Out(0).Name() + "s"
+		}
+		start, end = name+"{", "}"
+	}
+
+	var ss []string
+	switch vs := vs.(type) {
+	case pref.Names:
+		for i := 0; i < vs.Len(); i++ {
+			ss = append(ss, fmt.Sprint(vs.Get(i)))
+		}
+		return start + joinStrings(ss, false) + end
+	case pref.FieldNumbers:
+		for i := 0; i < vs.Len(); i++ {
+			ss = append(ss, fmt.Sprint(vs.Get(i)))
+		}
+		return start + joinStrings(ss, false) + end
+	case pref.FieldRanges:
+		for i := 0; i < vs.Len(); i++ {
+			r := vs.Get(i)
+			if r[0]+1 == r[1] {
+				ss = append(ss, fmt.Sprintf("%d", r[0]))
+			} else {
+				ss = append(ss, fmt.Sprintf("%d:%d", r[0], r[1])) // enum ranges are end exclusive
+			}
+		}
+		return start + joinStrings(ss, false) + end
+	case pref.EnumRanges:
+		for i := 0; i < vs.Len(); i++ {
+			r := vs.Get(i)
+			if r[0] == r[1] {
+				ss = append(ss, fmt.Sprintf("%d", r[0]))
+			} else {
+				ss = append(ss, fmt.Sprintf("%d:%d", r[0], int64(r[1])+1)) // enum ranges are end inclusive
+			}
+		}
+		return start + joinStrings(ss, false) + end
+	case pref.FileImports:
+		for i := 0; i < vs.Len(); i++ {
+			var rs records
+			rs.Append(reflect.ValueOf(vs.Get(i)), "Path", "Package", "IsPublic", "IsWeak")
+			ss = append(ss, "{"+rs.Join()+"}")
+		}
+		return start + joinStrings(ss, allowMulti) + end
+	default:
+		_, isEnumValue := vs.(pref.EnumValueDescriptors)
+		for i := 0; i < vs.Len(); i++ {
+			m := reflect.ValueOf(vs).MethodByName("Get")
+			v := m.Call([]reflect.Value{reflect.ValueOf(i)})[0].Interface()
+			ss = append(ss, formatDescOpt(v.(pref.Descriptor), false, allowMulti && !isEnumValue))
+		}
+		return start + joinStrings(ss, allowMulti && isEnumValue) + end
+	}
+}
+
+// descriptorAccessors is a list of accessors to print for each descriptor.
+//
+// Do not print all accessors since some contain redundant information,
+// while others are pointers that we do not want to follow since the descriptor
+// is actually a cyclic graph.
+//
+// Using a list allows us to print the accessors in a sensible order.
+var descriptorAccessors = map[reflect.Type][]string{
+	reflect.TypeOf((*pref.FileDescriptor)(nil)).Elem():      {"Path", "Package", "Imports", "Messages", "Enums", "Extensions", "Services"},
+	reflect.TypeOf((*pref.MessageDescriptor)(nil)).Elem():   {"IsMapEntry", "Fields", "Oneofs", "ReservedNames", "ReservedRanges", "RequiredNumbers", "ExtensionRanges", "Messages", "Enums", "Extensions"},
+	reflect.TypeOf((*pref.FieldDescriptor)(nil)).Elem():     {"Number", "Cardinality", "Kind", "HasJSONName", "JSONName", "IsPacked", "IsExtension", "IsWeak", "IsList", "IsMap", "MapKey", "MapValue", "HasDefault", "Default", "ContainingOneof", "ContainingMessage", "Message", "Enum"},
+	reflect.TypeOf((*pref.OneofDescriptor)(nil)).Elem():     {"Fields"}, // not directly used; must keep in sync with formatDescOpt
+	reflect.TypeOf((*pref.EnumDescriptor)(nil)).Elem():      {"Values", "ReservedNames", "ReservedRanges"},
+	reflect.TypeOf((*pref.EnumValueDescriptor)(nil)).Elem(): {"Number"},
+	reflect.TypeOf((*pref.ServiceDescriptor)(nil)).Elem():   {"Methods"},
+	reflect.TypeOf((*pref.MethodDescriptor)(nil)).Elem():    {"Input", "Output", "IsStreamingClient", "IsStreamingServer"},
+}
+
+func FormatDesc(s fmt.State, r rune, t pref.Descriptor) {
+	io.WriteString(s, formatDescOpt(t, true, r == 'v' && (s.Flag('+') || s.Flag('#'))))
+}
+func formatDescOpt(t pref.Descriptor, isRoot, allowMulti bool) string {
+	rv := reflect.ValueOf(t)
+	rt := rv.MethodByName("ProtoType").Type().In(0)
+
+	start, end := "{", "}"
+	if isRoot {
+		start = rt.Name() + "{"
+	}
+
+	_, isFile := t.(pref.FileDescriptor)
+	rs := records{allowMulti: allowMulti}
+	if t.IsPlaceholder() {
+		if isFile {
+			rs.Append(rv, "Path", "Package", "IsPlaceholder")
+		} else {
+			rs.Append(rv, "FullName", "IsPlaceholder")
+		}
+	} else {
+		switch {
+		case isFile:
+			rs.Append(rv, "Syntax")
+		case isRoot:
+			rs.Append(rv, "Syntax", "FullName")
+		default:
+			rs.Append(rv, "Name")
+		}
+		switch t := t.(type) {
+		case pref.FieldDescriptor:
+			for _, s := range descriptorAccessors[rt] {
+				switch s {
+				case "MapKey":
+					if k := t.MapKey(); k != nil {
+						rs.recs = append(rs.recs, [2]string{"MapKey", k.Kind().String()})
+					}
+				case "MapValue":
+					if v := t.MapValue(); v != nil {
+						switch v.Kind() {
+						case pref.EnumKind:
+							rs.recs = append(rs.recs, [2]string{"MapValue", string(v.Enum().FullName())})
+						case pref.MessageKind, pref.GroupKind:
+							rs.recs = append(rs.recs, [2]string{"MapValue", string(v.Message().FullName())})
+						default:
+							rs.recs = append(rs.recs, [2]string{"MapValue", v.Kind().String()})
+						}
+					}
+				case "ContainingOneof":
+					if od := t.ContainingOneof(); od != nil {
+						rs.recs = append(rs.recs, [2]string{"Oneof", string(od.Name())})
+					}
+				case "ContainingMessage":
+					if t.IsExtension() {
+						rs.recs = append(rs.recs, [2]string{"Extendee", string(t.ContainingMessage().FullName())})
+					}
+				case "Message":
+					if !t.IsMap() {
+						rs.Append(rv, s)
+					}
+				default:
+					rs.Append(rv, s)
+				}
+			}
+		case pref.OneofDescriptor:
+			var ss []string
+			fs := t.Fields()
+			for i := 0; i < fs.Len(); i++ {
+				ss = append(ss, string(fs.Get(i).Name()))
+			}
+			if len(ss) > 0 {
+				rs.recs = append(rs.recs, [2]string{"Fields", "[" + joinStrings(ss, false) + "]"})
+			}
+		default:
+			rs.Append(rv, descriptorAccessors[rt]...)
+		}
+		if rv.MethodByName("GoType").IsValid() {
+			rs.Append(rv, "GoType")
+		}
+	}
+	return start + rs.Join() + end
+}
+
+type records struct {
+	recs       [][2]string
+	allowMulti bool
+}
+
+func (rs *records) Append(v reflect.Value, accessors ...string) {
+	for _, a := range accessors {
+		var rv reflect.Value
+		if m := v.MethodByName(a); m.IsValid() {
+			rv = m.Call(nil)[0]
+		}
+		if v.Kind() == reflect.Struct && !rv.IsValid() {
+			rv = v.FieldByName(a)
+		}
+		if !rv.IsValid() {
+			panic(fmt.Sprintf("unknown accessor: %v.%s", v.Type(), a))
+		}
+		if _, ok := rv.Interface().(pref.Value); ok {
+			rv = rv.MethodByName("Interface").Call(nil)[0]
+			if !rv.IsNil() {
+				rv = rv.Elem()
+			}
+		}
+
+		// Ignore zero values.
+		var isZero bool
+		switch rv.Kind() {
+		case reflect.Interface, reflect.Slice:
+			isZero = rv.IsNil()
+		case reflect.Bool:
+			isZero = rv.Bool() == false
+		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+			isZero = rv.Int() == 0
+		case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+			isZero = rv.Uint() == 0
+		case reflect.String:
+			isZero = rv.String() == ""
+		}
+		if n, ok := rv.Interface().(list); ok {
+			isZero = n.Len() == 0
+		}
+		if isZero {
+			continue
+		}
+
+		// Format the value.
+		var s string
+		v := rv.Interface()
+		switch v := v.(type) {
+		case list:
+			s = formatListOpt(v, false, rs.allowMulti)
+		case pref.FieldDescriptor, pref.OneofDescriptor, pref.EnumValueDescriptor, pref.MethodDescriptor:
+			s = string(v.(pref.Descriptor).Name())
+		case pref.Descriptor:
+			s = string(v.FullName())
+		case string:
+			s = strconv.Quote(v)
+		case []byte:
+			s = fmt.Sprintf("%q", v)
+		default:
+			s = fmt.Sprint(v)
+		}
+		rs.recs = append(rs.recs, [2]string{a, s})
+	}
+}
+
+func (rs *records) Join() string {
+	var ss []string
+
+	// In single line mode, simply join all records with commas.
+	if !rs.allowMulti {
+		for _, r := range rs.recs {
+			ss = append(ss, r[0]+formatColon(0)+r[1])
+		}
+		return joinStrings(ss, false)
+	}
+
+	// In allowMulti line mode, align single line records for more readable output.
+	var maxLen int
+	flush := func(i int) {
+		for _, r := range rs.recs[len(ss):i] {
+			ss = append(ss, r[0]+formatColon(maxLen-len(r[0]))+r[1])
+		}
+		maxLen = 0
+	}
+	for i, r := range rs.recs {
+		if isMulti := strings.Contains(r[1], "\n"); isMulti {
+			flush(i)
+			ss = append(ss, r[0]+formatColon(0)+strings.Join(strings.Split(r[1], "\n"), "\n\t"))
+		} else if maxLen < len(r[0]) {
+			maxLen = len(r[0])
+		}
+	}
+	flush(len(rs.recs))
+	return joinStrings(ss, true)
+}
+
+func formatColon(padding int) string {
+	// Deliberately introduce instability into the debug output to
+	// discourage users from performing string comparisons.
+	// This provides us flexibility to change the output in the future.
+	if detrand.Bool() {
+		return ":" + strings.Repeat(" ", 1+padding) // use non-breaking spaces (U+00a0)
+	} else {
+		return ":" + strings.Repeat(" ", 1+padding) // use regular spaces (U+0020)
+	}
+}
+
+func joinStrings(ss []string, isMulti bool) string {
+	if len(ss) == 0 {
+		return ""
+	}
+	if isMulti {
+		return "\n\t" + strings.Join(ss, "\n\t") + "\n"
+	}
+	return strings.Join(ss, ", ")
+}
diff --git a/demo_test/vendor/google.golang.org/protobuf/internal/descopts/options.go b/demo_test/vendor/google.golang.org/protobuf/internal/descopts/options.go
new file mode 100644
index 0000000..8401be8
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/internal/descopts/options.go
@@ -0,0 +1,29 @@
+// 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 descopts contains the nil pointers to concrete descriptor options.
+//
+// This package exists as a form of reverse dependency injection so that certain
+// packages (e.g., internal/filedesc and internal/filetype can avoid a direct
+// dependency on the descriptor proto package).
+package descopts
+
+import pref "google.golang.org/protobuf/reflect/protoreflect"
+
+// These variables are set by the init function in descriptor.pb.go via logic
+// in internal/filetype. In other words, so long as the descriptor proto package
+// is linked in, these variables will be populated.
+//
+// Each variable is populated with a nil pointer to the options struct.
+var (
+	File           pref.ProtoMessage
+	Enum           pref.ProtoMessage
+	EnumValue      pref.ProtoMessage
+	Message        pref.ProtoMessage
+	Field          pref.ProtoMessage
+	Oneof          pref.ProtoMessage
+	ExtensionRange pref.ProtoMessage
+	Service        pref.ProtoMessage
+	Method         pref.ProtoMessage
+)
diff --git a/demo_test/vendor/google.golang.org/protobuf/internal/detrand/rand.go b/demo_test/vendor/google.golang.org/protobuf/internal/detrand/rand.go
new file mode 100644
index 0000000..a904dd1
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/internal/detrand/rand.go
@@ -0,0 +1,61 @@
+// 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 detrand provides deterministically random functionality.
+//
+// The pseudo-randomness of these functions is seeded by the program binary
+// itself and guarantees that the output does not change within a program,
+// while ensuring that the output is unstable across different builds.
+package detrand
+
+import (
+	"encoding/binary"
+	"hash/fnv"
+	"os"
+)
+
+// Disable disables detrand such that all functions returns the zero value.
+// This function is not concurrent-safe and must be called during program init.
+func Disable() {
+	randSeed = 0
+}
+
+// Bool returns a deterministically random boolean.
+func Bool() bool {
+	return randSeed%2 == 1
+}
+
+// randSeed is a best-effort at an approximate hash of the Go binary.
+var randSeed = binaryHash()
+
+func binaryHash() uint64 {
+	// Open the Go binary.
+	s, err := os.Executable()
+	if err != nil {
+		return 0
+	}
+	f, err := os.Open(s)
+	if err != nil {
+		return 0
+	}
+	defer f.Close()
+
+	// Hash the size and several samples of the Go binary.
+	const numSamples = 8
+	var buf [64]byte
+	h := fnv.New64()
+	fi, err := f.Stat()
+	if err != nil {
+		return 0
+	}
+	binary.LittleEndian.PutUint64(buf[:8], uint64(fi.Size()))
+	h.Write(buf[:8])
+	for i := int64(0); i < numSamples; i++ {
+		if _, err := f.ReadAt(buf[:], i*fi.Size()/numSamples); err != nil {
+			return 0
+		}
+		h.Write(buf[:])
+	}
+	return h.Sum64()
+}
diff --git a/demo_test/vendor/google.golang.org/protobuf/internal/encoding/defval/default.go b/demo_test/vendor/google.golang.org/protobuf/internal/encoding/defval/default.go
new file mode 100644
index 0000000..fdd9b13
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/internal/encoding/defval/default.go
@@ -0,0 +1,213 @@
+// 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 defval marshals and unmarshals textual forms of default values.
+//
+// This package handles both the form historically used in Go struct field tags
+// and also the form used by google.protobuf.FieldDescriptorProto.default_value
+// since they differ in superficial ways.
+package defval
+
+import (
+	"fmt"
+	"math"
+	"strconv"
+
+	ptext "google.golang.org/protobuf/internal/encoding/text"
+	errors "google.golang.org/protobuf/internal/errors"
+	pref "google.golang.org/protobuf/reflect/protoreflect"
+)
+
+// Format is the serialization format used to represent the default value.
+type Format int
+
+const (
+	_ Format = iota
+
+	// Descriptor uses the serialization format that protoc uses with the
+	// google.protobuf.FieldDescriptorProto.default_value field.
+	Descriptor
+
+	// GoTag uses the historical serialization format in Go struct field tags.
+	GoTag
+)
+
+// Unmarshal deserializes the default string s according to the given kind k.
+// When k is an enum, a list of enum value descriptors must be provided.
+func Unmarshal(s string, k pref.Kind, evs pref.EnumValueDescriptors, f Format) (pref.Value, pref.EnumValueDescriptor, error) {
+	switch k {
+	case pref.BoolKind:
+		if f == GoTag {
+			switch s {
+			case "1":
+				return pref.ValueOfBool(true), nil, nil
+			case "0":
+				return pref.ValueOfBool(false), nil, nil
+			}
+		} else {
+			switch s {
+			case "true":
+				return pref.ValueOfBool(true), nil, nil
+			case "false":
+				return pref.ValueOfBool(false), nil, nil
+			}
+		}
+	case pref.EnumKind:
+		if f == GoTag {
+			// Go tags use the numeric form of the enum value.
+			if n, err := strconv.ParseInt(s, 10, 32); err == nil {
+				if ev := evs.ByNumber(pref.EnumNumber(n)); ev != nil {
+					return pref.ValueOfEnum(ev.Number()), ev, nil
+				}
+			}
+		} else {
+			// Descriptor default_value use the enum identifier.
+			ev := evs.ByName(pref.Name(s))
+			if ev != nil {
+				return pref.ValueOfEnum(ev.Number()), ev, nil
+			}
+		}
+	case pref.Int32Kind, pref.Sint32Kind, pref.Sfixed32Kind:
+		if v, err := strconv.ParseInt(s, 10, 32); err == nil {
+			return pref.ValueOfInt32(int32(v)), nil, nil
+		}
+	case pref.Int64Kind, pref.Sint64Kind, pref.Sfixed64Kind:
+		if v, err := strconv.ParseInt(s, 10, 64); err == nil {
+			return pref.ValueOfInt64(int64(v)), nil, nil
+		}
+	case pref.Uint32Kind, pref.Fixed32Kind:
+		if v, err := strconv.ParseUint(s, 10, 32); err == nil {
+			return pref.ValueOfUint32(uint32(v)), nil, nil
+		}
+	case pref.Uint64Kind, pref.Fixed64Kind:
+		if v, err := strconv.ParseUint(s, 10, 64); err == nil {
+			return pref.ValueOfUint64(uint64(v)), nil, nil
+		}
+	case pref.FloatKind, pref.DoubleKind:
+		var v float64
+		var err error
+		switch s {
+		case "-inf":
+			v = math.Inf(-1)
+		case "inf":
+			v = math.Inf(+1)
+		case "nan":
+			v = math.NaN()
+		default:
+			v, err = strconv.ParseFloat(s, 64)
+		}
+		if err == nil {
+			if k == pref.FloatKind {
+				return pref.ValueOfFloat32(float32(v)), nil, nil
+			} else {
+				return pref.ValueOfFloat64(float64(v)), nil, nil
+			}
+		}
+	case pref.StringKind:
+		// String values are already unescaped and can be used as is.
+		return pref.ValueOfString(s), nil, nil
+	case pref.BytesKind:
+		if b, ok := unmarshalBytes(s); ok {
+			return pref.ValueOfBytes(b), nil, nil
+		}
+	}
+	return pref.Value{}, nil, errors.New("could not parse value for %v: %q", k, s)
+}
+
+// Marshal serializes v as the default string according to the given kind k.
+// When specifying the Descriptor format for an enum kind, the associated
+// enum value descriptor must be provided.
+func Marshal(v pref.Value, ev pref.EnumValueDescriptor, k pref.Kind, f Format) (string, error) {
+	switch k {
+	case pref.BoolKind:
+		if f == GoTag {
+			if v.Bool() {
+				return "1", nil
+			} else {
+				return "0", nil
+			}
+		} else {
+			if v.Bool() {
+				return "true", nil
+			} else {
+				return "false", nil
+			}
+		}
+	case pref.EnumKind:
+		if f == GoTag {
+			return strconv.FormatInt(int64(v.Enum()), 10), nil
+		} else {
+			return string(ev.Name()), nil
+		}
+	case pref.Int32Kind, pref.Sint32Kind, pref.Sfixed32Kind, pref.Int64Kind, pref.Sint64Kind, pref.Sfixed64Kind:
+		return strconv.FormatInt(v.Int(), 10), nil
+	case pref.Uint32Kind, pref.Fixed32Kind, pref.Uint64Kind, pref.Fixed64Kind:
+		return strconv.FormatUint(v.Uint(), 10), nil
+	case pref.FloatKind, pref.DoubleKind:
+		f := v.Float()
+		switch {
+		case math.IsInf(f, -1):
+			return "-inf", nil
+		case math.IsInf(f, +1):
+			return "inf", nil
+		case math.IsNaN(f):
+			return "nan", nil
+		default:
+			if k == pref.FloatKind {
+				return strconv.FormatFloat(f, 'g', -1, 32), nil
+			} else {
+				return strconv.FormatFloat(f, 'g', -1, 64), nil
+			}
+		}
+	case pref.StringKind:
+		// String values are serialized as is without any escaping.
+		return v.String(), nil
+	case pref.BytesKind:
+		if s, ok := marshalBytes(v.Bytes()); ok {
+			return s, nil
+		}
+	}
+	return "", errors.New("could not format value for %v: %v", k, v)
+}
+
+// unmarshalBytes deserializes bytes by applying C unescaping.
+func unmarshalBytes(s string) ([]byte, bool) {
+	// Bytes values use the same escaping as the text format,
+	// however they lack the surrounding double quotes.
+	v, err := ptext.UnmarshalString(`"` + s + `"`)
+	if err != nil {
+		return nil, false
+	}
+	return []byte(v), true
+}
+
+// marshalBytes serializes bytes by using C escaping.
+// To match the exact output of protoc, this is identical to the
+// CEscape function in strutil.cc of the protoc source code.
+func marshalBytes(b []byte) (string, bool) {
+	var s []byte
+	for _, c := range b {
+		switch c {
+		case '\n':
+			s = append(s, `\n`...)
+		case '\r':
+			s = append(s, `\r`...)
+		case '\t':
+			s = append(s, `\t`...)
+		case '"':
+			s = append(s, `\"`...)
+		case '\'':
+			s = append(s, `\'`...)
+		case '\\':
+			s = append(s, `\\`...)
+		default:
+			if printableASCII := c >= 0x20 && c <= 0x7e; printableASCII {
+				s = append(s, c)
+			} else {
+				s = append(s, fmt.Sprintf(`\%03o`, c)...)
+			}
+		}
+	}
+	return string(s), true
+}
diff --git a/demo_test/vendor/google.golang.org/protobuf/internal/encoding/messageset/messageset.go b/demo_test/vendor/google.golang.org/protobuf/internal/encoding/messageset/messageset.go
new file mode 100644
index 0000000..b1eeea5
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/internal/encoding/messageset/messageset.go
@@ -0,0 +1,258 @@
+// 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 messageset encodes and decodes the obsolete MessageSet wire format.
+package messageset
+
+import (
+	"math"
+
+	"google.golang.org/protobuf/encoding/protowire"
+	"google.golang.org/protobuf/internal/errors"
+	pref "google.golang.org/protobuf/reflect/protoreflect"
+	preg "google.golang.org/protobuf/reflect/protoregistry"
+)
+
+// The MessageSet wire format is equivalent to a message defiend as follows,
+// where each Item defines an extension field with a field number of 'type_id'
+// and content of 'message'. MessageSet extensions must be non-repeated message
+// fields.
+//
+//	message MessageSet {
+//		repeated group Item = 1 {
+//			required int32 type_id = 2;
+//			required string message = 3;
+//		}
+//	}
+const (
+	FieldItem    = protowire.Number(1)
+	FieldTypeID  = protowire.Number(2)
+	FieldMessage = protowire.Number(3)
+)
+
+// ExtensionName is the field name for extensions of MessageSet.
+//
+// A valid MessageSet extension must be of the form:
+//	message MyMessage {
+//		extend proto2.bridge.MessageSet {
+//			optional MyMessage message_set_extension = 1234;
+//		}
+//		...
+//	}
+const ExtensionName = "message_set_extension"
+
+// IsMessageSet returns whether the message uses the MessageSet wire format.
+func IsMessageSet(md pref.MessageDescriptor) bool {
+	xmd, ok := md.(interface{ IsMessageSet() bool })
+	return ok && xmd.IsMessageSet()
+}
+
+// IsMessageSetExtension reports this field extends a MessageSet.
+func IsMessageSetExtension(fd pref.FieldDescriptor) bool {
+	if fd.Name() != ExtensionName {
+		return false
+	}
+	if fd.FullName().Parent() != fd.Message().FullName() {
+		return false
+	}
+	return IsMessageSet(fd.ContainingMessage())
+}
+
+// FindMessageSetExtension locates a MessageSet extension field by name.
+// In text and JSON formats, the extension name used is the message itself.
+// The extension field name is derived by appending ExtensionName.
+func FindMessageSetExtension(r preg.ExtensionTypeResolver, s pref.FullName) (pref.ExtensionType, error) {
+	name := s.Append(ExtensionName)
+	xt, err := r.FindExtensionByName(name)
+	if err != nil {
+		if err == preg.NotFound {
+			return nil, err
+		}
+		return nil, errors.Wrap(err, "%q", name)
+	}
+	if !IsMessageSetExtension(xt.TypeDescriptor()) {
+		return nil, preg.NotFound
+	}
+	return xt, nil
+}
+
+// SizeField returns the size of a MessageSet item field containing an extension
+// with the given field number, not counting the contents of the message subfield.
+func SizeField(num protowire.Number) int {
+	return 2*protowire.SizeTag(FieldItem) + protowire.SizeTag(FieldTypeID) + protowire.SizeVarint(uint64(num))
+}
+
+// Unmarshal parses a MessageSet.
+//
+// It calls fn with the type ID and value of each item in the MessageSet.
+// Unknown fields are discarded.
+//
+// If wantLen is true, the item values include the varint length prefix.
+// This is ugly, but simplifies the fast-path decoder in internal/impl.
+func Unmarshal(b []byte, wantLen bool, fn func(typeID protowire.Number, value []byte) error) error {
+	for len(b) > 0 {
+		num, wtyp, n := protowire.ConsumeTag(b)
+		if n < 0 {
+			return protowire.ParseError(n)
+		}
+		b = b[n:]
+		if num != FieldItem || wtyp != protowire.StartGroupType {
+			n := protowire.ConsumeFieldValue(num, wtyp, b)
+			if n < 0 {
+				return protowire.ParseError(n)
+			}
+			b = b[n:]
+			continue
+		}
+		typeID, value, n, err := ConsumeFieldValue(b, wantLen)
+		if err != nil {
+			return err
+		}
+		b = b[n:]
+		if typeID == 0 {
+			continue
+		}
+		if err := fn(typeID, value); err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+// ConsumeFieldValue parses b as a MessageSet item field value until and including
+// the trailing end group marker. It assumes the start group tag has already been parsed.
+// It returns the contents of the type_id and message subfields and the total
+// item length.
+//
+// If wantLen is true, the returned message value includes the length prefix.
+func ConsumeFieldValue(b []byte, wantLen bool) (typeid protowire.Number, message []byte, n int, err error) {
+	ilen := len(b)
+	for {
+		num, wtyp, n := protowire.ConsumeTag(b)
+		if n < 0 {
+			return 0, nil, 0, protowire.ParseError(n)
+		}
+		b = b[n:]
+		switch {
+		case num == FieldItem && wtyp == protowire.EndGroupType:
+			if wantLen && len(message) == 0 {
+				// The message field was missing, which should never happen.
+				// Be prepared for this case anyway.
+				message = protowire.AppendVarint(message, 0)
+			}
+			return typeid, message, ilen - len(b), nil
+		case num == FieldTypeID && wtyp == protowire.VarintType:
+			v, n := protowire.ConsumeVarint(b)
+			if n < 0 {
+				return 0, nil, 0, protowire.ParseError(n)
+			}
+			b = b[n:]
+			if v < 1 || v > math.MaxInt32 {
+				return 0, nil, 0, errors.New("invalid type_id in message set")
+			}
+			typeid = protowire.Number(v)
+		case num == FieldMessage && wtyp == protowire.BytesType:
+			m, n := protowire.ConsumeBytes(b)
+			if n < 0 {
+				return 0, nil, 0, protowire.ParseError(n)
+			}
+			if message == nil {
+				if wantLen {
+					message = b[:n:n]
+				} else {
+					message = m[:len(m):len(m)]
+				}
+			} else {
+				// This case should never happen in practice, but handle it for
+				// correctness: The MessageSet item contains multiple message
+				// fields, which need to be merged.
+				//
+				// In the case where we're returning the length, this becomes
+				// quite inefficient since we need to strip the length off
+				// the existing data and reconstruct it with the combined length.
+				if wantLen {
+					_, nn := protowire.ConsumeVarint(message)
+					m0 := message[nn:]
+					message = nil
+					message = protowire.AppendVarint(message, uint64(len(m0)+len(m)))
+					message = append(message, m0...)
+					message = append(message, m...)
+				} else {
+					message = append(message, m...)
+				}
+			}
+			b = b[n:]
+		default:
+			// We have no place to put it, so we just ignore unknown fields.
+			n := protowire.ConsumeFieldValue(num, wtyp, b)
+			if n < 0 {
+				return 0, nil, 0, protowire.ParseError(n)
+			}
+			b = b[n:]
+		}
+	}
+}
+
+// AppendFieldStart appends the start of a MessageSet item field containing
+// an extension with the given number. The caller must add the message
+// subfield (including the tag).
+func AppendFieldStart(b []byte, num protowire.Number) []byte {
+	b = protowire.AppendTag(b, FieldItem, protowire.StartGroupType)
+	b = protowire.AppendTag(b, FieldTypeID, protowire.VarintType)
+	b = protowire.AppendVarint(b, uint64(num))
+	return b
+}
+
+// AppendFieldEnd appends the trailing end group marker for a MessageSet item field.
+func AppendFieldEnd(b []byte) []byte {
+	return protowire.AppendTag(b, FieldItem, protowire.EndGroupType)
+}
+
+// SizeUnknown returns the size of an unknown fields section in MessageSet format.
+//
+// See AppendUnknown.
+func SizeUnknown(unknown []byte) (size int) {
+	for len(unknown) > 0 {
+		num, typ, n := protowire.ConsumeTag(unknown)
+		if n < 0 || typ != protowire.BytesType {
+			return 0
+		}
+		unknown = unknown[n:]
+		_, n = protowire.ConsumeBytes(unknown)
+		if n < 0 {
+			return 0
+		}
+		unknown = unknown[n:]
+		size += SizeField(num) + protowire.SizeTag(FieldMessage) + n
+	}
+	return size
+}
+
+// AppendUnknown appends unknown fields to b in MessageSet format.
+//
+// For historic reasons, unresolved items in a MessageSet are stored in a
+// message's unknown fields section in non-MessageSet format. That is, an
+// unknown item with typeID T and value V appears in the unknown fields as
+// a field with number T and value V.
+//
+// This function converts the unknown fields back into MessageSet form.
+func AppendUnknown(b, unknown []byte) ([]byte, error) {
+	for len(unknown) > 0 {
+		num, typ, n := protowire.ConsumeTag(unknown)
+		if n < 0 || typ != protowire.BytesType {
+			return nil, errors.New("invalid data in message set unknown fields")
+		}
+		unknown = unknown[n:]
+		_, n = protowire.ConsumeBytes(unknown)
+		if n < 0 {
+			return nil, errors.New("invalid data in message set unknown fields")
+		}
+		b = AppendFieldStart(b, num)
+		b = protowire.AppendTag(b, FieldMessage, protowire.BytesType)
+		b = append(b, unknown[:n]...)
+		b = AppendFieldEnd(b)
+		unknown = unknown[n:]
+	}
+	return b, nil
+}
diff --git a/demo_test/vendor/google.golang.org/protobuf/internal/encoding/tag/tag.go b/demo_test/vendor/google.golang.org/protobuf/internal/encoding/tag/tag.go
new file mode 100644
index 0000000..16c02d7
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/internal/encoding/tag/tag.go
@@ -0,0 +1,207 @@
+// 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 tag marshals and unmarshals the legacy struct tags as generated
+// by historical versions of protoc-gen-go.
+package tag
+
+import (
+	"reflect"
+	"strconv"
+	"strings"
+
+	defval "google.golang.org/protobuf/internal/encoding/defval"
+	fdesc "google.golang.org/protobuf/internal/filedesc"
+	"google.golang.org/protobuf/internal/strs"
+	pref "google.golang.org/protobuf/reflect/protoreflect"
+)
+
+var byteType = reflect.TypeOf(byte(0))
+
+// Unmarshal decodes the tag into a prototype.Field.
+//
+// The goType is needed to determine the original protoreflect.Kind since the
+// tag does not record sufficient information to determine that.
+// The type is the underlying field type (e.g., a repeated field may be
+// represented by []T, but the Go type passed in is just T).
+// A list of enum value descriptors must be provided for enum fields.
+// This does not populate the Enum or Message (except for weak message).
+//
+// This function is a best effort attempt; parsing errors are ignored.
+func Unmarshal(tag string, goType reflect.Type, evs pref.EnumValueDescriptors) pref.FieldDescriptor {
+	f := new(fdesc.Field)
+	f.L0.ParentFile = fdesc.SurrogateProto2
+	for len(tag) > 0 {
+		i := strings.IndexByte(tag, ',')
+		if i < 0 {
+			i = len(tag)
+		}
+		switch s := tag[:i]; {
+		case strings.HasPrefix(s, "name="):
+			f.L0.FullName = pref.FullName(s[len("name="):])
+		case strings.Trim(s, "0123456789") == "":
+			n, _ := strconv.ParseUint(s, 10, 32)
+			f.L1.Number = pref.FieldNumber(n)
+		case s == "opt":
+			f.L1.Cardinality = pref.Optional
+		case s == "req":
+			f.L1.Cardinality = pref.Required
+		case s == "rep":
+			f.L1.Cardinality = pref.Repeated
+		case s == "varint":
+			switch goType.Kind() {
+			case reflect.Bool:
+				f.L1.Kind = pref.BoolKind
+			case reflect.Int32:
+				f.L1.Kind = pref.Int32Kind
+			case reflect.Int64:
+				f.L1.Kind = pref.Int64Kind
+			case reflect.Uint32:
+				f.L1.Kind = pref.Uint32Kind
+			case reflect.Uint64:
+				f.L1.Kind = pref.Uint64Kind
+			}
+		case s == "zigzag32":
+			if goType.Kind() == reflect.Int32 {
+				f.L1.Kind = pref.Sint32Kind
+			}
+		case s == "zigzag64":
+			if goType.Kind() == reflect.Int64 {
+				f.L1.Kind = pref.Sint64Kind
+			}
+		case s == "fixed32":
+			switch goType.Kind() {
+			case reflect.Int32:
+				f.L1.Kind = pref.Sfixed32Kind
+			case reflect.Uint32:
+				f.L1.Kind = pref.Fixed32Kind
+			case reflect.Float32:
+				f.L1.Kind = pref.FloatKind
+			}
+		case s == "fixed64":
+			switch goType.Kind() {
+			case reflect.Int64:
+				f.L1.Kind = pref.Sfixed64Kind
+			case reflect.Uint64:
+				f.L1.Kind = pref.Fixed64Kind
+			case reflect.Float64:
+				f.L1.Kind = pref.DoubleKind
+			}
+		case s == "bytes":
+			switch {
+			case goType.Kind() == reflect.String:
+				f.L1.Kind = pref.StringKind
+			case goType.Kind() == reflect.Slice && goType.Elem() == byteType:
+				f.L1.Kind = pref.BytesKind
+			default:
+				f.L1.Kind = pref.MessageKind
+			}
+		case s == "group":
+			f.L1.Kind = pref.GroupKind
+		case strings.HasPrefix(s, "enum="):
+			f.L1.Kind = pref.EnumKind
+		case strings.HasPrefix(s, "json="):
+			jsonName := s[len("json="):]
+			if jsonName != strs.JSONCamelCase(string(f.L0.FullName.Name())) {
+				f.L1.JSONName.Init(jsonName)
+			}
+		case s == "packed":
+			f.L1.HasPacked = true
+			f.L1.IsPacked = true
+		case strings.HasPrefix(s, "weak="):
+			f.L1.IsWeak = true
+			f.L1.Message = fdesc.PlaceholderMessage(pref.FullName(s[len("weak="):]))
+		case strings.HasPrefix(s, "def="):
+			// The default tag is special in that everything afterwards is the
+			// default regardless of the presence of commas.
+			s, i = tag[len("def="):], len(tag)
+			v, ev, _ := defval.Unmarshal(s, f.L1.Kind, evs, defval.GoTag)
+			f.L1.Default = fdesc.DefaultValue(v, ev)
+		case s == "proto3":
+			f.L0.ParentFile = fdesc.SurrogateProto3
+		}
+		tag = strings.TrimPrefix(tag[i:], ",")
+	}
+
+	// The generator uses the group message name instead of the field name.
+	// We obtain the real field name by lowercasing the group name.
+	if f.L1.Kind == pref.GroupKind {
+		f.L0.FullName = pref.FullName(strings.ToLower(string(f.L0.FullName)))
+	}
+	return f
+}
+
+// Marshal encodes the protoreflect.FieldDescriptor as a tag.
+//
+// The enumName must be provided if the kind is an enum.
+// Historically, the formulation of the enum "name" was the proto package
+// dot-concatenated with the generated Go identifier for the enum type.
+// Depending on the context on how Marshal is called, there are different ways
+// through which that information is determined. As such it is the caller's
+// responsibility to provide a function to obtain that information.
+func Marshal(fd pref.FieldDescriptor, enumName string) string {
+	var tag []string
+	switch fd.Kind() {
+	case pref.BoolKind, pref.EnumKind, pref.Int32Kind, pref.Uint32Kind, pref.Int64Kind, pref.Uint64Kind:
+		tag = append(tag, "varint")
+	case pref.Sint32Kind:
+		tag = append(tag, "zigzag32")
+	case pref.Sint64Kind:
+		tag = append(tag, "zigzag64")
+	case pref.Sfixed32Kind, pref.Fixed32Kind, pref.FloatKind:
+		tag = append(tag, "fixed32")
+	case pref.Sfixed64Kind, pref.Fixed64Kind, pref.DoubleKind:
+		tag = append(tag, "fixed64")
+	case pref.StringKind, pref.BytesKind, pref.MessageKind:
+		tag = append(tag, "bytes")
+	case pref.GroupKind:
+		tag = append(tag, "group")
+	}
+	tag = append(tag, strconv.Itoa(int(fd.Number())))
+	switch fd.Cardinality() {
+	case pref.Optional:
+		tag = append(tag, "opt")
+	case pref.Required:
+		tag = append(tag, "req")
+	case pref.Repeated:
+		tag = append(tag, "rep")
+	}
+	if fd.IsPacked() {
+		tag = append(tag, "packed")
+	}
+	name := string(fd.Name())
+	if fd.Kind() == pref.GroupKind {
+		// The name of the FieldDescriptor for a group field is
+		// lowercased. To find the original capitalization, we
+		// look in the field's MessageType.
+		name = string(fd.Message().Name())
+	}
+	tag = append(tag, "name="+name)
+	if jsonName := fd.JSONName(); jsonName != "" && jsonName != name && !fd.IsExtension() {
+		// NOTE: The jsonName != name condition is suspect, but it preserve
+		// the exact same semantics from the previous generator.
+		tag = append(tag, "json="+jsonName)
+	}
+	if fd.IsWeak() {
+		tag = append(tag, "weak="+string(fd.Message().FullName()))
+	}
+	// The previous implementation does not tag extension fields as proto3,
+	// even when the field is defined in a proto3 file. Match that behavior
+	// for consistency.
+	if fd.Syntax() == pref.Proto3 && !fd.IsExtension() {
+		tag = append(tag, "proto3")
+	}
+	if fd.Kind() == pref.EnumKind && enumName != "" {
+		tag = append(tag, "enum="+enumName)
+	}
+	if fd.ContainingOneof() != nil {
+		tag = append(tag, "oneof")
+	}
+	// This must appear last in the tag, since commas in strings aren't escaped.
+	if fd.HasDefault() {
+		def, _ := defval.Marshal(fd.Default(), fd.DefaultEnumValue(), fd.Kind(), defval.GoTag)
+		tag = append(tag, "def="+def)
+	}
+	return strings.Join(tag, ",")
+}
diff --git a/demo_test/vendor/google.golang.org/protobuf/internal/encoding/text/decode.go b/demo_test/vendor/google.golang.org/protobuf/internal/encoding/text/decode.go
new file mode 100644
index 0000000..eb10ea1
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/internal/encoding/text/decode.go
@@ -0,0 +1,665 @@
+// 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 text
+
+import (
+	"bytes"
+	"fmt"
+	"io"
+	"regexp"
+	"strconv"
+	"unicode/utf8"
+
+	"google.golang.org/protobuf/internal/errors"
+)
+
+// Decoder is a token-based textproto decoder.
+type Decoder struct {
+	// lastCall is last method called, either readCall or peekCall.
+	// Initial value is readCall.
+	lastCall call
+
+	// lastToken contains the last read token.
+	lastToken Token
+
+	// lastErr contains the last read error.
+	lastErr error
+
+	// openStack is a stack containing the byte characters for MessageOpen and
+	// ListOpen kinds. The top of stack represents the message or the list that
+	// the current token is nested in. An empty stack means the current token is
+	// at the top level message. The characters '{' and '<' both represent the
+	// MessageOpen kind.
+	openStack []byte
+
+	// orig is used in reporting line and column.
+	orig []byte
+	// in contains the unconsumed input.
+	in []byte
+}
+
+// NewDecoder returns a Decoder to read the given []byte.
+func NewDecoder(b []byte) *Decoder {
+	return &Decoder{orig: b, in: b}
+}
+
+// ErrUnexpectedEOF means that EOF was encountered in the middle of the input.
+var ErrUnexpectedEOF = errors.New("%v", io.ErrUnexpectedEOF)
+
+// call specifies which Decoder method was invoked.
+type call uint8
+
+const (
+	readCall call = iota
+	peekCall
+)
+
+// Peek looks ahead and returns the next token and error without advancing a read.
+func (d *Decoder) Peek() (Token, error) {
+	defer func() { d.lastCall = peekCall }()
+	if d.lastCall == readCall {
+		d.lastToken, d.lastErr = d.Read()
+	}
+	return d.lastToken, d.lastErr
+}
+
+// Read returns the next token.
+// It will return an error if there is no valid token.
+func (d *Decoder) Read() (Token, error) {
+	defer func() { d.lastCall = readCall }()
+	if d.lastCall == peekCall {
+		return d.lastToken, d.lastErr
+	}
+
+	tok, err := d.parseNext(d.lastToken.kind)
+	if err != nil {
+		return Token{}, err
+	}
+
+	switch tok.kind {
+	case comma, semicolon:
+		tok, err = d.parseNext(tok.kind)
+		if err != nil {
+			return Token{}, err
+		}
+	}
+	d.lastToken = tok
+	return tok, nil
+}
+
+const (
+	mismatchedFmt = "mismatched close character %q"
+	unexpectedFmt = "unexpected character %q"
+)
+
+// parseNext parses the next Token based on given last kind.
+func (d *Decoder) parseNext(lastKind Kind) (Token, error) {
+	// Trim leading spaces.
+	d.consume(0)
+	isEOF := false
+	if len(d.in) == 0 {
+		isEOF = true
+	}
+
+	switch lastKind {
+	case EOF:
+		return d.consumeToken(EOF, 0, 0), nil
+
+	case bof:
+		// Start of top level message. Next token can be EOF or Name.
+		if isEOF {
+			return d.consumeToken(EOF, 0, 0), nil
+		}
+		return d.parseFieldName()
+
+	case Name:
+		// Next token can be MessageOpen, ListOpen or Scalar.
+		if isEOF {
+			return Token{}, ErrUnexpectedEOF
+		}
+		switch ch := d.in[0]; ch {
+		case '{', '<':
+			d.pushOpenStack(ch)
+			return d.consumeToken(MessageOpen, 1, 0), nil
+		case '[':
+			d.pushOpenStack(ch)
+			return d.consumeToken(ListOpen, 1, 0), nil
+		default:
+			return d.parseScalar()
+		}
+
+	case Scalar:
+		openKind, closeCh := d.currentOpenKind()
+		switch openKind {
+		case bof:
+			// Top level message.
+			// 	Next token can be EOF, comma, semicolon or Name.
+			if isEOF {
+				return d.consumeToken(EOF, 0, 0), nil
+			}
+			switch d.in[0] {
+			case ',':
+				return d.consumeToken(comma, 1, 0), nil
+			case ';':
+				return d.consumeToken(semicolon, 1, 0), nil
+			default:
+				return d.parseFieldName()
+			}
+
+		case MessageOpen:
+			// Next token can be MessageClose, comma, semicolon or Name.
+			if isEOF {
+				return Token{}, ErrUnexpectedEOF
+			}
+			switch ch := d.in[0]; ch {
+			case closeCh:
+				d.popOpenStack()
+				return d.consumeToken(MessageClose, 1, 0), nil
+			case otherCloseChar[closeCh]:
+				return Token{}, d.newSyntaxError(mismatchedFmt, ch)
+			case ',':
+				return d.consumeToken(comma, 1, 0), nil
+			case ';':
+				return d.consumeToken(semicolon, 1, 0), nil
+			default:
+				return d.parseFieldName()
+			}
+
+		case ListOpen:
+			// Next token can be ListClose or comma.
+			if isEOF {
+				return Token{}, ErrUnexpectedEOF
+			}
+			switch ch := d.in[0]; ch {
+			case ']':
+				d.popOpenStack()
+				return d.consumeToken(ListClose, 1, 0), nil
+			case ',':
+				return d.consumeToken(comma, 1, 0), nil
+			default:
+				return Token{}, d.newSyntaxError(unexpectedFmt, ch)
+			}
+		}
+
+	case MessageOpen:
+		// Next token can be MessageClose or Name.
+		if isEOF {
+			return Token{}, ErrUnexpectedEOF
+		}
+		_, closeCh := d.currentOpenKind()
+		switch ch := d.in[0]; ch {
+		case closeCh:
+			d.popOpenStack()
+			return d.consumeToken(MessageClose, 1, 0), nil
+		case otherCloseChar[closeCh]:
+			return Token{}, d.newSyntaxError(mismatchedFmt, ch)
+		default:
+			return d.parseFieldName()
+		}
+
+	case MessageClose:
+		openKind, closeCh := d.currentOpenKind()
+		switch openKind {
+		case bof:
+			// Top level message.
+			// Next token can be EOF, comma, semicolon or Name.
+			if isEOF {
+				return d.consumeToken(EOF, 0, 0), nil
+			}
+			switch ch := d.in[0]; ch {
+			case ',':
+				return d.consumeToken(comma, 1, 0), nil
+			case ';':
+				return d.consumeToken(semicolon, 1, 0), nil
+			default:
+				return d.parseFieldName()
+			}
+
+		case MessageOpen:
+			// Next token can be MessageClose, comma, semicolon or Name.
+			if isEOF {
+				return Token{}, ErrUnexpectedEOF
+			}
+			switch ch := d.in[0]; ch {
+			case closeCh:
+				d.popOpenStack()
+				return d.consumeToken(MessageClose, 1, 0), nil
+			case otherCloseChar[closeCh]:
+				return Token{}, d.newSyntaxError(mismatchedFmt, ch)
+			case ',':
+				return d.consumeToken(comma, 1, 0), nil
+			case ';':
+				return d.consumeToken(semicolon, 1, 0), nil
+			default:
+				return d.parseFieldName()
+			}
+
+		case ListOpen:
+			// Next token can be ListClose or comma
+			if isEOF {
+				return Token{}, ErrUnexpectedEOF
+			}
+			switch ch := d.in[0]; ch {
+			case closeCh:
+				d.popOpenStack()
+				return d.consumeToken(ListClose, 1, 0), nil
+			case ',':
+				return d.consumeToken(comma, 1, 0), nil
+			default:
+				return Token{}, d.newSyntaxError(unexpectedFmt, ch)
+			}
+		}
+
+	case ListOpen:
+		// Next token can be ListClose, MessageStart or Scalar.
+		if isEOF {
+			return Token{}, ErrUnexpectedEOF
+		}
+		switch ch := d.in[0]; ch {
+		case ']':
+			d.popOpenStack()
+			return d.consumeToken(ListClose, 1, 0), nil
+		case '{', '<':
+			d.pushOpenStack(ch)
+			return d.consumeToken(MessageOpen, 1, 0), nil
+		default:
+			return d.parseScalar()
+		}
+
+	case ListClose:
+		openKind, closeCh := d.currentOpenKind()
+		switch openKind {
+		case bof:
+			// Top level message.
+			// Next token can be EOF, comma, semicolon or Name.
+			if isEOF {
+				return d.consumeToken(EOF, 0, 0), nil
+			}
+			switch ch := d.in[0]; ch {
+			case ',':
+				return d.consumeToken(comma, 1, 0), nil
+			case ';':
+				return d.consumeToken(semicolon, 1, 0), nil
+			default:
+				return d.parseFieldName()
+			}
+
+		case MessageOpen:
+			// Next token can be MessageClose, comma, semicolon or Name.
+			if isEOF {
+				return Token{}, ErrUnexpectedEOF
+			}
+			switch ch := d.in[0]; ch {
+			case closeCh:
+				d.popOpenStack()
+				return d.consumeToken(MessageClose, 1, 0), nil
+			case otherCloseChar[closeCh]:
+				return Token{}, d.newSyntaxError(mismatchedFmt, ch)
+			case ',':
+				return d.consumeToken(comma, 1, 0), nil
+			case ';':
+				return d.consumeToken(semicolon, 1, 0), nil
+			default:
+				return d.parseFieldName()
+			}
+
+		default:
+			// It is not possible to have this case. Let it panic below.
+		}
+
+	case comma, semicolon:
+		openKind, closeCh := d.currentOpenKind()
+		switch openKind {
+		case bof:
+			// Top level message. Next token can be EOF or Name.
+			if isEOF {
+				return d.consumeToken(EOF, 0, 0), nil
+			}
+			return d.parseFieldName()
+
+		case MessageOpen:
+			// Next token can be MessageClose or Name.
+			if isEOF {
+				return Token{}, ErrUnexpectedEOF
+			}
+			switch ch := d.in[0]; ch {
+			case closeCh:
+				d.popOpenStack()
+				return d.consumeToken(MessageClose, 1, 0), nil
+			case otherCloseChar[closeCh]:
+				return Token{}, d.newSyntaxError(mismatchedFmt, ch)
+			default:
+				return d.parseFieldName()
+			}
+
+		case ListOpen:
+			if lastKind == semicolon {
+				// It is not be possible to have this case as logic here
+				// should not have produced a semicolon Token when inside a
+				// list. Let it panic below.
+				break
+			}
+			// Next token can be MessageOpen or Scalar.
+			if isEOF {
+				return Token{}, ErrUnexpectedEOF
+			}
+			switch ch := d.in[0]; ch {
+			case '{', '<':
+				d.pushOpenStack(ch)
+				return d.consumeToken(MessageOpen, 1, 0), nil
+			default:
+				return d.parseScalar()
+			}
+		}
+	}
+
+	line, column := d.Position(len(d.orig) - len(d.in))
+	panic(fmt.Sprintf("Decoder.parseNext: bug at handling line %d:%d with lastKind=%v", line, column, lastKind))
+}
+
+var otherCloseChar = map[byte]byte{
+	'}': '>',
+	'>': '}',
+}
+
+// currentOpenKind indicates whether current position is inside a message, list
+// or top-level message by returning MessageOpen, ListOpen or bof respectively.
+// If the returned kind is either a MessageOpen or ListOpen, it also returns the
+// corresponding closing character.
+func (d *Decoder) currentOpenKind() (Kind, byte) {
+	if len(d.openStack) == 0 {
+		return bof, 0
+	}
+	openCh := d.openStack[len(d.openStack)-1]
+	switch openCh {
+	case '{':
+		return MessageOpen, '}'
+	case '<':
+		return MessageOpen, '>'
+	case '[':
+		return ListOpen, ']'
+	}
+	panic(fmt.Sprintf("Decoder: openStack contains invalid byte %s", string(openCh)))
+}
+
+func (d *Decoder) pushOpenStack(ch byte) {
+	d.openStack = append(d.openStack, ch)
+}
+
+func (d *Decoder) popOpenStack() {
+	d.openStack = d.openStack[:len(d.openStack)-1]
+}
+
+// parseFieldName parses field name and separator.
+func (d *Decoder) parseFieldName() (tok Token, err error) {
+	defer func() {
+		if err == nil && d.tryConsumeChar(':') {
+			tok.attrs |= hasSeparator
+		}
+	}()
+
+	// Extension or Any type URL.
+	if d.in[0] == '[' {
+		return d.parseTypeName()
+	}
+
+	// Identifier.
+	if size := parseIdent(d.in, false); size > 0 {
+		return d.consumeToken(Name, size, uint8(IdentName)), nil
+	}
+
+	// Field number. Identify if input is a valid number that is not negative
+	// and is decimal integer within 32-bit range.
+	if num := parseNumber(d.in); num.size > 0 {
+		if !num.neg && num.kind == numDec {
+			if _, err := strconv.ParseInt(string(d.in[:num.size]), 10, 32); err == nil {
+				return d.consumeToken(Name, num.size, uint8(FieldNumber)), nil
+			}
+		}
+		return Token{}, d.newSyntaxError("invalid field number: %s", d.in[:num.size])
+	}
+
+	return Token{}, d.newSyntaxError("invalid field name: %s", errRegexp.Find(d.in))
+}
+
+// parseTypeName parses Any type URL or extension field name. The name is
+// enclosed in [ and ] characters. The C++ parser does not handle many legal URL
+// strings. This implementation is more liberal and allows for the pattern
+// ^[-_a-zA-Z0-9]+([./][-_a-zA-Z0-9]+)*`). Whitespaces and comments are allowed
+// in between [ ], '.', '/' and the sub names.
+func (d *Decoder) parseTypeName() (Token, error) {
+	startPos := len(d.orig) - len(d.in)
+	// Use alias s to advance first in order to use d.in for error handling.
+	// Caller already checks for [ as first character.
+	s := consume(d.in[1:], 0)
+	if len(s) == 0 {
+		return Token{}, ErrUnexpectedEOF
+	}
+
+	var name []byte
+	for len(s) > 0 && isTypeNameChar(s[0]) {
+		name = append(name, s[0])
+		s = s[1:]
+	}
+	s = consume(s, 0)
+
+	var closed bool
+	for len(s) > 0 && !closed {
+		switch {
+		case s[0] == ']':
+			s = s[1:]
+			closed = true
+
+		case s[0] == '/', s[0] == '.':
+			if len(name) > 0 && (name[len(name)-1] == '/' || name[len(name)-1] == '.') {
+				return Token{}, d.newSyntaxError("invalid type URL/extension field name: %s",
+					d.orig[startPos:len(d.orig)-len(s)+1])
+			}
+			name = append(name, s[0])
+			s = s[1:]
+			s = consume(s, 0)
+			for len(s) > 0 && isTypeNameChar(s[0]) {
+				name = append(name, s[0])
+				s = s[1:]
+			}
+			s = consume(s, 0)
+
+		default:
+			return Token{}, d.newSyntaxError(
+				"invalid type URL/extension field name: %s", d.orig[startPos:len(d.orig)-len(s)+1])
+		}
+	}
+
+	if !closed {
+		return Token{}, ErrUnexpectedEOF
+	}
+
+	// First character cannot be '.'. Last character cannot be '.' or '/'.
+	size := len(name)
+	if size == 0 || name[0] == '.' || name[size-1] == '.' || name[size-1] == '/' {
+		return Token{}, d.newSyntaxError("invalid type URL/extension field name: %s",
+			d.orig[startPos:len(d.orig)-len(s)])
+	}
+
+	d.in = s
+	endPos := len(d.orig) - len(d.in)
+	d.consume(0)
+
+	return Token{
+		kind:  Name,
+		attrs: uint8(TypeName),
+		pos:   startPos,
+		raw:   d.orig[startPos:endPos],
+		str:   string(name),
+	}, nil
+}
+
+func isTypeNameChar(b byte) bool {
+	return (b == '-' || b == '_' ||
+		('0' <= b && b <= '9') ||
+		('a' <= b && b <= 'z') ||
+		('A' <= b && b <= 'Z'))
+}
+
+func isWhiteSpace(b byte) bool {
+	switch b {
+	case ' ', '\n', '\r', '\t':
+		return true
+	default:
+		return false
+	}
+}
+
+// parseIdent parses an unquoted proto identifier and returns size.
+// If allowNeg is true, it allows '-' to be the first character in the
+// identifier. This is used when parsing literal values like -infinity, etc.
+// Regular expression matches an identifier: `^[_a-zA-Z][_a-zA-Z0-9]*`
+func parseIdent(input []byte, allowNeg bool) int {
+	var size int
+
+	s := input
+	if len(s) == 0 {
+		return 0
+	}
+
+	if allowNeg && s[0] == '-' {
+		s = s[1:]
+		size++
+		if len(s) == 0 {
+			return 0
+		}
+	}
+
+	switch {
+	case s[0] == '_',
+		'a' <= s[0] && s[0] <= 'z',
+		'A' <= s[0] && s[0] <= 'Z':
+		s = s[1:]
+		size++
+	default:
+		return 0
+	}
+
+	for len(s) > 0 && (s[0] == '_' ||
+		'a' <= s[0] && s[0] <= 'z' ||
+		'A' <= s[0] && s[0] <= 'Z' ||
+		'0' <= s[0] && s[0] <= '9') {
+		s = s[1:]
+		size++
+	}
+
+	if len(s) > 0 && !isDelim(s[0]) {
+		return 0
+	}
+
+	return size
+}
+
+// parseScalar parses for a string, literal or number value.
+func (d *Decoder) parseScalar() (Token, error) {
+	if d.in[0] == '"' || d.in[0] == '\'' {
+		return d.parseStringValue()
+	}
+
+	if tok, ok := d.parseLiteralValue(); ok {
+		return tok, nil
+	}
+
+	if tok, ok := d.parseNumberValue(); ok {
+		return tok, nil
+	}
+
+	return Token{}, d.newSyntaxError("invalid scalar value: %s", errRegexp.Find(d.in))
+}
+
+// parseLiteralValue parses a literal value. A literal value is used for
+// bools, special floats and enums. This function simply identifies that the
+// field value is a literal.
+func (d *Decoder) parseLiteralValue() (Token, bool) {
+	size := parseIdent(d.in, true)
+	if size == 0 {
+		return Token{}, false
+	}
+	return d.consumeToken(Scalar, size, literalValue), true
+}
+
+// consumeToken constructs a Token for given Kind from d.in and consumes given
+// size-length from it.
+func (d *Decoder) consumeToken(kind Kind, size int, attrs uint8) Token {
+	// Important to compute raw and pos before consuming.
+	tok := Token{
+		kind:  kind,
+		attrs: attrs,
+		pos:   len(d.orig) - len(d.in),
+		raw:   d.in[:size],
+	}
+	d.consume(size)
+	return tok
+}
+
+// newSyntaxError returns a syntax error with line and column information for
+// current position.
+func (d *Decoder) newSyntaxError(f string, x ...interface{}) error {
+	e := errors.New(f, x...)
+	line, column := d.Position(len(d.orig) - len(d.in))
+	return errors.New("syntax error (line %d:%d): %v", line, column, e)
+}
+
+// Position returns line and column number of given index of the original input.
+// It will panic if index is out of range.
+func (d *Decoder) Position(idx int) (line int, column int) {
+	b := d.orig[:idx]
+	line = bytes.Count(b, []byte("\n")) + 1
+	if i := bytes.LastIndexByte(b, '\n'); i >= 0 {
+		b = b[i+1:]
+	}
+	column = utf8.RuneCount(b) + 1 // ignore multi-rune characters
+	return line, column
+}
+
+func (d *Decoder) tryConsumeChar(c byte) bool {
+	if len(d.in) > 0 && d.in[0] == c {
+		d.consume(1)
+		return true
+	}
+	return false
+}
+
+// consume consumes n bytes of input and any subsequent whitespace or comments.
+func (d *Decoder) consume(n int) {
+	d.in = consume(d.in, n)
+	return
+}
+
+// consume consumes n bytes of input and any subsequent whitespace or comments.
+func consume(b []byte, n int) []byte {
+	b = b[n:]
+	for len(b) > 0 {
+		switch b[0] {
+		case ' ', '\n', '\r', '\t':
+			b = b[1:]
+		case '#':
+			if i := bytes.IndexByte(b, '\n'); i >= 0 {
+				b = b[i+len("\n"):]
+			} else {
+				b = nil
+			}
+		default:
+			return b
+		}
+	}
+	return b
+}
+
+// Any sequence that looks like a non-delimiter (for error reporting).
+var errRegexp = regexp.MustCompile(`^([-+._a-zA-Z0-9\/]+|.)`)
+
+// isDelim returns true if given byte is a delimiter character.
+func isDelim(c byte) bool {
+	return !(c == '-' || c == '+' || c == '.' || c == '_' ||
+		('a' <= c && c <= 'z') ||
+		('A' <= c && c <= 'Z') ||
+		('0' <= c && c <= '9'))
+}
diff --git a/demo_test/vendor/google.golang.org/protobuf/internal/encoding/text/decode_number.go b/demo_test/vendor/google.golang.org/protobuf/internal/encoding/text/decode_number.go
new file mode 100644
index 0000000..f2d90b7
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/internal/encoding/text/decode_number.go
@@ -0,0 +1,190 @@
+// 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 text
+
+// parseNumberValue parses a number from the input and returns a Token object.
+func (d *Decoder) parseNumberValue() (Token, bool) {
+	in := d.in
+	num := parseNumber(in)
+	if num.size == 0 {
+		return Token{}, false
+	}
+	numAttrs := num.kind
+	if num.neg {
+		numAttrs |= isNegative
+	}
+	strSize := num.size
+	last := num.size - 1
+	if num.kind == numFloat && (d.in[last] == 'f' || d.in[last] == 'F') {
+		strSize = last
+	}
+	tok := Token{
+		kind:     Scalar,
+		attrs:    numberValue,
+		pos:      len(d.orig) - len(d.in),
+		raw:      d.in[:num.size],
+		str:      string(d.in[:strSize]),
+		numAttrs: numAttrs,
+	}
+	d.consume(num.size)
+	return tok, true
+}
+
+const (
+	numDec uint8 = (1 << iota) / 2
+	numHex
+	numOct
+	numFloat
+)
+
+// number is the result of parsing out a valid number from parseNumber. It
+// contains data for doing float or integer conversion via the strconv package
+// in conjunction with the input bytes.
+type number struct {
+	kind uint8
+	neg  bool
+	size int
+}
+
+// parseNumber constructs a number object from given input. It allows for the
+// following patterns:
+//   integer: ^-?([1-9][0-9]*|0[xX][0-9a-fA-F]+|0[0-7]*)
+//   float: ^-?((0|[1-9][0-9]*)?([.][0-9]*)?([eE][+-]?[0-9]+)?[fF]?)
+// It also returns the number of parsed bytes for the given number, 0 if it is
+// not a number.
+func parseNumber(input []byte) number {
+	kind := numDec
+	var size int
+	var neg bool
+
+	s := input
+	if len(s) == 0 {
+		return number{}
+	}
+
+	// Optional -
+	if s[0] == '-' {
+		neg = true
+		s = s[1:]
+		size++
+		if len(s) == 0 {
+			return number{}
+		}
+	}
+
+	// C++ allows for whitespace and comments in between the negative sign and
+	// the rest of the number. This logic currently does not but is consistent
+	// with v1.
+
+	switch {
+	case s[0] == '0':
+		if len(s) > 1 {
+			switch {
+			case s[1] == 'x' || s[1] == 'X':
+				// Parse as hex number.
+				kind = numHex
+				n := 2
+				s = s[2:]
+				for len(s) > 0 && (('0' <= s[0] && s[0] <= '9') ||
+					('a' <= s[0] && s[0] <= 'f') ||
+					('A' <= s[0] && s[0] <= 'F')) {
+					s = s[1:]
+					n++
+				}
+				if n == 2 {
+					return number{}
+				}
+				size += n
+
+			case '0' <= s[1] && s[1] <= '7':
+				// Parse as octal number.
+				kind = numOct
+				n := 2
+				s = s[2:]
+				for len(s) > 0 && '0' <= s[0] && s[0] <= '7' {
+					s = s[1:]
+					n++
+				}
+				size += n
+			}
+
+			if kind&(numHex|numOct) > 0 {
+				if len(s) > 0 && !isDelim(s[0]) {
+					return number{}
+				}
+				return number{kind: kind, neg: neg, size: size}
+			}
+		}
+		s = s[1:]
+		size++
+
+	case '1' <= s[0] && s[0] <= '9':
+		n := 1
+		s = s[1:]
+		for len(s) > 0 && '0' <= s[0] && s[0] <= '9' {
+			s = s[1:]
+			n++
+		}
+		size += n
+
+	case s[0] == '.':
+		// Set kind to numFloat to signify the intent to parse as float. And
+		// that it needs to have other digits after '.'.
+		kind = numFloat
+
+	default:
+		return number{}
+	}
+
+	// . followed by 0 or more digits.
+	if len(s) > 0 && s[0] == '.' {
+		n := 1
+		s = s[1:]
+		// If decimal point was before any digits, it should be followed by
+		// other digits.
+		if len(s) == 0 && kind == numFloat {
+			return number{}
+		}
+		for len(s) > 0 && '0' <= s[0] && s[0] <= '9' {
+			s = s[1:]
+			n++
+		}
+		size += n
+		kind = numFloat
+	}
+
+	// e or E followed by an optional - or + and 1 or more digits.
+	if len(s) >= 2 && (s[0] == 'e' || s[0] == 'E') {
+		kind = numFloat
+		s = s[1:]
+		n := 1
+		if s[0] == '+' || s[0] == '-' {
+			s = s[1:]
+			n++
+			if len(s) == 0 {
+				return number{}
+			}
+		}
+		for len(s) > 0 && '0' <= s[0] && s[0] <= '9' {
+			s = s[1:]
+			n++
+		}
+		size += n
+	}
+
+	// Optional suffix f or F for floats.
+	if len(s) > 0 && (s[0] == 'f' || s[0] == 'F') {
+		kind = numFloat
+		s = s[1:]
+		size++
+	}
+
+	// Check that next byte is a delimiter or it is at the end.
+	if len(s) > 0 && !isDelim(s[0]) {
+		return number{}
+	}
+
+	return number{kind: kind, neg: neg, size: size}
+}
diff --git a/demo_test/vendor/google.golang.org/protobuf/internal/encoding/text/decode_string.go b/demo_test/vendor/google.golang.org/protobuf/internal/encoding/text/decode_string.go
new file mode 100644
index 0000000..d4d3490
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/internal/encoding/text/decode_string.go
@@ -0,0 +1,161 @@
+// 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 text
+
+import (
+	"bytes"
+	"strconv"
+	"strings"
+	"unicode"
+	"unicode/utf16"
+	"unicode/utf8"
+
+	"google.golang.org/protobuf/internal/strs"
+)
+
+// parseStringValue parses string field token.
+// This differs from parseString since the text format allows
+// multiple back-to-back string literals where they are semantically treated
+// as a single large string with all values concatenated.
+//
+// E.g., `"foo" "bar" "baz"` => "foobarbaz"
+func (d *Decoder) parseStringValue() (Token, error) {
+	// Note that the ending quote is sufficient to unambiguously mark the end
+	// of a string. Thus, the text grammar does not require intervening
+	// whitespace or control characters in-between strings.
+	// Thus, the following is valid:
+	//	`"foo"'bar'"baz"` => "foobarbaz"
+	in0 := d.in
+	var ss []string
+	for len(d.in) > 0 && (d.in[0] == '"' || d.in[0] == '\'') {
+		s, err := d.parseString()
+		if err != nil {
+			return Token{}, err
+		}
+		ss = append(ss, s)
+	}
+	// d.in already points to the end of the value at this point.
+	return Token{
+		kind:  Scalar,
+		attrs: stringValue,
+		pos:   len(d.orig) - len(in0),
+		raw:   in0[:len(in0)-len(d.in)],
+		str:   strings.Join(ss, ""),
+	}, nil
+}
+
+// parseString parses a string value enclosed in " or '.
+func (d *Decoder) parseString() (string, error) {
+	in := d.in
+	if len(in) == 0 {
+		return "", ErrUnexpectedEOF
+	}
+	quote := in[0]
+	in = in[1:]
+	i := indexNeedEscapeInBytes(in)
+	in, out := in[i:], in[:i:i] // set cap to prevent mutations
+	for len(in) > 0 {
+		switch r, n := utf8.DecodeRune(in); {
+		case r == utf8.RuneError && n == 1:
+			return "", d.newSyntaxError("invalid UTF-8 detected")
+		case r == 0 || r == '\n':
+			return "", d.newSyntaxError("invalid character %q in string", r)
+		case r == rune(quote):
+			in = in[1:]
+			d.consume(len(d.in) - len(in))
+			return string(out), nil
+		case r == '\\':
+			if len(in) < 2 {
+				return "", ErrUnexpectedEOF
+			}
+			switch r := in[1]; r {
+			case '"', '\'', '\\', '?':
+				in, out = in[2:], append(out, r)
+			case 'a':
+				in, out = in[2:], append(out, '\a')
+			case 'b':
+				in, out = in[2:], append(out, '\b')
+			case 'n':
+				in, out = in[2:], append(out, '\n')
+			case 'r':
+				in, out = in[2:], append(out, '\r')
+			case 't':
+				in, out = in[2:], append(out, '\t')
+			case 'v':
+				in, out = in[2:], append(out, '\v')
+			case 'f':
+				in, out = in[2:], append(out, '\f')
+			case '0', '1', '2', '3', '4', '5', '6', '7':
+				// One, two, or three octal characters.
+				n := len(in[1:]) - len(bytes.TrimLeft(in[1:], "01234567"))
+				if n > 3 {
+					n = 3
+				}
+				v, err := strconv.ParseUint(string(in[1:1+n]), 8, 8)
+				if err != nil {
+					return "", d.newSyntaxError("invalid octal escape code %q in string", in[:1+n])
+				}
+				in, out = in[1+n:], append(out, byte(v))
+			case 'x':
+				// One or two hexadecimal characters.
+				n := len(in[2:]) - len(bytes.TrimLeft(in[2:], "0123456789abcdefABCDEF"))
+				if n > 2 {
+					n = 2
+				}
+				v, err := strconv.ParseUint(string(in[2:2+n]), 16, 8)
+				if err != nil {
+					return "", d.newSyntaxError("invalid hex escape code %q in string", in[:2+n])
+				}
+				in, out = in[2+n:], append(out, byte(v))
+			case 'u', 'U':
+				// Four or eight hexadecimal characters
+				n := 6
+				if r == 'U' {
+					n = 10
+				}
+				if len(in) < n {
+					return "", ErrUnexpectedEOF
+				}
+				v, err := strconv.ParseUint(string(in[2:n]), 16, 32)
+				if utf8.MaxRune < v || err != nil {
+					return "", d.newSyntaxError("invalid Unicode escape code %q in string", in[:n])
+				}
+				in = in[n:]
+
+				r := rune(v)
+				if utf16.IsSurrogate(r) {
+					if len(in) < 6 {
+						return "", ErrUnexpectedEOF
+					}
+					v, err := strconv.ParseUint(string(in[2:6]), 16, 16)
+					r = utf16.DecodeRune(r, rune(v))
+					if in[0] != '\\' || in[1] != 'u' || r == unicode.ReplacementChar || err != nil {
+						return "", d.newSyntaxError("invalid Unicode escape code %q in string", in[:6])
+					}
+					in = in[6:]
+				}
+				out = append(out, string(r)...)
+			default:
+				return "", d.newSyntaxError("invalid escape code %q in string", in[:2])
+			}
+		default:
+			i := indexNeedEscapeInBytes(in[n:])
+			in, out = in[n+i:], append(out, in[:n+i]...)
+		}
+	}
+	return "", ErrUnexpectedEOF
+}
+
+// indexNeedEscapeInString returns the index of the character that needs
+// escaping. If no characters need escaping, this returns the input length.
+func indexNeedEscapeInBytes(b []byte) int { return indexNeedEscapeInString(strs.UnsafeString(b)) }
+
+// UnmarshalString returns an unescaped string given a textproto string value.
+// String value needs to contain single or double quotes. This is only used by
+// internal/encoding/defval package for unmarshaling bytes.
+func UnmarshalString(s string) (string, error) {
+	d := NewDecoder([]byte(s))
+	return d.parseString()
+}
diff --git a/demo_test/vendor/google.golang.org/protobuf/internal/encoding/text/decode_token.go b/demo_test/vendor/google.golang.org/protobuf/internal/encoding/text/decode_token.go
new file mode 100644
index 0000000..83d2b0d
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/internal/encoding/text/decode_token.go
@@ -0,0 +1,373 @@
+// 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 text
+
+import (
+	"bytes"
+	"fmt"
+	"math"
+	"strconv"
+	"strings"
+
+	"google.golang.org/protobuf/internal/flags"
+)
+
+// Kind represents a token kind expressible in the textproto format.
+type Kind uint8
+
+// Kind values.
+const (
+	Invalid Kind = iota
+	EOF
+	Name   // Name indicates the field name.
+	Scalar // Scalar are scalar values, e.g. "string", 47, ENUM_LITERAL, true.
+	MessageOpen
+	MessageClose
+	ListOpen
+	ListClose
+
+	// comma and semi-colon are only for parsing in between values and should not be exposed.
+	comma
+	semicolon
+
+	// bof indicates beginning of file, which is the default token
+	// kind at the beginning of parsing.
+	bof = Invalid
+)
+
+func (t Kind) String() string {
+	switch t {
+	case Invalid:
+		return "<invalid>"
+	case EOF:
+		return "eof"
+	case Scalar:
+		return "scalar"
+	case Name:
+		return "name"
+	case MessageOpen:
+		return "{"
+	case MessageClose:
+		return "}"
+	case ListOpen:
+		return "["
+	case ListClose:
+		return "]"
+	case comma:
+		return ","
+	case semicolon:
+		return ";"
+	default:
+		return fmt.Sprintf("<invalid:%v>", uint8(t))
+	}
+}
+
+// NameKind represents different types of field names.
+type NameKind uint8
+
+// NameKind values.
+const (
+	IdentName NameKind = iota + 1
+	TypeName
+	FieldNumber
+)
+
+func (t NameKind) String() string {
+	switch t {
+	case IdentName:
+		return "IdentName"
+	case TypeName:
+		return "TypeName"
+	case FieldNumber:
+		return "FieldNumber"
+	default:
+		return fmt.Sprintf("<invalid:%v>", uint8(t))
+	}
+}
+
+// Bit mask in Token.attrs to indicate if a Name token is followed by the
+// separator char ':'. The field name separator char is optional for message
+// field or repeated message field, but required for all other types. Decoder
+// simply indicates whether a Name token is followed by separator or not.  It is
+// up to the prototext package to validate.
+const hasSeparator = 1 << 7
+
+// Scalar value types.
+const (
+	numberValue = iota + 1
+	stringValue
+	literalValue
+)
+
+// Bit mask in Token.numAttrs to indicate that the number is a negative.
+const isNegative = 1 << 7
+
+// Token provides a parsed token kind and value. Values are provided by the
+// different accessor methods.
+type Token struct {
+	// Kind of the Token object.
+	kind Kind
+	// attrs contains metadata for the following Kinds:
+	// Name: hasSeparator bit and one of NameKind.
+	// Scalar: one of numberValue, stringValue, literalValue.
+	attrs uint8
+	// numAttrs contains metadata for numberValue:
+	// - highest bit is whether negative or positive.
+	// - lower bits indicate one of numDec, numHex, numOct, numFloat.
+	numAttrs uint8
+	// pos provides the position of the token in the original input.
+	pos int
+	// raw bytes of the serialized token.
+	// This is a subslice into the original input.
+	raw []byte
+	// str contains parsed string for the following:
+	// - stringValue of Scalar kind
+	// - numberValue of Scalar kind
+	// - TypeName of Name kind
+	str string
+}
+
+// Kind returns the token kind.
+func (t Token) Kind() Kind {
+	return t.kind
+}
+
+// RawString returns the read value in string.
+func (t Token) RawString() string {
+	return string(t.raw)
+}
+
+// Pos returns the token position from the input.
+func (t Token) Pos() int {
+	return t.pos
+}
+
+// NameKind returns IdentName, TypeName or FieldNumber.
+// It panics if type is not Name.
+func (t Token) NameKind() NameKind {
+	if t.kind == Name {
+		return NameKind(t.attrs &^ hasSeparator)
+	}
+	panic(fmt.Sprintf("Token is not a Name type: %s", t.kind))
+}
+
+// HasSeparator returns true if the field name is followed by the separator char
+// ':', else false. It panics if type is not Name.
+func (t Token) HasSeparator() bool {
+	if t.kind == Name {
+		return t.attrs&hasSeparator != 0
+	}
+	panic(fmt.Sprintf("Token is not a Name type: %s", t.kind))
+}
+
+// IdentName returns the value for IdentName type.
+func (t Token) IdentName() string {
+	if t.kind == Name && t.attrs&uint8(IdentName) != 0 {
+		return string(t.raw)
+	}
+	panic(fmt.Sprintf("Token is not an IdentName: %s:%s", t.kind, NameKind(t.attrs&^hasSeparator)))
+}
+
+// TypeName returns the value for TypeName type.
+func (t Token) TypeName() string {
+	if t.kind == Name && t.attrs&uint8(TypeName) != 0 {
+		return t.str
+	}
+	panic(fmt.Sprintf("Token is not a TypeName: %s:%s", t.kind, NameKind(t.attrs&^hasSeparator)))
+}
+
+// FieldNumber returns the value for FieldNumber type. It returns a
+// non-negative int32 value. Caller will still need to validate for the correct
+// field number range.
+func (t Token) FieldNumber() int32 {
+	if t.kind != Name || t.attrs&uint8(FieldNumber) == 0 {
+		panic(fmt.Sprintf("Token is not a FieldNumber: %s:%s", t.kind, NameKind(t.attrs&^hasSeparator)))
+	}
+	// Following should not return an error as it had already been called right
+	// before this Token was constructed.
+	num, _ := strconv.ParseInt(string(t.raw), 10, 32)
+	return int32(num)
+}
+
+// String returns the string value for a Scalar type.
+func (t Token) String() (string, bool) {
+	if t.kind != Scalar || t.attrs != stringValue {
+		return "", false
+	}
+	return t.str, true
+}
+
+// Enum returns the literal value for a Scalar type for use as enum literals.
+func (t Token) Enum() (string, bool) {
+	if t.kind != Scalar || t.attrs != literalValue || (len(t.raw) > 0 && t.raw[0] == '-') {
+		return "", false
+	}
+	return string(t.raw), true
+}
+
+// Bool returns the bool value for a Scalar type.
+func (t Token) Bool() (bool, bool) {
+	if t.kind != Scalar {
+		return false, false
+	}
+	switch t.attrs {
+	case literalValue:
+		if b, ok := boolLits[string(t.raw)]; ok {
+			return b, true
+		}
+	case numberValue:
+		// Unsigned integer representation of 0 or 1 is permitted: 00, 0x0, 01,
+		// 0x1, etc.
+		n, err := strconv.ParseUint(t.str, 0, 64)
+		if err == nil {
+			switch n {
+			case 0:
+				return false, true
+			case 1:
+				return true, true
+			}
+		}
+	}
+	return false, false
+}
+
+// These exact boolean literals are the ones supported in C++.
+var boolLits = map[string]bool{
+	"t":     true,
+	"true":  true,
+	"True":  true,
+	"f":     false,
+	"false": false,
+	"False": false,
+}
+
+// Uint64 returns the uint64 value for a Scalar type.
+func (t Token) Uint64() (uint64, bool) {
+	if t.kind != Scalar || t.attrs != numberValue ||
+		t.numAttrs&isNegative > 0 || t.numAttrs&numFloat > 0 {
+		return 0, false
+	}
+	n, err := strconv.ParseUint(t.str, 0, 64)
+	if err != nil {
+		return 0, false
+	}
+	return n, true
+}
+
+// Uint32 returns the uint32 value for a Scalar type.
+func (t Token) Uint32() (uint32, bool) {
+	if t.kind != Scalar || t.attrs != numberValue ||
+		t.numAttrs&isNegative > 0 || t.numAttrs&numFloat > 0 {
+		return 0, false
+	}
+	n, err := strconv.ParseUint(t.str, 0, 32)
+	if err != nil {
+		return 0, false
+	}
+	return uint32(n), true
+}
+
+// Int64 returns the int64 value for a Scalar type.
+func (t Token) Int64() (int64, bool) {
+	if t.kind != Scalar || t.attrs != numberValue || t.numAttrs&numFloat > 0 {
+		return 0, false
+	}
+	if n, err := strconv.ParseInt(t.str, 0, 64); err == nil {
+		return n, true
+	}
+	// C++ accepts large positive hex numbers as negative values.
+	// This feature is here for proto1 backwards compatibility purposes.
+	if flags.ProtoLegacy && (t.numAttrs == numHex) {
+		if n, err := strconv.ParseUint(t.str, 0, 64); err == nil {
+			return int64(n), true
+		}
+	}
+	return 0, false
+}
+
+// Int32 returns the int32 value for a Scalar type.
+func (t Token) Int32() (int32, bool) {
+	if t.kind != Scalar || t.attrs != numberValue || t.numAttrs&numFloat > 0 {
+		return 0, false
+	}
+	if n, err := strconv.ParseInt(t.str, 0, 32); err == nil {
+		return int32(n), true
+	}
+	// C++ accepts large positive hex numbers as negative values.
+	// This feature is here for proto1 backwards compatibility purposes.
+	if flags.ProtoLegacy && (t.numAttrs == numHex) {
+		if n, err := strconv.ParseUint(t.str, 0, 32); err == nil {
+			return int32(n), true
+		}
+	}
+	return 0, false
+}
+
+// Float64 returns the float64 value for a Scalar type.
+func (t Token) Float64() (float64, bool) {
+	if t.kind != Scalar {
+		return 0, false
+	}
+	switch t.attrs {
+	case literalValue:
+		if f, ok := floatLits[strings.ToLower(string(t.raw))]; ok {
+			return f, true
+		}
+	case numberValue:
+		n, err := strconv.ParseFloat(t.str, 64)
+		if err == nil {
+			return n, true
+		}
+		nerr := err.(*strconv.NumError)
+		if nerr.Err == strconv.ErrRange {
+			return n, true
+		}
+	}
+	return 0, false
+}
+
+// Float32 returns the float32 value for a Scalar type.
+func (t Token) Float32() (float32, bool) {
+	if t.kind != Scalar {
+		return 0, false
+	}
+	switch t.attrs {
+	case literalValue:
+		if f, ok := floatLits[strings.ToLower(string(t.raw))]; ok {
+			return float32(f), true
+		}
+	case numberValue:
+		n, err := strconv.ParseFloat(t.str, 64)
+		if err == nil {
+			// Overflows are treated as (-)infinity.
+			return float32(n), true
+		}
+		nerr := err.(*strconv.NumError)
+		if nerr.Err == strconv.ErrRange {
+			return float32(n), true
+		}
+	}
+	return 0, false
+}
+
+// These are the supported float literals which C++ permits case-insensitive
+// variants of these.
+var floatLits = map[string]float64{
+	"nan":       math.NaN(),
+	"inf":       math.Inf(1),
+	"infinity":  math.Inf(1),
+	"-inf":      math.Inf(-1),
+	"-infinity": math.Inf(-1),
+}
+
+// TokenEquals returns true if given Tokens are equal, else false.
+func TokenEquals(x, y Token) bool {
+	return x.kind == y.kind &&
+		x.attrs == y.attrs &&
+		x.numAttrs == y.numAttrs &&
+		x.pos == y.pos &&
+		bytes.Equal(x.raw, y.raw) &&
+		x.str == y.str
+}
diff --git a/demo_test/vendor/google.golang.org/protobuf/internal/encoding/text/doc.go b/demo_test/vendor/google.golang.org/protobuf/internal/encoding/text/doc.go
new file mode 100644
index 0000000..0ce8d6f
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/internal/encoding/text/doc.go
@@ -0,0 +1,29 @@
+// 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 text implements the text format for protocol buffers.
+// This package has no semantic understanding for protocol buffers and is only
+// a parser and composer for the format.
+//
+// There is no formal specification for the protobuf text format, as such the
+// C++ implementation (see google::protobuf::TextFormat) is the reference
+// implementation of the text format.
+//
+// This package is neither a superset nor a subset of the C++ implementation.
+// This implementation permits a more liberal grammar in some cases to be
+// backwards compatible with the historical Go implementation.
+// Future parsings unique to Go should not be added.
+// Some grammars allowed by the C++ implementation are deliberately
+// not implemented here because they are considered a bug by the protobuf team
+// and should not be replicated.
+//
+// The Go implementation should implement a sufficient amount of the C++
+// grammar such that the default text serialization by C++ can be parsed by Go.
+// However, just because the C++ parser accepts some input does not mean that
+// the Go implementation should as well.
+//
+// The text format is almost a superset of JSON except:
+//	* message keys are not quoted strings, but identifiers
+//	* the top-level value must be a message without the delimiters
+package text
diff --git a/demo_test/vendor/google.golang.org/protobuf/internal/encoding/text/encode.go b/demo_test/vendor/google.golang.org/protobuf/internal/encoding/text/encode.go
new file mode 100644
index 0000000..c4ba1c5
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/internal/encoding/text/encode.go
@@ -0,0 +1,267 @@
+// 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 text
+
+import (
+	"math"
+	"math/bits"
+	"strconv"
+	"strings"
+	"unicode/utf8"
+
+	"google.golang.org/protobuf/internal/detrand"
+	"google.golang.org/protobuf/internal/errors"
+)
+
+// encType represents an encoding type.
+type encType uint8
+
+const (
+	_ encType = (1 << iota) / 2
+	name
+	scalar
+	messageOpen
+	messageClose
+)
+
+// Encoder provides methods to write out textproto constructs and values. The user is
+// responsible for producing valid sequences of constructs and values.
+type Encoder struct {
+	encoderState
+
+	indent      string
+	newline     string // set to "\n" if len(indent) > 0
+	delims      [2]byte
+	outputASCII bool
+}
+
+type encoderState struct {
+	lastType encType
+	indents  []byte
+	out      []byte
+}
+
+// NewEncoder returns an Encoder.
+//
+// If indent is a non-empty string, it causes every entry in a List or Message
+// to be preceded by the indent and trailed by a newline.
+//
+// If delims is not the zero value, it controls the delimiter characters used
+// for messages (e.g., "{}" vs "<>").
+//
+// If outputASCII is true, strings will be serialized in such a way that
+// multi-byte UTF-8 sequences are escaped. This property ensures that the
+// overall output is ASCII (as opposed to UTF-8).
+func NewEncoder(indent string, delims [2]byte, outputASCII bool) (*Encoder, error) {
+	e := &Encoder{}
+	if len(indent) > 0 {
+		if strings.Trim(indent, " \t") != "" {
+			return nil, errors.New("indent may only be composed of space and tab characters")
+		}
+		e.indent = indent
+		e.newline = "\n"
+	}
+	switch delims {
+	case [2]byte{0, 0}:
+		e.delims = [2]byte{'{', '}'}
+	case [2]byte{'{', '}'}, [2]byte{'<', '>'}:
+		e.delims = delims
+	default:
+		return nil, errors.New("delimiters may only be \"{}\" or \"<>\"")
+	}
+	e.outputASCII = outputASCII
+
+	return e, nil
+}
+
+// Bytes returns the content of the written bytes.
+func (e *Encoder) Bytes() []byte {
+	return e.out
+}
+
+// StartMessage writes out the '{' or '<' symbol.
+func (e *Encoder) StartMessage() {
+	e.prepareNext(messageOpen)
+	e.out = append(e.out, e.delims[0])
+}
+
+// EndMessage writes out the '}' or '>' symbol.
+func (e *Encoder) EndMessage() {
+	e.prepareNext(messageClose)
+	e.out = append(e.out, e.delims[1])
+}
+
+// WriteName writes out the field name and the separator ':'.
+func (e *Encoder) WriteName(s string) {
+	e.prepareNext(name)
+	e.out = append(e.out, s...)
+	e.out = append(e.out, ':')
+}
+
+// WriteBool writes out the given boolean value.
+func (e *Encoder) WriteBool(b bool) {
+	if b {
+		e.WriteLiteral("true")
+	} else {
+		e.WriteLiteral("false")
+	}
+}
+
+// WriteString writes out the given string value.
+func (e *Encoder) WriteString(s string) {
+	e.prepareNext(scalar)
+	e.out = appendString(e.out, s, e.outputASCII)
+}
+
+func appendString(out []byte, in string, outputASCII bool) []byte {
+	out = append(out, '"')
+	i := indexNeedEscapeInString(in)
+	in, out = in[i:], append(out, in[:i]...)
+	for len(in) > 0 {
+		switch r, n := utf8.DecodeRuneInString(in); {
+		case r == utf8.RuneError && n == 1:
+			// We do not report invalid UTF-8 because strings in the text format
+			// are used to represent both the proto string and bytes type.
+			r = rune(in[0])
+			fallthrough
+		case r < ' ' || r == '"' || r == '\\':
+			out = append(out, '\\')
+			switch r {
+			case '"', '\\':
+				out = append(out, byte(r))
+			case '\n':
+				out = append(out, 'n')
+			case '\r':
+				out = append(out, 'r')
+			case '\t':
+				out = append(out, 't')
+			default:
+				out = append(out, 'x')
+				out = append(out, "00"[1+(bits.Len32(uint32(r))-1)/4:]...)
+				out = strconv.AppendUint(out, uint64(r), 16)
+			}
+			in = in[n:]
+		case outputASCII && r >= utf8.RuneSelf:
+			out = append(out, '\\')
+			if r <= math.MaxUint16 {
+				out = append(out, 'u')
+				out = append(out, "0000"[1+(bits.Len32(uint32(r))-1)/4:]...)
+				out = strconv.AppendUint(out, uint64(r), 16)
+			} else {
+				out = append(out, 'U')
+				out = append(out, "00000000"[1+(bits.Len32(uint32(r))-1)/4:]...)
+				out = strconv.AppendUint(out, uint64(r), 16)
+			}
+			in = in[n:]
+		default:
+			i := indexNeedEscapeInString(in[n:])
+			in, out = in[n+i:], append(out, in[:n+i]...)
+		}
+	}
+	out = append(out, '"')
+	return out
+}
+
+// indexNeedEscapeInString returns the index of the character that needs
+// escaping. If no characters need escaping, this returns the input length.
+func indexNeedEscapeInString(s string) int {
+	for i := 0; i < len(s); i++ {
+		if c := s[i]; c < ' ' || c == '"' || c == '\'' || c == '\\' || c >= utf8.RuneSelf {
+			return i
+		}
+	}
+	return len(s)
+}
+
+// WriteFloat writes out the given float value for given bitSize.
+func (e *Encoder) WriteFloat(n float64, bitSize int) {
+	e.prepareNext(scalar)
+	e.out = appendFloat(e.out, n, bitSize)
+}
+
+func appendFloat(out []byte, n float64, bitSize int) []byte {
+	switch {
+	case math.IsNaN(n):
+		return append(out, "nan"...)
+	case math.IsInf(n, +1):
+		return append(out, "inf"...)
+	case math.IsInf(n, -1):
+		return append(out, "-inf"...)
+	default:
+		return strconv.AppendFloat(out, n, 'g', -1, bitSize)
+	}
+}
+
+// WriteInt writes out the given signed integer value.
+func (e *Encoder) WriteInt(n int64) {
+	e.prepareNext(scalar)
+	e.out = append(e.out, strconv.FormatInt(n, 10)...)
+}
+
+// WriteUint writes out the given unsigned integer value.
+func (e *Encoder) WriteUint(n uint64) {
+	e.prepareNext(scalar)
+	e.out = append(e.out, strconv.FormatUint(n, 10)...)
+}
+
+// WriteLiteral writes out the given string as a literal value without quotes.
+// This is used for writing enum literal strings.
+func (e *Encoder) WriteLiteral(s string) {
+	e.prepareNext(scalar)
+	e.out = append(e.out, s...)
+}
+
+// prepareNext adds possible space and indentation for the next value based
+// on last encType and indent option. It also updates e.lastType to next.
+func (e *Encoder) prepareNext(next encType) {
+	defer func() {
+		e.lastType = next
+	}()
+
+	// Single line.
+	if len(e.indent) == 0 {
+		// Add space after each field before the next one.
+		if e.lastType&(scalar|messageClose) != 0 && next == name {
+			e.out = append(e.out, ' ')
+			// Add a random extra space to make output unstable.
+			if detrand.Bool() {
+				e.out = append(e.out, ' ')
+			}
+		}
+		return
+	}
+
+	// Multi-line.
+	switch {
+	case e.lastType == name:
+		e.out = append(e.out, ' ')
+		// Add a random extra space after name: to make output unstable.
+		if detrand.Bool() {
+			e.out = append(e.out, ' ')
+		}
+
+	case e.lastType == messageOpen && next != messageClose:
+		e.indents = append(e.indents, e.indent...)
+		e.out = append(e.out, '\n')
+		e.out = append(e.out, e.indents...)
+
+	case e.lastType&(scalar|messageClose) != 0:
+		if next == messageClose {
+			e.indents = e.indents[:len(e.indents)-len(e.indent)]
+		}
+		e.out = append(e.out, '\n')
+		e.out = append(e.out, e.indents...)
+	}
+}
+
+// Snapshot returns the current snapshot for use in Reset.
+func (e *Encoder) Snapshot() encoderState {
+	return e.encoderState
+}
+
+// Reset resets the Encoder to the given encoderState from a Snapshot.
+func (e *Encoder) Reset(es encoderState) {
+	e.encoderState = es
+}
diff --git a/demo_test/vendor/google.golang.org/protobuf/internal/errors/errors.go b/demo_test/vendor/google.golang.org/protobuf/internal/errors/errors.go
new file mode 100644
index 0000000..20c17b3
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/internal/errors/errors.go
@@ -0,0 +1,89 @@
+// 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 errors implements functions to manipulate errors.
+package errors
+
+import (
+	"errors"
+	"fmt"
+
+	"google.golang.org/protobuf/internal/detrand"
+)
+
+// Error is a sentinel matching all errors produced by this package.
+var Error = errors.New("protobuf error")
+
+// New formats a string according to the format specifier and arguments and
+// returns an error that has a "proto" prefix.
+func New(f string, x ...interface{}) error {
+	return &prefixError{s: format(f, x...)}
+}
+
+type prefixError struct{ s string }
+
+var prefix = func() string {
+	// Deliberately introduce instability into the error message string to
+	// discourage users from performing error string comparisons.
+	if detrand.Bool() {
+		return "proto: " // use non-breaking spaces (U+00a0)
+	} else {
+		return "proto: " // use regular spaces (U+0020)
+	}
+}()
+
+func (e *prefixError) Error() string {
+	return prefix + e.s
+}
+
+func (e *prefixError) Unwrap() error {
+	return Error
+}
+
+// Wrap returns an error that has a "proto" prefix, the formatted string described
+// by the format specifier and arguments, and a suffix of err. The error wraps err.
+func Wrap(err error, f string, x ...interface{}) error {
+	return &wrapError{
+		s:   format(f, x...),
+		err: err,
+	}
+}
+
+type wrapError struct {
+	s   string
+	err error
+}
+
+func (e *wrapError) Error() string {
+	return format("%v%v: %v", prefix, e.s, e.err)
+}
+
+func (e *wrapError) Unwrap() error {
+	return e.err
+}
+
+func (e *wrapError) Is(target error) bool {
+	return target == Error
+}
+
+func format(f string, x ...interface{}) string {
+	// avoid "proto: " prefix when chaining
+	for i := 0; i < len(x); i++ {
+		switch e := x[i].(type) {
+		case *prefixError:
+			x[i] = e.s
+		case *wrapError:
+			x[i] = format("%v: %v", e.s, e.err)
+		}
+	}
+	return fmt.Sprintf(f, x...)
+}
+
+func InvalidUTF8(name string) error {
+	return New("field %v contains invalid UTF-8", name)
+}
+
+func RequiredNotSet(name string) error {
+	return New("required field %v not set", name)
+}
diff --git a/demo_test/vendor/google.golang.org/protobuf/internal/errors/is_go112.go b/demo_test/vendor/google.golang.org/protobuf/internal/errors/is_go112.go
new file mode 100644
index 0000000..f90e909
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/internal/errors/is_go112.go
@@ -0,0 +1,39 @@
+// 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.
+
+// +build !go1.13
+
+package errors
+
+import "reflect"
+
+// Is is a copy of Go 1.13's errors.Is for use with older Go versions.
+func Is(err, target error) bool {
+	if target == nil {
+		return err == target
+	}
+
+	isComparable := reflect.TypeOf(target).Comparable()
+	for {
+		if isComparable && err == target {
+			return true
+		}
+		if x, ok := err.(interface{ Is(error) bool }); ok && x.Is(target) {
+			return true
+		}
+		if err = unwrap(err); err == nil {
+			return false
+		}
+	}
+}
+
+func unwrap(err error) error {
+	u, ok := err.(interface {
+		Unwrap() error
+	})
+	if !ok {
+		return nil
+	}
+	return u.Unwrap()
+}
diff --git a/demo_test/vendor/google.golang.org/protobuf/internal/errors/is_go113.go b/demo_test/vendor/google.golang.org/protobuf/internal/errors/is_go113.go
new file mode 100644
index 0000000..dc05f41
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/internal/errors/is_go113.go
@@ -0,0 +1,12 @@
+// 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.
+
+// +build go1.13
+
+package errors
+
+import "errors"
+
+// Is is errors.Is.
+func Is(err, target error) bool { return errors.Is(err, target) }
diff --git a/demo_test/vendor/google.golang.org/protobuf/internal/fieldnum/any_gen.go b/demo_test/vendor/google.golang.org/protobuf/internal/fieldnum/any_gen.go
new file mode 100644
index 0000000..74c5fef
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/internal/fieldnum/any_gen.go
@@ -0,0 +1,13 @@
+// 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.
+
+// Code generated by generate-protos. DO NOT EDIT.
+
+package fieldnum
+
+// Field numbers for google.protobuf.Any.
+const (
+	Any_TypeUrl = 1 // optional string
+	Any_Value   = 2 // optional bytes
+)
diff --git a/demo_test/vendor/google.golang.org/protobuf/internal/fieldnum/api_gen.go b/demo_test/vendor/google.golang.org/protobuf/internal/fieldnum/api_gen.go
new file mode 100644
index 0000000..9a6b5f2
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/internal/fieldnum/api_gen.go
@@ -0,0 +1,35 @@
+// 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.
+
+// Code generated by generate-protos. DO NOT EDIT.
+
+package fieldnum
+
+// Field numbers for google.protobuf.Api.
+const (
+	Api_Name          = 1 // optional string
+	Api_Methods       = 2 // repeated google.protobuf.Method
+	Api_Options       = 3 // repeated google.protobuf.Option
+	Api_Version       = 4 // optional string
+	Api_SourceContext = 5 // optional google.protobuf.SourceContext
+	Api_Mixins        = 6 // repeated google.protobuf.Mixin
+	Api_Syntax        = 7 // optional google.protobuf.Syntax
+)
+
+// Field numbers for google.protobuf.Method.
+const (
+	Method_Name              = 1 // optional string
+	Method_RequestTypeUrl    = 2 // optional string
+	Method_RequestStreaming  = 3 // optional bool
+	Method_ResponseTypeUrl   = 4 // optional string
+	Method_ResponseStreaming = 5 // optional bool
+	Method_Options           = 6 // repeated google.protobuf.Option
+	Method_Syntax            = 7 // optional google.protobuf.Syntax
+)
+
+// Field numbers for google.protobuf.Mixin.
+const (
+	Mixin_Name = 1 // optional string
+	Mixin_Root = 2 // optional string
+)
diff --git a/demo_test/vendor/google.golang.org/protobuf/internal/fieldnum/descriptor_gen.go b/demo_test/vendor/google.golang.org/protobuf/internal/fieldnum/descriptor_gen.go
new file mode 100644
index 0000000..1629515
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/internal/fieldnum/descriptor_gen.go
@@ -0,0 +1,239 @@
+// 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.
+
+// Code generated by generate-protos. DO NOT EDIT.
+
+package fieldnum
+
+// Field numbers for google.protobuf.FileDescriptorSet.
+const (
+	FileDescriptorSet_File = 1 // repeated google.protobuf.FileDescriptorProto
+)
+
+// Field numbers for google.protobuf.FileDescriptorProto.
+const (
+	FileDescriptorProto_Name             = 1  // optional string
+	FileDescriptorProto_Package          = 2  // optional string
+	FileDescriptorProto_Dependency       = 3  // repeated string
+	FileDescriptorProto_PublicDependency = 10 // repeated int32
+	FileDescriptorProto_WeakDependency   = 11 // repeated int32
+	FileDescriptorProto_MessageType      = 4  // repeated google.protobuf.DescriptorProto
+	FileDescriptorProto_EnumType         = 5  // repeated google.protobuf.EnumDescriptorProto
+	FileDescriptorProto_Service          = 6  // repeated google.protobuf.ServiceDescriptorProto
+	FileDescriptorProto_Extension        = 7  // repeated google.protobuf.FieldDescriptorProto
+	FileDescriptorProto_Options          = 8  // optional google.protobuf.FileOptions
+	FileDescriptorProto_SourceCodeInfo   = 9  // optional google.protobuf.SourceCodeInfo
+	FileDescriptorProto_Syntax           = 12 // optional string
+)
+
+// Field numbers for google.protobuf.DescriptorProto.
+const (
+	DescriptorProto_Name           = 1  // optional string
+	DescriptorProto_Field          = 2  // repeated google.protobuf.FieldDescriptorProto
+	DescriptorProto_Extension      = 6  // repeated google.protobuf.FieldDescriptorProto
+	DescriptorProto_NestedType     = 3  // repeated google.protobuf.DescriptorProto
+	DescriptorProto_EnumType       = 4  // repeated google.protobuf.EnumDescriptorProto
+	DescriptorProto_ExtensionRange = 5  // repeated google.protobuf.DescriptorProto.ExtensionRange
+	DescriptorProto_OneofDecl      = 8  // repeated google.protobuf.OneofDescriptorProto
+	DescriptorProto_Options        = 7  // optional google.protobuf.MessageOptions
+	DescriptorProto_ReservedRange  = 9  // repeated google.protobuf.DescriptorProto.ReservedRange
+	DescriptorProto_ReservedName   = 10 // repeated string
+)
+
+// Field numbers for google.protobuf.DescriptorProto.ExtensionRange.
+const (
+	DescriptorProto_ExtensionRange_Start   = 1 // optional int32
+	DescriptorProto_ExtensionRange_End     = 2 // optional int32
+	DescriptorProto_ExtensionRange_Options = 3 // optional google.protobuf.ExtensionRangeOptions
+)
+
+// Field numbers for google.protobuf.DescriptorProto.ReservedRange.
+const (
+	DescriptorProto_ReservedRange_Start = 1 // optional int32
+	DescriptorProto_ReservedRange_End   = 2 // optional int32
+)
+
+// Field numbers for google.protobuf.ExtensionRangeOptions.
+const (
+	ExtensionRangeOptions_UninterpretedOption = 999 // repeated google.protobuf.UninterpretedOption
+)
+
+// Field numbers for google.protobuf.FieldDescriptorProto.
+const (
+	FieldDescriptorProto_Name         = 1  // optional string
+	FieldDescriptorProto_Number       = 3  // optional int32
+	FieldDescriptorProto_Label        = 4  // optional google.protobuf.FieldDescriptorProto.Label
+	FieldDescriptorProto_Type         = 5  // optional google.protobuf.FieldDescriptorProto.Type
+	FieldDescriptorProto_TypeName     = 6  // optional string
+	FieldDescriptorProto_Extendee     = 2  // optional string
+	FieldDescriptorProto_DefaultValue = 7  // optional string
+	FieldDescriptorProto_OneofIndex   = 9  // optional int32
+	FieldDescriptorProto_JsonName     = 10 // optional string
+	FieldDescriptorProto_Options      = 8  // optional google.protobuf.FieldOptions
+)
+
+// Field numbers for google.protobuf.OneofDescriptorProto.
+const (
+	OneofDescriptorProto_Name    = 1 // optional string
+	OneofDescriptorProto_Options = 2 // optional google.protobuf.OneofOptions
+)
+
+// Field numbers for google.protobuf.EnumDescriptorProto.
+const (
+	EnumDescriptorProto_Name          = 1 // optional string
+	EnumDescriptorProto_Value         = 2 // repeated google.protobuf.EnumValueDescriptorProto
+	EnumDescriptorProto_Options       = 3 // optional google.protobuf.EnumOptions
+	EnumDescriptorProto_ReservedRange = 4 // repeated google.protobuf.EnumDescriptorProto.EnumReservedRange
+	EnumDescriptorProto_ReservedName  = 5 // repeated string
+)
+
+// Field numbers for google.protobuf.EnumDescriptorProto.EnumReservedRange.
+const (
+	EnumDescriptorProto_EnumReservedRange_Start = 1 // optional int32
+	EnumDescriptorProto_EnumReservedRange_End   = 2 // optional int32
+)
+
+// Field numbers for google.protobuf.EnumValueDescriptorProto.
+const (
+	EnumValueDescriptorProto_Name    = 1 // optional string
+	EnumValueDescriptorProto_Number  = 2 // optional int32
+	EnumValueDescriptorProto_Options = 3 // optional google.protobuf.EnumValueOptions
+)
+
+// Field numbers for google.protobuf.ServiceDescriptorProto.
+const (
+	ServiceDescriptorProto_Name    = 1 // optional string
+	ServiceDescriptorProto_Method  = 2 // repeated google.protobuf.MethodDescriptorProto
+	ServiceDescriptorProto_Options = 3 // optional google.protobuf.ServiceOptions
+)
+
+// Field numbers for google.protobuf.MethodDescriptorProto.
+const (
+	MethodDescriptorProto_Name            = 1 // optional string
+	MethodDescriptorProto_InputType       = 2 // optional string
+	MethodDescriptorProto_OutputType      = 3 // optional string
+	MethodDescriptorProto_Options         = 4 // optional google.protobuf.MethodOptions
+	MethodDescriptorProto_ClientStreaming = 5 // optional bool
+	MethodDescriptorProto_ServerStreaming = 6 // optional bool
+)
+
+// Field numbers for google.protobuf.FileOptions.
+const (
+	FileOptions_JavaPackage               = 1   // optional string
+	FileOptions_JavaOuterClassname        = 8   // optional string
+	FileOptions_JavaMultipleFiles         = 10  // optional bool
+	FileOptions_JavaGenerateEqualsAndHash = 20  // optional bool
+	FileOptions_JavaStringCheckUtf8       = 27  // optional bool
+	FileOptions_OptimizeFor               = 9   // optional google.protobuf.FileOptions.OptimizeMode
+	FileOptions_GoPackage                 = 11  // optional string
+	FileOptions_CcGenericServices         = 16  // optional bool
+	FileOptions_JavaGenericServices       = 17  // optional bool
+	FileOptions_PyGenericServices         = 18  // optional bool
+	FileOptions_PhpGenericServices        = 42  // optional bool
+	FileOptions_Deprecated                = 23  // optional bool
+	FileOptions_CcEnableArenas            = 31  // optional bool
+	FileOptions_ObjcClassPrefix           = 36  // optional string
+	FileOptions_CsharpNamespace           = 37  // optional string
+	FileOptions_SwiftPrefix               = 39  // optional string
+	FileOptions_PhpClassPrefix            = 40  // optional string
+	FileOptions_PhpNamespace              = 41  // optional string
+	FileOptions_PhpMetadataNamespace      = 44  // optional string
+	FileOptions_RubyPackage               = 45  // optional string
+	FileOptions_UninterpretedOption       = 999 // repeated google.protobuf.UninterpretedOption
+)
+
+// Field numbers for google.protobuf.MessageOptions.
+const (
+	MessageOptions_MessageSetWireFormat         = 1   // optional bool
+	MessageOptions_NoStandardDescriptorAccessor = 2   // optional bool
+	MessageOptions_Deprecated                   = 3   // optional bool
+	MessageOptions_MapEntry                     = 7   // optional bool
+	MessageOptions_UninterpretedOption          = 999 // repeated google.protobuf.UninterpretedOption
+)
+
+// Field numbers for google.protobuf.FieldOptions.
+const (
+	FieldOptions_Ctype               = 1   // optional google.protobuf.FieldOptions.CType
+	FieldOptions_Packed              = 2   // optional bool
+	FieldOptions_Jstype              = 6   // optional google.protobuf.FieldOptions.JSType
+	FieldOptions_Lazy                = 5   // optional bool
+	FieldOptions_Deprecated          = 3   // optional bool
+	FieldOptions_Weak                = 10  // optional bool
+	FieldOptions_UninterpretedOption = 999 // repeated google.protobuf.UninterpretedOption
+)
+
+// Field numbers for google.protobuf.OneofOptions.
+const (
+	OneofOptions_UninterpretedOption = 999 // repeated google.protobuf.UninterpretedOption
+)
+
+// Field numbers for google.protobuf.EnumOptions.
+const (
+	EnumOptions_AllowAlias          = 2   // optional bool
+	EnumOptions_Deprecated          = 3   // optional bool
+	EnumOptions_UninterpretedOption = 999 // repeated google.protobuf.UninterpretedOption
+)
+
+// Field numbers for google.protobuf.EnumValueOptions.
+const (
+	EnumValueOptions_Deprecated          = 1   // optional bool
+	EnumValueOptions_UninterpretedOption = 999 // repeated google.protobuf.UninterpretedOption
+)
+
+// Field numbers for google.protobuf.ServiceOptions.
+const (
+	ServiceOptions_Deprecated          = 33  // optional bool
+	ServiceOptions_UninterpretedOption = 999 // repeated google.protobuf.UninterpretedOption
+)
+
+// Field numbers for google.protobuf.MethodOptions.
+const (
+	MethodOptions_Deprecated          = 33  // optional bool
+	MethodOptions_IdempotencyLevel    = 34  // optional google.protobuf.MethodOptions.IdempotencyLevel
+	MethodOptions_UninterpretedOption = 999 // repeated google.protobuf.UninterpretedOption
+)
+
+// Field numbers for google.protobuf.UninterpretedOption.
+const (
+	UninterpretedOption_Name             = 2 // repeated google.protobuf.UninterpretedOption.NamePart
+	UninterpretedOption_IdentifierValue  = 3 // optional string
+	UninterpretedOption_PositiveIntValue = 4 // optional uint64
+	UninterpretedOption_NegativeIntValue = 5 // optional int64
+	UninterpretedOption_DoubleValue      = 6 // optional double
+	UninterpretedOption_StringValue      = 7 // optional bytes
+	UninterpretedOption_AggregateValue   = 8 // optional string
+)
+
+// Field numbers for google.protobuf.UninterpretedOption.NamePart.
+const (
+	UninterpretedOption_NamePart_NamePart    = 1 // required string
+	UninterpretedOption_NamePart_IsExtension = 2 // required bool
+)
+
+// Field numbers for google.protobuf.SourceCodeInfo.
+const (
+	SourceCodeInfo_Location = 1 // repeated google.protobuf.SourceCodeInfo.Location
+)
+
+// Field numbers for google.protobuf.SourceCodeInfo.Location.
+const (
+	SourceCodeInfo_Location_Path                    = 1 // repeated int32
+	SourceCodeInfo_Location_Span                    = 2 // repeated int32
+	SourceCodeInfo_Location_LeadingComments         = 3 // optional string
+	SourceCodeInfo_Location_TrailingComments        = 4 // optional string
+	SourceCodeInfo_Location_LeadingDetachedComments = 6 // repeated string
+)
+
+// Field numbers for google.protobuf.GeneratedCodeInfo.
+const (
+	GeneratedCodeInfo_Annotation = 1 // repeated google.protobuf.GeneratedCodeInfo.Annotation
+)
+
+// Field numbers for google.protobuf.GeneratedCodeInfo.Annotation.
+const (
+	GeneratedCodeInfo_Annotation_Path       = 1 // repeated int32
+	GeneratedCodeInfo_Annotation_SourceFile = 2 // optional string
+	GeneratedCodeInfo_Annotation_Begin      = 3 // optional int32
+	GeneratedCodeInfo_Annotation_End        = 4 // optional int32
+)
diff --git a/demo_test/vendor/google.golang.org/protobuf/internal/fieldnum/doc.go b/demo_test/vendor/google.golang.org/protobuf/internal/fieldnum/doc.go
new file mode 100644
index 0000000..e597885
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/internal/fieldnum/doc.go
@@ -0,0 +1,7 @@
+// 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 fieldnum contains constants for field numbers of fields in messages
+// declared in descriptor.proto and any of the well-known types.
+package fieldnum
diff --git a/demo_test/vendor/google.golang.org/protobuf/internal/fieldnum/duration_gen.go b/demo_test/vendor/google.golang.org/protobuf/internal/fieldnum/duration_gen.go
new file mode 100644
index 0000000..8816c73
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/internal/fieldnum/duration_gen.go
@@ -0,0 +1,13 @@
+// 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.
+
+// Code generated by generate-protos. DO NOT EDIT.
+
+package fieldnum
+
+// Field numbers for google.protobuf.Duration.
+const (
+	Duration_Seconds = 1 // optional int64
+	Duration_Nanos   = 2 // optional int32
+)
diff --git a/demo_test/vendor/google.golang.org/protobuf/internal/fieldnum/empty_gen.go b/demo_test/vendor/google.golang.org/protobuf/internal/fieldnum/empty_gen.go
new file mode 100644
index 0000000..b5130a6
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/internal/fieldnum/empty_gen.go
@@ -0,0 +1,10 @@
+// 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.
+
+// Code generated by generate-protos. DO NOT EDIT.
+
+package fieldnum
+
+// Field numbers for google.protobuf.Empty.
+const ()
diff --git a/demo_test/vendor/google.golang.org/protobuf/internal/fieldnum/field_mask_gen.go b/demo_test/vendor/google.golang.org/protobuf/internal/fieldnum/field_mask_gen.go
new file mode 100644
index 0000000..7e3bfa2
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/internal/fieldnum/field_mask_gen.go
@@ -0,0 +1,12 @@
+// 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.
+
+// Code generated by generate-protos. DO NOT EDIT.
+
+package fieldnum
+
+// Field numbers for google.protobuf.FieldMask.
+const (
+	FieldMask_Paths = 1 // repeated string
+)
diff --git a/demo_test/vendor/google.golang.org/protobuf/internal/fieldnum/source_context_gen.go b/demo_test/vendor/google.golang.org/protobuf/internal/fieldnum/source_context_gen.go
new file mode 100644
index 0000000..241972b
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/internal/fieldnum/source_context_gen.go
@@ -0,0 +1,12 @@
+// 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.
+
+// Code generated by generate-protos. DO NOT EDIT.
+
+package fieldnum
+
+// Field numbers for google.protobuf.SourceContext.
+const (
+	SourceContext_FileName = 1 // optional string
+)
diff --git a/demo_test/vendor/google.golang.org/protobuf/internal/fieldnum/struct_gen.go b/demo_test/vendor/google.golang.org/protobuf/internal/fieldnum/struct_gen.go
new file mode 100644
index 0000000..c460aab
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/internal/fieldnum/struct_gen.go
@@ -0,0 +1,33 @@
+// 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.
+
+// Code generated by generate-protos. DO NOT EDIT.
+
+package fieldnum
+
+// Field numbers for google.protobuf.Struct.
+const (
+	Struct_Fields = 1 // repeated google.protobuf.Struct.FieldsEntry
+)
+
+// Field numbers for google.protobuf.Struct.FieldsEntry.
+const (
+	Struct_FieldsEntry_Key   = 1 // optional string
+	Struct_FieldsEntry_Value = 2 // optional google.protobuf.Value
+)
+
+// Field numbers for google.protobuf.Value.
+const (
+	Value_NullValue   = 1 // optional google.protobuf.NullValue
+	Value_NumberValue = 2 // optional double
+	Value_StringValue = 3 // optional string
+	Value_BoolValue   = 4 // optional bool
+	Value_StructValue = 5 // optional google.protobuf.Struct
+	Value_ListValue   = 6 // optional google.protobuf.ListValue
+)
+
+// Field numbers for google.protobuf.ListValue.
+const (
+	ListValue_Values = 1 // repeated google.protobuf.Value
+)
diff --git a/demo_test/vendor/google.golang.org/protobuf/internal/fieldnum/timestamp_gen.go b/demo_test/vendor/google.golang.org/protobuf/internal/fieldnum/timestamp_gen.go
new file mode 100644
index 0000000..b4346fb
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/internal/fieldnum/timestamp_gen.go
@@ -0,0 +1,13 @@
+// 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.
+
+// Code generated by generate-protos. DO NOT EDIT.
+
+package fieldnum
+
+// Field numbers for google.protobuf.Timestamp.
+const (
+	Timestamp_Seconds = 1 // optional int64
+	Timestamp_Nanos   = 2 // optional int32
+)
diff --git a/demo_test/vendor/google.golang.org/protobuf/internal/fieldnum/type_gen.go b/demo_test/vendor/google.golang.org/protobuf/internal/fieldnum/type_gen.go
new file mode 100644
index 0000000..b392e95
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/internal/fieldnum/type_gen.go
@@ -0,0 +1,53 @@
+// 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.
+
+// Code generated by generate-protos. DO NOT EDIT.
+
+package fieldnum
+
+// Field numbers for google.protobuf.Type.
+const (
+	Type_Name          = 1 // optional string
+	Type_Fields        = 2 // repeated google.protobuf.Field
+	Type_Oneofs        = 3 // repeated string
+	Type_Options       = 4 // repeated google.protobuf.Option
+	Type_SourceContext = 5 // optional google.protobuf.SourceContext
+	Type_Syntax        = 6 // optional google.protobuf.Syntax
+)
+
+// Field numbers for google.protobuf.Field.
+const (
+	Field_Kind         = 1  // optional google.protobuf.Field.Kind
+	Field_Cardinality  = 2  // optional google.protobuf.Field.Cardinality
+	Field_Number       = 3  // optional int32
+	Field_Name         = 4  // optional string
+	Field_TypeUrl      = 6  // optional string
+	Field_OneofIndex   = 7  // optional int32
+	Field_Packed       = 8  // optional bool
+	Field_Options      = 9  // repeated google.protobuf.Option
+	Field_JsonName     = 10 // optional string
+	Field_DefaultValue = 11 // optional string
+)
+
+// Field numbers for google.protobuf.Enum.
+const (
+	Enum_Name          = 1 // optional string
+	Enum_Enumvalue     = 2 // repeated google.protobuf.EnumValue
+	Enum_Options       = 3 // repeated google.protobuf.Option
+	Enum_SourceContext = 4 // optional google.protobuf.SourceContext
+	Enum_Syntax        = 5 // optional google.protobuf.Syntax
+)
+
+// Field numbers for google.protobuf.EnumValue.
+const (
+	EnumValue_Name    = 1 // optional string
+	EnumValue_Number  = 2 // optional int32
+	EnumValue_Options = 3 // repeated google.protobuf.Option
+)
+
+// Field numbers for google.protobuf.Option.
+const (
+	Option_Name  = 1 // optional string
+	Option_Value = 2 // optional google.protobuf.Any
+)
diff --git a/demo_test/vendor/google.golang.org/protobuf/internal/fieldnum/wrappers_gen.go b/demo_test/vendor/google.golang.org/protobuf/internal/fieldnum/wrappers_gen.go
new file mode 100644
index 0000000..42f846a
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/internal/fieldnum/wrappers_gen.go
@@ -0,0 +1,52 @@
+// 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.
+
+// Code generated by generate-protos. DO NOT EDIT.
+
+package fieldnum
+
+// Field numbers for google.protobuf.DoubleValue.
+const (
+	DoubleValue_Value = 1 // optional double
+)
+
+// Field numbers for google.protobuf.FloatValue.
+const (
+	FloatValue_Value = 1 // optional float
+)
+
+// Field numbers for google.protobuf.Int64Value.
+const (
+	Int64Value_Value = 1 // optional int64
+)
+
+// Field numbers for google.protobuf.UInt64Value.
+const (
+	UInt64Value_Value = 1 // optional uint64
+)
+
+// Field numbers for google.protobuf.Int32Value.
+const (
+	Int32Value_Value = 1 // optional int32
+)
+
+// Field numbers for google.protobuf.UInt32Value.
+const (
+	UInt32Value_Value = 1 // optional uint32
+)
+
+// Field numbers for google.protobuf.BoolValue.
+const (
+	BoolValue_Value = 1 // optional bool
+)
+
+// Field numbers for google.protobuf.StringValue.
+const (
+	StringValue_Value = 1 // optional string
+)
+
+// Field numbers for google.protobuf.BytesValue.
+const (
+	BytesValue_Value = 1 // optional bytes
+)
diff --git a/demo_test/vendor/google.golang.org/protobuf/internal/fieldsort/fieldsort.go b/demo_test/vendor/google.golang.org/protobuf/internal/fieldsort/fieldsort.go
new file mode 100644
index 0000000..1cb2d74
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/internal/fieldsort/fieldsort.go
@@ -0,0 +1,40 @@
+// 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 fieldsort defines an ordering of fields.
+//
+// The ordering defined by this package matches the historic behavior of the proto
+// package, placing extensions first and oneofs last.
+//
+// There is no guarantee about stability of the wire encoding, and users should not
+// depend on the order defined in this package as it is subject to change without
+// notice.
+package fieldsort
+
+import (
+	"google.golang.org/protobuf/reflect/protoreflect"
+)
+
+// Less returns true if field a comes before field j in ordered wire marshal output.
+func Less(a, b protoreflect.FieldDescriptor) bool {
+	ea := a.IsExtension()
+	eb := b.IsExtension()
+	oa := a.ContainingOneof()
+	ob := b.ContainingOneof()
+	switch {
+	case ea != eb:
+		return ea
+	case oa != nil && ob != nil:
+		if oa == ob {
+			return a.Number() < b.Number()
+		}
+		return oa.Index() < ob.Index()
+	case oa != nil:
+		return false
+	case ob != nil:
+		return true
+	default:
+		return a.Number() < b.Number()
+	}
+}
diff --git a/demo_test/vendor/google.golang.org/protobuf/internal/filedesc/build.go b/demo_test/vendor/google.golang.org/protobuf/internal/filedesc/build.go
new file mode 100644
index 0000000..462d384
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/internal/filedesc/build.go
@@ -0,0 +1,155 @@
+// 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 filedesc provides functionality for constructing descriptors.
+package filedesc
+
+import (
+	"google.golang.org/protobuf/encoding/protowire"
+	"google.golang.org/protobuf/internal/fieldnum"
+	"google.golang.org/protobuf/reflect/protoreflect"
+	pref "google.golang.org/protobuf/reflect/protoreflect"
+	preg "google.golang.org/protobuf/reflect/protoregistry"
+)
+
+// Builder construct a protoreflect.FileDescriptor from the raw descriptor.
+type Builder struct {
+	// GoPackagePath is the Go package path that is invoking this builder.
+	GoPackagePath string
+
+	// RawDescriptor is the wire-encoded bytes of FileDescriptorProto
+	// and must be populated.
+	RawDescriptor []byte
+
+	// NumEnums is the total number of enums declared in the file.
+	NumEnums int32
+	// NumMessages is the total number of messages declared in the file.
+	// It includes the implicit message declarations for map entries.
+	NumMessages int32
+	// NumExtensions is the total number of extensions declared in the file.
+	NumExtensions int32
+	// NumServices is the total number of services declared in the file.
+	NumServices int32
+
+	// TypeResolver resolves extension field types for descriptor options.
+	// If nil, it uses protoregistry.GlobalTypes.
+	TypeResolver interface {
+		preg.ExtensionTypeResolver
+	}
+
+	// FileRegistry is use to lookup file, enum, and message dependencies.
+	// Once constructed, the file descriptor is registered here.
+	// If nil, it uses protoregistry.GlobalFiles.
+	FileRegistry interface {
+		FindFileByPath(string) (protoreflect.FileDescriptor, error)
+		FindDescriptorByName(pref.FullName) (pref.Descriptor, error)
+		RegisterFile(pref.FileDescriptor) error
+	}
+}
+
+// resolverByIndex is an interface Builder.FileRegistry may implement.
+// If so, it permits looking up an enum or message dependency based on the
+// sub-list and element index into filetype.Builder.DependencyIndexes.
+type resolverByIndex interface {
+	FindEnumByIndex(int32, int32, []Enum, []Message) pref.EnumDescriptor
+	FindMessageByIndex(int32, int32, []Enum, []Message) pref.MessageDescriptor
+}
+
+// Indexes of each sub-list in filetype.Builder.DependencyIndexes.
+const (
+	listFieldDeps int32 = iota
+	listExtTargets
+	listExtDeps
+	listMethInDeps
+	listMethOutDeps
+)
+
+// Out is the output of the Builder.
+type Out struct {
+	File pref.FileDescriptor
+
+	// Enums is all enum descriptors in "flattened ordering".
+	Enums []Enum
+	// Messages is all message descriptors in "flattened ordering".
+	// It includes the implicit message declarations for map entries.
+	Messages []Message
+	// Extensions is all extension descriptors in "flattened ordering".
+	Extensions []Extension
+	// Service is all service descriptors in "flattened ordering".
+	Services []Service
+}
+
+// Build constructs a FileDescriptor given the parameters set in Builder.
+// It assumes that the inputs are well-formed and panics if any inconsistencies
+// are encountered.
+//
+// If NumEnums+NumMessages+NumExtensions+NumServices is zero,
+// then Build automatically derives them from the raw descriptor.
+func (db Builder) Build() (out Out) {
+	// Populate the counts if uninitialized.
+	if db.NumEnums+db.NumMessages+db.NumExtensions+db.NumServices == 0 {
+		db.unmarshalCounts(db.RawDescriptor, true)
+	}
+
+	// Initialize resolvers and registries if unpopulated.
+	if db.TypeResolver == nil {
+		db.TypeResolver = preg.GlobalTypes
+	}
+	if db.FileRegistry == nil {
+		db.FileRegistry = preg.GlobalFiles
+	}
+
+	fd := newRawFile(db)
+	out.File = fd
+	out.Enums = fd.allEnums
+	out.Messages = fd.allMessages
+	out.Extensions = fd.allExtensions
+	out.Services = fd.allServices
+
+	if err := db.FileRegistry.RegisterFile(fd); err != nil {
+		panic(err)
+	}
+	return out
+}
+
+// unmarshalCounts counts the number of enum, message, extension, and service
+// declarations in the raw message, which is either a FileDescriptorProto
+// or a MessageDescriptorProto depending on whether isFile is set.
+func (db *Builder) unmarshalCounts(b []byte, isFile bool) {
+	for len(b) > 0 {
+		num, typ, n := protowire.ConsumeTag(b)
+		b = b[n:]
+		switch typ {
+		case protowire.BytesType:
+			v, m := protowire.ConsumeBytes(b)
+			b = b[m:]
+			if isFile {
+				switch num {
+				case fieldnum.FileDescriptorProto_EnumType:
+					db.NumEnums++
+				case fieldnum.FileDescriptorProto_MessageType:
+					db.unmarshalCounts(v, false)
+					db.NumMessages++
+				case fieldnum.FileDescriptorProto_Extension:
+					db.NumExtensions++
+				case fieldnum.FileDescriptorProto_Service:
+					db.NumServices++
+				}
+			} else {
+				switch num {
+				case fieldnum.DescriptorProto_EnumType:
+					db.NumEnums++
+				case fieldnum.DescriptorProto_NestedType:
+					db.unmarshalCounts(v, false)
+					db.NumMessages++
+				case fieldnum.DescriptorProto_Extension:
+					db.NumExtensions++
+				}
+			}
+		default:
+			m := protowire.ConsumeFieldValue(num, typ, b)
+			b = b[m:]
+		}
+	}
+}
diff --git a/demo_test/vendor/google.golang.org/protobuf/internal/filedesc/desc.go b/demo_test/vendor/google.golang.org/protobuf/internal/filedesc/desc.go
new file mode 100644
index 0000000..a9fe07c
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/internal/filedesc/desc.go
@@ -0,0 +1,598 @@
+// 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 filedesc
+
+import (
+	"bytes"
+	"fmt"
+	"sync"
+	"sync/atomic"
+
+	"google.golang.org/protobuf/internal/descfmt"
+	"google.golang.org/protobuf/internal/descopts"
+	"google.golang.org/protobuf/internal/encoding/defval"
+	"google.golang.org/protobuf/internal/pragma"
+	"google.golang.org/protobuf/internal/strs"
+	pref "google.golang.org/protobuf/reflect/protoreflect"
+	"google.golang.org/protobuf/reflect/protoregistry"
+)
+
+// The types in this file may have a suffix:
+//	• L0: Contains fields common to all descriptors (except File) and
+//	must be initialized up front.
+//	• L1: Contains fields specific to a descriptor and
+//	must be initialized up front.
+//	• L2: Contains fields that are lazily initialized when constructing
+//	from the raw file descriptor. When constructing as a literal, the L2
+//	fields must be initialized up front.
+//
+// The types are exported so that packages like reflect/protodesc can
+// directly construct descriptors.
+
+type (
+	File struct {
+		fileRaw
+		L1 FileL1
+
+		once uint32     // atomically set if L2 is valid
+		mu   sync.Mutex // protects L2
+		L2   *FileL2
+	}
+	FileL1 struct {
+		Syntax  pref.Syntax
+		Path    string
+		Package pref.FullName
+
+		Enums      Enums
+		Messages   Messages
+		Extensions Extensions
+		Services   Services
+	}
+	FileL2 struct {
+		Options   func() pref.ProtoMessage
+		Imports   FileImports
+		Locations SourceLocations
+	}
+)
+
+func (fd *File) ParentFile() pref.FileDescriptor { return fd }
+func (fd *File) Parent() pref.Descriptor         { return nil }
+func (fd *File) Index() int                      { return 0 }
+func (fd *File) Syntax() pref.Syntax             { return fd.L1.Syntax }
+func (fd *File) Name() pref.Name                 { return fd.L1.Package.Name() }
+func (fd *File) FullName() pref.FullName         { return fd.L1.Package }
+func (fd *File) IsPlaceholder() bool             { return false }
+func (fd *File) Options() pref.ProtoMessage {
+	if f := fd.lazyInit().Options; f != nil {
+		return f()
+	}
+	return descopts.File
+}
+func (fd *File) Path() string                          { return fd.L1.Path }
+func (fd *File) Package() pref.FullName                { return fd.L1.Package }
+func (fd *File) Imports() pref.FileImports             { return &fd.lazyInit().Imports }
+func (fd *File) Enums() pref.EnumDescriptors           { return &fd.L1.Enums }
+func (fd *File) Messages() pref.MessageDescriptors     { return &fd.L1.Messages }
+func (fd *File) Extensions() pref.ExtensionDescriptors { return &fd.L1.Extensions }
+func (fd *File) Services() pref.ServiceDescriptors     { return &fd.L1.Services }
+func (fd *File) SourceLocations() pref.SourceLocations { return &fd.L2.Locations }
+func (fd *File) Format(s fmt.State, r rune)            { descfmt.FormatDesc(s, r, fd) }
+func (fd *File) ProtoType(pref.FileDescriptor)         {}
+func (fd *File) ProtoInternal(pragma.DoNotImplement)   {}
+
+func (fd *File) lazyInit() *FileL2 {
+	if atomic.LoadUint32(&fd.once) == 0 {
+		fd.lazyInitOnce()
+	}
+	return fd.L2
+}
+
+func (fd *File) lazyInitOnce() {
+	fd.mu.Lock()
+	if fd.L2 == nil {
+		fd.lazyRawInit() // recursively initializes all L2 structures
+	}
+	atomic.StoreUint32(&fd.once, 1)
+	fd.mu.Unlock()
+}
+
+// ProtoLegacyRawDesc is a pseudo-internal API for allowing the v1 code
+// to be able to retrieve the raw descriptor.
+//
+// WARNING: This method is exempt from the compatibility promise and may be
+// removed in the future without warning.
+func (fd *File) ProtoLegacyRawDesc() []byte {
+	return fd.builder.RawDescriptor
+}
+
+// GoPackagePath is a pseudo-internal API for determining the Go package path
+// that this file descriptor is declared in.
+//
+// WARNING: This method is exempt from the compatibility promise and may be
+// removed in the future without warning.
+func (fd *File) GoPackagePath() string {
+	return fd.builder.GoPackagePath
+}
+
+type (
+	Enum struct {
+		Base
+		L1 EnumL1
+		L2 *EnumL2 // protected by fileDesc.once
+	}
+	EnumL1 struct {
+		eagerValues bool // controls whether EnumL2.Values is already populated
+	}
+	EnumL2 struct {
+		Options        func() pref.ProtoMessage
+		Values         EnumValues
+		ReservedNames  Names
+		ReservedRanges EnumRanges
+	}
+
+	EnumValue struct {
+		Base
+		L1 EnumValueL1
+	}
+	EnumValueL1 struct {
+		Options func() pref.ProtoMessage
+		Number  pref.EnumNumber
+	}
+)
+
+func (ed *Enum) Options() pref.ProtoMessage {
+	if f := ed.lazyInit().Options; f != nil {
+		return f()
+	}
+	return descopts.Enum
+}
+func (ed *Enum) Values() pref.EnumValueDescriptors {
+	if ed.L1.eagerValues {
+		return &ed.L2.Values
+	}
+	return &ed.lazyInit().Values
+}
+func (ed *Enum) ReservedNames() pref.Names       { return &ed.lazyInit().ReservedNames }
+func (ed *Enum) ReservedRanges() pref.EnumRanges { return &ed.lazyInit().ReservedRanges }
+func (ed *Enum) Format(s fmt.State, r rune)      { descfmt.FormatDesc(s, r, ed) }
+func (ed *Enum) ProtoType(pref.EnumDescriptor)   {}
+func (ed *Enum) lazyInit() *EnumL2 {
+	ed.L0.ParentFile.lazyInit() // implicitly initializes L2
+	return ed.L2
+}
+
+func (ed *EnumValue) Options() pref.ProtoMessage {
+	if f := ed.L1.Options; f != nil {
+		return f()
+	}
+	return descopts.EnumValue
+}
+func (ed *EnumValue) Number() pref.EnumNumber            { return ed.L1.Number }
+func (ed *EnumValue) Format(s fmt.State, r rune)         { descfmt.FormatDesc(s, r, ed) }
+func (ed *EnumValue) ProtoType(pref.EnumValueDescriptor) {}
+
+type (
+	Message struct {
+		Base
+		L1 MessageL1
+		L2 *MessageL2 // protected by fileDesc.once
+	}
+	MessageL1 struct {
+		Enums        Enums
+		Messages     Messages
+		Extensions   Extensions
+		IsMapEntry   bool // promoted from google.protobuf.MessageOptions
+		IsMessageSet bool // promoted from google.protobuf.MessageOptions
+	}
+	MessageL2 struct {
+		Options               func() pref.ProtoMessage
+		Fields                Fields
+		Oneofs                Oneofs
+		ReservedNames         Names
+		ReservedRanges        FieldRanges
+		RequiredNumbers       FieldNumbers // must be consistent with Fields.Cardinality
+		ExtensionRanges       FieldRanges
+		ExtensionRangeOptions []func() pref.ProtoMessage // must be same length as ExtensionRanges
+	}
+
+	Field struct {
+		Base
+		L1 FieldL1
+	}
+	FieldL1 struct {
+		Options         func() pref.ProtoMessage
+		Number          pref.FieldNumber
+		Cardinality     pref.Cardinality // must be consistent with Message.RequiredNumbers
+		Kind            pref.Kind
+		JSONName        jsonName
+		IsWeak          bool // promoted from google.protobuf.FieldOptions
+		HasPacked       bool // promoted from google.protobuf.FieldOptions
+		IsPacked        bool // promoted from google.protobuf.FieldOptions
+		HasEnforceUTF8  bool // promoted from google.protobuf.FieldOptions
+		EnforceUTF8     bool // promoted from google.protobuf.FieldOptions
+		Default         defaultValue
+		ContainingOneof pref.OneofDescriptor // must be consistent with Message.Oneofs.Fields
+		Enum            pref.EnumDescriptor
+		Message         pref.MessageDescriptor
+	}
+
+	Oneof struct {
+		Base
+		L1 OneofL1
+	}
+	OneofL1 struct {
+		Options func() pref.ProtoMessage
+		Fields  OneofFields // must be consistent with Message.Fields.ContainingOneof
+	}
+)
+
+func (md *Message) Options() pref.ProtoMessage {
+	if f := md.lazyInit().Options; f != nil {
+		return f()
+	}
+	return descopts.Message
+}
+func (md *Message) IsMapEntry() bool                   { return md.L1.IsMapEntry }
+func (md *Message) Fields() pref.FieldDescriptors      { return &md.lazyInit().Fields }
+func (md *Message) Oneofs() pref.OneofDescriptors      { return &md.lazyInit().Oneofs }
+func (md *Message) ReservedNames() pref.Names          { return &md.lazyInit().ReservedNames }
+func (md *Message) ReservedRanges() pref.FieldRanges   { return &md.lazyInit().ReservedRanges }
+func (md *Message) RequiredNumbers() pref.FieldNumbers { return &md.lazyInit().RequiredNumbers }
+func (md *Message) ExtensionRanges() pref.FieldRanges  { return &md.lazyInit().ExtensionRanges }
+func (md *Message) ExtensionRangeOptions(i int) pref.ProtoMessage {
+	if f := md.lazyInit().ExtensionRangeOptions[i]; f != nil {
+		return f()
+	}
+	return descopts.ExtensionRange
+}
+func (md *Message) Enums() pref.EnumDescriptors           { return &md.L1.Enums }
+func (md *Message) Messages() pref.MessageDescriptors     { return &md.L1.Messages }
+func (md *Message) Extensions() pref.ExtensionDescriptors { return &md.L1.Extensions }
+func (md *Message) ProtoType(pref.MessageDescriptor)      {}
+func (md *Message) Format(s fmt.State, r rune)            { descfmt.FormatDesc(s, r, md) }
+func (md *Message) lazyInit() *MessageL2 {
+	md.L0.ParentFile.lazyInit() // implicitly initializes L2
+	return md.L2
+}
+
+// IsMessageSet is a pseudo-internal API for checking whether a message
+// should serialize in the proto1 message format.
+//
+// WARNING: This method is exempt from the compatibility promise and may be
+// removed in the future without warning.
+func (md *Message) IsMessageSet() bool {
+	return md.L1.IsMessageSet
+}
+
+func (fd *Field) Options() pref.ProtoMessage {
+	if f := fd.L1.Options; f != nil {
+		return f()
+	}
+	return descopts.Field
+}
+func (fd *Field) Number() pref.FieldNumber      { return fd.L1.Number }
+func (fd *Field) Cardinality() pref.Cardinality { return fd.L1.Cardinality }
+func (fd *Field) Kind() pref.Kind               { return fd.L1.Kind }
+func (fd *Field) HasJSONName() bool             { return fd.L1.JSONName.has }
+func (fd *Field) JSONName() string              { return fd.L1.JSONName.get(fd) }
+func (fd *Field) IsPacked() bool {
+	if !fd.L1.HasPacked && fd.L0.ParentFile.L1.Syntax != pref.Proto2 && fd.L1.Cardinality == pref.Repeated {
+		switch fd.L1.Kind {
+		case pref.StringKind, pref.BytesKind, pref.MessageKind, pref.GroupKind:
+		default:
+			return true
+		}
+	}
+	return fd.L1.IsPacked
+}
+func (fd *Field) IsExtension() bool { return false }
+func (fd *Field) IsWeak() bool      { return fd.L1.IsWeak }
+func (fd *Field) IsList() bool      { return fd.Cardinality() == pref.Repeated && !fd.IsMap() }
+func (fd *Field) IsMap() bool       { return fd.Message() != nil && fd.Message().IsMapEntry() }
+func (fd *Field) MapKey() pref.FieldDescriptor {
+	if !fd.IsMap() {
+		return nil
+	}
+	return fd.Message().Fields().ByNumber(1)
+}
+func (fd *Field) MapValue() pref.FieldDescriptor {
+	if !fd.IsMap() {
+		return nil
+	}
+	return fd.Message().Fields().ByNumber(2)
+}
+func (fd *Field) HasDefault() bool                           { return fd.L1.Default.has }
+func (fd *Field) Default() pref.Value                        { return fd.L1.Default.get(fd) }
+func (fd *Field) DefaultEnumValue() pref.EnumValueDescriptor { return fd.L1.Default.enum }
+func (fd *Field) ContainingOneof() pref.OneofDescriptor      { return fd.L1.ContainingOneof }
+func (fd *Field) ContainingMessage() pref.MessageDescriptor {
+	return fd.L0.Parent.(pref.MessageDescriptor)
+}
+func (fd *Field) Enum() pref.EnumDescriptor {
+	return fd.L1.Enum
+}
+func (fd *Field) Message() pref.MessageDescriptor {
+	if fd.L1.IsWeak {
+		if d, _ := protoregistry.GlobalFiles.FindDescriptorByName(fd.L1.Message.FullName()); d != nil {
+			return d.(pref.MessageDescriptor)
+		}
+	}
+	return fd.L1.Message
+}
+func (fd *Field) Format(s fmt.State, r rune)     { descfmt.FormatDesc(s, r, fd) }
+func (fd *Field) ProtoType(pref.FieldDescriptor) {}
+
+// EnforceUTF8 is a pseudo-internal API to determine whether to enforce UTF-8
+// validation for the string field. This exists for Google-internal use only
+// since proto3 did not enforce UTF-8 validity prior to the open-source release.
+// If this method does not exist, the default is to enforce valid UTF-8.
+//
+// WARNING: This method is exempt from the compatibility promise and may be
+// removed in the future without warning.
+func (fd *Field) EnforceUTF8() bool {
+	if fd.L1.HasEnforceUTF8 {
+		return fd.L1.EnforceUTF8
+	}
+	return fd.L0.ParentFile.L1.Syntax == pref.Proto3
+}
+
+func (od *Oneof) Options() pref.ProtoMessage {
+	if f := od.L1.Options; f != nil {
+		return f()
+	}
+	return descopts.Oneof
+}
+func (od *Oneof) Fields() pref.FieldDescriptors  { return &od.L1.Fields }
+func (od *Oneof) Format(s fmt.State, r rune)     { descfmt.FormatDesc(s, r, od) }
+func (od *Oneof) ProtoType(pref.OneofDescriptor) {}
+
+type (
+	Extension struct {
+		Base
+		L1 ExtensionL1
+		L2 *ExtensionL2 // protected by fileDesc.once
+	}
+	ExtensionL1 struct {
+		Number      pref.FieldNumber
+		Extendee    pref.MessageDescriptor
+		Cardinality pref.Cardinality
+		Kind        pref.Kind
+	}
+	ExtensionL2 struct {
+		Options  func() pref.ProtoMessage
+		JSONName jsonName
+		IsPacked bool // promoted from google.protobuf.FieldOptions
+		Default  defaultValue
+		Enum     pref.EnumDescriptor
+		Message  pref.MessageDescriptor
+	}
+)
+
+func (xd *Extension) Options() pref.ProtoMessage {
+	if f := xd.lazyInit().Options; f != nil {
+		return f()
+	}
+	return descopts.Field
+}
+func (xd *Extension) Number() pref.FieldNumber                   { return xd.L1.Number }
+func (xd *Extension) Cardinality() pref.Cardinality              { return xd.L1.Cardinality }
+func (xd *Extension) Kind() pref.Kind                            { return xd.L1.Kind }
+func (xd *Extension) HasJSONName() bool                          { return xd.lazyInit().JSONName.has }
+func (xd *Extension) JSONName() string                           { return xd.lazyInit().JSONName.get(xd) }
+func (xd *Extension) IsPacked() bool                             { return xd.lazyInit().IsPacked }
+func (xd *Extension) IsExtension() bool                          { return true }
+func (xd *Extension) IsWeak() bool                               { return false }
+func (xd *Extension) IsList() bool                               { return xd.Cardinality() == pref.Repeated }
+func (xd *Extension) IsMap() bool                                { return false }
+func (xd *Extension) MapKey() pref.FieldDescriptor               { return nil }
+func (xd *Extension) MapValue() pref.FieldDescriptor             { return nil }
+func (xd *Extension) HasDefault() bool                           { return xd.lazyInit().Default.has }
+func (xd *Extension) Default() pref.Value                        { return xd.lazyInit().Default.get(xd) }
+func (xd *Extension) DefaultEnumValue() pref.EnumValueDescriptor { return xd.lazyInit().Default.enum }
+func (xd *Extension) ContainingOneof() pref.OneofDescriptor      { return nil }
+func (xd *Extension) ContainingMessage() pref.MessageDescriptor  { return xd.L1.Extendee }
+func (xd *Extension) Enum() pref.EnumDescriptor                  { return xd.lazyInit().Enum }
+func (xd *Extension) Message() pref.MessageDescriptor            { return xd.lazyInit().Message }
+func (xd *Extension) Format(s fmt.State, r rune)                 { descfmt.FormatDesc(s, r, xd) }
+func (xd *Extension) ProtoType(pref.FieldDescriptor)             {}
+func (xd *Extension) ProtoInternal(pragma.DoNotImplement)        {}
+func (xd *Extension) lazyInit() *ExtensionL2 {
+	xd.L0.ParentFile.lazyInit() // implicitly initializes L2
+	return xd.L2
+}
+
+type (
+	Service struct {
+		Base
+		L1 ServiceL1
+		L2 *ServiceL2 // protected by fileDesc.once
+	}
+	ServiceL1 struct{}
+	ServiceL2 struct {
+		Options func() pref.ProtoMessage
+		Methods Methods
+	}
+
+	Method struct {
+		Base
+		L1 MethodL1
+	}
+	MethodL1 struct {
+		Options           func() pref.ProtoMessage
+		Input             pref.MessageDescriptor
+		Output            pref.MessageDescriptor
+		IsStreamingClient bool
+		IsStreamingServer bool
+	}
+)
+
+func (sd *Service) Options() pref.ProtoMessage {
+	if f := sd.lazyInit().Options; f != nil {
+		return f()
+	}
+	return descopts.Service
+}
+func (sd *Service) Methods() pref.MethodDescriptors     { return &sd.lazyInit().Methods }
+func (sd *Service) Format(s fmt.State, r rune)          { descfmt.FormatDesc(s, r, sd) }
+func (sd *Service) ProtoType(pref.ServiceDescriptor)    {}
+func (sd *Service) ProtoInternal(pragma.DoNotImplement) {}
+func (sd *Service) lazyInit() *ServiceL2 {
+	sd.L0.ParentFile.lazyInit() // implicitly initializes L2
+	return sd.L2
+}
+
+func (md *Method) Options() pref.ProtoMessage {
+	if f := md.L1.Options; f != nil {
+		return f()
+	}
+	return descopts.Method
+}
+func (md *Method) Input() pref.MessageDescriptor       { return md.L1.Input }
+func (md *Method) Output() pref.MessageDescriptor      { return md.L1.Output }
+func (md *Method) IsStreamingClient() bool             { return md.L1.IsStreamingClient }
+func (md *Method) IsStreamingServer() bool             { return md.L1.IsStreamingServer }
+func (md *Method) Format(s fmt.State, r rune)          { descfmt.FormatDesc(s, r, md) }
+func (md *Method) ProtoType(pref.MethodDescriptor)     {}
+func (md *Method) ProtoInternal(pragma.DoNotImplement) {}
+
+// Surrogate files are can be used to create standalone descriptors
+// where the syntax is only information derived from the parent file.
+var (
+	SurrogateProto2 = &File{L1: FileL1{Syntax: pref.Proto2}, L2: &FileL2{}}
+	SurrogateProto3 = &File{L1: FileL1{Syntax: pref.Proto3}, L2: &FileL2{}}
+)
+
+type (
+	Base struct {
+		L0 BaseL0
+	}
+	BaseL0 struct {
+		FullName   pref.FullName // must be populated
+		ParentFile *File         // must be populated
+		Parent     pref.Descriptor
+		Index      int
+	}
+)
+
+func (d *Base) Name() pref.Name         { return d.L0.FullName.Name() }
+func (d *Base) FullName() pref.FullName { return d.L0.FullName }
+func (d *Base) ParentFile() pref.FileDescriptor {
+	if d.L0.ParentFile == SurrogateProto2 || d.L0.ParentFile == SurrogateProto3 {
+		return nil // surrogate files are not real parents
+	}
+	return d.L0.ParentFile
+}
+func (d *Base) Parent() pref.Descriptor             { return d.L0.Parent }
+func (d *Base) Index() int                          { return d.L0.Index }
+func (d *Base) Syntax() pref.Syntax                 { return d.L0.ParentFile.Syntax() }
+func (d *Base) IsPlaceholder() bool                 { return false }
+func (d *Base) ProtoInternal(pragma.DoNotImplement) {}
+
+type jsonName struct {
+	has  bool
+	once sync.Once
+	name string
+}
+
+// Init initializes the name. It is exported for use by other internal packages.
+func (js *jsonName) Init(s string) {
+	js.has = true
+	js.name = s
+}
+
+func (js *jsonName) get(fd pref.FieldDescriptor) string {
+	if !js.has {
+		js.once.Do(func() {
+			js.name = strs.JSONCamelCase(string(fd.Name()))
+		})
+	}
+	return js.name
+}
+
+func DefaultValue(v pref.Value, ev pref.EnumValueDescriptor) defaultValue {
+	dv := defaultValue{has: v.IsValid(), val: v, enum: ev}
+	if b, ok := v.Interface().([]byte); ok {
+		// Store a copy of the default bytes, so that we can detect
+		// accidental mutations of the original value.
+		dv.bytes = append([]byte(nil), b...)
+	}
+	return dv
+}
+
+func unmarshalDefault(b []byte, k pref.Kind, pf *File, ed pref.EnumDescriptor) defaultValue {
+	var evs pref.EnumValueDescriptors
+	if k == pref.EnumKind {
+		// If the enum is declared within the same file, be careful not to
+		// blindly call the Values method, lest we bind ourselves in a deadlock.
+		if e, ok := ed.(*Enum); ok && e.L0.ParentFile == pf {
+			evs = &e.L2.Values
+		} else {
+			evs = ed.Values()
+		}
+
+		// If we are unable to resolve the enum dependency, use a placeholder
+		// enum value since we will not be able to parse the default value.
+		if ed.IsPlaceholder() && pref.Name(b).IsValid() {
+			v := pref.ValueOfEnum(0)
+			ev := PlaceholderEnumValue(ed.FullName().Parent().Append(pref.Name(b)))
+			return DefaultValue(v, ev)
+		}
+	}
+
+	v, ev, err := defval.Unmarshal(string(b), k, evs, defval.Descriptor)
+	if err != nil {
+		panic(err)
+	}
+	return DefaultValue(v, ev)
+}
+
+type defaultValue struct {
+	has   bool
+	val   pref.Value
+	enum  pref.EnumValueDescriptor
+	bytes []byte
+}
+
+func (dv *defaultValue) get(fd pref.FieldDescriptor) pref.Value {
+	// Return the zero value as the default if unpopulated.
+	if !dv.has {
+		if fd.Cardinality() == pref.Repeated {
+			return pref.Value{}
+		}
+		switch fd.Kind() {
+		case pref.BoolKind:
+			return pref.ValueOfBool(false)
+		case pref.Int32Kind, pref.Sint32Kind, pref.Sfixed32Kind:
+			return pref.ValueOfInt32(0)
+		case pref.Int64Kind, pref.Sint64Kind, pref.Sfixed64Kind:
+			return pref.ValueOfInt64(0)
+		case pref.Uint32Kind, pref.Fixed32Kind:
+			return pref.ValueOfUint32(0)
+		case pref.Uint64Kind, pref.Fixed64Kind:
+			return pref.ValueOfUint64(0)
+		case pref.FloatKind:
+			return pref.ValueOfFloat32(0)
+		case pref.DoubleKind:
+			return pref.ValueOfFloat64(0)
+		case pref.StringKind:
+			return pref.ValueOfString("")
+		case pref.BytesKind:
+			return pref.ValueOfBytes(nil)
+		case pref.EnumKind:
+			if evs := fd.Enum().Values(); evs.Len() > 0 {
+				return pref.ValueOfEnum(evs.Get(0).Number())
+			}
+			return pref.ValueOfEnum(0)
+		}
+	}
+
+	if len(dv.bytes) > 0 && !bytes.Equal(dv.bytes, dv.val.Bytes()) {
+		// TODO: Avoid panic if we're running with the race detector
+		// and instead spawn a goroutine that periodically resets
+		// this value back to the original to induce a race.
+		panic("detected mutation on the default bytes")
+	}
+	return dv.val
+}
diff --git a/demo_test/vendor/google.golang.org/protobuf/internal/filedesc/desc_init.go b/demo_test/vendor/google.golang.org/protobuf/internal/filedesc/desc_init.go
new file mode 100644
index 0000000..c0cddf8
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/internal/filedesc/desc_init.go
@@ -0,0 +1,471 @@
+// 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 filedesc
+
+import (
+	"sync"
+
+	"google.golang.org/protobuf/encoding/protowire"
+	"google.golang.org/protobuf/internal/fieldnum"
+	"google.golang.org/protobuf/internal/strs"
+	pref "google.golang.org/protobuf/reflect/protoreflect"
+)
+
+// fileRaw is a data struct used when initializing a file descriptor from
+// a raw FileDescriptorProto.
+type fileRaw struct {
+	builder       Builder
+	allEnums      []Enum
+	allMessages   []Message
+	allExtensions []Extension
+	allServices   []Service
+}
+
+func newRawFile(db Builder) *File {
+	fd := &File{fileRaw: fileRaw{builder: db}}
+	fd.initDecls(db.NumEnums, db.NumMessages, db.NumExtensions, db.NumServices)
+	fd.unmarshalSeed(db.RawDescriptor)
+
+	// Extended message targets are eagerly resolved since registration
+	// needs this information at program init time.
+	for i := range fd.allExtensions {
+		xd := &fd.allExtensions[i]
+		xd.L1.Extendee = fd.resolveMessageDependency(xd.L1.Extendee, listExtTargets, int32(i))
+	}
+
+	fd.checkDecls()
+	return fd
+}
+
+// initDecls pre-allocates slices for the exact number of enums, messages
+// (including map entries), extensions, and services declared in the proto file.
+// This is done to avoid regrowing the slice, which would change the address
+// for any previously seen declaration.
+//
+// The alloc methods "allocates" slices by pulling from the capacity.
+func (fd *File) initDecls(numEnums, numMessages, numExtensions, numServices int32) {
+	fd.allEnums = make([]Enum, 0, numEnums)
+	fd.allMessages = make([]Message, 0, numMessages)
+	fd.allExtensions = make([]Extension, 0, numExtensions)
+	fd.allServices = make([]Service, 0, numServices)
+}
+
+func (fd *File) allocEnums(n int) []Enum {
+	total := len(fd.allEnums)
+	es := fd.allEnums[total : total+n]
+	fd.allEnums = fd.allEnums[:total+n]
+	return es
+}
+func (fd *File) allocMessages(n int) []Message {
+	total := len(fd.allMessages)
+	ms := fd.allMessages[total : total+n]
+	fd.allMessages = fd.allMessages[:total+n]
+	return ms
+}
+func (fd *File) allocExtensions(n int) []Extension {
+	total := len(fd.allExtensions)
+	xs := fd.allExtensions[total : total+n]
+	fd.allExtensions = fd.allExtensions[:total+n]
+	return xs
+}
+func (fd *File) allocServices(n int) []Service {
+	total := len(fd.allServices)
+	xs := fd.allServices[total : total+n]
+	fd.allServices = fd.allServices[:total+n]
+	return xs
+}
+
+// checkDecls performs a sanity check that the expected number of expected
+// declarations matches the number that were found in the descriptor proto.
+func (fd *File) checkDecls() {
+	switch {
+	case len(fd.allEnums) != cap(fd.allEnums):
+	case len(fd.allMessages) != cap(fd.allMessages):
+	case len(fd.allExtensions) != cap(fd.allExtensions):
+	case len(fd.allServices) != cap(fd.allServices):
+	default:
+		return
+	}
+	panic("mismatching cardinality")
+}
+
+func (fd *File) unmarshalSeed(b []byte) {
+	sb := getBuilder()
+	defer putBuilder(sb)
+
+	var prevField pref.FieldNumber
+	var numEnums, numMessages, numExtensions, numServices int
+	var posEnums, posMessages, posExtensions, posServices int
+	b0 := b
+	for len(b) > 0 {
+		num, typ, n := protowire.ConsumeTag(b)
+		b = b[n:]
+		switch typ {
+		case protowire.BytesType:
+			v, m := protowire.ConsumeBytes(b)
+			b = b[m:]
+			switch num {
+			case fieldnum.FileDescriptorProto_Syntax:
+				switch string(v) {
+				case "proto2":
+					fd.L1.Syntax = pref.Proto2
+				case "proto3":
+					fd.L1.Syntax = pref.Proto3
+				default:
+					panic("invalid syntax")
+				}
+			case fieldnum.FileDescriptorProto_Name:
+				fd.L1.Path = sb.MakeString(v)
+			case fieldnum.FileDescriptorProto_Package:
+				fd.L1.Package = pref.FullName(sb.MakeString(v))
+			case fieldnum.FileDescriptorProto_EnumType:
+				if prevField != fieldnum.FileDescriptorProto_EnumType {
+					if numEnums > 0 {
+						panic("non-contiguous repeated field")
+					}
+					posEnums = len(b0) - len(b) - n - m
+				}
+				numEnums++
+			case fieldnum.FileDescriptorProto_MessageType:
+				if prevField != fieldnum.FileDescriptorProto_MessageType {
+					if numMessages > 0 {
+						panic("non-contiguous repeated field")
+					}
+					posMessages = len(b0) - len(b) - n - m
+				}
+				numMessages++
+			case fieldnum.FileDescriptorProto_Extension:
+				if prevField != fieldnum.FileDescriptorProto_Extension {
+					if numExtensions > 0 {
+						panic("non-contiguous repeated field")
+					}
+					posExtensions = len(b0) - len(b) - n - m
+				}
+				numExtensions++
+			case fieldnum.FileDescriptorProto_Service:
+				if prevField != fieldnum.FileDescriptorProto_Service {
+					if numServices > 0 {
+						panic("non-contiguous repeated field")
+					}
+					posServices = len(b0) - len(b) - n - m
+				}
+				numServices++
+			}
+			prevField = num
+		default:
+			m := protowire.ConsumeFieldValue(num, typ, b)
+			b = b[m:]
+			prevField = -1 // ignore known field numbers of unknown wire type
+		}
+	}
+
+	// If syntax is missing, it is assumed to be proto2.
+	if fd.L1.Syntax == 0 {
+		fd.L1.Syntax = pref.Proto2
+	}
+
+	// Must allocate all declarations before parsing each descriptor type
+	// to ensure we handled all descriptors in "flattened ordering".
+	if numEnums > 0 {
+		fd.L1.Enums.List = fd.allocEnums(numEnums)
+	}
+	if numMessages > 0 {
+		fd.L1.Messages.List = fd.allocMessages(numMessages)
+	}
+	if numExtensions > 0 {
+		fd.L1.Extensions.List = fd.allocExtensions(numExtensions)
+	}
+	if numServices > 0 {
+		fd.L1.Services.List = fd.allocServices(numServices)
+	}
+
+	if numEnums > 0 {
+		b := b0[posEnums:]
+		for i := range fd.L1.Enums.List {
+			_, n := protowire.ConsumeVarint(b)
+			v, m := protowire.ConsumeBytes(b[n:])
+			fd.L1.Enums.List[i].unmarshalSeed(v, sb, fd, fd, i)
+			b = b[n+m:]
+		}
+	}
+	if numMessages > 0 {
+		b := b0[posMessages:]
+		for i := range fd.L1.Messages.List {
+			_, n := protowire.ConsumeVarint(b)
+			v, m := protowire.ConsumeBytes(b[n:])
+			fd.L1.Messages.List[i].unmarshalSeed(v, sb, fd, fd, i)
+			b = b[n+m:]
+		}
+	}
+	if numExtensions > 0 {
+		b := b0[posExtensions:]
+		for i := range fd.L1.Extensions.List {
+			_, n := protowire.ConsumeVarint(b)
+			v, m := protowire.ConsumeBytes(b[n:])
+			fd.L1.Extensions.List[i].unmarshalSeed(v, sb, fd, fd, i)
+			b = b[n+m:]
+		}
+	}
+	if numServices > 0 {
+		b := b0[posServices:]
+		for i := range fd.L1.Services.List {
+			_, n := protowire.ConsumeVarint(b)
+			v, m := protowire.ConsumeBytes(b[n:])
+			fd.L1.Services.List[i].unmarshalSeed(v, sb, fd, fd, i)
+			b = b[n+m:]
+		}
+	}
+}
+
+func (ed *Enum) unmarshalSeed(b []byte, sb *strs.Builder, pf *File, pd pref.Descriptor, i int) {
+	ed.L0.ParentFile = pf
+	ed.L0.Parent = pd
+	ed.L0.Index = i
+
+	var numValues int
+	for b := b; len(b) > 0; {
+		num, typ, n := protowire.ConsumeTag(b)
+		b = b[n:]
+		switch typ {
+		case protowire.BytesType:
+			v, m := protowire.ConsumeBytes(b)
+			b = b[m:]
+			switch num {
+			case fieldnum.EnumDescriptorProto_Name:
+				ed.L0.FullName = appendFullName(sb, pd.FullName(), v)
+			case fieldnum.EnumDescriptorProto_Value:
+				numValues++
+			}
+		default:
+			m := protowire.ConsumeFieldValue(num, typ, b)
+			b = b[m:]
+		}
+	}
+
+	// Only construct enum value descriptors for top-level enums since
+	// they are needed for registration.
+	if pd != pf {
+		return
+	}
+	ed.L1.eagerValues = true
+	ed.L2 = new(EnumL2)
+	ed.L2.Values.List = make([]EnumValue, numValues)
+	for i := 0; len(b) > 0; {
+		num, typ, n := protowire.ConsumeTag(b)
+		b = b[n:]
+		switch typ {
+		case protowire.BytesType:
+			v, m := protowire.ConsumeBytes(b)
+			b = b[m:]
+			switch num {
+			case fieldnum.EnumDescriptorProto_Value:
+				ed.L2.Values.List[i].unmarshalFull(v, sb, pf, ed, i)
+				i++
+			}
+		default:
+			m := protowire.ConsumeFieldValue(num, typ, b)
+			b = b[m:]
+		}
+	}
+}
+
+func (md *Message) unmarshalSeed(b []byte, sb *strs.Builder, pf *File, pd pref.Descriptor, i int) {
+	md.L0.ParentFile = pf
+	md.L0.Parent = pd
+	md.L0.Index = i
+
+	var prevField pref.FieldNumber
+	var numEnums, numMessages, numExtensions int
+	var posEnums, posMessages, posExtensions int
+	b0 := b
+	for len(b) > 0 {
+		num, typ, n := protowire.ConsumeTag(b)
+		b = b[n:]
+		switch typ {
+		case protowire.BytesType:
+			v, m := protowire.ConsumeBytes(b)
+			b = b[m:]
+			switch num {
+			case fieldnum.DescriptorProto_Name:
+				md.L0.FullName = appendFullName(sb, pd.FullName(), v)
+			case fieldnum.DescriptorProto_EnumType:
+				if prevField != fieldnum.DescriptorProto_EnumType {
+					if numEnums > 0 {
+						panic("non-contiguous repeated field")
+					}
+					posEnums = len(b0) - len(b) - n - m
+				}
+				numEnums++
+			case fieldnum.DescriptorProto_NestedType:
+				if prevField != fieldnum.DescriptorProto_NestedType {
+					if numMessages > 0 {
+						panic("non-contiguous repeated field")
+					}
+					posMessages = len(b0) - len(b) - n - m
+				}
+				numMessages++
+			case fieldnum.DescriptorProto_Extension:
+				if prevField != fieldnum.DescriptorProto_Extension {
+					if numExtensions > 0 {
+						panic("non-contiguous repeated field")
+					}
+					posExtensions = len(b0) - len(b) - n - m
+				}
+				numExtensions++
+			case fieldnum.DescriptorProto_Options:
+				md.unmarshalSeedOptions(v)
+			}
+			prevField = num
+		default:
+			m := protowire.ConsumeFieldValue(num, typ, b)
+			b = b[m:]
+			prevField = -1 // ignore known field numbers of unknown wire type
+		}
+	}
+
+	// Must allocate all declarations before parsing each descriptor type
+	// to ensure we handled all descriptors in "flattened ordering".
+	if numEnums > 0 {
+		md.L1.Enums.List = pf.allocEnums(numEnums)
+	}
+	if numMessages > 0 {
+		md.L1.Messages.List = pf.allocMessages(numMessages)
+	}
+	if numExtensions > 0 {
+		md.L1.Extensions.List = pf.allocExtensions(numExtensions)
+	}
+
+	if numEnums > 0 {
+		b := b0[posEnums:]
+		for i := range md.L1.Enums.List {
+			_, n := protowire.ConsumeVarint(b)
+			v, m := protowire.ConsumeBytes(b[n:])
+			md.L1.Enums.List[i].unmarshalSeed(v, sb, pf, md, i)
+			b = b[n+m:]
+		}
+	}
+	if numMessages > 0 {
+		b := b0[posMessages:]
+		for i := range md.L1.Messages.List {
+			_, n := protowire.ConsumeVarint(b)
+			v, m := protowire.ConsumeBytes(b[n:])
+			md.L1.Messages.List[i].unmarshalSeed(v, sb, pf, md, i)
+			b = b[n+m:]
+		}
+	}
+	if numExtensions > 0 {
+		b := b0[posExtensions:]
+		for i := range md.L1.Extensions.List {
+			_, n := protowire.ConsumeVarint(b)
+			v, m := protowire.ConsumeBytes(b[n:])
+			md.L1.Extensions.List[i].unmarshalSeed(v, sb, pf, md, i)
+			b = b[n+m:]
+		}
+	}
+}
+
+func (md *Message) unmarshalSeedOptions(b []byte) {
+	for len(b) > 0 {
+		num, typ, n := protowire.ConsumeTag(b)
+		b = b[n:]
+		switch typ {
+		case protowire.VarintType:
+			v, m := protowire.ConsumeVarint(b)
+			b = b[m:]
+			switch num {
+			case fieldnum.MessageOptions_MapEntry:
+				md.L1.IsMapEntry = protowire.DecodeBool(v)
+			case fieldnum.MessageOptions_MessageSetWireFormat:
+				md.L1.IsMessageSet = protowire.DecodeBool(v)
+			}
+		default:
+			m := protowire.ConsumeFieldValue(num, typ, b)
+			b = b[m:]
+		}
+	}
+}
+
+func (xd *Extension) unmarshalSeed(b []byte, sb *strs.Builder, pf *File, pd pref.Descriptor, i int) {
+	xd.L0.ParentFile = pf
+	xd.L0.Parent = pd
+	xd.L0.Index = i
+
+	for len(b) > 0 {
+		num, typ, n := protowire.ConsumeTag(b)
+		b = b[n:]
+		switch typ {
+		case protowire.VarintType:
+			v, m := protowire.ConsumeVarint(b)
+			b = b[m:]
+			switch num {
+			case fieldnum.FieldDescriptorProto_Number:
+				xd.L1.Number = pref.FieldNumber(v)
+			case fieldnum.FieldDescriptorProto_Label:
+				xd.L1.Cardinality = pref.Cardinality(v)
+			case fieldnum.FieldDescriptorProto_Type:
+				xd.L1.Kind = pref.Kind(v)
+			}
+		case protowire.BytesType:
+			v, m := protowire.ConsumeBytes(b)
+			b = b[m:]
+			switch num {
+			case fieldnum.FieldDescriptorProto_Name:
+				xd.L0.FullName = appendFullName(sb, pd.FullName(), v)
+			case fieldnum.FieldDescriptorProto_Extendee:
+				xd.L1.Extendee = PlaceholderMessage(makeFullName(sb, v))
+			}
+		default:
+			m := protowire.ConsumeFieldValue(num, typ, b)
+			b = b[m:]
+		}
+	}
+}
+
+func (sd *Service) unmarshalSeed(b []byte, sb *strs.Builder, pf *File, pd pref.Descriptor, i int) {
+	sd.L0.ParentFile = pf
+	sd.L0.Parent = pd
+	sd.L0.Index = i
+
+	for len(b) > 0 {
+		num, typ, n := protowire.ConsumeTag(b)
+		b = b[n:]
+		switch typ {
+		case protowire.BytesType:
+			v, m := protowire.ConsumeBytes(b)
+			b = b[m:]
+			switch num {
+			case fieldnum.ServiceDescriptorProto_Name:
+				sd.L0.FullName = appendFullName(sb, pd.FullName(), v)
+			}
+		default:
+			m := protowire.ConsumeFieldValue(num, typ, b)
+			b = b[m:]
+		}
+	}
+}
+
+var nameBuilderPool = sync.Pool{
+	New: func() interface{} { return new(strs.Builder) },
+}
+
+func getBuilder() *strs.Builder {
+	return nameBuilderPool.Get().(*strs.Builder)
+}
+func putBuilder(b *strs.Builder) {
+	nameBuilderPool.Put(b)
+}
+
+// makeFullName converts b to a protoreflect.FullName,
+// where b must start with a leading dot.
+func makeFullName(sb *strs.Builder, b []byte) pref.FullName {
+	if len(b) == 0 || b[0] != '.' {
+		panic("name reference must be fully qualified")
+	}
+	return pref.FullName(sb.MakeString(b[1:]))
+}
+
+func appendFullName(sb *strs.Builder, prefix pref.FullName, suffix []byte) pref.FullName {
+	return sb.AppendFullName(prefix, pref.Name(strs.UnsafeString(suffix)))
+}
diff --git a/demo_test/vendor/google.golang.org/protobuf/internal/filedesc/desc_lazy.go b/demo_test/vendor/google.golang.org/protobuf/internal/filedesc/desc_lazy.go
new file mode 100644
index 0000000..cdf3164
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/internal/filedesc/desc_lazy.go
@@ -0,0 +1,695 @@
+// 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 filedesc
+
+import (
+	"reflect"
+	"sync"
+
+	"google.golang.org/protobuf/encoding/protowire"
+	"google.golang.org/protobuf/internal/descopts"
+	"google.golang.org/protobuf/internal/fieldnum"
+	"google.golang.org/protobuf/internal/strs"
+	"google.golang.org/protobuf/proto"
+	pref "google.golang.org/protobuf/reflect/protoreflect"
+)
+
+func (fd *File) lazyRawInit() {
+	fd.unmarshalFull(fd.builder.RawDescriptor)
+	fd.resolveMessages()
+	fd.resolveExtensions()
+	fd.resolveServices()
+}
+
+func (file *File) resolveMessages() {
+	var depIdx int32
+	for i := range file.allMessages {
+		md := &file.allMessages[i]
+
+		// Resolve message field dependencies.
+		for j := range md.L2.Fields.List {
+			fd := &md.L2.Fields.List[j]
+
+			// Weak fields are resolved upon actual use.
+			if fd.L1.IsWeak {
+				continue
+			}
+
+			// Resolve message field dependency.
+			switch fd.L1.Kind {
+			case pref.EnumKind:
+				fd.L1.Enum = file.resolveEnumDependency(fd.L1.Enum, listFieldDeps, depIdx)
+				depIdx++
+			case pref.MessageKind, pref.GroupKind:
+				fd.L1.Message = file.resolveMessageDependency(fd.L1.Message, listFieldDeps, depIdx)
+				depIdx++
+			}
+
+			// Default is resolved here since it depends on Enum being resolved.
+			if v := fd.L1.Default.val; v.IsValid() {
+				fd.L1.Default = unmarshalDefault(v.Bytes(), fd.L1.Kind, file, fd.L1.Enum)
+			}
+		}
+	}
+}
+
+func (file *File) resolveExtensions() {
+	var depIdx int32
+	for i := range file.allExtensions {
+		xd := &file.allExtensions[i]
+
+		// Resolve extension field dependency.
+		switch xd.L1.Kind {
+		case pref.EnumKind:
+			xd.L2.Enum = file.resolveEnumDependency(xd.L2.Enum, listExtDeps, depIdx)
+			depIdx++
+		case pref.MessageKind, pref.GroupKind:
+			xd.L2.Message = file.resolveMessageDependency(xd.L2.Message, listExtDeps, depIdx)
+			depIdx++
+		}
+
+		// Default is resolved here since it depends on Enum being resolved.
+		if v := xd.L2.Default.val; v.IsValid() {
+			xd.L2.Default = unmarshalDefault(v.Bytes(), xd.L1.Kind, file, xd.L2.Enum)
+		}
+	}
+}
+
+func (file *File) resolveServices() {
+	var depIdx int32
+	for i := range file.allServices {
+		sd := &file.allServices[i]
+
+		// Resolve method dependencies.
+		for j := range sd.L2.Methods.List {
+			md := &sd.L2.Methods.List[j]
+			md.L1.Input = file.resolveMessageDependency(md.L1.Input, listMethInDeps, depIdx)
+			md.L1.Output = file.resolveMessageDependency(md.L1.Output, listMethOutDeps, depIdx)
+			depIdx++
+		}
+	}
+}
+
+func (file *File) resolveEnumDependency(ed pref.EnumDescriptor, i, j int32) pref.EnumDescriptor {
+	r := file.builder.FileRegistry
+	if r, ok := r.(resolverByIndex); ok {
+		if ed2 := r.FindEnumByIndex(i, j, file.allEnums, file.allMessages); ed2 != nil {
+			return ed2
+		}
+	}
+	for i := range file.allEnums {
+		if ed2 := &file.allEnums[i]; ed2.L0.FullName == ed.FullName() {
+			return ed2
+		}
+	}
+	if d, _ := r.FindDescriptorByName(ed.FullName()); d != nil {
+		return d.(pref.EnumDescriptor)
+	}
+	return ed
+}
+
+func (file *File) resolveMessageDependency(md pref.MessageDescriptor, i, j int32) pref.MessageDescriptor {
+	r := file.builder.FileRegistry
+	if r, ok := r.(resolverByIndex); ok {
+		if md2 := r.FindMessageByIndex(i, j, file.allEnums, file.allMessages); md2 != nil {
+			return md2
+		}
+	}
+	for i := range file.allMessages {
+		if md2 := &file.allMessages[i]; md2.L0.FullName == md.FullName() {
+			return md2
+		}
+	}
+	if d, _ := r.FindDescriptorByName(md.FullName()); d != nil {
+		return d.(pref.MessageDescriptor)
+	}
+	return md
+}
+
+func (fd *File) unmarshalFull(b []byte) {
+	sb := getBuilder()
+	defer putBuilder(sb)
+
+	var enumIdx, messageIdx, extensionIdx, serviceIdx int
+	var rawOptions []byte
+	fd.L2 = new(FileL2)
+	for len(b) > 0 {
+		num, typ, n := protowire.ConsumeTag(b)
+		b = b[n:]
+		switch typ {
+		case protowire.VarintType:
+			v, m := protowire.ConsumeVarint(b)
+			b = b[m:]
+			switch num {
+			case fieldnum.FileDescriptorProto_PublicDependency:
+				fd.L2.Imports[v].IsPublic = true
+			case fieldnum.FileDescriptorProto_WeakDependency:
+				fd.L2.Imports[v].IsWeak = true
+			}
+		case protowire.BytesType:
+			v, m := protowire.ConsumeBytes(b)
+			b = b[m:]
+			switch num {
+			case fieldnum.FileDescriptorProto_Dependency:
+				path := sb.MakeString(v)
+				imp, _ := fd.builder.FileRegistry.FindFileByPath(path)
+				if imp == nil {
+					imp = PlaceholderFile(path)
+				}
+				fd.L2.Imports = append(fd.L2.Imports, pref.FileImport{FileDescriptor: imp})
+			case fieldnum.FileDescriptorProto_EnumType:
+				fd.L1.Enums.List[enumIdx].unmarshalFull(v, sb)
+				enumIdx++
+			case fieldnum.FileDescriptorProto_MessageType:
+				fd.L1.Messages.List[messageIdx].unmarshalFull(v, sb)
+				messageIdx++
+			case fieldnum.FileDescriptorProto_Extension:
+				fd.L1.Extensions.List[extensionIdx].unmarshalFull(v, sb)
+				extensionIdx++
+			case fieldnum.FileDescriptorProto_Service:
+				fd.L1.Services.List[serviceIdx].unmarshalFull(v, sb)
+				serviceIdx++
+			case fieldnum.FileDescriptorProto_Options:
+				rawOptions = appendOptions(rawOptions, v)
+			}
+		default:
+			m := protowire.ConsumeFieldValue(num, typ, b)
+			b = b[m:]
+		}
+	}
+	fd.L2.Options = fd.builder.optionsUnmarshaler(&descopts.File, rawOptions)
+}
+
+func (ed *Enum) unmarshalFull(b []byte, sb *strs.Builder) {
+	var rawValues [][]byte
+	var rawOptions []byte
+	if !ed.L1.eagerValues {
+		ed.L2 = new(EnumL2)
+	}
+	for len(b) > 0 {
+		num, typ, n := protowire.ConsumeTag(b)
+		b = b[n:]
+		switch typ {
+		case protowire.BytesType:
+			v, m := protowire.ConsumeBytes(b)
+			b = b[m:]
+			switch num {
+			case fieldnum.EnumDescriptorProto_Value:
+				rawValues = append(rawValues, v)
+			case fieldnum.EnumDescriptorProto_ReservedName:
+				ed.L2.ReservedNames.List = append(ed.L2.ReservedNames.List, pref.Name(sb.MakeString(v)))
+			case fieldnum.EnumDescriptorProto_ReservedRange:
+				ed.L2.ReservedRanges.List = append(ed.L2.ReservedRanges.List, unmarshalEnumReservedRange(v))
+			case fieldnum.EnumDescriptorProto_Options:
+				rawOptions = appendOptions(rawOptions, v)
+			}
+		default:
+			m := protowire.ConsumeFieldValue(num, typ, b)
+			b = b[m:]
+		}
+	}
+	if !ed.L1.eagerValues && len(rawValues) > 0 {
+		ed.L2.Values.List = make([]EnumValue, len(rawValues))
+		for i, b := range rawValues {
+			ed.L2.Values.List[i].unmarshalFull(b, sb, ed.L0.ParentFile, ed, i)
+		}
+	}
+	ed.L2.Options = ed.L0.ParentFile.builder.optionsUnmarshaler(&descopts.Enum, rawOptions)
+}
+
+func unmarshalEnumReservedRange(b []byte) (r [2]pref.EnumNumber) {
+	for len(b) > 0 {
+		num, typ, n := protowire.ConsumeTag(b)
+		b = b[n:]
+		switch typ {
+		case protowire.VarintType:
+			v, m := protowire.ConsumeVarint(b)
+			b = b[m:]
+			switch num {
+			case fieldnum.EnumDescriptorProto_EnumReservedRange_Start:
+				r[0] = pref.EnumNumber(v)
+			case fieldnum.EnumDescriptorProto_EnumReservedRange_End:
+				r[1] = pref.EnumNumber(v)
+			}
+		default:
+			m := protowire.ConsumeFieldValue(num, typ, b)
+			b = b[m:]
+		}
+	}
+	return r
+}
+
+func (vd *EnumValue) unmarshalFull(b []byte, sb *strs.Builder, pf *File, pd pref.Descriptor, i int) {
+	vd.L0.ParentFile = pf
+	vd.L0.Parent = pd
+	vd.L0.Index = i
+
+	var rawOptions []byte
+	for len(b) > 0 {
+		num, typ, n := protowire.ConsumeTag(b)
+		b = b[n:]
+		switch typ {
+		case protowire.VarintType:
+			v, m := protowire.ConsumeVarint(b)
+			b = b[m:]
+			switch num {
+			case fieldnum.EnumValueDescriptorProto_Number:
+				vd.L1.Number = pref.EnumNumber(v)
+			}
+		case protowire.BytesType:
+			v, m := protowire.ConsumeBytes(b)
+			b = b[m:]
+			switch num {
+			case fieldnum.EnumValueDescriptorProto_Name:
+				// NOTE: Enum values are in the same scope as the enum parent.
+				vd.L0.FullName = appendFullName(sb, pd.Parent().FullName(), v)
+			case fieldnum.EnumValueDescriptorProto_Options:
+				rawOptions = appendOptions(rawOptions, v)
+			}
+		default:
+			m := protowire.ConsumeFieldValue(num, typ, b)
+			b = b[m:]
+		}
+	}
+	vd.L1.Options = pf.builder.optionsUnmarshaler(&descopts.EnumValue, rawOptions)
+}
+
+func (md *Message) unmarshalFull(b []byte, sb *strs.Builder) {
+	var rawFields, rawOneofs [][]byte
+	var enumIdx, messageIdx, extensionIdx int
+	var rawOptions []byte
+	md.L2 = new(MessageL2)
+	for len(b) > 0 {
+		num, typ, n := protowire.ConsumeTag(b)
+		b = b[n:]
+		switch typ {
+		case protowire.BytesType:
+			v, m := protowire.ConsumeBytes(b)
+			b = b[m:]
+			switch num {
+			case fieldnum.DescriptorProto_Field:
+				rawFields = append(rawFields, v)
+			case fieldnum.DescriptorProto_OneofDecl:
+				rawOneofs = append(rawOneofs, v)
+			case fieldnum.DescriptorProto_ReservedName:
+				md.L2.ReservedNames.List = append(md.L2.ReservedNames.List, pref.Name(sb.MakeString(v)))
+			case fieldnum.DescriptorProto_ReservedRange:
+				md.L2.ReservedRanges.List = append(md.L2.ReservedRanges.List, unmarshalMessageReservedRange(v))
+			case fieldnum.DescriptorProto_ExtensionRange:
+				r, rawOptions := unmarshalMessageExtensionRange(v)
+				opts := md.L0.ParentFile.builder.optionsUnmarshaler(&descopts.ExtensionRange, rawOptions)
+				md.L2.ExtensionRanges.List = append(md.L2.ExtensionRanges.List, r)
+				md.L2.ExtensionRangeOptions = append(md.L2.ExtensionRangeOptions, opts)
+			case fieldnum.DescriptorProto_EnumType:
+				md.L1.Enums.List[enumIdx].unmarshalFull(v, sb)
+				enumIdx++
+			case fieldnum.DescriptorProto_NestedType:
+				md.L1.Messages.List[messageIdx].unmarshalFull(v, sb)
+				messageIdx++
+			case fieldnum.DescriptorProto_Extension:
+				md.L1.Extensions.List[extensionIdx].unmarshalFull(v, sb)
+				extensionIdx++
+			case fieldnum.DescriptorProto_Options:
+				md.unmarshalOptions(v)
+				rawOptions = appendOptions(rawOptions, v)
+			}
+		default:
+			m := protowire.ConsumeFieldValue(num, typ, b)
+			b = b[m:]
+		}
+	}
+	if len(rawFields) > 0 || len(rawOneofs) > 0 {
+		md.L2.Fields.List = make([]Field, len(rawFields))
+		md.L2.Oneofs.List = make([]Oneof, len(rawOneofs))
+		for i, b := range rawFields {
+			fd := &md.L2.Fields.List[i]
+			fd.unmarshalFull(b, sb, md.L0.ParentFile, md, i)
+			if fd.L1.Cardinality == pref.Required {
+				md.L2.RequiredNumbers.List = append(md.L2.RequiredNumbers.List, fd.L1.Number)
+			}
+		}
+		for i, b := range rawOneofs {
+			od := &md.L2.Oneofs.List[i]
+			od.unmarshalFull(b, sb, md.L0.ParentFile, md, i)
+		}
+	}
+	md.L2.Options = md.L0.ParentFile.builder.optionsUnmarshaler(&descopts.Message, rawOptions)
+}
+
+func (md *Message) unmarshalOptions(b []byte) {
+	for len(b) > 0 {
+		num, typ, n := protowire.ConsumeTag(b)
+		b = b[n:]
+		switch typ {
+		case protowire.VarintType:
+			v, m := protowire.ConsumeVarint(b)
+			b = b[m:]
+			switch num {
+			case fieldnum.MessageOptions_MapEntry:
+				md.L1.IsMapEntry = protowire.DecodeBool(v)
+			case fieldnum.MessageOptions_MessageSetWireFormat:
+				md.L1.IsMessageSet = protowire.DecodeBool(v)
+			}
+		default:
+			m := protowire.ConsumeFieldValue(num, typ, b)
+			b = b[m:]
+		}
+	}
+}
+
+func unmarshalMessageReservedRange(b []byte) (r [2]pref.FieldNumber) {
+	for len(b) > 0 {
+		num, typ, n := protowire.ConsumeTag(b)
+		b = b[n:]
+		switch typ {
+		case protowire.VarintType:
+			v, m := protowire.ConsumeVarint(b)
+			b = b[m:]
+			switch num {
+			case fieldnum.DescriptorProto_ReservedRange_Start:
+				r[0] = pref.FieldNumber(v)
+			case fieldnum.DescriptorProto_ReservedRange_End:
+				r[1] = pref.FieldNumber(v)
+			}
+		default:
+			m := protowire.ConsumeFieldValue(num, typ, b)
+			b = b[m:]
+		}
+	}
+	return r
+}
+
+func unmarshalMessageExtensionRange(b []byte) (r [2]pref.FieldNumber, rawOptions []byte) {
+	for len(b) > 0 {
+		num, typ, n := protowire.ConsumeTag(b)
+		b = b[n:]
+		switch typ {
+		case protowire.VarintType:
+			v, m := protowire.ConsumeVarint(b)
+			b = b[m:]
+			switch num {
+			case fieldnum.DescriptorProto_ExtensionRange_Start:
+				r[0] = pref.FieldNumber(v)
+			case fieldnum.DescriptorProto_ExtensionRange_End:
+				r[1] = pref.FieldNumber(v)
+			}
+		case protowire.BytesType:
+			v, m := protowire.ConsumeBytes(b)
+			b = b[m:]
+			switch num {
+			case fieldnum.DescriptorProto_ExtensionRange_Options:
+				rawOptions = appendOptions(rawOptions, v)
+			}
+		default:
+			m := protowire.ConsumeFieldValue(num, typ, b)
+			b = b[m:]
+		}
+	}
+	return r, rawOptions
+}
+
+func (fd *Field) unmarshalFull(b []byte, sb *strs.Builder, pf *File, pd pref.Descriptor, i int) {
+	fd.L0.ParentFile = pf
+	fd.L0.Parent = pd
+	fd.L0.Index = i
+
+	var rawTypeName []byte
+	var rawOptions []byte
+	for len(b) > 0 {
+		num, typ, n := protowire.ConsumeTag(b)
+		b = b[n:]
+		switch typ {
+		case protowire.VarintType:
+			v, m := protowire.ConsumeVarint(b)
+			b = b[m:]
+			switch num {
+			case fieldnum.FieldDescriptorProto_Number:
+				fd.L1.Number = pref.FieldNumber(v)
+			case fieldnum.FieldDescriptorProto_Label:
+				fd.L1.Cardinality = pref.Cardinality(v)
+			case fieldnum.FieldDescriptorProto_Type:
+				fd.L1.Kind = pref.Kind(v)
+			case fieldnum.FieldDescriptorProto_OneofIndex:
+				// In Message.unmarshalFull, we allocate slices for both
+				// the field and oneof descriptors before unmarshaling either
+				// of them. This ensures pointers to slice elements are stable.
+				od := &pd.(*Message).L2.Oneofs.List[v]
+				od.L1.Fields.List = append(od.L1.Fields.List, fd)
+				if fd.L1.ContainingOneof != nil {
+					panic("oneof type already set")
+				}
+				fd.L1.ContainingOneof = od
+			}
+		case protowire.BytesType:
+			v, m := protowire.ConsumeBytes(b)
+			b = b[m:]
+			switch num {
+			case fieldnum.FieldDescriptorProto_Name:
+				fd.L0.FullName = appendFullName(sb, pd.FullName(), v)
+			case fieldnum.FieldDescriptorProto_JsonName:
+				fd.L1.JSONName.Init(sb.MakeString(v))
+			case fieldnum.FieldDescriptorProto_DefaultValue:
+				fd.L1.Default.val = pref.ValueOfBytes(v) // temporarily store as bytes; later resolved in resolveMessages
+			case fieldnum.FieldDescriptorProto_TypeName:
+				rawTypeName = v
+			case fieldnum.FieldDescriptorProto_Options:
+				fd.unmarshalOptions(v)
+				rawOptions = appendOptions(rawOptions, v)
+			}
+		default:
+			m := protowire.ConsumeFieldValue(num, typ, b)
+			b = b[m:]
+		}
+	}
+	if rawTypeName != nil {
+		name := makeFullName(sb, rawTypeName)
+		switch fd.L1.Kind {
+		case pref.EnumKind:
+			fd.L1.Enum = PlaceholderEnum(name)
+		case pref.MessageKind, pref.GroupKind:
+			fd.L1.Message = PlaceholderMessage(name)
+		}
+	}
+	fd.L1.Options = pf.builder.optionsUnmarshaler(&descopts.Field, rawOptions)
+}
+
+func (fd *Field) unmarshalOptions(b []byte) {
+	const FieldOptions_EnforceUTF8 = 13
+
+	for len(b) > 0 {
+		num, typ, n := protowire.ConsumeTag(b)
+		b = b[n:]
+		switch typ {
+		case protowire.VarintType:
+			v, m := protowire.ConsumeVarint(b)
+			b = b[m:]
+			switch num {
+			case fieldnum.FieldOptions_Packed:
+				fd.L1.HasPacked = true
+				fd.L1.IsPacked = protowire.DecodeBool(v)
+			case fieldnum.FieldOptions_Weak:
+				fd.L1.IsWeak = protowire.DecodeBool(v)
+			case FieldOptions_EnforceUTF8:
+				fd.L1.HasEnforceUTF8 = true
+				fd.L1.EnforceUTF8 = protowire.DecodeBool(v)
+			}
+		default:
+			m := protowire.ConsumeFieldValue(num, typ, b)
+			b = b[m:]
+		}
+	}
+}
+
+func (od *Oneof) unmarshalFull(b []byte, sb *strs.Builder, pf *File, pd pref.Descriptor, i int) {
+	od.L0.ParentFile = pf
+	od.L0.Parent = pd
+	od.L0.Index = i
+
+	var rawOptions []byte
+	for len(b) > 0 {
+		num, typ, n := protowire.ConsumeTag(b)
+		b = b[n:]
+		switch typ {
+		case protowire.BytesType:
+			v, m := protowire.ConsumeBytes(b)
+			b = b[m:]
+			switch num {
+			case fieldnum.OneofDescriptorProto_Name:
+				od.L0.FullName = appendFullName(sb, pd.FullName(), v)
+			case fieldnum.OneofDescriptorProto_Options:
+				rawOptions = appendOptions(rawOptions, v)
+			}
+		default:
+			m := protowire.ConsumeFieldValue(num, typ, b)
+			b = b[m:]
+		}
+	}
+	od.L1.Options = pf.builder.optionsUnmarshaler(&descopts.Oneof, rawOptions)
+}
+
+func (xd *Extension) unmarshalFull(b []byte, sb *strs.Builder) {
+	var rawTypeName []byte
+	var rawOptions []byte
+	xd.L2 = new(ExtensionL2)
+	for len(b) > 0 {
+		num, typ, n := protowire.ConsumeTag(b)
+		b = b[n:]
+		switch typ {
+		case protowire.BytesType:
+			v, m := protowire.ConsumeBytes(b)
+			b = b[m:]
+			switch num {
+			case fieldnum.FieldDescriptorProto_JsonName:
+				xd.L2.JSONName.Init(sb.MakeString(v))
+			case fieldnum.FieldDescriptorProto_DefaultValue:
+				xd.L2.Default.val = pref.ValueOfBytes(v) // temporarily store as bytes; later resolved in resolveExtensions
+			case fieldnum.FieldDescriptorProto_TypeName:
+				rawTypeName = v
+			case fieldnum.FieldDescriptorProto_Options:
+				xd.unmarshalOptions(v)
+				rawOptions = appendOptions(rawOptions, v)
+			}
+		default:
+			m := protowire.ConsumeFieldValue(num, typ, b)
+			b = b[m:]
+		}
+	}
+	if rawTypeName != nil {
+		name := makeFullName(sb, rawTypeName)
+		switch xd.L1.Kind {
+		case pref.EnumKind:
+			xd.L2.Enum = PlaceholderEnum(name)
+		case pref.MessageKind, pref.GroupKind:
+			xd.L2.Message = PlaceholderMessage(name)
+		}
+	}
+	xd.L2.Options = xd.L0.ParentFile.builder.optionsUnmarshaler(&descopts.Field, rawOptions)
+}
+
+func (xd *Extension) unmarshalOptions(b []byte) {
+	for len(b) > 0 {
+		num, typ, n := protowire.ConsumeTag(b)
+		b = b[n:]
+		switch typ {
+		case protowire.VarintType:
+			v, m := protowire.ConsumeVarint(b)
+			b = b[m:]
+			switch num {
+			case fieldnum.FieldOptions_Packed:
+				xd.L2.IsPacked = protowire.DecodeBool(v)
+			}
+		default:
+			m := protowire.ConsumeFieldValue(num, typ, b)
+			b = b[m:]
+		}
+	}
+}
+
+func (sd *Service) unmarshalFull(b []byte, sb *strs.Builder) {
+	var rawMethods [][]byte
+	var rawOptions []byte
+	sd.L2 = new(ServiceL2)
+	for len(b) > 0 {
+		num, typ, n := protowire.ConsumeTag(b)
+		b = b[n:]
+		switch typ {
+		case protowire.BytesType:
+			v, m := protowire.ConsumeBytes(b)
+			b = b[m:]
+			switch num {
+			case fieldnum.ServiceDescriptorProto_Method:
+				rawMethods = append(rawMethods, v)
+			case fieldnum.ServiceDescriptorProto_Options:
+				rawOptions = appendOptions(rawOptions, v)
+			}
+		default:
+			m := protowire.ConsumeFieldValue(num, typ, b)
+			b = b[m:]
+		}
+	}
+	if len(rawMethods) > 0 {
+		sd.L2.Methods.List = make([]Method, len(rawMethods))
+		for i, b := range rawMethods {
+			sd.L2.Methods.List[i].unmarshalFull(b, sb, sd.L0.ParentFile, sd, i)
+		}
+	}
+	sd.L2.Options = sd.L0.ParentFile.builder.optionsUnmarshaler(&descopts.Service, rawOptions)
+}
+
+func (md *Method) unmarshalFull(b []byte, sb *strs.Builder, pf *File, pd pref.Descriptor, i int) {
+	md.L0.ParentFile = pf
+	md.L0.Parent = pd
+	md.L0.Index = i
+
+	var rawOptions []byte
+	for len(b) > 0 {
+		num, typ, n := protowire.ConsumeTag(b)
+		b = b[n:]
+		switch typ {
+		case protowire.VarintType:
+			v, m := protowire.ConsumeVarint(b)
+			b = b[m:]
+			switch num {
+			case fieldnum.MethodDescriptorProto_ClientStreaming:
+				md.L1.IsStreamingClient = protowire.DecodeBool(v)
+			case fieldnum.MethodDescriptorProto_ServerStreaming:
+				md.L1.IsStreamingServer = protowire.DecodeBool(v)
+			}
+		case protowire.BytesType:
+			v, m := protowire.ConsumeBytes(b)
+			b = b[m:]
+			switch num {
+			case fieldnum.MethodDescriptorProto_Name:
+				md.L0.FullName = appendFullName(sb, pd.FullName(), v)
+			case fieldnum.MethodDescriptorProto_InputType:
+				md.L1.Input = PlaceholderMessage(makeFullName(sb, v))
+			case fieldnum.MethodDescriptorProto_OutputType:
+				md.L1.Output = PlaceholderMessage(makeFullName(sb, v))
+			case fieldnum.MethodDescriptorProto_Options:
+				rawOptions = appendOptions(rawOptions, v)
+			}
+		default:
+			m := protowire.ConsumeFieldValue(num, typ, b)
+			b = b[m:]
+		}
+	}
+	md.L1.Options = pf.builder.optionsUnmarshaler(&descopts.Method, rawOptions)
+}
+
+// appendOptions appends src to dst, where the returned slice is never nil.
+// This is necessary to distinguish between empty and unpopulated options.
+func appendOptions(dst, src []byte) []byte {
+	if dst == nil {
+		dst = []byte{}
+	}
+	return append(dst, src...)
+}
+
+// optionsUnmarshaler constructs a lazy unmarshal function for an options message.
+//
+// The type of message to unmarshal to is passed as a pointer since the
+// vars in descopts may not yet be populated at the time this function is called.
+func (db *Builder) optionsUnmarshaler(p *pref.ProtoMessage, b []byte) func() pref.ProtoMessage {
+	if b == nil {
+		return nil
+	}
+	var opts pref.ProtoMessage
+	var once sync.Once
+	return func() pref.ProtoMessage {
+		once.Do(func() {
+			if *p == nil {
+				panic("Descriptor.Options called without importing the descriptor package")
+			}
+			opts = reflect.New(reflect.TypeOf(*p).Elem()).Interface().(pref.ProtoMessage)
+			if err := (proto.UnmarshalOptions{
+				AllowPartial: true,
+				Resolver:     db.TypeResolver,
+			}).Unmarshal(b, opts); err != nil {
+				panic(err)
+			}
+		})
+		return opts
+	}
+}
diff --git a/demo_test/vendor/google.golang.org/protobuf/internal/filedesc/desc_list.go b/demo_test/vendor/google.golang.org/protobuf/internal/filedesc/desc_list.go
new file mode 100644
index 0000000..1b7089b
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/internal/filedesc/desc_list.go
@@ -0,0 +1,286 @@
+// 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 filedesc
+
+import (
+	"fmt"
+	"math"
+	"sort"
+	"sync"
+
+	"google.golang.org/protobuf/encoding/protowire"
+	"google.golang.org/protobuf/internal/descfmt"
+	"google.golang.org/protobuf/internal/errors"
+	"google.golang.org/protobuf/internal/pragma"
+	"google.golang.org/protobuf/reflect/protoreflect"
+	pref "google.golang.org/protobuf/reflect/protoreflect"
+)
+
+type FileImports []pref.FileImport
+
+func (p *FileImports) Len() int                            { return len(*p) }
+func (p *FileImports) Get(i int) pref.FileImport           { return (*p)[i] }
+func (p *FileImports) Format(s fmt.State, r rune)          { descfmt.FormatList(s, r, p) }
+func (p *FileImports) ProtoInternal(pragma.DoNotImplement) {}
+
+type Names struct {
+	List []pref.Name
+	once sync.Once
+	has  map[pref.Name]int // protected by once
+}
+
+func (p *Names) Len() int                            { return len(p.List) }
+func (p *Names) Get(i int) pref.Name                 { return p.List[i] }
+func (p *Names) Has(s pref.Name) bool                { return p.lazyInit().has[s] > 0 }
+func (p *Names) Format(s fmt.State, r rune)          { descfmt.FormatList(s, r, p) }
+func (p *Names) ProtoInternal(pragma.DoNotImplement) {}
+func (p *Names) lazyInit() *Names {
+	p.once.Do(func() {
+		if len(p.List) > 0 {
+			p.has = make(map[pref.Name]int, len(p.List))
+			for _, s := range p.List {
+				p.has[s] = p.has[s] + 1
+			}
+		}
+	})
+	return p
+}
+
+// CheckValid reports any errors with the set of names with an error message
+// that completes the sentence: "ranges is invalid because it has ..."
+func (p *Names) CheckValid() error {
+	for s, n := range p.lazyInit().has {
+		switch {
+		case n > 1:
+			return errors.New("duplicate name: %q", s)
+		case false && !s.IsValid():
+			// NOTE: The C++ implementation does not validate the identifier.
+			// See https://github.com/protocolbuffers/protobuf/issues/6335.
+			return errors.New("invalid name: %q", s)
+		}
+	}
+	return nil
+}
+
+type EnumRanges struct {
+	List   [][2]pref.EnumNumber // start inclusive; end inclusive
+	once   sync.Once
+	sorted [][2]pref.EnumNumber // protected by once
+}
+
+func (p *EnumRanges) Len() int                     { return len(p.List) }
+func (p *EnumRanges) Get(i int) [2]pref.EnumNumber { return p.List[i] }
+func (p *EnumRanges) Has(n pref.EnumNumber) bool {
+	for ls := p.lazyInit().sorted; len(ls) > 0; {
+		i := len(ls) / 2
+		switch r := enumRange(ls[i]); {
+		case n < r.Start():
+			ls = ls[:i] // search lower
+		case n > r.End():
+			ls = ls[i+1:] // search upper
+		default:
+			return true
+		}
+	}
+	return false
+}
+func (p *EnumRanges) Format(s fmt.State, r rune)          { descfmt.FormatList(s, r, p) }
+func (p *EnumRanges) ProtoInternal(pragma.DoNotImplement) {}
+func (p *EnumRanges) lazyInit() *EnumRanges {
+	p.once.Do(func() {
+		p.sorted = append(p.sorted, p.List...)
+		sort.Slice(p.sorted, func(i, j int) bool {
+			return p.sorted[i][0] < p.sorted[j][0]
+		})
+	})
+	return p
+}
+
+// CheckValid reports any errors with the set of names with an error message
+// that completes the sentence: "ranges is invalid because it has ..."
+func (p *EnumRanges) CheckValid() error {
+	var rp enumRange
+	for i, r := range p.lazyInit().sorted {
+		r := enumRange(r)
+		switch {
+		case !(r.Start() <= r.End()):
+			return errors.New("invalid range: %v", r)
+		case !(rp.End() < r.Start()) && i > 0:
+			return errors.New("overlapping ranges: %v with %v", rp, r)
+		}
+		rp = r
+	}
+	return nil
+}
+
+type enumRange [2]protoreflect.EnumNumber
+
+func (r enumRange) Start() protoreflect.EnumNumber { return r[0] } // inclusive
+func (r enumRange) End() protoreflect.EnumNumber   { return r[1] } // inclusive
+func (r enumRange) String() string {
+	if r.Start() == r.End() {
+		return fmt.Sprintf("%d", r.Start())
+	}
+	return fmt.Sprintf("%d to %d", r.Start(), r.End())
+}
+
+type FieldRanges struct {
+	List   [][2]pref.FieldNumber // start inclusive; end exclusive
+	once   sync.Once
+	sorted [][2]pref.FieldNumber // protected by once
+}
+
+func (p *FieldRanges) Len() int                      { return len(p.List) }
+func (p *FieldRanges) Get(i int) [2]pref.FieldNumber { return p.List[i] }
+func (p *FieldRanges) Has(n pref.FieldNumber) bool {
+	for ls := p.lazyInit().sorted; len(ls) > 0; {
+		i := len(ls) / 2
+		switch r := fieldRange(ls[i]); {
+		case n < r.Start():
+			ls = ls[:i] // search lower
+		case n > r.End():
+			ls = ls[i+1:] // search upper
+		default:
+			return true
+		}
+	}
+	return false
+}
+func (p *FieldRanges) Format(s fmt.State, r rune)          { descfmt.FormatList(s, r, p) }
+func (p *FieldRanges) ProtoInternal(pragma.DoNotImplement) {}
+func (p *FieldRanges) lazyInit() *FieldRanges {
+	p.once.Do(func() {
+		p.sorted = append(p.sorted, p.List...)
+		sort.Slice(p.sorted, func(i, j int) bool {
+			return p.sorted[i][0] < p.sorted[j][0]
+		})
+	})
+	return p
+}
+
+// CheckValid reports any errors with the set of ranges with an error message
+// that completes the sentence: "ranges is invalid because it has ..."
+func (p *FieldRanges) CheckValid(isMessageSet bool) error {
+	var rp fieldRange
+	for i, r := range p.lazyInit().sorted {
+		r := fieldRange(r)
+		switch {
+		case !isValidFieldNumber(r.Start(), isMessageSet):
+			return errors.New("invalid field number: %d", r.Start())
+		case !isValidFieldNumber(r.End(), isMessageSet):
+			return errors.New("invalid field number: %d", r.End())
+		case !(r.Start() <= r.End()):
+			return errors.New("invalid range: %v", r)
+		case !(rp.End() < r.Start()) && i > 0:
+			return errors.New("overlapping ranges: %v with %v", rp, r)
+		}
+		rp = r
+	}
+	return nil
+}
+
+// isValidFieldNumber reports whether the field number is valid.
+// Unlike the FieldNumber.IsValid method, it allows ranges that cover the
+// reserved number range.
+func isValidFieldNumber(n protoreflect.FieldNumber, isMessageSet bool) bool {
+	if isMessageSet {
+		return protowire.MinValidNumber <= n && n <= math.MaxInt32
+	}
+	return protowire.MinValidNumber <= n && n <= protowire.MaxValidNumber
+}
+
+// CheckOverlap reports an error if p and q overlap.
+func (p *FieldRanges) CheckOverlap(q *FieldRanges) error {
+	rps := p.lazyInit().sorted
+	rqs := q.lazyInit().sorted
+	for pi, qi := 0, 0; pi < len(rps) && qi < len(rqs); {
+		rp := fieldRange(rps[pi])
+		rq := fieldRange(rqs[qi])
+		if !(rp.End() < rq.Start() || rq.End() < rp.Start()) {
+			return errors.New("overlapping ranges: %v with %v", rp, rq)
+		}
+		if rp.Start() < rq.Start() {
+			pi++
+		} else {
+			qi++
+		}
+	}
+	return nil
+}
+
+type fieldRange [2]protoreflect.FieldNumber
+
+func (r fieldRange) Start() protoreflect.FieldNumber { return r[0] }     // inclusive
+func (r fieldRange) End() protoreflect.FieldNumber   { return r[1] - 1 } // inclusive
+func (r fieldRange) String() string {
+	if r.Start() == r.End() {
+		return fmt.Sprintf("%d", r.Start())
+	}
+	return fmt.Sprintf("%d to %d", r.Start(), r.End())
+}
+
+type FieldNumbers struct {
+	List []pref.FieldNumber
+	once sync.Once
+	has  map[pref.FieldNumber]struct{} // protected by once
+}
+
+func (p *FieldNumbers) Len() int                   { return len(p.List) }
+func (p *FieldNumbers) Get(i int) pref.FieldNumber { return p.List[i] }
+func (p *FieldNumbers) Has(n pref.FieldNumber) bool {
+	p.once.Do(func() {
+		if len(p.List) > 0 {
+			p.has = make(map[pref.FieldNumber]struct{}, len(p.List))
+			for _, n := range p.List {
+				p.has[n] = struct{}{}
+			}
+		}
+	})
+	_, ok := p.has[n]
+	return ok
+}
+func (p *FieldNumbers) Format(s fmt.State, r rune)          { descfmt.FormatList(s, r, p) }
+func (p *FieldNumbers) ProtoInternal(pragma.DoNotImplement) {}
+
+type OneofFields struct {
+	List   []pref.FieldDescriptor
+	once   sync.Once
+	byName map[pref.Name]pref.FieldDescriptor        // protected by once
+	byJSON map[string]pref.FieldDescriptor           // protected by once
+	byNum  map[pref.FieldNumber]pref.FieldDescriptor // protected by once
+}
+
+func (p *OneofFields) Len() int                                         { return len(p.List) }
+func (p *OneofFields) Get(i int) pref.FieldDescriptor                   { return p.List[i] }
+func (p *OneofFields) ByName(s pref.Name) pref.FieldDescriptor          { return p.lazyInit().byName[s] }
+func (p *OneofFields) ByJSONName(s string) pref.FieldDescriptor         { return p.lazyInit().byJSON[s] }
+func (p *OneofFields) ByNumber(n pref.FieldNumber) pref.FieldDescriptor { return p.lazyInit().byNum[n] }
+func (p *OneofFields) Format(s fmt.State, r rune)                       { descfmt.FormatList(s, r, p) }
+func (p *OneofFields) ProtoInternal(pragma.DoNotImplement)              {}
+
+func (p *OneofFields) lazyInit() *OneofFields {
+	p.once.Do(func() {
+		if len(p.List) > 0 {
+			p.byName = make(map[pref.Name]pref.FieldDescriptor, len(p.List))
+			p.byJSON = make(map[string]pref.FieldDescriptor, len(p.List))
+			p.byNum = make(map[pref.FieldNumber]pref.FieldDescriptor, len(p.List))
+			for _, f := range p.List {
+				// Field names and numbers are guaranteed to be unique.
+				p.byName[f.Name()] = f
+				p.byJSON[f.JSONName()] = f
+				p.byNum[f.Number()] = f
+			}
+		}
+	})
+	return p
+}
+
+type SourceLocations struct {
+	List []pref.SourceLocation
+}
+
+func (p *SourceLocations) Len() int                            { return len(p.List) }
+func (p *SourceLocations) Get(i int) pref.SourceLocation       { return p.List[i] }
+func (p *SourceLocations) ProtoInternal(pragma.DoNotImplement) {}
diff --git a/demo_test/vendor/google.golang.org/protobuf/internal/filedesc/desc_list_gen.go b/demo_test/vendor/google.golang.org/protobuf/internal/filedesc/desc_list_gen.go
new file mode 100644
index 0000000..6a8825e
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/internal/filedesc/desc_list_gen.go
@@ -0,0 +1,345 @@
+// 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 filedesc
+
+import (
+	"fmt"
+	"sync"
+
+	"google.golang.org/protobuf/internal/descfmt"
+	"google.golang.org/protobuf/internal/pragma"
+	"google.golang.org/protobuf/reflect/protoreflect"
+)
+
+type Enums struct {
+	List   []Enum
+	once   sync.Once
+	byName map[protoreflect.Name]*Enum // protected by once
+}
+
+func (p *Enums) Len() int {
+	return len(p.List)
+}
+func (p *Enums) Get(i int) protoreflect.EnumDescriptor {
+	return &p.List[i]
+}
+func (p *Enums) ByName(s protoreflect.Name) protoreflect.EnumDescriptor {
+	if d := p.lazyInit().byName[s]; d != nil {
+		return d
+	}
+	return nil
+}
+func (p *Enums) Format(s fmt.State, r rune) {
+	descfmt.FormatList(s, r, p)
+}
+func (p *Enums) ProtoInternal(pragma.DoNotImplement) {}
+func (p *Enums) lazyInit() *Enums {
+	p.once.Do(func() {
+		if len(p.List) > 0 {
+			p.byName = make(map[protoreflect.Name]*Enum, len(p.List))
+			for i := range p.List {
+				d := &p.List[i]
+				if _, ok := p.byName[d.Name()]; !ok {
+					p.byName[d.Name()] = d
+				}
+			}
+		}
+	})
+	return p
+}
+
+type EnumValues struct {
+	List   []EnumValue
+	once   sync.Once
+	byName map[protoreflect.Name]*EnumValue       // protected by once
+	byNum  map[protoreflect.EnumNumber]*EnumValue // protected by once
+}
+
+func (p *EnumValues) Len() int {
+	return len(p.List)
+}
+func (p *EnumValues) Get(i int) protoreflect.EnumValueDescriptor {
+	return &p.List[i]
+}
+func (p *EnumValues) ByName(s protoreflect.Name) protoreflect.EnumValueDescriptor {
+	if d := p.lazyInit().byName[s]; d != nil {
+		return d
+	}
+	return nil
+}
+func (p *EnumValues) ByNumber(n protoreflect.EnumNumber) protoreflect.EnumValueDescriptor {
+	if d := p.lazyInit().byNum[n]; d != nil {
+		return d
+	}
+	return nil
+}
+func (p *EnumValues) Format(s fmt.State, r rune) {
+	descfmt.FormatList(s, r, p)
+}
+func (p *EnumValues) ProtoInternal(pragma.DoNotImplement) {}
+func (p *EnumValues) lazyInit() *EnumValues {
+	p.once.Do(func() {
+		if len(p.List) > 0 {
+			p.byName = make(map[protoreflect.Name]*EnumValue, len(p.List))
+			p.byNum = make(map[protoreflect.EnumNumber]*EnumValue, len(p.List))
+			for i := range p.List {
+				d := &p.List[i]
+				if _, ok := p.byName[d.Name()]; !ok {
+					p.byName[d.Name()] = d
+				}
+				if _, ok := p.byNum[d.Number()]; !ok {
+					p.byNum[d.Number()] = d
+				}
+			}
+		}
+	})
+	return p
+}
+
+type Messages struct {
+	List   []Message
+	once   sync.Once
+	byName map[protoreflect.Name]*Message // protected by once
+}
+
+func (p *Messages) Len() int {
+	return len(p.List)
+}
+func (p *Messages) Get(i int) protoreflect.MessageDescriptor {
+	return &p.List[i]
+}
+func (p *Messages) ByName(s protoreflect.Name) protoreflect.MessageDescriptor {
+	if d := p.lazyInit().byName[s]; d != nil {
+		return d
+	}
+	return nil
+}
+func (p *Messages) Format(s fmt.State, r rune) {
+	descfmt.FormatList(s, r, p)
+}
+func (p *Messages) ProtoInternal(pragma.DoNotImplement) {}
+func (p *Messages) lazyInit() *Messages {
+	p.once.Do(func() {
+		if len(p.List) > 0 {
+			p.byName = make(map[protoreflect.Name]*Message, len(p.List))
+			for i := range p.List {
+				d := &p.List[i]
+				if _, ok := p.byName[d.Name()]; !ok {
+					p.byName[d.Name()] = d
+				}
+			}
+		}
+	})
+	return p
+}
+
+type Fields struct {
+	List   []Field
+	once   sync.Once
+	byName map[protoreflect.Name]*Field        // protected by once
+	byJSON map[string]*Field                   // protected by once
+	byNum  map[protoreflect.FieldNumber]*Field // protected by once
+}
+
+func (p *Fields) Len() int {
+	return len(p.List)
+}
+func (p *Fields) Get(i int) protoreflect.FieldDescriptor {
+	return &p.List[i]
+}
+func (p *Fields) ByName(s protoreflect.Name) protoreflect.FieldDescriptor {
+	if d := p.lazyInit().byName[s]; d != nil {
+		return d
+	}
+	return nil
+}
+func (p *Fields) ByJSONName(s string) protoreflect.FieldDescriptor {
+	if d := p.lazyInit().byJSON[s]; d != nil {
+		return d
+	}
+	return nil
+}
+func (p *Fields) ByNumber(n protoreflect.FieldNumber) protoreflect.FieldDescriptor {
+	if d := p.lazyInit().byNum[n]; d != nil {
+		return d
+	}
+	return nil
+}
+func (p *Fields) Format(s fmt.State, r rune) {
+	descfmt.FormatList(s, r, p)
+}
+func (p *Fields) ProtoInternal(pragma.DoNotImplement) {}
+func (p *Fields) lazyInit() *Fields {
+	p.once.Do(func() {
+		if len(p.List) > 0 {
+			p.byName = make(map[protoreflect.Name]*Field, len(p.List))
+			p.byJSON = make(map[string]*Field, len(p.List))
+			p.byNum = make(map[protoreflect.FieldNumber]*Field, len(p.List))
+			for i := range p.List {
+				d := &p.List[i]
+				if _, ok := p.byName[d.Name()]; !ok {
+					p.byName[d.Name()] = d
+				}
+				if _, ok := p.byJSON[d.JSONName()]; !ok {
+					p.byJSON[d.JSONName()] = d
+				}
+				if _, ok := p.byNum[d.Number()]; !ok {
+					p.byNum[d.Number()] = d
+				}
+			}
+		}
+	})
+	return p
+}
+
+type Oneofs struct {
+	List   []Oneof
+	once   sync.Once
+	byName map[protoreflect.Name]*Oneof // protected by once
+}
+
+func (p *Oneofs) Len() int {
+	return len(p.List)
+}
+func (p *Oneofs) Get(i int) protoreflect.OneofDescriptor {
+	return &p.List[i]
+}
+func (p *Oneofs) ByName(s protoreflect.Name) protoreflect.OneofDescriptor {
+	if d := p.lazyInit().byName[s]; d != nil {
+		return d
+	}
+	return nil
+}
+func (p *Oneofs) Format(s fmt.State, r rune) {
+	descfmt.FormatList(s, r, p)
+}
+func (p *Oneofs) ProtoInternal(pragma.DoNotImplement) {}
+func (p *Oneofs) lazyInit() *Oneofs {
+	p.once.Do(func() {
+		if len(p.List) > 0 {
+			p.byName = make(map[protoreflect.Name]*Oneof, len(p.List))
+			for i := range p.List {
+				d := &p.List[i]
+				if _, ok := p.byName[d.Name()]; !ok {
+					p.byName[d.Name()] = d
+				}
+			}
+		}
+	})
+	return p
+}
+
+type Extensions struct {
+	List   []Extension
+	once   sync.Once
+	byName map[protoreflect.Name]*Extension // protected by once
+}
+
+func (p *Extensions) Len() int {
+	return len(p.List)
+}
+func (p *Extensions) Get(i int) protoreflect.ExtensionDescriptor {
+	return &p.List[i]
+}
+func (p *Extensions) ByName(s protoreflect.Name) protoreflect.ExtensionDescriptor {
+	if d := p.lazyInit().byName[s]; d != nil {
+		return d
+	}
+	return nil
+}
+func (p *Extensions) Format(s fmt.State, r rune) {
+	descfmt.FormatList(s, r, p)
+}
+func (p *Extensions) ProtoInternal(pragma.DoNotImplement) {}
+func (p *Extensions) lazyInit() *Extensions {
+	p.once.Do(func() {
+		if len(p.List) > 0 {
+			p.byName = make(map[protoreflect.Name]*Extension, len(p.List))
+			for i := range p.List {
+				d := &p.List[i]
+				if _, ok := p.byName[d.Name()]; !ok {
+					p.byName[d.Name()] = d
+				}
+			}
+		}
+	})
+	return p
+}
+
+type Services struct {
+	List   []Service
+	once   sync.Once
+	byName map[protoreflect.Name]*Service // protected by once
+}
+
+func (p *Services) Len() int {
+	return len(p.List)
+}
+func (p *Services) Get(i int) protoreflect.ServiceDescriptor {
+	return &p.List[i]
+}
+func (p *Services) ByName(s protoreflect.Name) protoreflect.ServiceDescriptor {
+	if d := p.lazyInit().byName[s]; d != nil {
+		return d
+	}
+	return nil
+}
+func (p *Services) Format(s fmt.State, r rune) {
+	descfmt.FormatList(s, r, p)
+}
+func (p *Services) ProtoInternal(pragma.DoNotImplement) {}
+func (p *Services) lazyInit() *Services {
+	p.once.Do(func() {
+		if len(p.List) > 0 {
+			p.byName = make(map[protoreflect.Name]*Service, len(p.List))
+			for i := range p.List {
+				d := &p.List[i]
+				if _, ok := p.byName[d.Name()]; !ok {
+					p.byName[d.Name()] = d
+				}
+			}
+		}
+	})
+	return p
+}
+
+type Methods struct {
+	List   []Method
+	once   sync.Once
+	byName map[protoreflect.Name]*Method // protected by once
+}
+
+func (p *Methods) Len() int {
+	return len(p.List)
+}
+func (p *Methods) Get(i int) protoreflect.MethodDescriptor {
+	return &p.List[i]
+}
+func (p *Methods) ByName(s protoreflect.Name) protoreflect.MethodDescriptor {
+	if d := p.lazyInit().byName[s]; d != nil {
+		return d
+	}
+	return nil
+}
+func (p *Methods) Format(s fmt.State, r rune) {
+	descfmt.FormatList(s, r, p)
+}
+func (p *Methods) ProtoInternal(pragma.DoNotImplement) {}
+func (p *Methods) lazyInit() *Methods {
+	p.once.Do(func() {
+		if len(p.List) > 0 {
+			p.byName = make(map[protoreflect.Name]*Method, len(p.List))
+			for i := range p.List {
+				d := &p.List[i]
+				if _, ok := p.byName[d.Name()]; !ok {
+					p.byName[d.Name()] = d
+				}
+			}
+		}
+	})
+	return p
+}
diff --git a/demo_test/vendor/google.golang.org/protobuf/internal/filedesc/placeholder.go b/demo_test/vendor/google.golang.org/protobuf/internal/filedesc/placeholder.go
new file mode 100644
index 0000000..dbf2c60
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/internal/filedesc/placeholder.go
@@ -0,0 +1,107 @@
+// 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 filedesc
+
+import (
+	"google.golang.org/protobuf/internal/descopts"
+	"google.golang.org/protobuf/internal/pragma"
+	pref "google.golang.org/protobuf/reflect/protoreflect"
+)
+
+var (
+	emptyNames           = new(Names)
+	emptyEnumRanges      = new(EnumRanges)
+	emptyFieldRanges     = new(FieldRanges)
+	emptyFieldNumbers    = new(FieldNumbers)
+	emptySourceLocations = new(SourceLocations)
+
+	emptyFiles      = new(FileImports)
+	emptyMessages   = new(Messages)
+	emptyFields     = new(Fields)
+	emptyOneofs     = new(Oneofs)
+	emptyEnums      = new(Enums)
+	emptyEnumValues = new(EnumValues)
+	emptyExtensions = new(Extensions)
+	emptyServices   = new(Services)
+)
+
+// PlaceholderFile is a placeholder, representing only the file path.
+type PlaceholderFile string
+
+func (f PlaceholderFile) ParentFile() pref.FileDescriptor       { return f }
+func (f PlaceholderFile) Parent() pref.Descriptor               { return nil }
+func (f PlaceholderFile) Index() int                            { return 0 }
+func (f PlaceholderFile) Syntax() pref.Syntax                   { return 0 }
+func (f PlaceholderFile) Name() pref.Name                       { return "" }
+func (f PlaceholderFile) FullName() pref.FullName               { return "" }
+func (f PlaceholderFile) IsPlaceholder() bool                   { return true }
+func (f PlaceholderFile) Options() pref.ProtoMessage            { return descopts.File }
+func (f PlaceholderFile) Path() string                          { return string(f) }
+func (f PlaceholderFile) Package() pref.FullName                { return "" }
+func (f PlaceholderFile) Imports() pref.FileImports             { return emptyFiles }
+func (f PlaceholderFile) Messages() pref.MessageDescriptors     { return emptyMessages }
+func (f PlaceholderFile) Enums() pref.EnumDescriptors           { return emptyEnums }
+func (f PlaceholderFile) Extensions() pref.ExtensionDescriptors { return emptyExtensions }
+func (f PlaceholderFile) Services() pref.ServiceDescriptors     { return emptyServices }
+func (f PlaceholderFile) SourceLocations() pref.SourceLocations { return emptySourceLocations }
+func (f PlaceholderFile) ProtoType(pref.FileDescriptor)         { return }
+func (f PlaceholderFile) ProtoInternal(pragma.DoNotImplement)   { return }
+
+// PlaceholderEnum is a placeholder, representing only the full name.
+type PlaceholderEnum pref.FullName
+
+func (e PlaceholderEnum) ParentFile() pref.FileDescriptor     { return nil }
+func (e PlaceholderEnum) Parent() pref.Descriptor             { return nil }
+func (e PlaceholderEnum) Index() int                          { return 0 }
+func (e PlaceholderEnum) Syntax() pref.Syntax                 { return 0 }
+func (e PlaceholderEnum) Name() pref.Name                     { return pref.FullName(e).Name() }
+func (e PlaceholderEnum) FullName() pref.FullName             { return pref.FullName(e) }
+func (e PlaceholderEnum) IsPlaceholder() bool                 { return true }
+func (e PlaceholderEnum) Options() pref.ProtoMessage          { return descopts.Enum }
+func (e PlaceholderEnum) Values() pref.EnumValueDescriptors   { return emptyEnumValues }
+func (e PlaceholderEnum) ReservedNames() pref.Names           { return emptyNames }
+func (e PlaceholderEnum) ReservedRanges() pref.EnumRanges     { return emptyEnumRanges }
+func (e PlaceholderEnum) ProtoType(pref.EnumDescriptor)       { return }
+func (e PlaceholderEnum) ProtoInternal(pragma.DoNotImplement) { return }
+
+// PlaceholderEnumValue is a placeholder, representing only the full name.
+type PlaceholderEnumValue pref.FullName
+
+func (e PlaceholderEnumValue) ParentFile() pref.FileDescriptor     { return nil }
+func (e PlaceholderEnumValue) Parent() pref.Descriptor             { return nil }
+func (e PlaceholderEnumValue) Index() int                          { return 0 }
+func (e PlaceholderEnumValue) Syntax() pref.Syntax                 { return 0 }
+func (e PlaceholderEnumValue) Name() pref.Name                     { return pref.FullName(e).Name() }
+func (e PlaceholderEnumValue) FullName() pref.FullName             { return pref.FullName(e) }
+func (e PlaceholderEnumValue) IsPlaceholder() bool                 { return true }
+func (e PlaceholderEnumValue) Options() pref.ProtoMessage          { return descopts.EnumValue }
+func (e PlaceholderEnumValue) Number() pref.EnumNumber             { return 0 }
+func (e PlaceholderEnumValue) ProtoType(pref.EnumValueDescriptor)  { return }
+func (e PlaceholderEnumValue) ProtoInternal(pragma.DoNotImplement) { return }
+
+// PlaceholderMessage is a placeholder, representing only the full name.
+type PlaceholderMessage pref.FullName
+
+func (m PlaceholderMessage) ParentFile() pref.FileDescriptor             { return nil }
+func (m PlaceholderMessage) Parent() pref.Descriptor                     { return nil }
+func (m PlaceholderMessage) Index() int                                  { return 0 }
+func (m PlaceholderMessage) Syntax() pref.Syntax                         { return 0 }
+func (m PlaceholderMessage) Name() pref.Name                             { return pref.FullName(m).Name() }
+func (m PlaceholderMessage) FullName() pref.FullName                     { return pref.FullName(m) }
+func (m PlaceholderMessage) IsPlaceholder() bool                         { return true }
+func (m PlaceholderMessage) Options() pref.ProtoMessage                  { return descopts.Message }
+func (m PlaceholderMessage) IsMapEntry() bool                            { return false }
+func (m PlaceholderMessage) Fields() pref.FieldDescriptors               { return emptyFields }
+func (m PlaceholderMessage) Oneofs() pref.OneofDescriptors               { return emptyOneofs }
+func (m PlaceholderMessage) ReservedNames() pref.Names                   { return emptyNames }
+func (m PlaceholderMessage) ReservedRanges() pref.FieldRanges            { return emptyFieldRanges }
+func (m PlaceholderMessage) RequiredNumbers() pref.FieldNumbers          { return emptyFieldNumbers }
+func (m PlaceholderMessage) ExtensionRanges() pref.FieldRanges           { return emptyFieldRanges }
+func (m PlaceholderMessage) ExtensionRangeOptions(int) pref.ProtoMessage { panic("index out of range") }
+func (m PlaceholderMessage) Messages() pref.MessageDescriptors           { return emptyMessages }
+func (m PlaceholderMessage) Enums() pref.EnumDescriptors                 { return emptyEnums }
+func (m PlaceholderMessage) Extensions() pref.ExtensionDescriptors       { return emptyExtensions }
+func (m PlaceholderMessage) ProtoType(pref.MessageDescriptor)            { return }
+func (m PlaceholderMessage) ProtoInternal(pragma.DoNotImplement)         { return }
diff --git a/demo_test/vendor/google.golang.org/protobuf/internal/filetype/build.go b/demo_test/vendor/google.golang.org/protobuf/internal/filetype/build.go
new file mode 100644
index 0000000..0a0dd35
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/internal/filetype/build.go
@@ -0,0 +1,297 @@
+// 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 filetype provides functionality for wrapping descriptors
+// with Go type information.
+package filetype
+
+import (
+	"reflect"
+
+	"google.golang.org/protobuf/internal/descopts"
+	fdesc "google.golang.org/protobuf/internal/filedesc"
+	pimpl "google.golang.org/protobuf/internal/impl"
+	pref "google.golang.org/protobuf/reflect/protoreflect"
+	preg "google.golang.org/protobuf/reflect/protoregistry"
+)
+
+// Builder constructs type descriptors from a raw file descriptor
+// and associated Go types for each enum and message declaration.
+//
+//
+// Flattened Ordering
+//
+// The protobuf type system represents declarations as a tree. Certain nodes in
+// the tree require us to either associate it with a concrete Go type or to
+// resolve a dependency, which is information that must be provided separately
+// since it cannot be derived from the file descriptor alone.
+//
+// However, representing a tree as Go literals is difficult to simply do in a
+// space and time efficient way. Thus, we store them as a flattened list of
+// objects where the serialization order from the tree-based form is important.
+//
+// The "flattened ordering" is defined as a tree traversal of all enum, message,
+// extension, and service declarations using the following algorithm:
+//
+//	def VisitFileDecls(fd):
+//		for e in fd.Enums:      yield e
+//		for m in fd.Messages:   yield m
+//		for x in fd.Extensions: yield x
+//		for s in fd.Services:   yield s
+//		for m in fd.Messages:   yield from VisitMessageDecls(m)
+//
+//	def VisitMessageDecls(md):
+//		for e in md.Enums:      yield e
+//		for m in md.Messages:   yield m
+//		for x in md.Extensions: yield x
+//		for m in md.Messages:   yield from VisitMessageDecls(m)
+//
+// The traversal starts at the root file descriptor and yields each direct
+// declaration within each node before traversing into sub-declarations
+// that children themselves may have.
+type Builder struct {
+	// File is the underlying file descriptor builder.
+	File fdesc.Builder
+
+	// GoTypes is a unique set of the Go types for all declarations and
+	// dependencies. Each type is represented as a zero value of the Go type.
+	//
+	// Declarations are Go types generated for enums and messages directly
+	// declared (not publicly imported) in the proto source file.
+	// Messages for map entries are accounted for, but represented by nil.
+	// Enum declarations in "flattened ordering" come first, followed by
+	// message declarations in "flattened ordering".
+	//
+	// Dependencies are Go types for enums or messages referenced by
+	// message fields (excluding weak fields), for parent extended messages of
+	// extension fields, for enums or messages referenced by extension fields,
+	// and for input and output messages referenced by service methods.
+	// Dependencies must come after declarations, but the ordering of
+	// dependencies themselves is unspecified.
+	GoTypes []interface{}
+
+	// DependencyIndexes is an ordered list of indexes into GoTypes for the
+	// dependencies of messages, extensions, or services.
+	//
+	// There are 5 sub-lists in "flattened ordering" concatenated back-to-back:
+	//	0. Message field dependencies: list of the enum or message type
+	//	referred to by every message field.
+	//	1. Extension field targets: list of the extended parent message of
+	//	every extension.
+	//	2. Extension field dependencies: list of the enum or message type
+	//	referred to by every extension field.
+	//	3. Service method inputs: list of the input message type
+	//	referred to by every service method.
+	//	4. Service method outputs: list of the output message type
+	//	referred to by every service method.
+	//
+	// The offset into DependencyIndexes for the start of each sub-list
+	// is appended to the end in reverse order.
+	DependencyIndexes []int32
+
+	// EnumInfos is a list of enum infos in "flattened ordering".
+	EnumInfos []pimpl.EnumInfo
+
+	// MessageInfos is a list of message infos in "flattened ordering".
+	// If provided, the GoType and PBType for each element is populated.
+	//
+	// Requirement: len(MessageInfos) == len(Build.Messages)
+	MessageInfos []pimpl.MessageInfo
+
+	// ExtensionInfos is a list of extension infos in "flattened ordering".
+	// Each element is initialized and registered with the protoregistry package.
+	//
+	// Requirement: len(LegacyExtensions) == len(Build.Extensions)
+	ExtensionInfos []pimpl.ExtensionInfo
+
+	// TypeRegistry is the registry to register each type descriptor.
+	// If nil, it uses protoregistry.GlobalTypes.
+	TypeRegistry interface {
+		RegisterMessage(pref.MessageType) error
+		RegisterEnum(pref.EnumType) error
+		RegisterExtension(pref.ExtensionType) error
+	}
+}
+
+// Out is the output of the builder.
+type Out struct {
+	File pref.FileDescriptor
+}
+
+func (tb Builder) Build() (out Out) {
+	// Replace the resolver with one that resolves dependencies by index,
+	// which is faster and more reliable than relying on the global registry.
+	if tb.File.FileRegistry == nil {
+		tb.File.FileRegistry = preg.GlobalFiles
+	}
+	tb.File.FileRegistry = &resolverByIndex{
+		goTypes:      tb.GoTypes,
+		depIdxs:      tb.DependencyIndexes,
+		fileRegistry: tb.File.FileRegistry,
+	}
+
+	// Initialize registry if unpopulated.
+	if tb.TypeRegistry == nil {
+		tb.TypeRegistry = preg.GlobalTypes
+	}
+
+	fbOut := tb.File.Build()
+	out.File = fbOut.File
+
+	// Process enums.
+	enumGoTypes := tb.GoTypes[:len(fbOut.Enums)]
+	if len(tb.EnumInfos) != len(fbOut.Enums) {
+		panic("mismatching enum lengths")
+	}
+	if len(fbOut.Enums) > 0 {
+		for i := range fbOut.Enums {
+			tb.EnumInfos[i] = pimpl.EnumInfo{
+				GoReflectType: reflect.TypeOf(enumGoTypes[i]),
+				Desc:          &fbOut.Enums[i],
+			}
+			// Register enum types.
+			if err := tb.TypeRegistry.RegisterEnum(&tb.EnumInfos[i]); err != nil {
+				panic(err)
+			}
+		}
+	}
+
+	// Process messages.
+	messageGoTypes := tb.GoTypes[len(fbOut.Enums):][:len(fbOut.Messages)]
+	if len(tb.MessageInfos) != len(fbOut.Messages) {
+		panic("mismatching message lengths")
+	}
+	if len(fbOut.Messages) > 0 {
+		for i := range fbOut.Messages {
+			if messageGoTypes[i] == nil {
+				continue // skip map entry
+			}
+
+			tb.MessageInfos[i].GoReflectType = reflect.TypeOf(messageGoTypes[i])
+			tb.MessageInfos[i].Desc = &fbOut.Messages[i]
+
+			// Register message types.
+			if err := tb.TypeRegistry.RegisterMessage(&tb.MessageInfos[i]); err != nil {
+				panic(err)
+			}
+		}
+
+		// As a special-case for descriptor.proto,
+		// locally register concrete message type for the options.
+		if out.File.Path() == "google/protobuf/descriptor.proto" && out.File.Package() == "google.protobuf" {
+			for i := range fbOut.Messages {
+				switch fbOut.Messages[i].Name() {
+				case "FileOptions":
+					descopts.File = messageGoTypes[i].(pref.ProtoMessage)
+				case "EnumOptions":
+					descopts.Enum = messageGoTypes[i].(pref.ProtoMessage)
+				case "EnumValueOptions":
+					descopts.EnumValue = messageGoTypes[i].(pref.ProtoMessage)
+				case "MessageOptions":
+					descopts.Message = messageGoTypes[i].(pref.ProtoMessage)
+				case "FieldOptions":
+					descopts.Field = messageGoTypes[i].(pref.ProtoMessage)
+				case "OneofOptions":
+					descopts.Oneof = messageGoTypes[i].(pref.ProtoMessage)
+				case "ExtensionRangeOptions":
+					descopts.ExtensionRange = messageGoTypes[i].(pref.ProtoMessage)
+				case "ServiceOptions":
+					descopts.Service = messageGoTypes[i].(pref.ProtoMessage)
+				case "MethodOptions":
+					descopts.Method = messageGoTypes[i].(pref.ProtoMessage)
+				}
+			}
+		}
+	}
+
+	// Process extensions.
+	if len(tb.ExtensionInfos) != len(fbOut.Extensions) {
+		panic("mismatching extension lengths")
+	}
+	var depIdx int32
+	for i := range fbOut.Extensions {
+		// For enum and message kinds, determine the referent Go type so
+		// that we can construct their constructors.
+		const listExtDeps = 2
+		var goType reflect.Type
+		switch fbOut.Extensions[i].L1.Kind {
+		case pref.EnumKind:
+			j := depIdxs.Get(tb.DependencyIndexes, listExtDeps, depIdx)
+			goType = reflect.TypeOf(tb.GoTypes[j])
+			depIdx++
+		case pref.MessageKind, pref.GroupKind:
+			j := depIdxs.Get(tb.DependencyIndexes, listExtDeps, depIdx)
+			goType = reflect.TypeOf(tb.GoTypes[j])
+			depIdx++
+		default:
+			goType = goTypeForPBKind[fbOut.Extensions[i].L1.Kind]
+		}
+		if fbOut.Extensions[i].IsList() {
+			goType = reflect.SliceOf(goType)
+		}
+
+		pimpl.InitExtensionInfo(&tb.ExtensionInfos[i], &fbOut.Extensions[i], goType)
+
+		// Register extension types.
+		if err := tb.TypeRegistry.RegisterExtension(&tb.ExtensionInfos[i]); err != nil {
+			panic(err)
+		}
+	}
+
+	return out
+}
+
+var goTypeForPBKind = map[pref.Kind]reflect.Type{
+	pref.BoolKind:     reflect.TypeOf(bool(false)),
+	pref.Int32Kind:    reflect.TypeOf(int32(0)),
+	pref.Sint32Kind:   reflect.TypeOf(int32(0)),
+	pref.Sfixed32Kind: reflect.TypeOf(int32(0)),
+	pref.Int64Kind:    reflect.TypeOf(int64(0)),
+	pref.Sint64Kind:   reflect.TypeOf(int64(0)),
+	pref.Sfixed64Kind: reflect.TypeOf(int64(0)),
+	pref.Uint32Kind:   reflect.TypeOf(uint32(0)),
+	pref.Fixed32Kind:  reflect.TypeOf(uint32(0)),
+	pref.Uint64Kind:   reflect.TypeOf(uint64(0)),
+	pref.Fixed64Kind:  reflect.TypeOf(uint64(0)),
+	pref.FloatKind:    reflect.TypeOf(float32(0)),
+	pref.DoubleKind:   reflect.TypeOf(float64(0)),
+	pref.StringKind:   reflect.TypeOf(string("")),
+	pref.BytesKind:    reflect.TypeOf([]byte(nil)),
+}
+
+type depIdxs []int32
+
+// Get retrieves the jth element of the ith sub-list.
+func (x depIdxs) Get(i, j int32) int32 {
+	return x[x[int32(len(x))-i-1]+j]
+}
+
+type (
+	resolverByIndex struct {
+		goTypes []interface{}
+		depIdxs depIdxs
+		fileRegistry
+	}
+	fileRegistry interface {
+		FindFileByPath(string) (pref.FileDescriptor, error)
+		FindDescriptorByName(pref.FullName) (pref.Descriptor, error)
+		RegisterFile(pref.FileDescriptor) error
+	}
+)
+
+func (r *resolverByIndex) FindEnumByIndex(i, j int32, es []fdesc.Enum, ms []fdesc.Message) pref.EnumDescriptor {
+	if depIdx := int(r.depIdxs.Get(i, j)); int(depIdx) < len(es)+len(ms) {
+		return &es[depIdx]
+	} else {
+		return pimpl.Export{}.EnumDescriptorOf(r.goTypes[depIdx])
+	}
+}
+
+func (r *resolverByIndex) FindMessageByIndex(i, j int32, es []fdesc.Enum, ms []fdesc.Message) pref.MessageDescriptor {
+	if depIdx := int(r.depIdxs.Get(i, j)); depIdx < len(es)+len(ms) {
+		return &ms[depIdx-len(es)]
+	} else {
+		return pimpl.Export{}.MessageDescriptorOf(r.goTypes[depIdx])
+	}
+}
diff --git a/demo_test/vendor/google.golang.org/protobuf/internal/flags/flags.go b/demo_test/vendor/google.golang.org/protobuf/internal/flags/flags.go
new file mode 100644
index 0000000..58372dd
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/internal/flags/flags.go
@@ -0,0 +1,24 @@
+// 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 flags provides a set of flags controlled by build tags.
+package flags
+
+// ProtoLegacy specifies whether to enable support for legacy functionality
+// such as MessageSets, weak fields, and various other obscure behavior
+// that is necessary to maintain backwards compatibility with proto1 or
+// the pre-release variants of proto2 and proto3.
+//
+// This is disabled by default unless built with the "protolegacy" tag.
+//
+// WARNING: The compatibility agreement covers nothing provided by this flag.
+// As such, functionality may suddenly be removed or changed at our discretion.
+const ProtoLegacy = protoLegacy
+
+// LazyUnmarshalExtensions specifies whether to lazily unmarshal extensions.
+//
+// Lazy extension unmarshaling validates the contents of message-valued
+// extension fields at unmarshal time, but defers creating the message
+// structure until the extension is first accessed.
+const LazyUnmarshalExtensions = ProtoLegacy
diff --git a/demo_test/vendor/google.golang.org/protobuf/internal/flags/proto_legacy_disable.go b/demo_test/vendor/google.golang.org/protobuf/internal/flags/proto_legacy_disable.go
new file mode 100644
index 0000000..a72995f
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/internal/flags/proto_legacy_disable.go
@@ -0,0 +1,9 @@
+// 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 !protolegacy
+
+package flags
+
+const protoLegacy = false
diff --git a/demo_test/vendor/google.golang.org/protobuf/internal/flags/proto_legacy_enable.go b/demo_test/vendor/google.golang.org/protobuf/internal/flags/proto_legacy_enable.go
new file mode 100644
index 0000000..772e2f0
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/internal/flags/proto_legacy_enable.go
@@ -0,0 +1,9 @@
+// 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 protolegacy
+
+package flags
+
+const protoLegacy = true
diff --git a/demo_test/vendor/google.golang.org/protobuf/internal/genname/name.go b/demo_test/vendor/google.golang.org/protobuf/internal/genname/name.go
new file mode 100644
index 0000000..f45509f
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/internal/genname/name.go
@@ -0,0 +1,25 @@
+// 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 genname contains constants for generated names.
+package genname
+
+const (
+	State = "state"
+
+	SizeCache  = "sizeCache"
+	SizeCacheA = "XXX_sizecache"
+
+	WeakFields  = "weakFields"
+	WeakFieldsA = "XXX_weak"
+
+	UnknownFields  = "unknownFields"
+	UnknownFieldsA = "XXX_unrecognized"
+
+	ExtensionFields  = "extensionFields"
+	ExtensionFieldsA = "XXX_InternalExtensions"
+	ExtensionFieldsB = "XXX_extensions"
+
+	WeakFieldPrefix = "XXX_weak_"
+)
diff --git a/demo_test/vendor/google.golang.org/protobuf/internal/impl/api_export.go b/demo_test/vendor/google.golang.org/protobuf/internal/impl/api_export.go
new file mode 100644
index 0000000..4d22c96
--- /dev/null
+++ b/demo_test/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/demo_test/vendor/google.golang.org/protobuf/internal/impl/checkinit.go b/demo_test/vendor/google.golang.org/protobuf/internal/impl/checkinit.go
new file mode 100644
index 0000000..b82341e
--- /dev/null
+++ b/demo_test/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/demo_test/vendor/google.golang.org/protobuf/internal/impl/codec_extension.go b/demo_test/vendor/google.golang.org/protobuf/internal/impl/codec_extension.go
new file mode 100644
index 0000000..08d3517
--- /dev/null
+++ b/demo_test/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/demo_test/vendor/google.golang.org/protobuf/internal/impl/codec_field.go b/demo_test/vendor/google.golang.org/protobuf/internal/impl/codec_field.go
new file mode 100644
index 0000000..c00744d
--- /dev/null
+++ b/demo_test/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/demo_test/vendor/google.golang.org/protobuf/internal/impl/codec_gen.go b/demo_test/vendor/google.golang.org/protobuf/internal/impl/codec_gen.go
new file mode 100644
index 0000000..2c43b11
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/internal/impl/codec_gen.go
@@ -0,0 +1,5597 @@
+// 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,
+}
+
+// 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/demo_test/vendor/google.golang.org/protobuf/internal/impl/codec_map.go b/demo_test/vendor/google.golang.org/protobuf/internal/impl/codec_map.go
new file mode 100644
index 0000000..35a67c2
--- /dev/null
+++ b/demo_test/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/demo_test/vendor/google.golang.org/protobuf/internal/impl/codec_map_go111.go b/demo_test/vendor/google.golang.org/protobuf/internal/impl/codec_map_go111.go
new file mode 100644
index 0000000..2706bb6
--- /dev/null
+++ b/demo_test/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/demo_test/vendor/google.golang.org/protobuf/internal/impl/codec_map_go112.go b/demo_test/vendor/google.golang.org/protobuf/internal/impl/codec_map_go112.go
new file mode 100644
index 0000000..1533ef6
--- /dev/null
+++ b/demo_test/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/demo_test/vendor/google.golang.org/protobuf/internal/impl/codec_message.go b/demo_test/vendor/google.golang.org/protobuf/internal/impl/codec_message.go
new file mode 100644
index 0000000..370ec65
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/internal/impl/codec_message.go
@@ -0,0 +1,157 @@
+// 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()
+	for i := 0; i < fields.Len(); i++ {
+		fd := fields.Get(i)
+
+		fs := si.fieldsByNumber[fd.Number()]
+		if fd.ContainingOneof() != nil {
+			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 fd.ContainingOneof() != nil:
+			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 := &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.Kind() == pref.MessageKind ||
+				fd.Kind() == pref.GroupKind ||
+				fd.Syntax() != pref.Proto3),
+			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++ {
+		mi.initOneofFieldCoders(oneofs.Get(i), 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/demo_test/vendor/google.golang.org/protobuf/internal/impl/codec_messageset.go b/demo_test/vendor/google.golang.org/protobuf/internal/impl/codec_messageset.go
new file mode 100644
index 0000000..cfb68e1
--- /dev/null
+++ b/demo_test/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/demo_test/vendor/google.golang.org/protobuf/internal/impl/codec_reflect.go b/demo_test/vendor/google.golang.org/protobuf/internal/impl/codec_reflect.go
new file mode 100644
index 0000000..86f7dc3
--- /dev/null
+++ b/demo_test/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/demo_test/vendor/google.golang.org/protobuf/internal/impl/codec_tables.go b/demo_test/vendor/google.golang.org/protobuf/internal/impl/codec_tables.go
new file mode 100644
index 0000000..c934c8d
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/internal/impl/codec_tables.go
@@ -0,0 +1,554 @@
+// 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 {
+				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/demo_test/vendor/google.golang.org/protobuf/internal/impl/codec_unsafe.go b/demo_test/vendor/google.golang.org/protobuf/internal/impl/codec_unsafe.go
new file mode 100644
index 0000000..e118af1
--- /dev/null
+++ b/demo_test/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/demo_test/vendor/google.golang.org/protobuf/internal/impl/convert.go b/demo_test/vendor/google.golang.org/protobuf/internal/impl/convert.go
new file mode 100644
index 0000000..9fc384a
--- /dev/null
+++ b/demo_test/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.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.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.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.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.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.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.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.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.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.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.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/demo_test/vendor/google.golang.org/protobuf/internal/impl/convert_list.go b/demo_test/vendor/google.golang.org/protobuf/internal/impl/convert_list.go
new file mode 100644
index 0000000..fe9384a
--- /dev/null
+++ b/demo_test/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
+	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 && list.IsValid()
+}
+
+func (c *listConverter) IsValidGo(v reflect.Value) bool {
+	return 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
+	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.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/demo_test/vendor/google.golang.org/protobuf/internal/impl/convert_map.go b/demo_test/vendor/google.golang.org/protobuf/internal/impl/convert_map.go
new file mode 100644
index 0000000..3ef36d3
--- /dev/null
+++ b/demo_test/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
+	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 && mapv.IsValid()
+}
+
+func (c *mapConverter) IsValidGo(v reflect.Value) bool {
+	return 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/demo_test/vendor/google.golang.org/protobuf/internal/impl/decode.go b/demo_test/vendor/google.golang.org/protobuf/internal/impl/decode.go
new file mode 100644
index 0000000..85ba1d3
--- /dev/null
+++ b/demo_test/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/demo_test/vendor/google.golang.org/protobuf/internal/impl/encode.go b/demo_test/vendor/google.golang.org/protobuf/internal/impl/encode.go
new file mode 100644
index 0000000..8c8a794
--- /dev/null
+++ b/demo_test/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/demo_test/vendor/google.golang.org/protobuf/internal/impl/enum.go b/demo_test/vendor/google.golang.org/protobuf/internal/impl/enum.go
new file mode 100644
index 0000000..8c1eab4
--- /dev/null
+++ b/demo_test/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/demo_test/vendor/google.golang.org/protobuf/internal/impl/extension.go b/demo_test/vendor/google.golang.org/protobuf/internal/impl/extension.go
new file mode 100644
index 0000000..e904fd9
--- /dev/null
+++ b/demo_test/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/demo_test/vendor/google.golang.org/protobuf/internal/impl/legacy_enum.go b/demo_test/vendor/google.golang.org/protobuf/internal/impl/legacy_enum.go
new file mode 100644
index 0000000..f7d7ffb
--- /dev/null
+++ b/demo_test/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/demo_test/vendor/google.golang.org/protobuf/internal/impl/legacy_export.go b/demo_test/vendor/google.golang.org/protobuf/internal/impl/legacy_export.go
new file mode 100644
index 0000000..94f4572
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/internal/impl/legacy_export.go
@@ -0,0 +1,104 @@
+// 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"
+	"fmt"
+	"hash/crc32"
+	"math"
+	"reflect"
+
+	"google.golang.org/protobuf/internal/errors"
+	pref "google.golang.org/protobuf/reflect/protoreflect"
+	"google.golang.org/protobuf/reflect/protoregistry"
+	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
+}
+
+// WeakNil returns a typed nil pointer to a concrete message.
+// It panics if the message is not linked into the binary.
+func (Export) WeakNil(s pref.FullName) piface.MessageV1 {
+	mt, err := protoregistry.GlobalTypes.FindMessageByName(s)
+	if err != nil {
+		panic(fmt.Sprintf("weak message %v is not linked in", s))
+	}
+	return mt.Zero().Interface().(piface.MessageV1)
+}
diff --git a/demo_test/vendor/google.golang.org/protobuf/internal/impl/legacy_extension.go b/demo_test/vendor/google.golang.org/protobuf/internal/impl/legacy_extension.go
new file mode 100644
index 0000000..93c318f
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/internal/impl/legacy_extension.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.
+
+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) 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/demo_test/vendor/google.golang.org/protobuf/internal/impl/legacy_file.go b/demo_test/vendor/google.golang.org/protobuf/internal/impl/legacy_file.go
new file mode 100644
index 0000000..9ab0910
--- /dev/null
+++ b/demo_test/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/demo_test/vendor/google.golang.org/protobuf/internal/impl/legacy_message.go b/demo_test/vendor/google.golang.org/protobuf/internal/impl/legacy_message.go
new file mode 100644
index 0000000..06c68e1
--- /dev/null
+++ b/demo_test/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/demo_test/vendor/google.golang.org/protobuf/internal/impl/merge.go b/demo_test/vendor/google.golang.org/protobuf/internal/impl/merge.go
new file mode 100644
index 0000000..cdc4267
--- /dev/null
+++ b/demo_test/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/demo_test/vendor/google.golang.org/protobuf/internal/impl/merge_gen.go b/demo_test/vendor/google.golang.org/protobuf/internal/impl/merge_gen.go
new file mode 100644
index 0000000..8816c27
--- /dev/null
+++ b/demo_test/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/demo_test/vendor/google.golang.org/protobuf/internal/impl/message.go b/demo_test/vendor/google.golang.org/protobuf/internal/impl/message.go
new file mode 100644
index 0000000..c1d8902
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/internal/impl/message.go
@@ -0,0 +1,216 @@
+// 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"
+	piface "google.golang.org/protobuf/runtime/protoiface"
+)
+
+// 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]piface.MessageV1
+	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/demo_test/vendor/google.golang.org/protobuf/internal/impl/message_reflect.go b/demo_test/vendor/google.golang.org/protobuf/internal/impl/message_reflect.go
new file mode 100644
index 0000000..aac55ee
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/internal/impl/message_reflect.go
@@ -0,0 +1,346 @@
+// 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:
+			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.oneofsByName[od.Name()], mi.Exporter, si.oneofWrappersByType)
+	}
+
+	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 {
+			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
+	}
+	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) {
+	if !xt.IsValidValue(v) {
+		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(xt.TypeDescriptor().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 {
+			panic("mismatching field descriptor")
+		}
+		return fi, nil
+	}
+
+	if fd.IsExtension() {
+		if fd.ContainingMessage().FullName() != mi.Desc.FullName() {
+			// TODO: Should this be exact containing message descriptor match?
+			panic("mismatching containing message")
+		}
+		if !mi.Desc.ExtensionRanges().Has(fd.Number()) {
+			panic("invalid extension field")
+		}
+		xtd, ok := fd.(pref.ExtensionTypeDescriptor)
+		if !ok {
+			panic("extension descriptor does not implement ExtensionTypeDescriptor")
+		}
+		return nil, xtd.Type()
+	}
+	panic("invalid field descriptor")
+}
diff --git a/demo_test/vendor/google.golang.org/protobuf/internal/impl/message_reflect_field.go b/demo_test/vendor/google.golang.org/protobuf/internal/impl/message_reflect_field.go
new file mode 100644
index 0000000..7b87d47
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/internal/impl/message_reflect_field.go
@@ -0,0 +1,448 @@
+// 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("invalid type: got %v, want interface kind", ft))
+	}
+	if ot.Kind() != reflect.Struct {
+		panic(fmt.Sprintf("invalid type: got %v, want struct kind", ot))
+	}
+	if !reflect.PtrTo(ot).Implements(ft) {
+		panic(fmt.Sprintf("invalid type: %v does not implement %v", 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("invalid Mutable on field with non-composite type")
+			}
+			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("invalid type: got %v, want map kind", 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("invalid value: setting map field to read-only value"))
+			}
+			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("invalid type: got %v, want slice kind", 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("invalid value: setting repeated field to read-only value"))
+			}
+			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.Syntax() == pref.Proto2
+	isBytes := ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8
+	if nullable {
+		if ft.Kind() != reflect.Ptr && ft.Kind() != reflect.Slice {
+			panic(fmt.Sprintf("invalid type: got %v, want pointer", 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("invalid type: %v", 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 in proto2
+				} else {
+					rv.Set(nilBytes) // do not preserve presence in proto3
+				}
+			}
+		},
+		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 is not linked in", messageName))
+			}
+		})
+	}
+
+	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() {
+				panic("mismatching message descriptor")
+			}
+			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("invalid nil pointer")
+			}
+		},
+		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, fs reflect.StructField, x exporter, wrappersByType map[reflect.Type]pref.FieldNumber) *oneofInfo {
+	fieldOffset := offsetOf(fs, x)
+	return &oneofInfo{
+		oneofDesc: od,
+		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 wrappersByType[rv.Type().Elem()]
+		},
+	}
+}
diff --git a/demo_test/vendor/google.golang.org/protobuf/internal/impl/message_reflect_gen.go b/demo_test/vendor/google.golang.org/protobuf/internal/impl/message_reflect_gen.go
new file mode 100644
index 0000000..7d65f5c
--- /dev/null
+++ b/demo_test/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")
+}
+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")
+}
+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/demo_test/vendor/google.golang.org/protobuf/internal/impl/pointer_reflect.go b/demo_test/vendor/google.golang.org/protobuf/internal/impl/pointer_reflect.go
new file mode 100644
index 0000000..67b4ede
--- /dev/null
+++ b/demo_test/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/demo_test/vendor/google.golang.org/protobuf/internal/impl/pointer_unsafe.go b/demo_test/vendor/google.golang.org/protobuf/internal/impl/pointer_unsafe.go
new file mode 100644
index 0000000..2741643
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/internal/impl/pointer_unsafe.go
@@ -0,0 +1,169 @@
+// 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 {
+	return ms.LoadMessageInfo()
+}
+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/demo_test/vendor/google.golang.org/protobuf/internal/impl/validate.go b/demo_test/vendor/google.golang.org/protobuf/internal/impl/validate.go
new file mode 100644
index 0000000..39d62fd
--- /dev/null
+++ b/demo_test/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:
+		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/demo_test/vendor/google.golang.org/protobuf/internal/impl/weak.go b/demo_test/vendor/google.golang.org/protobuf/internal/impl/weak.go
new file mode 100644
index 0000000..575c988
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/internal/impl/weak.go
@@ -0,0 +1,46 @@
+// 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"
+)
+
+// 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, ok bool) {
+	if *w == nil {
+		return nil, false
+	}
+	m, ok := (*w)[int32(num)]
+	if !ok {
+		return nil, false
+	}
+	// As a legacy quirk, consider a typed nil to be unset.
+	//
+	// TODO: Consider fixing the generated set methods to clear the field
+	// when provided with a typed nil.
+	if v := reflect.ValueOf(m); v.Kind() == reflect.Ptr && v.IsNil() {
+		return nil, false
+	}
+	return Export{}.ProtoMessageV2Of(m), true
+}
+
+func (w *weakFields) set(num pref.FieldNumber, m pref.ProtoMessage) {
+	if *w == nil {
+		*w = make(weakFields)
+	}
+	(*w)[int32(num)] = Export{}.ProtoMessageV1Of(m)
+}
+
+func (w *weakFields) clear(num pref.FieldNumber) {
+	delete(*w, int32(num))
+}
diff --git a/demo_test/vendor/google.golang.org/protobuf/internal/mapsort/mapsort.go b/demo_test/vendor/google.golang.org/protobuf/internal/mapsort/mapsort.go
new file mode 100644
index 0000000..a3de1cf
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/internal/mapsort/mapsort.go
@@ -0,0 +1,43 @@
+// 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 mapsort provides sorted access to maps.
+package mapsort
+
+import (
+	"sort"
+
+	"google.golang.org/protobuf/reflect/protoreflect"
+)
+
+// Range iterates over every map entry in sorted key order,
+// calling f for each key and value encountered.
+func Range(mapv protoreflect.Map, keyKind protoreflect.Kind, f func(protoreflect.MapKey, protoreflect.Value) bool) {
+	var keys []protoreflect.MapKey
+	mapv.Range(func(key protoreflect.MapKey, _ protoreflect.Value) bool {
+		keys = append(keys, key)
+		return true
+	})
+	sort.Slice(keys, func(i, j int) bool {
+		switch keyKind {
+		case protoreflect.BoolKind:
+			return !keys[i].Bool() && keys[j].Bool()
+		case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind,
+			protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind:
+			return keys[i].Int() < keys[j].Int()
+		case protoreflect.Uint32Kind, protoreflect.Fixed32Kind,
+			protoreflect.Uint64Kind, protoreflect.Fixed64Kind:
+			return keys[i].Uint() < keys[j].Uint()
+		case protoreflect.StringKind:
+			return keys[i].String() < keys[j].String()
+		default:
+			panic("invalid kind: " + keyKind.String())
+		}
+	})
+	for _, key := range keys {
+		if !f(key, mapv.Get(key)) {
+			break
+		}
+	}
+}
diff --git a/demo_test/vendor/google.golang.org/protobuf/internal/pragma/pragma.go b/demo_test/vendor/google.golang.org/protobuf/internal/pragma/pragma.go
new file mode 100644
index 0000000..49dc4fc
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/internal/pragma/pragma.go
@@ -0,0 +1,29 @@
+// 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 pragma provides types that can be embedded into a struct to
+// statically enforce or prevent certain language properties.
+package pragma
+
+import "sync"
+
+// NoUnkeyedLiterals can be embedded in a struct to prevent unkeyed literals.
+type NoUnkeyedLiterals struct{}
+
+// DoNotImplement can be embedded in an interface to prevent trivial
+// implementations of the interface.
+//
+// This is useful to prevent unauthorized implementations of an interface
+// so that it can be extended in the future for any protobuf language changes.
+type DoNotImplement interface{ ProtoInternal(DoNotImplement) }
+
+// DoNotCompare can be embedded in a struct to prevent comparability.
+type DoNotCompare [0]func()
+
+// DoNotCopy can be embedded in a struct to help prevent shallow copies.
+// This does not rely on a Go language feature, but rather a special case
+// within the vet checker.
+//
+// See https://golang.org/issues/8005.
+type DoNotCopy [0]sync.Mutex
diff --git a/demo_test/vendor/google.golang.org/protobuf/internal/set/ints.go b/demo_test/vendor/google.golang.org/protobuf/internal/set/ints.go
new file mode 100644
index 0000000..d3d7f89
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/internal/set/ints.go
@@ -0,0 +1,58 @@
+// 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 set provides simple set data structures for uint64s.
+package set
+
+import "math/bits"
+
+// int64s represents a set of integers within the range of 0..63.
+type int64s uint64
+
+func (bs *int64s) Len() int {
+	return bits.OnesCount64(uint64(*bs))
+}
+func (bs *int64s) Has(n uint64) bool {
+	return uint64(*bs)&(uint64(1)<<n) > 0
+}
+func (bs *int64s) Set(n uint64) {
+	*(*uint64)(bs) |= uint64(1) << n
+}
+func (bs *int64s) Clear(n uint64) {
+	*(*uint64)(bs) &^= uint64(1) << n
+}
+
+// Ints represents a set of integers within the range of 0..math.MaxUint64.
+type Ints struct {
+	lo int64s
+	hi map[uint64]struct{}
+}
+
+func (bs *Ints) Len() int {
+	return bs.lo.Len() + len(bs.hi)
+}
+func (bs *Ints) Has(n uint64) bool {
+	if n < 64 {
+		return bs.lo.Has(n)
+	}
+	_, ok := bs.hi[n]
+	return ok
+}
+func (bs *Ints) Set(n uint64) {
+	if n < 64 {
+		bs.lo.Set(n)
+		return
+	}
+	if bs.hi == nil {
+		bs.hi = make(map[uint64]struct{})
+	}
+	bs.hi[n] = struct{}{}
+}
+func (bs *Ints) Clear(n uint64) {
+	if n < 64 {
+		bs.lo.Clear(n)
+		return
+	}
+	delete(bs.hi, n)
+}
diff --git a/demo_test/vendor/google.golang.org/protobuf/internal/strs/strings.go b/demo_test/vendor/google.golang.org/protobuf/internal/strs/strings.go
new file mode 100644
index 0000000..0b74e76
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/internal/strs/strings.go
@@ -0,0 +1,196 @@
+// 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 strs provides string manipulation functionality specific to protobuf.
+package strs
+
+import (
+	"go/token"
+	"strings"
+	"unicode"
+	"unicode/utf8"
+
+	"google.golang.org/protobuf/internal/flags"
+	"google.golang.org/protobuf/reflect/protoreflect"
+)
+
+// EnforceUTF8 reports whether to enforce strict UTF-8 validation.
+func EnforceUTF8(fd protoreflect.FieldDescriptor) bool {
+	if flags.ProtoLegacy {
+		if fd, ok := fd.(interface{ EnforceUTF8() bool }); ok {
+			return fd.EnforceUTF8()
+		}
+	}
+	return fd.Syntax() == protoreflect.Proto3
+}
+
+// GoCamelCase camel-cases a protobuf name for use as a Go identifier.
+//
+// If there is an interior underscore followed by a lower case letter,
+// drop the underscore and convert the letter to upper case.
+func GoCamelCase(s string) string {
+	// Invariant: if the next letter is lower case, it must be converted
+	// to upper case.
+	// That is, we process a word at a time, where words are marked by _ or
+	// upper case letter. Digits are treated as words.
+	var b []byte
+	for i := 0; i < len(s); i++ {
+		c := s[i]
+		switch {
+		case c == '.' && i+1 < len(s) && isASCIILower(s[i+1]):
+			// Skip over '.' in ".{{lowercase}}".
+		case c == '.':
+			b = append(b, '_') // convert '.' to '_'
+		case c == '_' && (i == 0 || s[i-1] == '.'):
+			// Convert initial '_' to ensure we start with a capital letter.
+			// Do the same for '_' after '.' to match historic behavior.
+			b = append(b, 'X') // convert '_' to 'X'
+		case c == '_' && i+1 < len(s) && isASCIILower(s[i+1]):
+			// Skip over '_' in "_{{lowercase}}".
+		case isASCIIDigit(c):
+			b = append(b, c)
+		default:
+			// Assume we have a letter now - if not, it's a bogus identifier.
+			// The next word is a sequence of characters that must start upper case.
+			if isASCIILower(c) {
+				c -= 'a' - 'A' // convert lowercase to uppercase
+			}
+			b = append(b, c)
+
+			// Accept lower case sequence that follows.
+			for ; i+1 < len(s) && isASCIILower(s[i+1]); i++ {
+				b = append(b, s[i+1])
+			}
+		}
+	}
+	return string(b)
+}
+
+// GoSanitized converts a string to a valid Go identifier.
+func GoSanitized(s string) string {
+	// Sanitize the input to the set of valid characters,
+	// which must be '_' or be in the Unicode L or N categories.
+	s = strings.Map(func(r rune) rune {
+		if unicode.IsLetter(r) || unicode.IsDigit(r) {
+			return r
+		}
+		return '_'
+	}, s)
+
+	// Prepend '_' in the event of a Go keyword conflict or if
+	// the identifier is invalid (does not start in the Unicode L category).
+	r, _ := utf8.DecodeRuneInString(s)
+	if token.Lookup(s).IsKeyword() || !unicode.IsLetter(r) {
+		return "_" + s
+	}
+	return s
+}
+
+// JSONCamelCase converts a snake_case identifier to a camelCase identifier,
+// according to the protobuf JSON specification.
+func JSONCamelCase(s string) string {
+	var b []byte
+	var wasUnderscore bool
+	for i := 0; i < len(s); i++ { // proto identifiers are always ASCII
+		c := s[i]
+		if c != '_' {
+			if wasUnderscore && isASCIILower(c) {
+				c -= 'a' - 'A' // convert to uppercase
+			}
+			b = append(b, c)
+		}
+		wasUnderscore = c == '_'
+	}
+	return string(b)
+}
+
+// JSONSnakeCase converts a camelCase identifier to a snake_case identifier,
+// according to the protobuf JSON specification.
+func JSONSnakeCase(s string) string {
+	var b []byte
+	for i := 0; i < len(s); i++ { // proto identifiers are always ASCII
+		c := s[i]
+		if isASCIIUpper(c) {
+			b = append(b, '_')
+			c += 'a' - 'A' // convert to lowercase
+		}
+		b = append(b, c)
+	}
+	return string(b)
+}
+
+// MapEntryName derives the name of the map entry message given the field name.
+// See protoc v3.8.0: src/google/protobuf/descriptor.cc:254-276,6057
+func MapEntryName(s string) string {
+	var b []byte
+	upperNext := true
+	for _, c := range s {
+		switch {
+		case c == '_':
+			upperNext = true
+		case upperNext:
+			b = append(b, byte(unicode.ToUpper(c)))
+			upperNext = false
+		default:
+			b = append(b, byte(c))
+		}
+	}
+	b = append(b, "Entry"...)
+	return string(b)
+}
+
+// EnumValueName derives the camel-cased enum value name.
+// See protoc v3.8.0: src/google/protobuf/descriptor.cc:297-313
+func EnumValueName(s string) string {
+	var b []byte
+	upperNext := true
+	for _, c := range s {
+		switch {
+		case c == '_':
+			upperNext = true
+		case upperNext:
+			b = append(b, byte(unicode.ToUpper(c)))
+			upperNext = false
+		default:
+			b = append(b, byte(unicode.ToLower(c)))
+			upperNext = false
+		}
+	}
+	return string(b)
+}
+
+// TrimEnumPrefix trims the enum name prefix from an enum value name,
+// where the prefix is all lowercase without underscores.
+// See protoc v3.8.0: src/google/protobuf/descriptor.cc:330-375
+func TrimEnumPrefix(s, prefix string) string {
+	s0 := s // original input
+	for len(s) > 0 && len(prefix) > 0 {
+		if s[0] == '_' {
+			s = s[1:]
+			continue
+		}
+		if unicode.ToLower(rune(s[0])) != rune(prefix[0]) {
+			return s0 // no prefix match
+		}
+		s, prefix = s[1:], prefix[1:]
+	}
+	if len(prefix) > 0 {
+		return s0 // no prefix match
+	}
+	s = strings.TrimLeft(s, "_")
+	if len(s) == 0 {
+		return s0 // avoid returning empty string
+	}
+	return s
+}
+
+func isASCIILower(c byte) bool {
+	return 'a' <= c && c <= 'z'
+}
+func isASCIIUpper(c byte) bool {
+	return 'A' <= c && c <= 'Z'
+}
+func isASCIIDigit(c byte) bool {
+	return '0' <= c && c <= '9'
+}
diff --git a/demo_test/vendor/google.golang.org/protobuf/internal/strs/strings_pure.go b/demo_test/vendor/google.golang.org/protobuf/internal/strs/strings_pure.go
new file mode 100644
index 0000000..85e074c
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/internal/strs/strings_pure.go
@@ -0,0 +1,27 @@
+// 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 strs
+
+import pref "google.golang.org/protobuf/reflect/protoreflect"
+
+func UnsafeString(b []byte) string {
+	return string(b)
+}
+
+func UnsafeBytes(s string) []byte {
+	return []byte(s)
+}
+
+type Builder struct{}
+
+func (*Builder) AppendFullName(prefix pref.FullName, name pref.Name) pref.FullName {
+	return prefix.Append(name)
+}
+
+func (*Builder) MakeString(b []byte) string {
+	return string(b)
+}
diff --git a/demo_test/vendor/google.golang.org/protobuf/internal/strs/strings_unsafe.go b/demo_test/vendor/google.golang.org/protobuf/internal/strs/strings_unsafe.go
new file mode 100644
index 0000000..2160c70
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/internal/strs/strings_unsafe.go
@@ -0,0 +1,94 @@
+// 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 strs
+
+import (
+	"unsafe"
+
+	pref "google.golang.org/protobuf/reflect/protoreflect"
+)
+
+type (
+	stringHeader struct {
+		Data unsafe.Pointer
+		Len  int
+	}
+	sliceHeader struct {
+		Data unsafe.Pointer
+		Len  int
+		Cap  int
+	}
+)
+
+// UnsafeString returns an unsafe string reference of b.
+// The caller must treat the input slice as immutable.
+//
+// WARNING: Use carefully. The returned result must not leak to the end user
+// unless the input slice is provably immutable.
+func UnsafeString(b []byte) (s string) {
+	src := (*sliceHeader)(unsafe.Pointer(&b))
+	dst := (*stringHeader)(unsafe.Pointer(&s))
+	dst.Data = src.Data
+	dst.Len = src.Len
+	return s
+}
+
+// UnsafeBytes returns an unsafe bytes slice reference of s.
+// The caller must treat returned slice as immutable.
+//
+// WARNING: Use carefully. The returned result must not leak to the end user.
+func UnsafeBytes(s string) (b []byte) {
+	src := (*stringHeader)(unsafe.Pointer(&s))
+	dst := (*sliceHeader)(unsafe.Pointer(&b))
+	dst.Data = src.Data
+	dst.Len = src.Len
+	dst.Cap = src.Len
+	return b
+}
+
+// Builder builds a set of strings with shared lifetime.
+// This differs from strings.Builder, which is for building a single string.
+type Builder struct {
+	buf []byte
+}
+
+// AppendFullName is equivalent to protoreflect.FullName.Append,
+// but optimized for large batches where each name has a shared lifetime.
+func (sb *Builder) AppendFullName(prefix pref.FullName, name pref.Name) pref.FullName {
+	n := len(prefix) + len(".") + len(name)
+	if len(prefix) == 0 {
+		n -= len(".")
+	}
+	sb.grow(n)
+	sb.buf = append(sb.buf, prefix...)
+	sb.buf = append(sb.buf, '.')
+	sb.buf = append(sb.buf, name...)
+	return pref.FullName(sb.last(n))
+}
+
+// MakeString is equivalent to string(b), but optimized for large batches
+// with a shared lifetime.
+func (sb *Builder) MakeString(b []byte) string {
+	sb.grow(len(b))
+	sb.buf = append(sb.buf, b...)
+	return sb.last(len(b))
+}
+
+func (sb *Builder) grow(n int) {
+	if cap(sb.buf)-len(sb.buf) >= n {
+		return
+	}
+
+	// Unlike strings.Builder, we do not need to copy over the contents
+	// of the old buffer since our builder provides no API for
+	// retrieving previously created strings.
+	sb.buf = make([]byte, 2*(cap(sb.buf)+n))
+}
+
+func (sb *Builder) last(n int) string {
+	return UnsafeString(sb.buf[len(sb.buf)-n:])
+}
diff --git a/demo_test/vendor/google.golang.org/protobuf/internal/version/version.go b/demo_test/vendor/google.golang.org/protobuf/internal/version/version.go
new file mode 100644
index 0000000..cd84284
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/internal/version/version.go
@@ -0,0 +1,79 @@
+// 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 version records versioning information about this module.
+package version
+
+import (
+	"fmt"
+	"strings"
+)
+
+// These constants determine the current version of this module.
+//
+//
+// For our release process, we enforce the following rules:
+//	* Tagged releases use a tag that is identical to String.
+//	* Tagged releases never reference a commit where the String
+//	contains "devel".
+//	* The set of all commits in this repository where String
+//	does not contain "devel" must have a unique String.
+//
+//
+// Steps for tagging a new release:
+//	1. Create a new CL.
+//
+//	2. Update Minor, Patch, and/or PreRelease as necessary.
+//	PreRelease must not contain the string "devel".
+//
+//	3. Since the last released minor version, have there been any changes to
+//	generator that relies on new functionality in the runtime?
+//	If yes, then increment RequiredGenerated.
+//
+//	4. Since the last released minor version, have there been any changes to
+//	the runtime that removes support for old .pb.go source code?
+//	If yes, then increment SupportMinimum.
+//
+//	5. Send out the CL for review and submit it.
+//	Note that the next CL in step 8 must be submitted after this CL
+//	without any other CLs in-between.
+//
+//	6. Tag a new version, where the tag is is the current String.
+//
+//	7. Write release notes for all notable changes
+//	between this release and the last release.
+//
+//	8. Create a new CL.
+//
+//	9. Update PreRelease to include the string "devel".
+//	For example: "" -> "devel" or "rc.1" -> "rc.1.devel"
+//
+//	10. Send out the CL for review and submit it.
+const (
+	Major      = 1
+	Minor      = 21
+	Patch      = 0
+	PreRelease = ""
+)
+
+// String formats the version string for this module in semver format.
+//
+// Examples:
+//	v1.20.1
+//	v1.21.0-rc.1
+func String() string {
+	v := fmt.Sprintf("v%d.%d.%d", Major, Minor, Patch)
+	if PreRelease != "" {
+		v += "-" + PreRelease
+
+		// TODO: Add metadata about the commit or build hash.
+		// See https://golang.org/issue/29814
+		// See https://golang.org/issue/33533
+		var metadata string
+		if strings.Contains(PreRelease, "devel") && metadata != "" {
+			v += "+" + metadata
+		}
+	}
+	return v
+}
diff --git a/demo_test/vendor/google.golang.org/protobuf/proto/checkinit.go b/demo_test/vendor/google.golang.org/protobuf/proto/checkinit.go
new file mode 100644
index 0000000..d7c9923
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/proto/checkinit.go
@@ -0,0 +1,65 @@
+// 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 proto
+
+import (
+	"google.golang.org/protobuf/internal/errors"
+	"google.golang.org/protobuf/reflect/protoreflect"
+	"google.golang.org/protobuf/runtime/protoiface"
+)
+
+// CheckInitialized returns an error if any required fields in m are not set.
+func CheckInitialized(m Message) error {
+	return checkInitialized(m.ProtoReflect())
+}
+
+// CheckInitialized returns an error if any required fields in m are not set.
+func checkInitialized(m protoreflect.Message) error {
+	if methods := protoMethods(m); methods != nil && methods.CheckInitialized != nil {
+		_, err := methods.CheckInitialized(protoiface.CheckInitializedInput{
+			Message: m,
+		})
+		return err
+	}
+	return checkInitializedSlow(m)
+}
+
+func checkInitializedSlow(m protoreflect.Message) error {
+	md := m.Descriptor()
+	fds := md.Fields()
+	for i, nums := 0, md.RequiredNumbers(); i < nums.Len(); i++ {
+		fd := fds.ByNumber(nums.Get(i))
+		if !m.Has(fd) {
+			return errors.RequiredNotSet(string(fd.FullName()))
+		}
+	}
+	var err error
+	m.Range(func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool {
+		switch {
+		case fd.IsList():
+			if fd.Message() == nil {
+				return true
+			}
+			for i, list := 0, v.List(); i < list.Len() && err == nil; i++ {
+				err = checkInitialized(list.Get(i).Message())
+			}
+		case fd.IsMap():
+			if fd.MapValue().Message() == nil {
+				return true
+			}
+			v.Map().Range(func(key protoreflect.MapKey, v protoreflect.Value) bool {
+				err = checkInitialized(v.Message())
+				return err == nil
+			})
+		default:
+			if fd.Message() == nil {
+				return true
+			}
+			err = checkInitialized(v.Message())
+		}
+		return err == nil
+	})
+	return err
+}
diff --git a/demo_test/vendor/google.golang.org/protobuf/proto/decode.go b/demo_test/vendor/google.golang.org/protobuf/proto/decode.go
new file mode 100644
index 0000000..1282147
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/proto/decode.go
@@ -0,0 +1,270 @@
+// 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 proto
+
+import (
+	"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"
+	"google.golang.org/protobuf/internal/pragma"
+	"google.golang.org/protobuf/reflect/protoreflect"
+	"google.golang.org/protobuf/reflect/protoregistry"
+	"google.golang.org/protobuf/runtime/protoiface"
+)
+
+// UnmarshalOptions configures the unmarshaler.
+//
+// Example usage:
+//   err := UnmarshalOptions{DiscardUnknown: true}.Unmarshal(b, m)
+type UnmarshalOptions struct {
+	pragma.NoUnkeyedLiterals
+
+	// Merge merges the input into the destination message.
+	// The default behavior is to always reset the message before unmarshaling,
+	// unless Merge is specified.
+	Merge bool
+
+	// AllowPartial accepts input for messages that will result in missing
+	// required fields. If AllowPartial is false (the default), Unmarshal will
+	// return an error if there are any missing required fields.
+	AllowPartial bool
+
+	// If DiscardUnknown is set, unknown fields are ignored.
+	DiscardUnknown bool
+
+	// Resolver is used for looking up types when unmarshaling extension fields.
+	// If nil, this defaults to using protoregistry.GlobalTypes.
+	Resolver interface {
+		FindExtensionByName(field protoreflect.FullName) (protoreflect.ExtensionType, error)
+		FindExtensionByNumber(message protoreflect.FullName, field protoreflect.FieldNumber) (protoreflect.ExtensionType, error)
+	}
+}
+
+// Unmarshal parses the wire-format message in b and places the result in m.
+func Unmarshal(b []byte, m Message) error {
+	_, err := UnmarshalOptions{}.unmarshal(b, m.ProtoReflect())
+	return err
+}
+
+// Unmarshal parses the wire-format message in b and places the result in m.
+func (o UnmarshalOptions) Unmarshal(b []byte, m Message) error {
+	_, err := o.unmarshal(b, m.ProtoReflect())
+	return err
+}
+
+// UnmarshalState parses a wire-format message and places the result in m.
+//
+// This method permits fine-grained control over the unmarshaler.
+// Most users should use Unmarshal instead.
+func (o UnmarshalOptions) UnmarshalState(in protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) {
+	return o.unmarshal(in.Buf, in.Message)
+}
+
+func (o UnmarshalOptions) unmarshal(b []byte, m protoreflect.Message) (out protoiface.UnmarshalOutput, err error) {
+	if o.Resolver == nil {
+		o.Resolver = protoregistry.GlobalTypes
+	}
+	if !o.Merge {
+		Reset(m.Interface()) // TODO
+	}
+	allowPartial := o.AllowPartial
+	o.Merge = true
+	o.AllowPartial = true
+	methods := protoMethods(m)
+	if methods != nil && methods.Unmarshal != nil &&
+		!(o.DiscardUnknown && methods.Flags&protoiface.SupportUnmarshalDiscardUnknown == 0) {
+		in := protoiface.UnmarshalInput{
+			Message:  m,
+			Buf:      b,
+			Resolver: o.Resolver,
+		}
+		if o.DiscardUnknown {
+			in.Flags |= protoiface.UnmarshalDiscardUnknown
+		}
+		out, err = methods.Unmarshal(in)
+	} else {
+		err = o.unmarshalMessageSlow(b, m)
+	}
+	if err != nil {
+		return out, err
+	}
+	if allowPartial || (out.Flags&protoiface.UnmarshalInitialized != 0) {
+		return out, nil
+	}
+	return out, checkInitialized(m)
+}
+
+func (o UnmarshalOptions) unmarshalMessage(b []byte, m protoreflect.Message) error {
+	_, err := o.unmarshal(b, m)
+	return err
+}
+
+func (o UnmarshalOptions) unmarshalMessageSlow(b []byte, m protoreflect.Message) error {
+	md := m.Descriptor()
+	if messageset.IsMessageSet(md) {
+		return unmarshalMessageSet(b, m, o)
+	}
+	fields := md.Fields()
+	for len(b) > 0 {
+		// Parse the tag (field number and wire type).
+		num, wtyp, tagLen := protowire.ConsumeTag(b)
+		if tagLen < 0 {
+			return protowire.ParseError(tagLen)
+		}
+		if num > protowire.MaxValidNumber {
+			return errors.New("invalid field number")
+		}
+
+		// Find the field descriptor for this field number.
+		fd := fields.ByNumber(num)
+		if fd == nil && md.ExtensionRanges().Has(num) {
+			extType, err := o.Resolver.FindExtensionByNumber(md.FullName(), num)
+			if err != nil && err != protoregistry.NotFound {
+				return errors.New("%v: unable to resolve extension %v: %v", md.FullName(), num, err)
+			}
+			if extType != nil {
+				fd = extType.TypeDescriptor()
+			}
+		}
+		var err error
+		if fd == nil {
+			err = errUnknown
+		} else if flags.ProtoLegacy {
+			if fd.IsWeak() && fd.Message().IsPlaceholder() {
+				err = errUnknown // weak referent is not linked in
+			}
+		}
+
+		// Parse the field value.
+		var valLen int
+		switch {
+		case err != nil:
+		case fd.IsList():
+			valLen, err = o.unmarshalList(b[tagLen:], wtyp, m.Mutable(fd).List(), fd)
+		case fd.IsMap():
+			valLen, err = o.unmarshalMap(b[tagLen:], wtyp, m.Mutable(fd).Map(), fd)
+		default:
+			valLen, err = o.unmarshalSingular(b[tagLen:], wtyp, m, fd)
+		}
+		if err != nil {
+			if err != errUnknown {
+				return err
+			}
+			valLen = protowire.ConsumeFieldValue(num, wtyp, b[tagLen:])
+			if valLen < 0 {
+				return protowire.ParseError(valLen)
+			}
+			if !o.DiscardUnknown {
+				m.SetUnknown(append(m.GetUnknown(), b[:tagLen+valLen]...))
+			}
+		}
+		b = b[tagLen+valLen:]
+	}
+	return nil
+}
+
+func (o UnmarshalOptions) unmarshalSingular(b []byte, wtyp protowire.Type, m protoreflect.Message, fd protoreflect.FieldDescriptor) (n int, err error) {
+	v, n, err := o.unmarshalScalar(b, wtyp, fd)
+	if err != nil {
+		return 0, err
+	}
+	switch fd.Kind() {
+	case protoreflect.GroupKind, protoreflect.MessageKind:
+		m2 := m.Mutable(fd).Message()
+		if err := o.unmarshalMessage(v.Bytes(), m2); err != nil {
+			return n, err
+		}
+	default:
+		// Non-message scalars replace the previous value.
+		m.Set(fd, v)
+	}
+	return n, nil
+}
+
+func (o UnmarshalOptions) unmarshalMap(b []byte, wtyp protowire.Type, mapv protoreflect.Map, fd protoreflect.FieldDescriptor) (n int, err error) {
+	if wtyp != protowire.BytesType {
+		return 0, errUnknown
+	}
+	b, n = protowire.ConsumeBytes(b)
+	if n < 0 {
+		return 0, protowire.ParseError(n)
+	}
+	var (
+		keyField = fd.MapKey()
+		valField = fd.MapValue()
+		key      protoreflect.Value
+		val      protoreflect.Value
+		haveKey  bool
+		haveVal  bool
+	)
+	switch valField.Kind() {
+	case protoreflect.GroupKind, protoreflect.MessageKind:
+		val = mapv.NewValue()
+	}
+	// Map entries are represented as a two-element message with fields
+	// containing the key and value.
+	for len(b) > 0 {
+		num, wtyp, n := protowire.ConsumeTag(b)
+		if n < 0 {
+			return 0, protowire.ParseError(n)
+		}
+		if num > protowire.MaxValidNumber {
+			return 0, errors.New("invalid field number")
+		}
+		b = b[n:]
+		err = errUnknown
+		switch num {
+		case 1:
+			key, n, err = o.unmarshalScalar(b, wtyp, keyField)
+			if err != nil {
+				break
+			}
+			haveKey = true
+		case 2:
+			var v protoreflect.Value
+			v, n, err = o.unmarshalScalar(b, wtyp, valField)
+			if err != nil {
+				break
+			}
+			switch valField.Kind() {
+			case protoreflect.GroupKind, protoreflect.MessageKind:
+				if err := o.unmarshalMessage(v.Bytes(), val.Message()); err != nil {
+					return 0, err
+				}
+			default:
+				val = v
+			}
+			haveVal = true
+		}
+		if err == errUnknown {
+			n = protowire.ConsumeFieldValue(num, wtyp, b)
+			if n < 0 {
+				return 0, protowire.ParseError(n)
+			}
+		} else if err != nil {
+			return 0, err
+		}
+		b = b[n:]
+	}
+	// Every map entry should have entries for key and value, but this is not strictly required.
+	if !haveKey {
+		key = keyField.Default()
+	}
+	if !haveVal {
+		switch valField.Kind() {
+		case protoreflect.GroupKind, protoreflect.MessageKind:
+		default:
+			val = valField.Default()
+		}
+	}
+	mapv.Set(key.MapKey(), val)
+	return n, nil
+}
+
+// errUnknown is used internally to indicate fields which should be added
+// to the unknown field set of a message. It is never returned from an exported
+// function.
+var errUnknown = errors.New("BUG: internal error (unknown)")
diff --git a/demo_test/vendor/google.golang.org/protobuf/proto/decode_gen.go b/demo_test/vendor/google.golang.org/protobuf/proto/decode_gen.go
new file mode 100644
index 0000000..d6dc904
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/proto/decode_gen.go
@@ -0,0 +1,603 @@
+// 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 proto
+
+import (
+	"math"
+	"unicode/utf8"
+
+	"google.golang.org/protobuf/encoding/protowire"
+	"google.golang.org/protobuf/internal/errors"
+	"google.golang.org/protobuf/internal/strs"
+	"google.golang.org/protobuf/reflect/protoreflect"
+)
+
+// unmarshalScalar decodes a value of the given kind.
+//
+// Message values are decoded into a []byte which aliases the input data.
+func (o UnmarshalOptions) unmarshalScalar(b []byte, wtyp protowire.Type, fd protoreflect.FieldDescriptor) (val protoreflect.Value, n int, err error) {
+	switch fd.Kind() {
+	case protoreflect.BoolKind:
+		if wtyp != protowire.VarintType {
+			return val, 0, errUnknown
+		}
+		v, n := protowire.ConsumeVarint(b)
+		if n < 0 {
+			return val, 0, protowire.ParseError(n)
+		}
+		return protoreflect.ValueOfBool(protowire.DecodeBool(v)), n, nil
+	case protoreflect.EnumKind:
+		if wtyp != protowire.VarintType {
+			return val, 0, errUnknown
+		}
+		v, n := protowire.ConsumeVarint(b)
+		if n < 0 {
+			return val, 0, protowire.ParseError(n)
+		}
+		return protoreflect.ValueOfEnum(protoreflect.EnumNumber(v)), n, nil
+	case protoreflect.Int32Kind:
+		if wtyp != protowire.VarintType {
+			return val, 0, errUnknown
+		}
+		v, n := protowire.ConsumeVarint(b)
+		if n < 0 {
+			return val, 0, protowire.ParseError(n)
+		}
+		return protoreflect.ValueOfInt32(int32(v)), n, nil
+	case protoreflect.Sint32Kind:
+		if wtyp != protowire.VarintType {
+			return val, 0, errUnknown
+		}
+		v, n := protowire.ConsumeVarint(b)
+		if n < 0 {
+			return val, 0, protowire.ParseError(n)
+		}
+		return protoreflect.ValueOfInt32(int32(protowire.DecodeZigZag(v & math.MaxUint32))), n, nil
+	case protoreflect.Uint32Kind:
+		if wtyp != protowire.VarintType {
+			return val, 0, errUnknown
+		}
+		v, n := protowire.ConsumeVarint(b)
+		if n < 0 {
+			return val, 0, protowire.ParseError(n)
+		}
+		return protoreflect.ValueOfUint32(uint32(v)), n, nil
+	case protoreflect.Int64Kind:
+		if wtyp != protowire.VarintType {
+			return val, 0, errUnknown
+		}
+		v, n := protowire.ConsumeVarint(b)
+		if n < 0 {
+			return val, 0, protowire.ParseError(n)
+		}
+		return protoreflect.ValueOfInt64(int64(v)), n, nil
+	case protoreflect.Sint64Kind:
+		if wtyp != protowire.VarintType {
+			return val, 0, errUnknown
+		}
+		v, n := protowire.ConsumeVarint(b)
+		if n < 0 {
+			return val, 0, protowire.ParseError(n)
+		}
+		return protoreflect.ValueOfInt64(protowire.DecodeZigZag(v)), n, nil
+	case protoreflect.Uint64Kind:
+		if wtyp != protowire.VarintType {
+			return val, 0, errUnknown
+		}
+		v, n := protowire.ConsumeVarint(b)
+		if n < 0 {
+			return val, 0, protowire.ParseError(n)
+		}
+		return protoreflect.ValueOfUint64(v), n, nil
+	case protoreflect.Sfixed32Kind:
+		if wtyp != protowire.Fixed32Type {
+			return val, 0, errUnknown
+		}
+		v, n := protowire.ConsumeFixed32(b)
+		if n < 0 {
+			return val, 0, protowire.ParseError(n)
+		}
+		return protoreflect.ValueOfInt32(int32(v)), n, nil
+	case protoreflect.Fixed32Kind:
+		if wtyp != protowire.Fixed32Type {
+			return val, 0, errUnknown
+		}
+		v, n := protowire.ConsumeFixed32(b)
+		if n < 0 {
+			return val, 0, protowire.ParseError(n)
+		}
+		return protoreflect.ValueOfUint32(uint32(v)), n, nil
+	case protoreflect.FloatKind:
+		if wtyp != protowire.Fixed32Type {
+			return val, 0, errUnknown
+		}
+		v, n := protowire.ConsumeFixed32(b)
+		if n < 0 {
+			return val, 0, protowire.ParseError(n)
+		}
+		return protoreflect.ValueOfFloat32(math.Float32frombits(uint32(v))), n, nil
+	case protoreflect.Sfixed64Kind:
+		if wtyp != protowire.Fixed64Type {
+			return val, 0, errUnknown
+		}
+		v, n := protowire.ConsumeFixed64(b)
+		if n < 0 {
+			return val, 0, protowire.ParseError(n)
+		}
+		return protoreflect.ValueOfInt64(int64(v)), n, nil
+	case protoreflect.Fixed64Kind:
+		if wtyp != protowire.Fixed64Type {
+			return val, 0, errUnknown
+		}
+		v, n := protowire.ConsumeFixed64(b)
+		if n < 0 {
+			return val, 0, protowire.ParseError(n)
+		}
+		return protoreflect.ValueOfUint64(v), n, nil
+	case protoreflect.DoubleKind:
+		if wtyp != protowire.Fixed64Type {
+			return val, 0, errUnknown
+		}
+		v, n := protowire.ConsumeFixed64(b)
+		if n < 0 {
+			return val, 0, protowire.ParseError(n)
+		}
+		return protoreflect.ValueOfFloat64(math.Float64frombits(v)), n, nil
+	case protoreflect.StringKind:
+		if wtyp != protowire.BytesType {
+			return val, 0, errUnknown
+		}
+		v, n := protowire.ConsumeBytes(b)
+		if n < 0 {
+			return val, 0, protowire.ParseError(n)
+		}
+		if strs.EnforceUTF8(fd) && !utf8.Valid(v) {
+			return protoreflect.Value{}, 0, errors.InvalidUTF8(string(fd.FullName()))
+		}
+		return protoreflect.ValueOfString(string(v)), n, nil
+	case protoreflect.BytesKind:
+		if wtyp != protowire.BytesType {
+			return val, 0, errUnknown
+		}
+		v, n := protowire.ConsumeBytes(b)
+		if n < 0 {
+			return val, 0, protowire.ParseError(n)
+		}
+		return protoreflect.ValueOfBytes(append(emptyBuf[:], v...)), n, nil
+	case protoreflect.MessageKind:
+		if wtyp != protowire.BytesType {
+			return val, 0, errUnknown
+		}
+		v, n := protowire.ConsumeBytes(b)
+		if n < 0 {
+			return val, 0, protowire.ParseError(n)
+		}
+		return protoreflect.ValueOfBytes(v), n, nil
+	case protoreflect.GroupKind:
+		if wtyp != protowire.StartGroupType {
+			return val, 0, errUnknown
+		}
+		v, n := protowire.ConsumeGroup(fd.Number(), b)
+		if n < 0 {
+			return val, 0, protowire.ParseError(n)
+		}
+		return protoreflect.ValueOfBytes(v), n, nil
+	default:
+		return val, 0, errUnknown
+	}
+}
+
+func (o UnmarshalOptions) unmarshalList(b []byte, wtyp protowire.Type, list protoreflect.List, fd protoreflect.FieldDescriptor) (n int, err error) {
+	switch fd.Kind() {
+	case protoreflect.BoolKind:
+		if wtyp == protowire.BytesType {
+			buf, n := protowire.ConsumeBytes(b)
+			if n < 0 {
+				return 0, protowire.ParseError(n)
+			}
+			for len(buf) > 0 {
+				v, n := protowire.ConsumeVarint(buf)
+				if n < 0 {
+					return 0, protowire.ParseError(n)
+				}
+				buf = buf[n:]
+				list.Append(protoreflect.ValueOfBool(protowire.DecodeBool(v)))
+			}
+			return n, nil
+		}
+		if wtyp != protowire.VarintType {
+			return 0, errUnknown
+		}
+		v, n := protowire.ConsumeVarint(b)
+		if n < 0 {
+			return 0, protowire.ParseError(n)
+		}
+		list.Append(protoreflect.ValueOfBool(protowire.DecodeBool(v)))
+		return n, nil
+	case protoreflect.EnumKind:
+		if wtyp == protowire.BytesType {
+			buf, n := protowire.ConsumeBytes(b)
+			if n < 0 {
+				return 0, protowire.ParseError(n)
+			}
+			for len(buf) > 0 {
+				v, n := protowire.ConsumeVarint(buf)
+				if n < 0 {
+					return 0, protowire.ParseError(n)
+				}
+				buf = buf[n:]
+				list.Append(protoreflect.ValueOfEnum(protoreflect.EnumNumber(v)))
+			}
+			return n, nil
+		}
+		if wtyp != protowire.VarintType {
+			return 0, errUnknown
+		}
+		v, n := protowire.ConsumeVarint(b)
+		if n < 0 {
+			return 0, protowire.ParseError(n)
+		}
+		list.Append(protoreflect.ValueOfEnum(protoreflect.EnumNumber(v)))
+		return n, nil
+	case protoreflect.Int32Kind:
+		if wtyp == protowire.BytesType {
+			buf, n := protowire.ConsumeBytes(b)
+			if n < 0 {
+				return 0, protowire.ParseError(n)
+			}
+			for len(buf) > 0 {
+				v, n := protowire.ConsumeVarint(buf)
+				if n < 0 {
+					return 0, protowire.ParseError(n)
+				}
+				buf = buf[n:]
+				list.Append(protoreflect.ValueOfInt32(int32(v)))
+			}
+			return n, nil
+		}
+		if wtyp != protowire.VarintType {
+			return 0, errUnknown
+		}
+		v, n := protowire.ConsumeVarint(b)
+		if n < 0 {
+			return 0, protowire.ParseError(n)
+		}
+		list.Append(protoreflect.ValueOfInt32(int32(v)))
+		return n, nil
+	case protoreflect.Sint32Kind:
+		if wtyp == protowire.BytesType {
+			buf, n := protowire.ConsumeBytes(b)
+			if n < 0 {
+				return 0, protowire.ParseError(n)
+			}
+			for len(buf) > 0 {
+				v, n := protowire.ConsumeVarint(buf)
+				if n < 0 {
+					return 0, protowire.ParseError(n)
+				}
+				buf = buf[n:]
+				list.Append(protoreflect.ValueOfInt32(int32(protowire.DecodeZigZag(v & math.MaxUint32))))
+			}
+			return n, nil
+		}
+		if wtyp != protowire.VarintType {
+			return 0, errUnknown
+		}
+		v, n := protowire.ConsumeVarint(b)
+		if n < 0 {
+			return 0, protowire.ParseError(n)
+		}
+		list.Append(protoreflect.ValueOfInt32(int32(protowire.DecodeZigZag(v & math.MaxUint32))))
+		return n, nil
+	case protoreflect.Uint32Kind:
+		if wtyp == protowire.BytesType {
+			buf, n := protowire.ConsumeBytes(b)
+			if n < 0 {
+				return 0, protowire.ParseError(n)
+			}
+			for len(buf) > 0 {
+				v, n := protowire.ConsumeVarint(buf)
+				if n < 0 {
+					return 0, protowire.ParseError(n)
+				}
+				buf = buf[n:]
+				list.Append(protoreflect.ValueOfUint32(uint32(v)))
+			}
+			return n, nil
+		}
+		if wtyp != protowire.VarintType {
+			return 0, errUnknown
+		}
+		v, n := protowire.ConsumeVarint(b)
+		if n < 0 {
+			return 0, protowire.ParseError(n)
+		}
+		list.Append(protoreflect.ValueOfUint32(uint32(v)))
+		return n, nil
+	case protoreflect.Int64Kind:
+		if wtyp == protowire.BytesType {
+			buf, n := protowire.ConsumeBytes(b)
+			if n < 0 {
+				return 0, protowire.ParseError(n)
+			}
+			for len(buf) > 0 {
+				v, n := protowire.ConsumeVarint(buf)
+				if n < 0 {
+					return 0, protowire.ParseError(n)
+				}
+				buf = buf[n:]
+				list.Append(protoreflect.ValueOfInt64(int64(v)))
+			}
+			return n, nil
+		}
+		if wtyp != protowire.VarintType {
+			return 0, errUnknown
+		}
+		v, n := protowire.ConsumeVarint(b)
+		if n < 0 {
+			return 0, protowire.ParseError(n)
+		}
+		list.Append(protoreflect.ValueOfInt64(int64(v)))
+		return n, nil
+	case protoreflect.Sint64Kind:
+		if wtyp == protowire.BytesType {
+			buf, n := protowire.ConsumeBytes(b)
+			if n < 0 {
+				return 0, protowire.ParseError(n)
+			}
+			for len(buf) > 0 {
+				v, n := protowire.ConsumeVarint(buf)
+				if n < 0 {
+					return 0, protowire.ParseError(n)
+				}
+				buf = buf[n:]
+				list.Append(protoreflect.ValueOfInt64(protowire.DecodeZigZag(v)))
+			}
+			return n, nil
+		}
+		if wtyp != protowire.VarintType {
+			return 0, errUnknown
+		}
+		v, n := protowire.ConsumeVarint(b)
+		if n < 0 {
+			return 0, protowire.ParseError(n)
+		}
+		list.Append(protoreflect.ValueOfInt64(protowire.DecodeZigZag(v)))
+		return n, nil
+	case protoreflect.Uint64Kind:
+		if wtyp == protowire.BytesType {
+			buf, n := protowire.ConsumeBytes(b)
+			if n < 0 {
+				return 0, protowire.ParseError(n)
+			}
+			for len(buf) > 0 {
+				v, n := protowire.ConsumeVarint(buf)
+				if n < 0 {
+					return 0, protowire.ParseError(n)
+				}
+				buf = buf[n:]
+				list.Append(protoreflect.ValueOfUint64(v))
+			}
+			return n, nil
+		}
+		if wtyp != protowire.VarintType {
+			return 0, errUnknown
+		}
+		v, n := protowire.ConsumeVarint(b)
+		if n < 0 {
+			return 0, protowire.ParseError(n)
+		}
+		list.Append(protoreflect.ValueOfUint64(v))
+		return n, nil
+	case protoreflect.Sfixed32Kind:
+		if wtyp == protowire.BytesType {
+			buf, n := protowire.ConsumeBytes(b)
+			if n < 0 {
+				return 0, protowire.ParseError(n)
+			}
+			for len(buf) > 0 {
+				v, n := protowire.ConsumeFixed32(buf)
+				if n < 0 {
+					return 0, protowire.ParseError(n)
+				}
+				buf = buf[n:]
+				list.Append(protoreflect.ValueOfInt32(int32(v)))
+			}
+			return n, nil
+		}
+		if wtyp != protowire.Fixed32Type {
+			return 0, errUnknown
+		}
+		v, n := protowire.ConsumeFixed32(b)
+		if n < 0 {
+			return 0, protowire.ParseError(n)
+		}
+		list.Append(protoreflect.ValueOfInt32(int32(v)))
+		return n, nil
+	case protoreflect.Fixed32Kind:
+		if wtyp == protowire.BytesType {
+			buf, n := protowire.ConsumeBytes(b)
+			if n < 0 {
+				return 0, protowire.ParseError(n)
+			}
+			for len(buf) > 0 {
+				v, n := protowire.ConsumeFixed32(buf)
+				if n < 0 {
+					return 0, protowire.ParseError(n)
+				}
+				buf = buf[n:]
+				list.Append(protoreflect.ValueOfUint32(uint32(v)))
+			}
+			return n, nil
+		}
+		if wtyp != protowire.Fixed32Type {
+			return 0, errUnknown
+		}
+		v, n := protowire.ConsumeFixed32(b)
+		if n < 0 {
+			return 0, protowire.ParseError(n)
+		}
+		list.Append(protoreflect.ValueOfUint32(uint32(v)))
+		return n, nil
+	case protoreflect.FloatKind:
+		if wtyp == protowire.BytesType {
+			buf, n := protowire.ConsumeBytes(b)
+			if n < 0 {
+				return 0, protowire.ParseError(n)
+			}
+			for len(buf) > 0 {
+				v, n := protowire.ConsumeFixed32(buf)
+				if n < 0 {
+					return 0, protowire.ParseError(n)
+				}
+				buf = buf[n:]
+				list.Append(protoreflect.ValueOfFloat32(math.Float32frombits(uint32(v))))
+			}
+			return n, nil
+		}
+		if wtyp != protowire.Fixed32Type {
+			return 0, errUnknown
+		}
+		v, n := protowire.ConsumeFixed32(b)
+		if n < 0 {
+			return 0, protowire.ParseError(n)
+		}
+		list.Append(protoreflect.ValueOfFloat32(math.Float32frombits(uint32(v))))
+		return n, nil
+	case protoreflect.Sfixed64Kind:
+		if wtyp == protowire.BytesType {
+			buf, n := protowire.ConsumeBytes(b)
+			if n < 0 {
+				return 0, protowire.ParseError(n)
+			}
+			for len(buf) > 0 {
+				v, n := protowire.ConsumeFixed64(buf)
+				if n < 0 {
+					return 0, protowire.ParseError(n)
+				}
+				buf = buf[n:]
+				list.Append(protoreflect.ValueOfInt64(int64(v)))
+			}
+			return n, nil
+		}
+		if wtyp != protowire.Fixed64Type {
+			return 0, errUnknown
+		}
+		v, n := protowire.ConsumeFixed64(b)
+		if n < 0 {
+			return 0, protowire.ParseError(n)
+		}
+		list.Append(protoreflect.ValueOfInt64(int64(v)))
+		return n, nil
+	case protoreflect.Fixed64Kind:
+		if wtyp == protowire.BytesType {
+			buf, n := protowire.ConsumeBytes(b)
+			if n < 0 {
+				return 0, protowire.ParseError(n)
+			}
+			for len(buf) > 0 {
+				v, n := protowire.ConsumeFixed64(buf)
+				if n < 0 {
+					return 0, protowire.ParseError(n)
+				}
+				buf = buf[n:]
+				list.Append(protoreflect.ValueOfUint64(v))
+			}
+			return n, nil
+		}
+		if wtyp != protowire.Fixed64Type {
+			return 0, errUnknown
+		}
+		v, n := protowire.ConsumeFixed64(b)
+		if n < 0 {
+			return 0, protowire.ParseError(n)
+		}
+		list.Append(protoreflect.ValueOfUint64(v))
+		return n, nil
+	case protoreflect.DoubleKind:
+		if wtyp == protowire.BytesType {
+			buf, n := protowire.ConsumeBytes(b)
+			if n < 0 {
+				return 0, protowire.ParseError(n)
+			}
+			for len(buf) > 0 {
+				v, n := protowire.ConsumeFixed64(buf)
+				if n < 0 {
+					return 0, protowire.ParseError(n)
+				}
+				buf = buf[n:]
+				list.Append(protoreflect.ValueOfFloat64(math.Float64frombits(v)))
+			}
+			return n, nil
+		}
+		if wtyp != protowire.Fixed64Type {
+			return 0, errUnknown
+		}
+		v, n := protowire.ConsumeFixed64(b)
+		if n < 0 {
+			return 0, protowire.ParseError(n)
+		}
+		list.Append(protoreflect.ValueOfFloat64(math.Float64frombits(v)))
+		return n, nil
+	case protoreflect.StringKind:
+		if wtyp != protowire.BytesType {
+			return 0, errUnknown
+		}
+		v, n := protowire.ConsumeBytes(b)
+		if n < 0 {
+			return 0, protowire.ParseError(n)
+		}
+		if strs.EnforceUTF8(fd) && !utf8.Valid(v) {
+			return 0, errors.InvalidUTF8(string(fd.FullName()))
+		}
+		list.Append(protoreflect.ValueOfString(string(v)))
+		return n, nil
+	case protoreflect.BytesKind:
+		if wtyp != protowire.BytesType {
+			return 0, errUnknown
+		}
+		v, n := protowire.ConsumeBytes(b)
+		if n < 0 {
+			return 0, protowire.ParseError(n)
+		}
+		list.Append(protoreflect.ValueOfBytes(append(emptyBuf[:], v...)))
+		return n, nil
+	case protoreflect.MessageKind:
+		if wtyp != protowire.BytesType {
+			return 0, errUnknown
+		}
+		v, n := protowire.ConsumeBytes(b)
+		if n < 0 {
+			return 0, protowire.ParseError(n)
+		}
+		m := list.NewElement()
+		if err := o.unmarshalMessage(v, m.Message()); err != nil {
+			return 0, err
+		}
+		list.Append(m)
+		return n, nil
+	case protoreflect.GroupKind:
+		if wtyp != protowire.StartGroupType {
+			return 0, errUnknown
+		}
+		v, n := protowire.ConsumeGroup(fd.Number(), b)
+		if n < 0 {
+			return 0, protowire.ParseError(n)
+		}
+		m := list.NewElement()
+		if err := o.unmarshalMessage(v, m.Message()); err != nil {
+			return 0, err
+		}
+		list.Append(m)
+		return n, nil
+	default:
+		return 0, errUnknown
+	}
+}
+
+// We append to an empty array rather than a nil []byte to get non-nil zero-length byte slices.
+var emptyBuf [0]byte
diff --git a/demo_test/vendor/google.golang.org/protobuf/proto/doc.go b/demo_test/vendor/google.golang.org/protobuf/proto/doc.go
new file mode 100644
index 0000000..c52d8c4
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/proto/doc.go
@@ -0,0 +1,94 @@
+// 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 proto provides functions operating on protocol buffer messages.
+//
+// For documentation on protocol buffers in general, see:
+//
+//   https://developers.google.com/protocol-buffers
+//
+// For a tutorial on using protocol buffers with Go, see:
+//
+//   https://developers.google.com/protocol-buffers/docs/gotutorial
+//
+// For a guide to generated Go protocol buffer code, see:
+//
+//   https://developers.google.com/protocol-buffers/docs/reference/go-generated
+//
+//
+// Binary serialization
+//
+// This package contains functions to convert to and from the wire format,
+// an efficient binary serialization of protocol buffers.
+//
+// • Size reports the size of a message in the wire format.
+//
+// • Marshal converts a message to the wire format.
+// The MarshalOptions type provides more control over wire marshaling.
+//
+// • Unmarshal converts a message from the wire format.
+// The UnmarshalOptions type provides more control over wire unmarshaling.
+//
+//
+// Basic message operations
+//
+// • Clone makes a deep copy of a message.
+//
+// • Merge merges the content of a message into another.
+//
+// • Equal compares two messages. For more control over comparisons
+// and detailed reporting of differences, see package
+// "google.golang.org/protobuf/testing/protocmp".
+//
+// • Reset clears the content of a message.
+//
+// • CheckInitialized reports whether all required fields in a message are set.
+//
+//
+// Optional scalar constructors
+//
+// The API for some generated messages represents optional scalar fields
+// as pointers to a value. For example, an optional string field has the
+// Go type *string.
+//
+// • Bool, Int32, Int64, Uint32, Uint64, Float32, Float64, and String
+// take a value and return a pointer to a new instance of it,
+// to simplify construction of optional field values.
+//
+// Generated enum types usually have an Enum method which performs the
+// same operation.
+//
+// Optional scalar fields are only supported in proto2.
+//
+//
+// Extension accessors
+//
+// • HasExtension, GetExtension, SetExtension, and ClearExtension
+// access extension field values in a protocol buffer message.
+//
+// Extension fields are only supported in proto2.
+//
+//
+// Related packages
+//
+// • Package "google.golang.org/protobuf/encoding/protojson" converts messages to
+// and from JSON.
+//
+// • Package "google.golang.org/protobuf/encoding/prototext" converts messages to
+// and from the text format.
+//
+// • Package "google.golang.org/protobuf/reflect/protoreflect" provides a
+// reflection interface for protocol buffer data types.
+//
+// • Package "google.golang.org/protobuf/testing/protocmp" provides features
+// to compare protocol buffer messages with the "github.com/google/go-cmp/cmp"
+// package.
+//
+// • Package "google.golang.org/protobuf/types/dynamicpb" provides a dynamic
+// message type, suitable for working with messages where the protocol buffer
+// type is only known at runtime.
+//
+// This module contains additional packages for more specialized use cases.
+// Consult the individual package documentation for details.
+package proto
diff --git a/demo_test/vendor/google.golang.org/protobuf/proto/encode.go b/demo_test/vendor/google.golang.org/protobuf/proto/encode.go
new file mode 100644
index 0000000..fa738a1
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/proto/encode.go
@@ -0,0 +1,308 @@
+// 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 proto
+
+import (
+	"sort"
+
+	"google.golang.org/protobuf/encoding/protowire"
+	"google.golang.org/protobuf/internal/encoding/messageset"
+	"google.golang.org/protobuf/internal/fieldsort"
+	"google.golang.org/protobuf/internal/mapsort"
+	"google.golang.org/protobuf/internal/pragma"
+	"google.golang.org/protobuf/reflect/protoreflect"
+	"google.golang.org/protobuf/runtime/protoiface"
+)
+
+// MarshalOptions configures the marshaler.
+//
+// Example usage:
+//   b, err := MarshalOptions{Deterministic: true}.Marshal(m)
+type MarshalOptions struct {
+	pragma.NoUnkeyedLiterals
+
+	// AllowPartial allows messages that have missing required fields to marshal
+	// without returning an error. If AllowPartial is false (the default),
+	// Marshal will return an error if there are any missing required fields.
+	AllowPartial bool
+
+	// Deterministic controls whether the same message will always be
+	// serialized to the same bytes within the same binary.
+	//
+	// Setting this option guarantees that repeated serialization of
+	// the same message will return the same bytes, and that different
+	// processes of the same binary (which may be executing on different
+	// machines) will serialize equal messages to the same bytes.
+	// It has no effect on the resulting size of the encoded message compared
+	// to a non-deterministic marshal.
+	//
+	// Note that the deterministic serialization is NOT canonical across
+	// languages. It is not guaranteed to remain stable over time. It is
+	// unstable across different builds with schema changes due to unknown
+	// fields. Users who need canonical serialization (e.g., persistent
+	// storage in a canonical form, fingerprinting, etc.) must define
+	// their own canonicalization specification and implement their own
+	// serializer rather than relying on this API.
+	//
+	// If deterministic serialization is requested, map entries will be
+	// sorted by keys in lexographical order. This is an implementation
+	// detail and subject to change.
+	Deterministic bool
+
+	// UseCachedSize indicates that the result of a previous Size call
+	// may be reused.
+	//
+	// Setting this option asserts that:
+	//
+	// 1. Size has previously been called on this message with identical
+	// options (except for UseCachedSize itself).
+	//
+	// 2. The message and all its submessages have not changed in any
+	// way since the Size call.
+	//
+	// If either of these invariants is violated,
+	// the results are undefined and may include panics or corrupted output.
+	//
+	// Implementations MAY take this option into account to provide
+	// better performance, but there is no guarantee that they will do so.
+	// There is absolutely no guarantee that Size followed by Marshal with
+	// UseCachedSize set will perform equivalently to Marshal alone.
+	UseCachedSize bool
+}
+
+// Marshal returns the wire-format encoding of m.
+func Marshal(m Message) ([]byte, error) {
+	out, err := MarshalOptions{}.marshal(nil, m.ProtoReflect())
+	return out.Buf, err
+}
+
+// Marshal returns the wire-format encoding of m.
+func (o MarshalOptions) Marshal(m Message) ([]byte, error) {
+	out, err := o.marshal(nil, m.ProtoReflect())
+	return out.Buf, err
+}
+
+// MarshalAppend appends the wire-format encoding of m to b,
+// returning the result.
+func (o MarshalOptions) MarshalAppend(b []byte, m Message) ([]byte, error) {
+	out, err := o.marshal(b, m.ProtoReflect())
+	return out.Buf, err
+}
+
+// MarshalState returns the wire-format encoding of a message.
+//
+// This method permits fine-grained control over the marshaler.
+// Most users should use Marshal instead.
+func (o MarshalOptions) MarshalState(in protoiface.MarshalInput) (protoiface.MarshalOutput, error) {
+	return o.marshal(in.Buf, in.Message)
+}
+
+func (o MarshalOptions) marshal(b []byte, m protoreflect.Message) (out protoiface.MarshalOutput, err error) {
+	allowPartial := o.AllowPartial
+	o.AllowPartial = true
+	if methods := protoMethods(m); methods != nil && methods.Marshal != nil &&
+		!(o.Deterministic && methods.Flags&protoiface.SupportMarshalDeterministic == 0) {
+		in := protoiface.MarshalInput{
+			Message: m,
+			Buf:     b,
+		}
+		if o.Deterministic {
+			in.Flags |= protoiface.MarshalDeterministic
+		}
+		if o.UseCachedSize {
+			in.Flags |= protoiface.MarshalUseCachedSize
+		}
+		if methods.Size != nil {
+			sout := methods.Size(protoiface.SizeInput{
+				Message: m,
+				Flags:   in.Flags,
+			})
+			if cap(b) < len(b)+sout.Size {
+				in.Buf = make([]byte, len(b), growcap(cap(b), len(b)+sout.Size))
+				copy(in.Buf, b)
+			}
+			in.Flags |= protoiface.MarshalUseCachedSize
+		}
+		out, err = methods.Marshal(in)
+	} else {
+		out.Buf, err = o.marshalMessageSlow(b, m)
+	}
+	if err != nil {
+		return out, err
+	}
+	if allowPartial {
+		return out, nil
+	}
+	return out, checkInitialized(m)
+}
+
+func (o MarshalOptions) marshalMessage(b []byte, m protoreflect.Message) ([]byte, error) {
+	out, err := o.marshal(b, m)
+	return out.Buf, err
+}
+
+// growcap scales up the capacity of a slice.
+//
+// Given a slice with a current capacity of oldcap and a desired
+// capacity of wantcap, growcap returns a new capacity >= wantcap.
+//
+// The algorithm is mostly identical to the one used by append as of Go 1.14.
+func growcap(oldcap, wantcap int) (newcap int) {
+	if wantcap > oldcap*2 {
+		newcap = wantcap
+	} else if oldcap < 1024 {
+		// The Go 1.14 runtime takes this case when len(s) < 1024,
+		// not when cap(s) < 1024. The difference doesn't seem
+		// significant here.
+		newcap = oldcap * 2
+	} else {
+		newcap = oldcap
+		for 0 < newcap && newcap < wantcap {
+			newcap += newcap / 4
+		}
+		if newcap <= 0 {
+			newcap = wantcap
+		}
+	}
+	return newcap
+}
+
+func (o MarshalOptions) marshalMessageSlow(b []byte, m protoreflect.Message) ([]byte, error) {
+	if messageset.IsMessageSet(m.Descriptor()) {
+		return marshalMessageSet(b, m, o)
+	}
+	// There are many choices for what order we visit fields in. The default one here
+	// is chosen for reasonable efficiency and simplicity given the protoreflect API.
+	// It is not deterministic, since Message.Range does not return fields in any
+	// defined order.
+	//
+	// When using deterministic serialization, we sort the known fields.
+	var err error
+	o.rangeFields(m, func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool {
+		b, err = o.marshalField(b, fd, v)
+		return err == nil
+	})
+	if err != nil {
+		return b, err
+	}
+	b = append(b, m.GetUnknown()...)
+	return b, nil
+}
+
+// rangeFields visits fields in a defined order when deterministic serialization is enabled.
+func (o MarshalOptions) rangeFields(m protoreflect.Message, f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) {
+	if !o.Deterministic {
+		m.Range(f)
+		return
+	}
+	var fds []protoreflect.FieldDescriptor
+	m.Range(func(fd protoreflect.FieldDescriptor, _ protoreflect.Value) bool {
+		fds = append(fds, fd)
+		return true
+	})
+	sort.Slice(fds, func(a, b int) bool {
+		return fieldsort.Less(fds[a], fds[b])
+	})
+	for _, fd := range fds {
+		if !f(fd, m.Get(fd)) {
+			break
+		}
+	}
+}
+
+func (o MarshalOptions) marshalField(b []byte, fd protoreflect.FieldDescriptor, value protoreflect.Value) ([]byte, error) {
+	switch {
+	case fd.IsList():
+		return o.marshalList(b, fd, value.List())
+	case fd.IsMap():
+		return o.marshalMap(b, fd, value.Map())
+	default:
+		b = protowire.AppendTag(b, fd.Number(), wireTypes[fd.Kind()])
+		return o.marshalSingular(b, fd, value)
+	}
+}
+
+func (o MarshalOptions) marshalList(b []byte, fd protoreflect.FieldDescriptor, list protoreflect.List) ([]byte, error) {
+	if fd.IsPacked() && list.Len() > 0 {
+		b = protowire.AppendTag(b, fd.Number(), protowire.BytesType)
+		b, pos := appendSpeculativeLength(b)
+		for i, llen := 0, list.Len(); i < llen; i++ {
+			var err error
+			b, err = o.marshalSingular(b, fd, list.Get(i))
+			if err != nil {
+				return b, err
+			}
+		}
+		b = finishSpeculativeLength(b, pos)
+		return b, nil
+	}
+
+	kind := fd.Kind()
+	for i, llen := 0, list.Len(); i < llen; i++ {
+		var err error
+		b = protowire.AppendTag(b, fd.Number(), wireTypes[kind])
+		b, err = o.marshalSingular(b, fd, list.Get(i))
+		if err != nil {
+			return b, err
+		}
+	}
+	return b, nil
+}
+
+func (o MarshalOptions) marshalMap(b []byte, fd protoreflect.FieldDescriptor, mapv protoreflect.Map) ([]byte, error) {
+	keyf := fd.MapKey()
+	valf := fd.MapValue()
+	var err error
+	o.rangeMap(mapv, keyf.Kind(), func(key protoreflect.MapKey, value protoreflect.Value) bool {
+		b = protowire.AppendTag(b, fd.Number(), protowire.BytesType)
+		var pos int
+		b, pos = appendSpeculativeLength(b)
+
+		b, err = o.marshalField(b, keyf, key.Value())
+		if err != nil {
+			return false
+		}
+		b, err = o.marshalField(b, valf, value)
+		if err != nil {
+			return false
+		}
+		b = finishSpeculativeLength(b, pos)
+		return true
+	})
+	return b, err
+}
+
+func (o MarshalOptions) rangeMap(mapv protoreflect.Map, kind protoreflect.Kind, f func(protoreflect.MapKey, protoreflect.Value) bool) {
+	if !o.Deterministic {
+		mapv.Range(f)
+		return
+	}
+	mapsort.Range(mapv, kind, f)
+}
+
+// When encoding length-prefixed fields, we speculatively set aside some number of bytes
+// for the length, encode the data, and then encode the length (shifting the data if necessary
+// to make room).
+const speculativeLength = 1
+
+func appendSpeculativeLength(b []byte) ([]byte, int) {
+	pos := len(b)
+	b = append(b, "\x00\x00\x00\x00"[:speculativeLength]...)
+	return b, pos
+}
+
+func finishSpeculativeLength(b []byte, pos int) []byte {
+	mlen := len(b) - pos - speculativeLength
+	msiz := protowire.SizeVarint(uint64(mlen))
+	if msiz != speculativeLength {
+		for i := 0; i < msiz-speculativeLength; i++ {
+			b = append(b, 0)
+		}
+		copy(b[pos+msiz:], b[pos+speculativeLength:])
+		b = b[:pos+msiz+mlen]
+	}
+	protowire.AppendVarint(b[:pos], uint64(mlen))
+	return b
+}
diff --git a/demo_test/vendor/google.golang.org/protobuf/proto/encode_gen.go b/demo_test/vendor/google.golang.org/protobuf/proto/encode_gen.go
new file mode 100644
index 0000000..185dacf
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/proto/encode_gen.go
@@ -0,0 +1,97 @@
+// 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 proto
+
+import (
+	"math"
+	"unicode/utf8"
+
+	"google.golang.org/protobuf/encoding/protowire"
+	"google.golang.org/protobuf/internal/errors"
+	"google.golang.org/protobuf/internal/strs"
+	"google.golang.org/protobuf/reflect/protoreflect"
+)
+
+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,
+}
+
+func (o MarshalOptions) marshalSingular(b []byte, fd protoreflect.FieldDescriptor, v protoreflect.Value) ([]byte, error) {
+	switch fd.Kind() {
+	case protoreflect.BoolKind:
+		b = protowire.AppendVarint(b, protowire.EncodeBool(v.Bool()))
+	case protoreflect.EnumKind:
+		b = protowire.AppendVarint(b, uint64(v.Enum()))
+	case protoreflect.Int32Kind:
+		b = protowire.AppendVarint(b, uint64(int32(v.Int())))
+	case protoreflect.Sint32Kind:
+		b = protowire.AppendVarint(b, protowire.EncodeZigZag(int64(int32(v.Int()))))
+	case protoreflect.Uint32Kind:
+		b = protowire.AppendVarint(b, uint64(uint32(v.Uint())))
+	case protoreflect.Int64Kind:
+		b = protowire.AppendVarint(b, uint64(v.Int()))
+	case protoreflect.Sint64Kind:
+		b = protowire.AppendVarint(b, protowire.EncodeZigZag(v.Int()))
+	case protoreflect.Uint64Kind:
+		b = protowire.AppendVarint(b, v.Uint())
+	case protoreflect.Sfixed32Kind:
+		b = protowire.AppendFixed32(b, uint32(v.Int()))
+	case protoreflect.Fixed32Kind:
+		b = protowire.AppendFixed32(b, uint32(v.Uint()))
+	case protoreflect.FloatKind:
+		b = protowire.AppendFixed32(b, math.Float32bits(float32(v.Float())))
+	case protoreflect.Sfixed64Kind:
+		b = protowire.AppendFixed64(b, uint64(v.Int()))
+	case protoreflect.Fixed64Kind:
+		b = protowire.AppendFixed64(b, v.Uint())
+	case protoreflect.DoubleKind:
+		b = protowire.AppendFixed64(b, math.Float64bits(v.Float()))
+	case protoreflect.StringKind:
+		if strs.EnforceUTF8(fd) && !utf8.ValidString(v.String()) {
+			return b, errors.InvalidUTF8(string(fd.FullName()))
+		}
+		b = protowire.AppendString(b, v.String())
+	case protoreflect.BytesKind:
+		b = protowire.AppendBytes(b, v.Bytes())
+	case protoreflect.MessageKind:
+		var pos int
+		var err error
+		b, pos = appendSpeculativeLength(b)
+		b, err = o.marshalMessage(b, v.Message())
+		if err != nil {
+			return b, err
+		}
+		b = finishSpeculativeLength(b, pos)
+	case protoreflect.GroupKind:
+		var err error
+		b, err = o.marshalMessage(b, v.Message())
+		if err != nil {
+			return b, err
+		}
+		b = protowire.AppendVarint(b, protowire.EncodeTag(fd.Number(), protowire.EndGroupType))
+	default:
+		return b, errors.New("invalid kind %v", fd.Kind())
+	}
+	return b, nil
+}
diff --git a/demo_test/vendor/google.golang.org/protobuf/proto/equal.go b/demo_test/vendor/google.golang.org/protobuf/proto/equal.go
new file mode 100644
index 0000000..10902bd
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/proto/equal.go
@@ -0,0 +1,154 @@
+// 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 proto
+
+import (
+	"bytes"
+	"math"
+	"reflect"
+
+	"google.golang.org/protobuf/encoding/protowire"
+	pref "google.golang.org/protobuf/reflect/protoreflect"
+)
+
+// Equal reports whether two messages are equal.
+// If two messages marshal to the same bytes under deterministic serialization,
+// then Equal is guaranteed to report true.
+//
+// Two messages are equal if they belong to the same message descriptor,
+// have the same set of populated known and extension field values,
+// and the same set of unknown fields values. If either of the top-level
+// messages are invalid, then Equal reports true only if both are invalid.
+//
+// Scalar values are compared with the equivalent of the == operator in Go,
+// except bytes values which are compared using bytes.Equal and
+// floating point values which specially treat NaNs as equal.
+// Message values are compared by recursively calling Equal.
+// Lists are equal if each element value is also equal.
+// Maps are equal if they have the same set of keys, where the pair of values
+// for each key is also equal.
+func Equal(x, y Message) bool {
+	if x == nil || y == nil {
+		return x == nil && y == nil
+	}
+	mx := x.ProtoReflect()
+	my := y.ProtoReflect()
+	if mx.IsValid() != my.IsValid() {
+		return false
+	}
+	return equalMessage(mx, my)
+}
+
+// equalMessage compares two messages.
+func equalMessage(mx, my pref.Message) bool {
+	if mx.Descriptor() != my.Descriptor() {
+		return false
+	}
+
+	nx := 0
+	equal := true
+	mx.Range(func(fd pref.FieldDescriptor, vx pref.Value) bool {
+		nx++
+		vy := my.Get(fd)
+		equal = my.Has(fd) && equalField(fd, vx, vy)
+		return equal
+	})
+	if !equal {
+		return false
+	}
+	ny := 0
+	my.Range(func(fd pref.FieldDescriptor, vx pref.Value) bool {
+		ny++
+		return true
+	})
+	if nx != ny {
+		return false
+	}
+
+	return equalUnknown(mx.GetUnknown(), my.GetUnknown())
+}
+
+// equalField compares two fields.
+func equalField(fd pref.FieldDescriptor, x, y pref.Value) bool {
+	switch {
+	case fd.IsList():
+		return equalList(fd, x.List(), y.List())
+	case fd.IsMap():
+		return equalMap(fd, x.Map(), y.Map())
+	default:
+		return equalValue(fd, x, y)
+	}
+}
+
+// equalMap compares two maps.
+func equalMap(fd pref.FieldDescriptor, x, y pref.Map) bool {
+	if x.Len() != y.Len() {
+		return false
+	}
+	equal := true
+	x.Range(func(k pref.MapKey, vx pref.Value) bool {
+		vy := y.Get(k)
+		equal = y.Has(k) && equalValue(fd.MapValue(), vx, vy)
+		return equal
+	})
+	return equal
+}
+
+// equalList compares two lists.
+func equalList(fd pref.FieldDescriptor, x, y pref.List) bool {
+	if x.Len() != y.Len() {
+		return false
+	}
+	for i := x.Len() - 1; i >= 0; i-- {
+		if !equalValue(fd, x.Get(i), y.Get(i)) {
+			return false
+		}
+	}
+	return true
+}
+
+// equalValue compares two singular values.
+func equalValue(fd pref.FieldDescriptor, x, y pref.Value) bool {
+	switch {
+	case fd.Message() != nil:
+		return equalMessage(x.Message(), y.Message())
+	case fd.Kind() == pref.BytesKind:
+		return bytes.Equal(x.Bytes(), y.Bytes())
+	case fd.Kind() == pref.FloatKind, fd.Kind() == pref.DoubleKind:
+		fx := x.Float()
+		fy := y.Float()
+		if math.IsNaN(fx) || math.IsNaN(fy) {
+			return math.IsNaN(fx) && math.IsNaN(fy)
+		}
+		return fx == fy
+	default:
+		return x.Interface() == y.Interface()
+	}
+}
+
+// equalUnknown compares unknown fields by direct comparison on the raw bytes
+// of each individual field number.
+func equalUnknown(x, y pref.RawFields) bool {
+	if len(x) != len(y) {
+		return false
+	}
+	if bytes.Equal([]byte(x), []byte(y)) {
+		return true
+	}
+
+	mx := make(map[pref.FieldNumber]pref.RawFields)
+	my := make(map[pref.FieldNumber]pref.RawFields)
+	for len(x) > 0 {
+		fnum, _, n := protowire.ConsumeField(x)
+		mx[fnum] = append(mx[fnum], x[:n]...)
+		x = x[n:]
+	}
+	for len(y) > 0 {
+		fnum, _, n := protowire.ConsumeField(y)
+		my[fnum] = append(my[fnum], y[:n]...)
+		y = y[n:]
+	}
+	return reflect.DeepEqual(mx, my)
+}
diff --git a/demo_test/vendor/google.golang.org/protobuf/proto/extension.go b/demo_test/vendor/google.golang.org/protobuf/proto/extension.go
new file mode 100644
index 0000000..73f2431
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/proto/extension.go
@@ -0,0 +1,36 @@
+// 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 proto
+
+import (
+	"google.golang.org/protobuf/reflect/protoreflect"
+)
+
+// HasExtension reports whether an extension field is populated.
+// It panics if ext does not extend m.
+func HasExtension(m Message, ext protoreflect.ExtensionType) bool {
+	return m.ProtoReflect().Has(ext.TypeDescriptor())
+}
+
+// ClearExtension clears an extension field such that subsequent
+// HasExtension calls return false.
+// It panics if ext does not extend m.
+func ClearExtension(m Message, ext protoreflect.ExtensionType) {
+	m.ProtoReflect().Clear(ext.TypeDescriptor())
+}
+
+// GetExtension retrieves the value for an extension field.
+// If the field is unpopulated, it returns the default value for
+// scalars and an immutable, empty value for lists, maps, or messages.
+// It panics if ext does not extend m.
+func GetExtension(m Message, ext protoreflect.ExtensionType) interface{} {
+	return ext.InterfaceOf(m.ProtoReflect().Get(ext.TypeDescriptor()))
+}
+
+// SetExtension stores the value of an extension field.
+// It panics if ext does not extend m or if value type is invalid for the field.
+func SetExtension(m Message, ext protoreflect.ExtensionType, value interface{}) {
+	m.ProtoReflect().Set(ext.TypeDescriptor(), ext.ValueOf(value))
+}
diff --git a/demo_test/vendor/google.golang.org/protobuf/proto/merge.go b/demo_test/vendor/google.golang.org/protobuf/proto/merge.go
new file mode 100644
index 0000000..df72f98
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/proto/merge.go
@@ -0,0 +1,131 @@
+// 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 proto
+
+import (
+	"google.golang.org/protobuf/reflect/protoreflect"
+	"google.golang.org/protobuf/runtime/protoiface"
+)
+
+// Merge merges src into dst, which must be a message with the same descriptor.
+//
+// Populated scalar fields in src are copied to dst, while populated
+// singular messages in src are merged into dst by recursively calling Merge.
+// The elements of every list field in src is appended to the corresponded
+// list fields in dst. The entries of every map field in src is copied into
+// the corresponding map field in dst, possibly replacing existing entries.
+// The unknown fields of src are appended to the unknown fields of dst.
+//
+// It is semantically equivalent to unmarshaling the encoded form of src
+// into dst with the UnmarshalOptions.Merge option specified.
+func Merge(dst, src Message) {
+	dstMsg, srcMsg := dst.ProtoReflect(), src.ProtoReflect()
+	if dstMsg.Descriptor() != srcMsg.Descriptor() {
+		panic("descriptor mismatch")
+	}
+	mergeOptions{}.mergeMessage(dstMsg, srcMsg)
+}
+
+// Clone returns a deep copy of m.
+// If the top-level message is invalid, it returns an invalid message as well.
+func Clone(m Message) Message {
+	// NOTE: Most usages of Clone assume the following properties:
+	//	t := reflect.TypeOf(m)
+	//	t == reflect.TypeOf(m.ProtoReflect().New().Interface())
+	//	t == reflect.TypeOf(m.ProtoReflect().Type().Zero().Interface())
+	//
+	// Embedding protobuf messages breaks this since the parent type will have
+	// a forwarded ProtoReflect method, but the Interface method will return
+	// the underlying embedded message type.
+	if m == nil {
+		return nil
+	}
+	src := m.ProtoReflect()
+	if !src.IsValid() {
+		return src.Type().Zero().Interface()
+	}
+	dst := src.New()
+	mergeOptions{}.mergeMessage(dst, src)
+	return dst.Interface()
+}
+
+// mergeOptions provides a namespace for merge functions, and can be
+// exported in the future if we add user-visible merge options.
+type mergeOptions struct{}
+
+func (o mergeOptions) mergeMessage(dst, src protoreflect.Message) {
+	methods := protoMethods(dst)
+	if methods != nil && methods.Merge != nil {
+		in := protoiface.MergeInput{
+			Destination: dst,
+			Source:      src,
+		}
+		out := methods.Merge(in)
+		if out.Flags&protoiface.MergeComplete != 0 {
+			return
+		}
+	}
+
+	if !dst.IsValid() {
+		panic("cannot merge into invalid destination message")
+	}
+
+	src.Range(func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool {
+		switch {
+		case fd.IsList():
+			o.mergeList(dst.Mutable(fd).List(), v.List(), fd)
+		case fd.IsMap():
+			o.mergeMap(dst.Mutable(fd).Map(), v.Map(), fd.MapValue())
+		case fd.Message() != nil:
+			o.mergeMessage(dst.Mutable(fd).Message(), v.Message())
+		case fd.Kind() == protoreflect.BytesKind:
+			dst.Set(fd, o.cloneBytes(v))
+		default:
+			dst.Set(fd, v)
+		}
+		return true
+	})
+
+	if len(src.GetUnknown()) > 0 {
+		dst.SetUnknown(append(dst.GetUnknown(), src.GetUnknown()...))
+	}
+}
+
+func (o mergeOptions) mergeList(dst, src protoreflect.List, fd protoreflect.FieldDescriptor) {
+	// Merge semantics appends to the end of the existing list.
+	for i, n := 0, src.Len(); i < n; i++ {
+		switch v := src.Get(i); {
+		case fd.Message() != nil:
+			dstv := dst.NewElement()
+			o.mergeMessage(dstv.Message(), v.Message())
+			dst.Append(dstv)
+		case fd.Kind() == protoreflect.BytesKind:
+			dst.Append(o.cloneBytes(v))
+		default:
+			dst.Append(v)
+		}
+	}
+}
+
+func (o mergeOptions) mergeMap(dst, src protoreflect.Map, fd protoreflect.FieldDescriptor) {
+	// Merge semantics replaces, rather than merges into existing entries.
+	src.Range(func(k protoreflect.MapKey, v protoreflect.Value) bool {
+		switch {
+		case fd.Message() != nil:
+			dstv := dst.NewValue()
+			o.mergeMessage(dstv.Message(), v.Message())
+			dst.Set(k, dstv)
+		case fd.Kind() == protoreflect.BytesKind:
+			dst.Set(k, o.cloneBytes(v))
+		default:
+			dst.Set(k, v)
+		}
+		return true
+	})
+}
+
+func (o mergeOptions) cloneBytes(v protoreflect.Value) protoreflect.Value {
+	return protoreflect.ValueOfBytes(append([]byte{}, v.Bytes()...))
+}
diff --git a/demo_test/vendor/google.golang.org/protobuf/proto/messageset.go b/demo_test/vendor/google.golang.org/protobuf/proto/messageset.go
new file mode 100644
index 0000000..b6b3de5
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/proto/messageset.go
@@ -0,0 +1,88 @@
+// 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 proto
+
+import (
+	"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"
+	"google.golang.org/protobuf/reflect/protoreflect"
+	"google.golang.org/protobuf/reflect/protoregistry"
+)
+
+func sizeMessageSet(m protoreflect.Message) (size int) {
+	m.Range(func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool {
+		size += messageset.SizeField(fd.Number())
+		size += protowire.SizeTag(messageset.FieldMessage)
+		size += protowire.SizeBytes(sizeMessage(v.Message()))
+		return true
+	})
+	size += messageset.SizeUnknown(m.GetUnknown())
+	return size
+}
+
+func marshalMessageSet(b []byte, m protoreflect.Message, o MarshalOptions) ([]byte, error) {
+	if !flags.ProtoLegacy {
+		return b, errors.New("no support for message_set_wire_format")
+	}
+	var err error
+	o.rangeFields(m, func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool {
+		b, err = marshalMessageSetField(b, fd, v, o)
+		return err == nil
+	})
+	if err != nil {
+		return b, err
+	}
+	return messageset.AppendUnknown(b, m.GetUnknown())
+}
+
+func marshalMessageSetField(b []byte, fd protoreflect.FieldDescriptor, value protoreflect.Value, o MarshalOptions) ([]byte, error) {
+	b = messageset.AppendFieldStart(b, fd.Number())
+	b = protowire.AppendTag(b, messageset.FieldMessage, protowire.BytesType)
+	b = protowire.AppendVarint(b, uint64(o.Size(value.Message().Interface())))
+	b, err := o.marshalMessage(b, value.Message())
+	if err != nil {
+		return b, err
+	}
+	b = messageset.AppendFieldEnd(b)
+	return b, nil
+}
+
+func unmarshalMessageSet(b []byte, m protoreflect.Message, o UnmarshalOptions) error {
+	if !flags.ProtoLegacy {
+		return errors.New("no support for message_set_wire_format")
+	}
+	return messageset.Unmarshal(b, false, func(num protowire.Number, v []byte) error {
+		err := unmarshalMessageSetField(m, num, v, o)
+		if err == errUnknown {
+			unknown := m.GetUnknown()
+			unknown = protowire.AppendTag(unknown, num, protowire.BytesType)
+			unknown = protowire.AppendBytes(unknown, v)
+			m.SetUnknown(unknown)
+			return nil
+		}
+		return err
+	})
+}
+
+func unmarshalMessageSetField(m protoreflect.Message, num protowire.Number, v []byte, o UnmarshalOptions) error {
+	md := m.Descriptor()
+	if !md.ExtensionRanges().Has(num) {
+		return errUnknown
+	}
+	xt, err := o.Resolver.FindExtensionByNumber(md.FullName(), num)
+	if err == protoregistry.NotFound {
+		return errUnknown
+	}
+	if err != nil {
+		return errors.New("%v: unable to resolve extension %v: %v", md.FullName(), num, err)
+	}
+	xd := xt.TypeDescriptor()
+	if err := o.unmarshalMessage(v, m.Mutable(xd).Message()); err != nil {
+		return err
+	}
+	return nil
+}
diff --git a/demo_test/vendor/google.golang.org/protobuf/proto/proto.go b/demo_test/vendor/google.golang.org/protobuf/proto/proto.go
new file mode 100644
index 0000000..ca14b09
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/proto/proto.go
@@ -0,0 +1,34 @@
+// 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 proto
+
+import (
+	"google.golang.org/protobuf/internal/errors"
+	"google.golang.org/protobuf/reflect/protoreflect"
+)
+
+// Message is the top-level interface that all messages must implement.
+// It provides access to a reflective view of a message.
+// Any implementation of this interface may be used with all functions in the
+// protobuf module that accept a Message, except where otherwise specified.
+//
+// This is the v2 interface definition for protobuf messages.
+// The v1 interface definition is "github.com/golang/protobuf/proto".Message.
+//
+// To convert a v1 message to a v2 message,
+// use "github.com/golang/protobuf/proto".MessageV2.
+// To convert a v2 message to a v1 message,
+// use "github.com/golang/protobuf/proto".MessageV1.
+type Message = protoreflect.ProtoMessage
+
+// Error matches all errors produced by packages in the protobuf module.
+//
+// That is, errors.Is(err, Error) reports whether an error is produced
+// by this module.
+var Error error
+
+func init() {
+	Error = errors.Error
+}
diff --git a/demo_test/vendor/google.golang.org/protobuf/proto/proto_methods.go b/demo_test/vendor/google.golang.org/protobuf/proto/proto_methods.go
new file mode 100644
index 0000000..d8dd604
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/proto/proto_methods.go
@@ -0,0 +1,19 @@
+// 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.
+
+// The protoreflect build tag disables use of fast-path methods.
+// +build !protoreflect
+
+package proto
+
+import (
+	"google.golang.org/protobuf/reflect/protoreflect"
+	"google.golang.org/protobuf/runtime/protoiface"
+)
+
+const hasProtoMethods = true
+
+func protoMethods(m protoreflect.Message) *protoiface.Methods {
+	return m.ProtoMethods()
+}
diff --git a/demo_test/vendor/google.golang.org/protobuf/proto/proto_reflect.go b/demo_test/vendor/google.golang.org/protobuf/proto/proto_reflect.go
new file mode 100644
index 0000000..b103d43
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/proto/proto_reflect.go
@@ -0,0 +1,19 @@
+// 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.
+
+// The protoreflect build tag disables use of fast-path methods.
+// +build protoreflect
+
+package proto
+
+import (
+	"google.golang.org/protobuf/reflect/protoreflect"
+	"google.golang.org/protobuf/runtime/protoiface"
+)
+
+const hasProtoMethods = false
+
+func protoMethods(m protoreflect.Message) *protoiface.Methods {
+	return nil
+}
diff --git a/demo_test/vendor/google.golang.org/protobuf/proto/reset.go b/demo_test/vendor/google.golang.org/protobuf/proto/reset.go
new file mode 100644
index 0000000..22048bc
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/proto/reset.go
@@ -0,0 +1,39 @@
+// 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 proto
+
+import "google.golang.org/protobuf/reflect/protoreflect"
+
+// Reset clears every field in the message.
+// The resulting message shares no observable memory with its previous state
+// other than the memory for the message itself.
+func Reset(m Message) {
+	if mr, ok := m.(interface{ Reset() }); ok && hasProtoMethods {
+		mr.Reset()
+		return
+	}
+	resetMessage(m.ProtoReflect())
+}
+
+func resetMessage(m protoreflect.Message) {
+	if !m.IsValid() {
+		panic("cannot reset invalid message")
+	}
+
+	// Clear all known fields.
+	fds := m.Descriptor().Fields()
+	for i := 0; i < fds.Len(); i++ {
+		m.Clear(fds.Get(i))
+	}
+
+	// Clear extension fields.
+	m.Range(func(fd protoreflect.FieldDescriptor, _ protoreflect.Value) bool {
+		m.Clear(fd)
+		return true
+	})
+
+	// Clear unknown fields.
+	m.SetUnknown(nil)
+}
diff --git a/demo_test/vendor/google.golang.org/protobuf/proto/size.go b/demo_test/vendor/google.golang.org/protobuf/proto/size.go
new file mode 100644
index 0000000..a4e72bd
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/proto/size.go
@@ -0,0 +1,89 @@
+// 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 proto
+
+import (
+	"google.golang.org/protobuf/encoding/protowire"
+	"google.golang.org/protobuf/internal/encoding/messageset"
+	"google.golang.org/protobuf/reflect/protoreflect"
+	"google.golang.org/protobuf/runtime/protoiface"
+)
+
+// Size returns the size in bytes of the wire-format encoding of m.
+func Size(m Message) int {
+	return MarshalOptions{}.Size(m)
+}
+
+// Size returns the size in bytes of the wire-format encoding of m.
+func (o MarshalOptions) Size(m Message) int {
+	return sizeMessage(m.ProtoReflect())
+}
+
+func sizeMessage(m protoreflect.Message) (size int) {
+	methods := protoMethods(m)
+	if methods != nil && methods.Size != nil {
+		out := methods.Size(protoiface.SizeInput{
+			Message: m,
+		})
+		return out.Size
+	}
+	if methods != nil && methods.Marshal != nil {
+		// This is not efficient, but we don't have any choice.
+		// This case is mainly used for legacy types with a Marshal method.
+		out, _ := methods.Marshal(protoiface.MarshalInput{
+			Message: m,
+		})
+		return len(out.Buf)
+	}
+	return sizeMessageSlow(m)
+}
+
+func sizeMessageSlow(m protoreflect.Message) (size int) {
+	if messageset.IsMessageSet(m.Descriptor()) {
+		return sizeMessageSet(m)
+	}
+	m.Range(func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool {
+		size += sizeField(fd, v)
+		return true
+	})
+	size += len(m.GetUnknown())
+	return size
+}
+
+func sizeField(fd protoreflect.FieldDescriptor, value protoreflect.Value) (size int) {
+	num := fd.Number()
+	switch {
+	case fd.IsList():
+		return sizeList(num, fd, value.List())
+	case fd.IsMap():
+		return sizeMap(num, fd, value.Map())
+	default:
+		return protowire.SizeTag(num) + sizeSingular(num, fd.Kind(), value)
+	}
+}
+
+func sizeList(num protowire.Number, fd protoreflect.FieldDescriptor, list protoreflect.List) (size int) {
+	if fd.IsPacked() && list.Len() > 0 {
+		content := 0
+		for i, llen := 0, list.Len(); i < llen; i++ {
+			content += sizeSingular(num, fd.Kind(), list.Get(i))
+		}
+		return protowire.SizeTag(num) + protowire.SizeBytes(content)
+	}
+
+	for i, llen := 0, list.Len(); i < llen; i++ {
+		size += protowire.SizeTag(num) + sizeSingular(num, fd.Kind(), list.Get(i))
+	}
+	return size
+}
+
+func sizeMap(num protowire.Number, fd protoreflect.FieldDescriptor, mapv protoreflect.Map) (size int) {
+	mapv.Range(func(key protoreflect.MapKey, value protoreflect.Value) bool {
+		size += protowire.SizeTag(num)
+		size += protowire.SizeBytes(sizeField(fd.MapKey(), key.Value()) + sizeField(fd.MapValue(), value))
+		return true
+	})
+	return size
+}
diff --git a/demo_test/vendor/google.golang.org/protobuf/proto/size_gen.go b/demo_test/vendor/google.golang.org/protobuf/proto/size_gen.go
new file mode 100644
index 0000000..1118460
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/proto/size_gen.go
@@ -0,0 +1,55 @@
+// 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 proto
+
+import (
+	"google.golang.org/protobuf/encoding/protowire"
+	"google.golang.org/protobuf/reflect/protoreflect"
+)
+
+func sizeSingular(num protowire.Number, kind protoreflect.Kind, v protoreflect.Value) int {
+	switch kind {
+	case protoreflect.BoolKind:
+		return protowire.SizeVarint(protowire.EncodeBool(v.Bool()))
+	case protoreflect.EnumKind:
+		return protowire.SizeVarint(uint64(v.Enum()))
+	case protoreflect.Int32Kind:
+		return protowire.SizeVarint(uint64(int32(v.Int())))
+	case protoreflect.Sint32Kind:
+		return protowire.SizeVarint(protowire.EncodeZigZag(int64(int32(v.Int()))))
+	case protoreflect.Uint32Kind:
+		return protowire.SizeVarint(uint64(uint32(v.Uint())))
+	case protoreflect.Int64Kind:
+		return protowire.SizeVarint(uint64(v.Int()))
+	case protoreflect.Sint64Kind:
+		return protowire.SizeVarint(protowire.EncodeZigZag(v.Int()))
+	case protoreflect.Uint64Kind:
+		return protowire.SizeVarint(v.Uint())
+	case protoreflect.Sfixed32Kind:
+		return protowire.SizeFixed32()
+	case protoreflect.Fixed32Kind:
+		return protowire.SizeFixed32()
+	case protoreflect.FloatKind:
+		return protowire.SizeFixed32()
+	case protoreflect.Sfixed64Kind:
+		return protowire.SizeFixed64()
+	case protoreflect.Fixed64Kind:
+		return protowire.SizeFixed64()
+	case protoreflect.DoubleKind:
+		return protowire.SizeFixed64()
+	case protoreflect.StringKind:
+		return protowire.SizeBytes(len(v.String()))
+	case protoreflect.BytesKind:
+		return protowire.SizeBytes(len(v.Bytes()))
+	case protoreflect.MessageKind:
+		return protowire.SizeBytes(sizeMessage(v.Message()))
+	case protoreflect.GroupKind:
+		return protowire.SizeGroup(num, sizeMessage(v.Message()))
+	default:
+		return 0
+	}
+}
diff --git a/demo_test/vendor/google.golang.org/protobuf/proto/wrappers.go b/demo_test/vendor/google.golang.org/protobuf/proto/wrappers.go
new file mode 100644
index 0000000..653b12c
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/proto/wrappers.go
@@ -0,0 +1,29 @@
+// 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 proto
+
+// Bool stores v in a new bool value and returns a pointer to it.
+func Bool(v bool) *bool { return &v }
+
+// Int32 stores v in a new int32 value and returns a pointer to it.
+func Int32(v int32) *int32 { return &v }
+
+// Int64 stores v in a new int64 value and returns a pointer to it.
+func Int64(v int64) *int64 { return &v }
+
+// Float32 stores v in a new float32 value and returns a pointer to it.
+func Float32(v float32) *float32 { return &v }
+
+// Float64 stores v in a new float64 value and returns a pointer to it.
+func Float64(v float64) *float64 { return &v }
+
+// Uint32 stores v in a new uint32 value and returns a pointer to it.
+func Uint32(v uint32) *uint32 { return &v }
+
+// Uint64 stores v in a new uint64 value and returns a pointer to it.
+func Uint64(v uint64) *uint64 { return &v }
+
+// String stores v in a new string value and returns a pointer to it.
+func String(v string) *string { return &v }
diff --git a/demo_test/vendor/google.golang.org/protobuf/reflect/protoreflect/methods.go b/demo_test/vendor/google.golang.org/protobuf/reflect/protoreflect/methods.go
new file mode 100644
index 0000000..6be5d16
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/reflect/protoreflect/methods.go
@@ -0,0 +1,77 @@
+// 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 protoreflect
+
+import (
+	"google.golang.org/protobuf/internal/pragma"
+)
+
+// The following types are used by the fast-path Message.ProtoMethods method.
+//
+// To avoid polluting the public protoreflect API with types used only by
+// low-level implementations, the canonical definitions of these types are
+// in the runtime/protoiface package. The definitions here and in protoiface
+// must be kept in sync.
+type (
+	methods = struct {
+		pragma.NoUnkeyedLiterals
+		Flags            supportFlags
+		Size             func(sizeInput) sizeOutput
+		Marshal          func(marshalInput) (marshalOutput, error)
+		Unmarshal        func(unmarshalInput) (unmarshalOutput, error)
+		Merge            func(mergeInput) mergeOutput
+		CheckInitialized func(checkInitializedInput) (checkInitializedOutput, error)
+	}
+	supportFlags = uint64
+	sizeInput    = struct {
+		pragma.NoUnkeyedLiterals
+		Message Message
+		Flags   uint8
+	}
+	sizeOutput = struct {
+		pragma.NoUnkeyedLiterals
+		Size int
+	}
+	marshalInput = struct {
+		pragma.NoUnkeyedLiterals
+		Message Message
+		Buf     []byte
+		Flags   uint8
+	}
+	marshalOutput = struct {
+		pragma.NoUnkeyedLiterals
+		Buf []byte
+	}
+	unmarshalInput = struct {
+		pragma.NoUnkeyedLiterals
+		Message  Message
+		Buf      []byte
+		Flags    uint8
+		Resolver interface {
+			FindExtensionByName(field FullName) (ExtensionType, error)
+			FindExtensionByNumber(message FullName, field FieldNumber) (ExtensionType, error)
+		}
+	}
+	unmarshalOutput = struct {
+		pragma.NoUnkeyedLiterals
+		Flags uint8
+	}
+	mergeInput = struct {
+		pragma.NoUnkeyedLiterals
+		Source      Message
+		Destination Message
+	}
+	mergeOutput = struct {
+		pragma.NoUnkeyedLiterals
+		Flags uint8
+	}
+	checkInitializedInput = struct {
+		pragma.NoUnkeyedLiterals
+		Message Message
+	}
+	checkInitializedOutput = struct {
+		pragma.NoUnkeyedLiterals
+	}
+)
diff --git a/demo_test/vendor/google.golang.org/protobuf/reflect/protoreflect/proto.go b/demo_test/vendor/google.golang.org/protobuf/reflect/protoreflect/proto.go
new file mode 100644
index 0000000..1b89bed
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/reflect/protoreflect/proto.go
@@ -0,0 +1,477 @@
+// 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 protoreflect provides interfaces to dynamically manipulate messages.
+//
+// This package includes type descriptors which describe the structure of types
+// defined in proto source files and value interfaces which provide the
+// ability to examine and manipulate the contents of messages.
+//
+//
+// Protocol Buffer Descriptors
+//
+// Protobuf descriptors (e.g., EnumDescriptor or MessageDescriptor)
+// are immutable objects that represent protobuf type information.
+// They are wrappers around the messages declared in descriptor.proto.
+// Protobuf descriptors alone lack any information regarding Go types.
+//
+// Enums and messages generated by this module implement Enum and ProtoMessage,
+// where the Descriptor and ProtoReflect.Descriptor accessors respectively
+// return the protobuf descriptor for the values.
+//
+// The protobuf descriptor interfaces are not meant to be implemented by
+// user code since they might need to be extended in the future to support
+// additions to the protobuf language. Protobuf descriptors can be constructed
+// using the "google.golang.org/protobuf/reflect/protodesc" package.
+//
+//
+// Go Type Descriptors
+//
+// A type descriptor (e.g., EnumType or MessageType) is a constructor for
+// a concrete Go type that represents the associated protobuf descriptor.
+// There is commonly a one-to-one relationship between protobuf descriptors and
+// Go type descriptors, but it can potentially be a one-to-many relationship.
+//
+// Enums and messages generated by this module implement Enum and ProtoMessage,
+// where the Type and ProtoReflect.Type accessors respectively
+// return the protobuf descriptor for the values.
+//
+// The "google.golang.org/protobuf/types/dynamicpb" package can be used to
+// create Go type descriptors from protobuf descriptors.
+//
+//
+// Value Interfaces
+//
+// The Enum and Message interfaces provide a reflective view over an
+// enum or message instance. For enums, it provides the ability to retrieve
+// the enum value number for any concrete enum type. For messages, it provides
+// the ability to access or manipulate fields of the message.
+//
+// To convert a proto.Message to a protoreflect.Message, use the
+// former's ProtoReflect method. Since the ProtoReflect method is new to the
+// v2 message interface, it may not be present on older message implementations.
+// The "github.com/golang/protobuf/proto".MessageReflect function can be used
+// to obtain a reflective view on older messages.
+//
+//
+// Relationships
+//
+// The following diagrams demonstrate the relationships between
+// various types declared in this package.
+//
+//
+//	                       ┌───────────────────────────────────┐
+//	                       V                                   │
+//	   ┌────────────── New(n) ─────────────┐                   │
+//	   │                                   │                   │
+//	   │      ┌──── Descriptor() ──┐       │  ┌── Number() ──┐ │
+//	   │      │                    V       V  │              V │
+//	╔════════════╗  ╔════════════════╗  ╔════════╗  ╔════════════╗
+//	║  EnumType  ║  ║ EnumDescriptor ║  ║  Enum  ║  ║ EnumNumber ║
+//	╚════════════╝  ╚════════════════╝  ╚════════╝  ╚════════════╝
+//	      Λ           Λ                   │ │
+//	      │           └─── Descriptor() ──┘ │
+//	      │                                 │
+//	      └────────────────── Type() ───────┘
+//
+// • An EnumType describes a concrete Go enum type.
+// It has an EnumDescriptor and can construct an Enum instance.
+//
+// • An EnumDescriptor describes an abstract protobuf enum type.
+//
+// • An Enum is a concrete enum instance. Generated enums implement Enum.
+//
+//
+//	  ┌──────────────── New() ─────────────────┐
+//	  │                                        │
+//	  │         ┌─── Descriptor() ─────┐       │   ┌── Interface() ───┐
+//	  │         │                      V       V   │                  V
+//	╔═════════════╗  ╔═══════════════════╗  ╔═════════╗  ╔══════════════╗
+//	║ MessageType ║  ║ MessageDescriptor ║  ║ Message ║  ║ ProtoMessage ║
+//	╚═════════════╝  ╚═══════════════════╝  ╚═════════╝  ╚══════════════╝
+//	       Λ           Λ                      │ │  Λ                  │
+//	       │           └──── Descriptor() ────┘ │  └─ ProtoReflect() ─┘
+//	       │                                    │
+//	       └─────────────────── Type() ─────────┘
+//
+// • A MessageType describes a concrete Go message type.
+// It has a MessageDescriptor and can construct a Message instance.
+//
+// • A MessageDescriptor describes an abstract protobuf message type.
+//
+// • A Message is a concrete message instance. Generated messages implement
+// ProtoMessage, which can convert to/from a Message.
+//
+//
+//	      ┌── TypeDescriptor() ──┐    ┌───── Descriptor() ─────┐
+//	      │                      V    │                        V
+//	╔═══════════════╗  ╔═════════════════════════╗  ╔═════════════════════╗
+//	║ ExtensionType ║  ║ ExtensionTypeDescriptor ║  ║ ExtensionDescriptor ║
+//	╚═══════════════╝  ╚═════════════════════════╝  ╚═════════════════════╝
+//	      Λ                      │   │ Λ                      │ Λ
+//	      └─────── Type() ───────┘   │ └─── may implement ────┘ │
+//	                                 │                          │
+//	                                 └────── implements ────────┘
+//
+// • An ExtensionType describes a concrete Go implementation of an extension.
+// It has an ExtensionTypeDescriptor and can convert to/from
+// abstract Values and Go values.
+//
+// • An ExtensionTypeDescriptor is an ExtensionDescriptor
+// which also has an ExtensionType.
+//
+// • An ExtensionDescriptor describes an abstract protobuf extension field and
+// may not always be an ExtensionTypeDescriptor.
+package protoreflect
+
+import (
+	"fmt"
+	"regexp"
+	"strings"
+
+	"google.golang.org/protobuf/encoding/protowire"
+	"google.golang.org/protobuf/internal/pragma"
+)
+
+type doNotImplement pragma.DoNotImplement
+
+// ProtoMessage is the top-level interface that all proto messages implement.
+// This is declared in the protoreflect package to avoid a cyclic dependency;
+// use the proto.Message type instead, which aliases this type.
+type ProtoMessage interface{ ProtoReflect() Message }
+
+// Syntax is the language version of the proto file.
+type Syntax syntax
+
+type syntax int8 // keep exact type opaque as the int type may change
+
+const (
+	Proto2 Syntax = 2
+	Proto3 Syntax = 3
+)
+
+// IsValid reports whether the syntax is valid.
+func (s Syntax) IsValid() bool {
+	switch s {
+	case Proto2, Proto3:
+		return true
+	default:
+		return false
+	}
+}
+
+// String returns s as a proto source identifier (e.g., "proto2").
+func (s Syntax) String() string {
+	switch s {
+	case Proto2:
+		return "proto2"
+	case Proto3:
+		return "proto3"
+	default:
+		return fmt.Sprintf("<unknown:%d>", s)
+	}
+}
+
+// GoString returns s as a Go source identifier (e.g., "Proto2").
+func (s Syntax) GoString() string {
+	switch s {
+	case Proto2:
+		return "Proto2"
+	case Proto3:
+		return "Proto3"
+	default:
+		return fmt.Sprintf("Syntax(%d)", s)
+	}
+}
+
+// Cardinality determines whether a field is optional, required, or repeated.
+type Cardinality cardinality
+
+type cardinality int8 // keep exact type opaque as the int type may change
+
+// Constants as defined by the google.protobuf.Cardinality enumeration.
+const (
+	Optional Cardinality = 1 // appears zero or one times
+	Required Cardinality = 2 // appears exactly one time; invalid with Proto3
+	Repeated Cardinality = 3 // appears zero or more times
+)
+
+// IsValid reports whether the cardinality is valid.
+func (c Cardinality) IsValid() bool {
+	switch c {
+	case Optional, Required, Repeated:
+		return true
+	default:
+		return false
+	}
+}
+
+// String returns c as a proto source identifier (e.g., "optional").
+func (c Cardinality) String() string {
+	switch c {
+	case Optional:
+		return "optional"
+	case Required:
+		return "required"
+	case Repeated:
+		return "repeated"
+	default:
+		return fmt.Sprintf("<unknown:%d>", c)
+	}
+}
+
+// GoString returns c as a Go source identifier (e.g., "Optional").
+func (c Cardinality) GoString() string {
+	switch c {
+	case Optional:
+		return "Optional"
+	case Required:
+		return "Required"
+	case Repeated:
+		return "Repeated"
+	default:
+		return fmt.Sprintf("Cardinality(%d)", c)
+	}
+}
+
+// Kind indicates the basic proto kind of a field.
+type Kind kind
+
+type kind int8 // keep exact type opaque as the int type may change
+
+// Constants as defined by the google.protobuf.Field.Kind enumeration.
+const (
+	BoolKind     Kind = 8
+	EnumKind     Kind = 14
+	Int32Kind    Kind = 5
+	Sint32Kind   Kind = 17
+	Uint32Kind   Kind = 13
+	Int64Kind    Kind = 3
+	Sint64Kind   Kind = 18
+	Uint64Kind   Kind = 4
+	Sfixed32Kind Kind = 15
+	Fixed32Kind  Kind = 7
+	FloatKind    Kind = 2
+	Sfixed64Kind Kind = 16
+	Fixed64Kind  Kind = 6
+	DoubleKind   Kind = 1
+	StringKind   Kind = 9
+	BytesKind    Kind = 12
+	MessageKind  Kind = 11
+	GroupKind    Kind = 10
+)
+
+// IsValid reports whether the kind is valid.
+func (k Kind) IsValid() bool {
+	switch k {
+	case BoolKind, EnumKind,
+		Int32Kind, Sint32Kind, Uint32Kind,
+		Int64Kind, Sint64Kind, Uint64Kind,
+		Sfixed32Kind, Fixed32Kind, FloatKind,
+		Sfixed64Kind, Fixed64Kind, DoubleKind,
+		StringKind, BytesKind, MessageKind, GroupKind:
+		return true
+	default:
+		return false
+	}
+}
+
+// String returns k as a proto source identifier (e.g., "bool").
+func (k Kind) String() string {
+	switch k {
+	case BoolKind:
+		return "bool"
+	case EnumKind:
+		return "enum"
+	case Int32Kind:
+		return "int32"
+	case Sint32Kind:
+		return "sint32"
+	case Uint32Kind:
+		return "uint32"
+	case Int64Kind:
+		return "int64"
+	case Sint64Kind:
+		return "sint64"
+	case Uint64Kind:
+		return "uint64"
+	case Sfixed32Kind:
+		return "sfixed32"
+	case Fixed32Kind:
+		return "fixed32"
+	case FloatKind:
+		return "float"
+	case Sfixed64Kind:
+		return "sfixed64"
+	case Fixed64Kind:
+		return "fixed64"
+	case DoubleKind:
+		return "double"
+	case StringKind:
+		return "string"
+	case BytesKind:
+		return "bytes"
+	case MessageKind:
+		return "message"
+	case GroupKind:
+		return "group"
+	default:
+		return fmt.Sprintf("<unknown:%d>", k)
+	}
+}
+
+// GoString returns k as a Go source identifier (e.g., "BoolKind").
+func (k Kind) GoString() string {
+	switch k {
+	case BoolKind:
+		return "BoolKind"
+	case EnumKind:
+		return "EnumKind"
+	case Int32Kind:
+		return "Int32Kind"
+	case Sint32Kind:
+		return "Sint32Kind"
+	case Uint32Kind:
+		return "Uint32Kind"
+	case Int64Kind:
+		return "Int64Kind"
+	case Sint64Kind:
+		return "Sint64Kind"
+	case Uint64Kind:
+		return "Uint64Kind"
+	case Sfixed32Kind:
+		return "Sfixed32Kind"
+	case Fixed32Kind:
+		return "Fixed32Kind"
+	case FloatKind:
+		return "FloatKind"
+	case Sfixed64Kind:
+		return "Sfixed64Kind"
+	case Fixed64Kind:
+		return "Fixed64Kind"
+	case DoubleKind:
+		return "DoubleKind"
+	case StringKind:
+		return "StringKind"
+	case BytesKind:
+		return "BytesKind"
+	case MessageKind:
+		return "MessageKind"
+	case GroupKind:
+		return "GroupKind"
+	default:
+		return fmt.Sprintf("Kind(%d)", k)
+	}
+}
+
+// FieldNumber is the field number in a message.
+type FieldNumber = protowire.Number
+
+// FieldNumbers represent a list of field numbers.
+type FieldNumbers interface {
+	// Len reports the number of fields in the list.
+	Len() int
+	// Get returns the ith field number. It panics if out of bounds.
+	Get(i int) FieldNumber
+	// Has reports whether n is within the list of fields.
+	Has(n FieldNumber) bool
+
+	doNotImplement
+}
+
+// FieldRanges represent a list of field number ranges.
+type FieldRanges interface {
+	// Len reports the number of ranges in the list.
+	Len() int
+	// Get returns the ith range. It panics if out of bounds.
+	Get(i int) [2]FieldNumber // start inclusive; end exclusive
+	// Has reports whether n is within any of the ranges.
+	Has(n FieldNumber) bool
+
+	doNotImplement
+}
+
+// EnumNumber is the numeric value for an enum.
+type EnumNumber int32
+
+// EnumRanges represent a list of enum number ranges.
+type EnumRanges interface {
+	// Len reports the number of ranges in the list.
+	Len() int
+	// Get returns the ith range. It panics if out of bounds.
+	Get(i int) [2]EnumNumber // start inclusive; end inclusive
+	// Has reports whether n is within any of the ranges.
+	Has(n EnumNumber) bool
+
+	doNotImplement
+}
+
+var (
+	regexName     = regexp.MustCompile(`^[_a-zA-Z][_a-zA-Z0-9]*$`)
+	regexFullName = regexp.MustCompile(`^[_a-zA-Z][_a-zA-Z0-9]*(\.[_a-zA-Z][_a-zA-Z0-9]*)*$`)
+)
+
+// Name is the short name for a proto declaration. This is not the name
+// as used in Go source code, which might not be identical to the proto name.
+type Name string // e.g., "Kind"
+
+// IsValid reports whether n is a syntactically valid name.
+// An empty name is invalid.
+func (n Name) IsValid() bool {
+	return regexName.MatchString(string(n))
+}
+
+// Names represent a list of names.
+type Names interface {
+	// Len reports the number of names in the list.
+	Len() int
+	// Get returns the ith name. It panics if out of bounds.
+	Get(i int) Name
+	// Has reports whether s matches any names in the list.
+	Has(s Name) bool
+
+	doNotImplement
+}
+
+// FullName is a qualified name that uniquely identifies a proto declaration.
+// A qualified name is the concatenation of the proto package along with the
+// fully-declared name (i.e., name of parent preceding the name of the child),
+// with a '.' delimiter placed between each Name.
+//
+// This should not have any leading or trailing dots.
+type FullName string // e.g., "google.protobuf.Field.Kind"
+
+// IsValid reports whether n is a syntactically valid full name.
+// An empty full name is invalid.
+func (n FullName) IsValid() bool {
+	return regexFullName.MatchString(string(n))
+}
+
+// Name returns the short name, which is the last identifier segment.
+// A single segment FullName is the Name itself.
+func (n FullName) Name() Name {
+	if i := strings.LastIndexByte(string(n), '.'); i >= 0 {
+		return Name(n[i+1:])
+	}
+	return Name(n)
+}
+
+// Parent returns the full name with the trailing identifier removed.
+// A single segment FullName has no parent.
+func (n FullName) Parent() FullName {
+	if i := strings.LastIndexByte(string(n), '.'); i >= 0 {
+		return n[:i]
+	}
+	return ""
+}
+
+// Append returns the qualified name appended with the provided short name.
+//
+// Invariant: n == n.Parent().Append(n.Name()) // assuming n is valid
+func (n FullName) Append(s Name) FullName {
+	if n == "" {
+		return FullName(s)
+	}
+	return n + "." + FullName(s)
+}
diff --git a/demo_test/vendor/google.golang.org/protobuf/reflect/protoreflect/source.go b/demo_test/vendor/google.golang.org/protobuf/reflect/protoreflect/source.go
new file mode 100644
index 0000000..32ea3d9
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/reflect/protoreflect/source.go
@@ -0,0 +1,52 @@
+// 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 protoreflect
+
+// SourceLocations is a list of source locations.
+type SourceLocations interface {
+	// Len reports the number of source locations in the proto file.
+	Len() int
+	// Get returns the ith SourceLocation. It panics if out of bounds.
+	Get(int) SourceLocation
+
+	doNotImplement
+
+	// TODO: Add ByPath and ByDescriptor helper methods.
+}
+
+// SourceLocation describes a source location and
+// corresponds with the google.protobuf.SourceCodeInfo.Location message.
+type SourceLocation struct {
+	// Path is the path to the declaration from the root file descriptor.
+	// The contents of this slice must not be mutated.
+	Path SourcePath
+
+	// StartLine and StartColumn are the zero-indexed starting location
+	// in the source file for the declaration.
+	StartLine, StartColumn int
+	// EndLine and EndColumn are the zero-indexed ending location
+	// in the source file for the declaration.
+	// In the descriptor.proto, the end line may be omitted if it is identical
+	// to the start line. Here, it is always populated.
+	EndLine, EndColumn int
+
+	// LeadingDetachedComments are the leading detached comments
+	// for the declaration. The contents of this slice must not be mutated.
+	LeadingDetachedComments []string
+	// LeadingComments is the leading attached comment for the declaration.
+	LeadingComments string
+	// TrailingComments is the trailing attached comment for the declaration.
+	TrailingComments string
+}
+
+// SourcePath identifies part of a file descriptor for a source location.
+// The SourcePath is a sequence of either field numbers or indexes into
+// a repeated field that form a path starting from the root file descriptor.
+//
+// See google.protobuf.SourceCodeInfo.Location.path.
+type SourcePath []int32
+
+// TODO: Add SourcePath.String method to pretty-print the path. For example:
+//	".message_type[6].nested_type[15].field[3]"
diff --git a/demo_test/vendor/google.golang.org/protobuf/reflect/protoreflect/type.go b/demo_test/vendor/google.golang.org/protobuf/reflect/protoreflect/type.go
new file mode 100644
index 0000000..41d560e
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/reflect/protoreflect/type.go
@@ -0,0 +1,618 @@
+// 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 protoreflect
+
+// Descriptor provides a set of accessors that are common to every descriptor.
+// Each descriptor type wraps the equivalent google.protobuf.XXXDescriptorProto,
+// but provides efficient lookup and immutability.
+//
+// Each descriptor is comparable. Equality implies that the two types are
+// exactly identical. However, it is possible for the same semantically
+// identical proto type to be represented by multiple type descriptors.
+//
+// For example, suppose we have t1 and t2 which are both MessageDescriptors.
+// If t1 == t2, then the types are definitely equal and all accessors return
+// the same information. However, if t1 != t2, then it is still possible that
+// they still represent the same proto type (e.g., t1.FullName == t2.FullName).
+// This can occur if a descriptor type is created dynamically, or multiple
+// versions of the same proto type are accidentally linked into the Go binary.
+type Descriptor interface {
+	// ParentFile returns the parent file descriptor that this descriptor
+	// is declared within. The parent file for the file descriptor is itself.
+	//
+	// Support for this functionality is optional and may return nil.
+	ParentFile() FileDescriptor
+
+	// Parent returns the parent containing this descriptor declaration.
+	// The following shows the mapping from child type to possible parent types:
+	//
+	//	╔═════════════════════╤═══════════════════════════════════╗
+	//	║ Child type          │ Possible parent types             ║
+	//	╠═════════════════════╪═══════════════════════════════════╣
+	//	║ FileDescriptor      │ nil                               ║
+	//	║ MessageDescriptor   │ FileDescriptor, MessageDescriptor ║
+	//	║ FieldDescriptor     │ FileDescriptor, MessageDescriptor ║
+	//	║ OneofDescriptor     │ MessageDescriptor                 ║
+	//	║ EnumDescriptor      │ FileDescriptor, MessageDescriptor ║
+	//	║ EnumValueDescriptor │ EnumDescriptor                    ║
+	//	║ ServiceDescriptor   │ FileDescriptor                    ║
+	//	║ MethodDescriptor    │ ServiceDescriptor                 ║
+	//	╚═════════════════════╧═══════════════════════════════════╝
+	//
+	// Support for this functionality is optional and may return nil.
+	Parent() Descriptor
+
+	// Index returns the index of this descriptor within its parent.
+	// It returns 0 if the descriptor does not have a parent or if the parent
+	// is unknown.
+	Index() int
+
+	// Syntax is the protobuf syntax.
+	Syntax() Syntax // e.g., Proto2 or Proto3
+
+	// Name is the short name of the declaration (i.e., FullName.Name).
+	Name() Name // e.g., "Any"
+
+	// FullName is the fully-qualified name of the declaration.
+	//
+	// The FullName is a concatenation of the full name of the type that this
+	// type is declared within and the declaration name. For example,
+	// field "foo_field" in message "proto.package.MyMessage" is
+	// uniquely identified as "proto.package.MyMessage.foo_field".
+	// Enum values are an exception to the rule (see EnumValueDescriptor).
+	FullName() FullName // e.g., "google.protobuf.Any"
+
+	// IsPlaceholder reports whether type information is missing since a
+	// dependency is not resolved, in which case only name information is known.
+	//
+	// Placeholder types may only be returned by the following accessors
+	// as a result of unresolved dependencies or weak imports:
+	//
+	//	╔═══════════════════════════════════╤═════════════════════╗
+	//	║ Accessor                          │ Descriptor          ║
+	//	╠═══════════════════════════════════╪═════════════════════╣
+	//	║ FileImports.FileDescriptor        │ FileDescriptor      ║
+	//	║ FieldDescriptor.Enum              │ EnumDescriptor      ║
+	//	║ FieldDescriptor.Message           │ MessageDescriptor   ║
+	//	║ FieldDescriptor.DefaultEnumValue  │ EnumValueDescriptor ║
+	//	║ FieldDescriptor.ContainingMessage │ MessageDescriptor   ║
+	//	║ MethodDescriptor.Input            │ MessageDescriptor   ║
+	//	║ MethodDescriptor.Output           │ MessageDescriptor   ║
+	//	╚═══════════════════════════════════╧═════════════════════╝
+	//
+	// If true, only Name and FullName are valid.
+	// For FileDescriptor, the Path is also valid.
+	IsPlaceholder() bool
+
+	// Options returns the descriptor options. The caller must not modify
+	// the returned value.
+	//
+	// To avoid a dependency cycle, this function returns a proto.Message value.
+	// The proto message type returned for each descriptor type is as follows:
+	//	╔═════════════════════╤══════════════════════════════════════════╗
+	//	║ Go type             │ Protobuf message type                    ║
+	//	╠═════════════════════╪══════════════════════════════════════════╣
+	//	║ FileDescriptor      │ google.protobuf.FileOptions              ║
+	//	║ EnumDescriptor      │ google.protobuf.EnumOptions              ║
+	//	║ EnumValueDescriptor │ google.protobuf.EnumValueOptions         ║
+	//	║ MessageDescriptor   │ google.protobuf.MessageOptions           ║
+	//	║ FieldDescriptor     │ google.protobuf.FieldOptions             ║
+	//	║ OneofDescriptor     │ google.protobuf.OneofOptions             ║
+	//	║ ServiceDescriptor   │ google.protobuf.ServiceOptions           ║
+	//	║ MethodDescriptor    │ google.protobuf.MethodOptions            ║
+	//	╚═════════════════════╧══════════════════════════════════════════╝
+	//
+	// This method returns a typed nil-pointer if no options are present.
+	// The caller must import the descriptorpb package to use this.
+	Options() ProtoMessage
+
+	doNotImplement
+}
+
+// FileDescriptor describes the types in a complete proto file and
+// corresponds with the google.protobuf.FileDescriptorProto message.
+//
+// Top-level declarations:
+// EnumDescriptor, MessageDescriptor, FieldDescriptor, and/or ServiceDescriptor.
+type FileDescriptor interface {
+	Descriptor // Descriptor.FullName is identical to Package
+
+	// Path returns the file name, relative to the source tree root.
+	Path() string // e.g., "path/to/file.proto"
+	// Package returns the protobuf package namespace.
+	Package() FullName // e.g., "google.protobuf"
+
+	// Imports is a list of imported proto files.
+	Imports() FileImports
+
+	// Enums is a list of the top-level enum declarations.
+	Enums() EnumDescriptors
+	// Messages is a list of the top-level message declarations.
+	Messages() MessageDescriptors
+	// Extensions is a list of the top-level extension declarations.
+	Extensions() ExtensionDescriptors
+	// Services is a list of the top-level service declarations.
+	Services() ServiceDescriptors
+
+	// SourceLocations is a list of source locations.
+	SourceLocations() SourceLocations
+
+	isFileDescriptor
+}
+type isFileDescriptor interface{ ProtoType(FileDescriptor) }
+
+// FileImports is a list of file imports.
+type FileImports interface {
+	// Len reports the number of files imported by this proto file.
+	Len() int
+	// Get returns the ith FileImport. It panics if out of bounds.
+	Get(i int) FileImport
+
+	doNotImplement
+}
+
+// FileImport is the declaration for a proto file import.
+type FileImport struct {
+	// FileDescriptor is the file type for the given import.
+	// It is a placeholder descriptor if IsWeak is set or if a dependency has
+	// not been regenerated to implement the new reflection APIs.
+	FileDescriptor
+
+	// IsPublic reports whether this is a public import, which causes this file
+	// to alias declarations within the imported file. The intended use cases
+	// for this feature is the ability to move proto files without breaking
+	// existing dependencies.
+	//
+	// The current file and the imported file must be within proto package.
+	IsPublic bool
+
+	// IsWeak reports whether this is a weak import, which does not impose
+	// a direct dependency on the target file.
+	//
+	// Weak imports are a legacy proto1 feature. Equivalent behavior is
+	// achieved using proto2 extension fields or proto3 Any messages.
+	IsWeak bool
+}
+
+// MessageDescriptor describes a message and
+// corresponds with the google.protobuf.DescriptorProto message.
+//
+// Nested declarations:
+// FieldDescriptor, OneofDescriptor, FieldDescriptor, EnumDescriptor,
+// and/or MessageDescriptor.
+type MessageDescriptor interface {
+	Descriptor
+
+	// IsMapEntry indicates that this is an auto-generated message type to
+	// represent the entry type for a map field.
+	//
+	// Map entry messages have only two fields:
+	//	• a "key" field with a field number of 1
+	//	• a "value" field with a field number of 2
+	// The key and value types are determined by these two fields.
+	//
+	// If IsMapEntry is true, it implies that FieldDescriptor.IsMap is true
+	// for some field with this message type.
+	IsMapEntry() bool
+
+	// Fields is a list of nested field declarations.
+	Fields() FieldDescriptors
+	// Oneofs is a list of nested oneof declarations.
+	Oneofs() OneofDescriptors
+
+	// ReservedNames is a list of reserved field names.
+	ReservedNames() Names
+	// ReservedRanges is a list of reserved ranges of field numbers.
+	ReservedRanges() FieldRanges
+	// RequiredNumbers is a list of required field numbers.
+	// In Proto3, it is always an empty list.
+	RequiredNumbers() FieldNumbers
+	// ExtensionRanges is the field ranges used for extension fields.
+	// In Proto3, it is always an empty ranges.
+	ExtensionRanges() FieldRanges
+	// ExtensionRangeOptions returns the ith extension range options.
+	//
+	// To avoid a dependency cycle, this method returns a proto.Message value,
+	// which always contains a google.protobuf.ExtensionRangeOptions message.
+	// This method returns a typed nil-pointer if no options are present.
+	// The caller must import the descriptorpb package to use this.
+	ExtensionRangeOptions(i int) ProtoMessage
+
+	// Enums is a list of nested enum declarations.
+	Enums() EnumDescriptors
+	// Messages is a list of nested message declarations.
+	Messages() MessageDescriptors
+	// Extensions is a list of nested extension declarations.
+	Extensions() ExtensionDescriptors
+
+	isMessageDescriptor
+}
+type isMessageDescriptor interface{ ProtoType(MessageDescriptor) }
+
+// MessageType encapsulates a MessageDescriptor with a concrete Go implementation.
+type MessageType interface {
+	// New returns a newly allocated empty message.
+	New() Message
+
+	// Zero returns an empty, read-only message.
+	Zero() Message
+
+	// Descriptor returns the message descriptor.
+	//
+	// Invariant: t.Descriptor() == t.New().Descriptor()
+	Descriptor() MessageDescriptor
+}
+
+// MessageDescriptors is a list of message declarations.
+type MessageDescriptors interface {
+	// Len reports the number of messages.
+	Len() int
+	// Get returns the ith MessageDescriptor. It panics if out of bounds.
+	Get(i int) MessageDescriptor
+	// ByName returns the MessageDescriptor for a message named s.
+	// It returns nil if not found.
+	ByName(s Name) MessageDescriptor
+
+	doNotImplement
+}
+
+// FieldDescriptor describes a field within a message and
+// corresponds with the google.protobuf.FieldDescriptorProto message.
+//
+// It is used for both normal fields defined within the parent message
+// (e.g., MessageDescriptor.Fields) and fields that extend some remote message
+// (e.g., FileDescriptor.Extensions or MessageDescriptor.Extensions).
+type FieldDescriptor interface {
+	Descriptor
+
+	// Number reports the unique number for this field.
+	Number() FieldNumber
+	// Cardinality reports the cardinality for this field.
+	Cardinality() Cardinality
+	// Kind reports the basic kind for this field.
+	Kind() Kind
+
+	// HasJSONName reports whether this field has an explicitly set JSON name.
+	HasJSONName() bool
+
+	// JSONName reports the name used for JSON serialization.
+	// It is usually the camel-cased form of the field name.
+	JSONName() string
+
+	// IsExtension reports whether this is an extension field. If false,
+	// then Parent and ContainingMessage refer to the same message.
+	// Otherwise, ContainingMessage and Parent likely differ.
+	IsExtension() bool
+
+	// IsWeak reports whether this is a weak field, which does not impose a
+	// direct dependency on the target type.
+	// If true, then Message returns a placeholder type.
+	IsWeak() bool
+
+	// IsPacked reports whether repeated primitive numeric kinds should be
+	// serialized using a packed encoding.
+	// If true, then it implies Cardinality is Repeated.
+	IsPacked() bool
+
+	// IsList reports whether this field represents a list,
+	// where the value type for the associated field is a List.
+	// It is equivalent to checking whether Cardinality is Repeated and
+	// that IsMap reports false.
+	IsList() bool
+
+	// IsMap reports whether this field represents a map,
+	// where the value type for the associated field is a Map.
+	// It is equivalent to checking whether Cardinality is Repeated,
+	// that the Kind is MessageKind, and that Message.IsMapEntry reports true.
+	IsMap() bool
+
+	// MapKey returns the field descriptor for the key in the map entry.
+	// It returns nil if IsMap reports false.
+	MapKey() FieldDescriptor
+
+	// MapValue returns the field descriptor for the value in the map entry.
+	// It returns nil if IsMap reports false.
+	MapValue() FieldDescriptor
+
+	// HasDefault reports whether this field has a default value.
+	HasDefault() bool
+
+	// Default returns the default value for scalar fields.
+	// For proto2, it is the default value as specified in the proto file,
+	// or the zero value if unspecified.
+	// For proto3, it is always the zero value of the scalar.
+	// The Value type is determined by the Kind.
+	Default() Value
+
+	// DefaultEnumValue returns the enum value descriptor for the default value
+	// of an enum field, and is nil for any other kind of field.
+	DefaultEnumValue() EnumValueDescriptor
+
+	// ContainingOneof is the containing oneof that this field belongs to,
+	// and is nil if this field is not part of a oneof.
+	ContainingOneof() OneofDescriptor
+
+	// ContainingMessage is the containing message that this field belongs to.
+	// For extension fields, this may not necessarily be the parent message
+	// that the field is declared within.
+	ContainingMessage() MessageDescriptor
+
+	// Enum is the enum descriptor if Kind is EnumKind.
+	// It returns nil for any other Kind.
+	Enum() EnumDescriptor
+
+	// Message is the message descriptor if Kind is
+	// MessageKind or GroupKind. It returns nil for any other Kind.
+	Message() MessageDescriptor
+
+	isFieldDescriptor
+}
+type isFieldDescriptor interface{ ProtoType(FieldDescriptor) }
+
+// FieldDescriptors is a list of field declarations.
+type FieldDescriptors interface {
+	// Len reports the number of fields.
+	Len() int
+	// Get returns the ith FieldDescriptor. It panics if out of bounds.
+	Get(i int) FieldDescriptor
+	// ByName returns the FieldDescriptor for a field named s.
+	// It returns nil if not found.
+	ByName(s Name) FieldDescriptor
+	// ByJSONName returns the FieldDescriptor for a field with s as the JSON name.
+	// It returns nil if not found.
+	ByJSONName(s string) FieldDescriptor
+	// ByNumber returns the FieldDescriptor for a field numbered n.
+	// It returns nil if not found.
+	ByNumber(n FieldNumber) FieldDescriptor
+
+	doNotImplement
+}
+
+// OneofDescriptor describes a oneof field set within a given message and
+// corresponds with the google.protobuf.OneofDescriptorProto message.
+type OneofDescriptor interface {
+	Descriptor
+
+	// Fields is a list of fields belonging to this oneof.
+	Fields() FieldDescriptors
+
+	isOneofDescriptor
+}
+type isOneofDescriptor interface{ ProtoType(OneofDescriptor) }
+
+// OneofDescriptors is a list of oneof declarations.
+type OneofDescriptors interface {
+	// Len reports the number of oneof fields.
+	Len() int
+	// Get returns the ith OneofDescriptor. It panics if out of bounds.
+	Get(i int) OneofDescriptor
+	// ByName returns the OneofDescriptor for a oneof named s.
+	// It returns nil if not found.
+	ByName(s Name) OneofDescriptor
+
+	doNotImplement
+}
+
+// ExtensionDescriptor is an alias of FieldDescriptor for documentation.
+type ExtensionDescriptor = FieldDescriptor
+
+// ExtensionTypeDescriptor is an ExtensionDescriptor with an associated ExtensionType.
+type ExtensionTypeDescriptor interface {
+	ExtensionDescriptor
+
+	// Type returns the associated ExtensionType.
+	Type() ExtensionType
+
+	// Descriptor returns the plain ExtensionDescriptor without the
+	// associated ExtensionType.
+	Descriptor() ExtensionDescriptor
+}
+
+// ExtensionDescriptors is a list of field declarations.
+type ExtensionDescriptors interface {
+	// Len reports the number of fields.
+	Len() int
+	// Get returns the ith ExtensionDescriptor. It panics if out of bounds.
+	Get(i int) ExtensionDescriptor
+	// ByName returns the ExtensionDescriptor for a field named s.
+	// It returns nil if not found.
+	ByName(s Name) ExtensionDescriptor
+
+	doNotImplement
+}
+
+// ExtensionType encapsulates an ExtensionDescriptor with a concrete
+// Go implementation. The nested field descriptor must be for a extension field.
+//
+// While a normal field is a member of the parent message that it is declared
+// within (see Descriptor.Parent), an extension field is a member of some other
+// target message (see ExtensionDescriptor.Extendee) and may have no
+// relationship with the parent. However, the full name of an extension field is
+// relative to the parent that it is declared within.
+//
+// For example:
+//	syntax = "proto2";
+//	package example;
+//	message FooMessage {
+//		extensions 100 to max;
+//	}
+//	message BarMessage {
+//		extends FooMessage { optional BarMessage bar_field = 100; }
+//	}
+//
+// Field "bar_field" is an extension of FooMessage, but its full name is
+// "example.BarMessage.bar_field" instead of "example.FooMessage.bar_field".
+type ExtensionType interface {
+	// New returns a new value for the field.
+	// For scalars, this returns the default value in native Go form.
+	New() Value
+
+	// Zero returns a new value for the field.
+	// For scalars, this returns the default value in native Go form.
+	// For composite types, this returns an empty, read-only message, list, or map.
+	Zero() Value
+
+	// TypeDescriptor returns the extension type descriptor.
+	TypeDescriptor() ExtensionTypeDescriptor
+
+	// ValueOf wraps the input and returns it as a Value.
+	// ValueOf panics if the input value is invalid or not the appropriate type.
+	//
+	// ValueOf is more extensive than protoreflect.ValueOf for a given field's
+	// value as it has more type information available.
+	ValueOf(interface{}) Value
+
+	// InterfaceOf completely unwraps the Value to the underlying Go type.
+	// InterfaceOf panics if the input is nil or does not represent the
+	// appropriate underlying Go type. For composite types, it panics if the
+	// value is not mutable.
+	//
+	// InterfaceOf is able to unwrap the Value further than Value.Interface
+	// as it has more type information available.
+	InterfaceOf(Value) interface{}
+
+	// IsValidValue reports whether the Value is valid to assign to the field.
+	IsValidValue(Value) bool
+
+	// IsValidInterface reports whether the input is valid to assign to the field.
+	IsValidInterface(interface{}) bool
+}
+
+// EnumDescriptor describes an enum and
+// corresponds with the google.protobuf.EnumDescriptorProto message.
+//
+// Nested declarations:
+// EnumValueDescriptor.
+type EnumDescriptor interface {
+	Descriptor
+
+	// Values is a list of nested enum value declarations.
+	Values() EnumValueDescriptors
+
+	// ReservedNames is a list of reserved enum names.
+	ReservedNames() Names
+	// ReservedRanges is a list of reserved ranges of enum numbers.
+	ReservedRanges() EnumRanges
+
+	isEnumDescriptor
+}
+type isEnumDescriptor interface{ ProtoType(EnumDescriptor) }
+
+// EnumType encapsulates an EnumDescriptor with a concrete Go implementation.
+type EnumType interface {
+	// New returns an instance of this enum type with its value set to n.
+	New(n EnumNumber) Enum
+
+	// Descriptor returns the enum descriptor.
+	//
+	// Invariant: t.Descriptor() == t.New(0).Descriptor()
+	Descriptor() EnumDescriptor
+}
+
+// EnumDescriptors is a list of enum declarations.
+type EnumDescriptors interface {
+	// Len reports the number of enum types.
+	Len() int
+	// Get returns the ith EnumDescriptor. It panics if out of bounds.
+	Get(i int) EnumDescriptor
+	// ByName returns the EnumDescriptor for an enum named s.
+	// It returns nil if not found.
+	ByName(s Name) EnumDescriptor
+
+	doNotImplement
+}
+
+// EnumValueDescriptor describes an enum value and
+// corresponds with the google.protobuf.EnumValueDescriptorProto message.
+//
+// All other proto declarations are in the namespace of the parent.
+// However, enum values do not follow this rule and are within the namespace
+// of the parent's parent (i.e., they are a sibling of the containing enum).
+// Thus, a value named "FOO_VALUE" declared within an enum uniquely identified
+// as "proto.package.MyEnum" has a full name of "proto.package.FOO_VALUE".
+type EnumValueDescriptor interface {
+	Descriptor
+
+	// Number returns the enum value as an integer.
+	Number() EnumNumber
+
+	isEnumValueDescriptor
+}
+type isEnumValueDescriptor interface{ ProtoType(EnumValueDescriptor) }
+
+// EnumValueDescriptors is a list of enum value declarations.
+type EnumValueDescriptors interface {
+	// Len reports the number of enum values.
+	Len() int
+	// Get returns the ith EnumValueDescriptor. It panics if out of bounds.
+	Get(i int) EnumValueDescriptor
+	// ByName returns the EnumValueDescriptor for the enum value named s.
+	// It returns nil if not found.
+	ByName(s Name) EnumValueDescriptor
+	// ByNumber returns the EnumValueDescriptor for the enum value numbered n.
+	// If multiple have the same number, the first one defined is returned
+	// It returns nil if not found.
+	ByNumber(n EnumNumber) EnumValueDescriptor
+
+	doNotImplement
+}
+
+// ServiceDescriptor describes a service and
+// corresponds with the google.protobuf.ServiceDescriptorProto message.
+//
+// Nested declarations: MethodDescriptor.
+type ServiceDescriptor interface {
+	Descriptor
+
+	// Methods is a list of nested message declarations.
+	Methods() MethodDescriptors
+
+	isServiceDescriptor
+}
+type isServiceDescriptor interface{ ProtoType(ServiceDescriptor) }
+
+// ServiceDescriptors is a list of service declarations.
+type ServiceDescriptors interface {
+	// Len reports the number of services.
+	Len() int
+	// Get returns the ith ServiceDescriptor. It panics if out of bounds.
+	Get(i int) ServiceDescriptor
+	// ByName returns the ServiceDescriptor for a service named s.
+	// It returns nil if not found.
+	ByName(s Name) ServiceDescriptor
+
+	doNotImplement
+}
+
+// MethodDescriptor describes a method and
+// corresponds with the google.protobuf.MethodDescriptorProto message.
+type MethodDescriptor interface {
+	Descriptor
+
+	// Input is the input message descriptor.
+	Input() MessageDescriptor
+	// Output is the output message descriptor.
+	Output() MessageDescriptor
+	// IsStreamingClient reports whether the client streams multiple messages.
+	IsStreamingClient() bool
+	// IsStreamingServer reports whether the server streams multiple messages.
+	IsStreamingServer() bool
+
+	isMethodDescriptor
+}
+type isMethodDescriptor interface{ ProtoType(MethodDescriptor) }
+
+// MethodDescriptors is a list of method declarations.
+type MethodDescriptors interface {
+	// Len reports the number of methods.
+	Len() int
+	// Get returns the ith MethodDescriptor. It panics if out of bounds.
+	Get(i int) MethodDescriptor
+	// ByName returns the MethodDescriptor for a service method named s.
+	// It returns nil if not found.
+	ByName(s Name) MethodDescriptor
+
+	doNotImplement
+}
diff --git a/demo_test/vendor/google.golang.org/protobuf/reflect/protoreflect/value.go b/demo_test/vendor/google.golang.org/protobuf/reflect/protoreflect/value.go
new file mode 100644
index 0000000..a352ed9
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/reflect/protoreflect/value.go
@@ -0,0 +1,285 @@
+// 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 protoreflect
+
+import "google.golang.org/protobuf/encoding/protowire"
+
+// Enum is a reflection interface for a concrete enum value,
+// which provides type information and a getter for the enum number.
+// Enum does not provide a mutable API since enums are commonly backed by
+// Go constants, which are not addressable.
+type Enum interface {
+	// Descriptor returns enum descriptor, which contains only the protobuf
+	// type information for the enum.
+	Descriptor() EnumDescriptor
+
+	// Type returns the enum type, which encapsulates both Go and protobuf
+	// type information. If the Go type information is not needed,
+	// it is recommended that the enum descriptor be used instead.
+	Type() EnumType
+
+	// Number returns the enum value as an integer.
+	Number() EnumNumber
+}
+
+// Message is a reflective interface for a concrete message value,
+// encapsulating both type and value information for the message.
+//
+// Accessor/mutators for individual fields are keyed by FieldDescriptor.
+// For non-extension fields, the descriptor must exactly match the
+// field known by the parent message.
+// For extension fields, the descriptor must implement ExtensionTypeDescriptor,
+// extend the parent message (i.e., have the same message FullName), and
+// be within the parent's extension range.
+//
+// Each field Value can be a scalar or a composite type (Message, List, or Map).
+// See Value for the Go types associated with a FieldDescriptor.
+// Providing a Value that is invalid or of an incorrect type panics.
+type Message interface {
+	// Descriptor returns message descriptor, which contains only the protobuf
+	// type information for the message.
+	Descriptor() MessageDescriptor
+
+	// Type returns the message type, which encapsulates both Go and protobuf
+	// type information. If the Go type information is not needed,
+	// it is recommended that the message descriptor be used instead.
+	Type() MessageType
+
+	// New returns a newly allocated and mutable empty message.
+	New() Message
+
+	// Interface unwraps the message reflection interface and
+	// returns the underlying ProtoMessage interface.
+	Interface() ProtoMessage
+
+	// Range iterates over every populated field in an undefined order,
+	// calling f for each field descriptor and value encountered.
+	// Range returns immediately if f returns false.
+	// While iterating, mutating operations may only be performed
+	// on the current field descriptor.
+	Range(f func(FieldDescriptor, Value) bool)
+
+	// Has reports whether a field is populated.
+	//
+	// Some fields have the property of nullability where it is possible to
+	// distinguish between the default value of a field and whether the field
+	// was explicitly populated with the default value. Singular message fields,
+	// member fields of a oneof, and proto2 scalar fields are nullable. Such
+	// fields are populated only if explicitly set.
+	//
+	// In other cases (aside from the nullable cases above),
+	// a proto3 scalar field is populated if it contains a non-zero value, and
+	// a repeated field is populated if it is non-empty.
+	Has(FieldDescriptor) bool
+
+	// Clear clears the field such that a subsequent Has call reports false.
+	//
+	// Clearing an extension field clears both the extension type and value
+	// associated with the given field number.
+	//
+	// Clear is a mutating operation and unsafe for concurrent use.
+	Clear(FieldDescriptor)
+
+	// Get retrieves the value for a field.
+	//
+	// For unpopulated scalars, it returns the default value, where
+	// the default value of a bytes scalar is guaranteed to be a copy.
+	// For unpopulated composite types, it returns an empty, read-only view
+	// of the value; to obtain a mutable reference, use Mutable.
+	Get(FieldDescriptor) Value
+
+	// Set stores the value for a field.
+	//
+	// For a field belonging to a oneof, it implicitly clears any other field
+	// that may be currently set within the same oneof.
+	// For extension fields, it implicitly stores the provided ExtensionType.
+	// When setting a composite type, it is unspecified whether the stored value
+	// aliases the source's memory in any way. If the composite value is an
+	// empty, read-only value, then it panics.
+	//
+	// Set is a mutating operation and unsafe for concurrent use.
+	Set(FieldDescriptor, Value)
+
+	// Mutable returns a mutable reference to a composite type.
+	//
+	// If the field is unpopulated, it may allocate a composite value.
+	// For a field belonging to a oneof, it implicitly clears any other field
+	// that may be currently set within the same oneof.
+	// For extension fields, it implicitly stores the provided ExtensionType
+	// if not already stored.
+	// It panics if the field does not contain a composite type.
+	//
+	// Mutable is a mutating operation and unsafe for concurrent use.
+	Mutable(FieldDescriptor) Value
+
+	// NewField returns a new value for assignable to the field of a given descriptor.
+	// For scalars, this returns the default value.
+	// For lists, maps, and messages, this returns a new, empty, mutable value.
+	NewField(FieldDescriptor) Value
+
+	// WhichOneof reports which field within the oneof is populated,
+	// returning nil if none are populated.
+	// It panics if the oneof descriptor does not belong to this message.
+	WhichOneof(OneofDescriptor) FieldDescriptor
+
+	// GetUnknown retrieves the entire list of unknown fields.
+	// The caller may only mutate the contents of the RawFields
+	// if the mutated bytes are stored back into the message with SetUnknown.
+	GetUnknown() RawFields
+
+	// SetUnknown stores an entire list of unknown fields.
+	// The raw fields must be syntactically valid according to the wire format.
+	// An implementation may panic if this is not the case.
+	// Once stored, the caller must not mutate the content of the RawFields.
+	// An empty RawFields may be passed to clear the fields.
+	//
+	// SetUnknown is a mutating operation and unsafe for concurrent use.
+	SetUnknown(RawFields)
+
+	// IsValid reports whether the message is valid.
+	//
+	// An invalid message is an empty, read-only value.
+	//
+	// An invalid message often corresponds to a nil pointer of the concrete
+	// message type, but the details are implementation dependent.
+	// Validity is not part of the protobuf data model, and may not
+	// be preserved in marshaling or other operations.
+	IsValid() bool
+
+	// ProtoMethods returns optional fast-path implementions of various operations.
+	// This method may return nil.
+	//
+	// The returned methods type is identical to
+	// "google.golang.org/protobuf/runtime/protoiface".Methods.
+	// Consult the protoiface package documentation for details.
+	ProtoMethods() *methods
+}
+
+// RawFields is the raw bytes for an ordered sequence of fields.
+// Each field contains both the tag (representing field number and wire type),
+// and also the wire data itself.
+type RawFields []byte
+
+// IsValid reports whether b is syntactically correct wire format.
+func (b RawFields) IsValid() bool {
+	for len(b) > 0 {
+		_, _, n := protowire.ConsumeField(b)
+		if n < 0 {
+			return false
+		}
+		b = b[n:]
+	}
+	return true
+}
+
+// List is a zero-indexed, ordered list.
+// The element Value type is determined by FieldDescriptor.Kind.
+// Providing a Value that is invalid or of an incorrect type panics.
+type List interface {
+	// Len reports the number of entries in the List.
+	// Get, Set, and Truncate panic with out of bound indexes.
+	Len() int
+
+	// Get retrieves the value at the given index.
+	// It never returns an invalid value.
+	Get(int) Value
+
+	// Set stores a value for the given index.
+	// When setting a composite type, it is unspecified whether the set
+	// value aliases the source's memory in any way.
+	//
+	// Set is a mutating operation and unsafe for concurrent use.
+	Set(int, Value)
+
+	// Append appends the provided value to the end of the list.
+	// When appending a composite type, it is unspecified whether the appended
+	// value aliases the source's memory in any way.
+	//
+	// Append is a mutating operation and unsafe for concurrent use.
+	Append(Value)
+
+	// AppendMutable appends a new, empty, mutable message value to the end
+	// of the list and returns it.
+	// It panics if the list does not contain a message type.
+	AppendMutable() Value
+
+	// Truncate truncates the list to a smaller length.
+	//
+	// Truncate is a mutating operation and unsafe for concurrent use.
+	Truncate(int)
+
+	// NewElement returns a new value for a list element.
+	// For enums, this returns the first enum value.
+	// For other scalars, this returns the zero value.
+	// For messages, this returns a new, empty, mutable value.
+	NewElement() Value
+
+	// IsValid reports whether the list is valid.
+	//
+	// An invalid list is an empty, read-only value.
+	//
+	// Validity is not part of the protobuf data model, and may not
+	// be preserved in marshaling or other operations.
+	IsValid() bool
+}
+
+// Map is an unordered, associative map.
+// The entry MapKey type is determined by FieldDescriptor.MapKey.Kind.
+// The entry Value type is determined by FieldDescriptor.MapValue.Kind.
+// Providing a MapKey or Value that is invalid or of an incorrect type panics.
+type Map interface {
+	// Len reports the number of elements in the map.
+	Len() int
+
+	// Range iterates over every map entry in an undefined order,
+	// calling f for each key and value encountered.
+	// Range calls f Len times unless f returns false, which stops iteration.
+	// While iterating, mutating operations may only be performed
+	// on the current map key.
+	Range(f func(MapKey, Value) bool)
+
+	// Has reports whether an entry with the given key is in the map.
+	Has(MapKey) bool
+
+	// Clear clears the entry associated with they given key.
+	// The operation does nothing if there is no entry associated with the key.
+	//
+	// Clear is a mutating operation and unsafe for concurrent use.
+	Clear(MapKey)
+
+	// Get retrieves the value for an entry with the given key.
+	// It returns an invalid value for non-existent entries.
+	Get(MapKey) Value
+
+	// Set stores the value for an entry with the given key.
+	// It panics when given a key or value that is invalid or the wrong type.
+	// When setting a composite type, it is unspecified whether the set
+	// value aliases the source's memory in any way.
+	//
+	// Set is a mutating operation and unsafe for concurrent use.
+	Set(MapKey, Value)
+
+	// Mutable retrieves a mutable reference to the entry for the given key.
+	// If no entry exists for the key, it creates a new, empty, mutable value
+	// and stores it as the entry for the key.
+	// It panics if the map value is not a message.
+	Mutable(MapKey) Value
+
+	// NewValue returns a new value assignable as a map value.
+	// For enums, this returns the first enum value.
+	// For other scalars, this returns the zero value.
+	// For messages, this returns a new, empty, mutable value.
+	NewValue() Value
+
+	// IsValid reports whether the map is valid.
+	//
+	// An invalid map is an empty, read-only value.
+	//
+	// An invalid message often corresponds to a nil Go map value,
+	// but the details are implementation dependent.
+	// Validity is not part of the protobuf data model, and may not
+	// be preserved in marshaling or other operations.
+	IsValid() bool
+}
diff --git a/demo_test/vendor/google.golang.org/protobuf/reflect/protoreflect/value_pure.go b/demo_test/vendor/google.golang.org/protobuf/reflect/protoreflect/value_pure.go
new file mode 100644
index 0000000..918e685
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/reflect/protoreflect/value_pure.go
@@ -0,0 +1,59 @@
+// 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 protoreflect
+
+import "google.golang.org/protobuf/internal/pragma"
+
+type valueType int
+
+const (
+	nilType valueType = iota
+	boolType
+	int32Type
+	int64Type
+	uint32Type
+	uint64Type
+	float32Type
+	float64Type
+	stringType
+	bytesType
+	enumType
+	ifaceType
+)
+
+// value is a union where only one type can be represented at a time.
+// This uses a distinct field for each type. This is type safe in Go, but
+// occupies more memory than necessary (72B).
+type value struct {
+	pragma.DoNotCompare // 0B
+
+	typ   valueType   // 8B
+	num   uint64      // 8B
+	str   string      // 16B
+	bin   []byte      // 24B
+	iface interface{} // 16B
+}
+
+func valueOfString(v string) Value {
+	return Value{typ: stringType, str: v}
+}
+func valueOfBytes(v []byte) Value {
+	return Value{typ: bytesType, bin: v}
+}
+func valueOfIface(v interface{}) Value {
+	return Value{typ: ifaceType, iface: v}
+}
+
+func (v Value) getString() string {
+	return v.str
+}
+func (v Value) getBytes() []byte {
+	return v.bin
+}
+func (v Value) getIface() interface{} {
+	return v.iface
+}
diff --git a/demo_test/vendor/google.golang.org/protobuf/reflect/protoreflect/value_union.go b/demo_test/vendor/google.golang.org/protobuf/reflect/protoreflect/value_union.go
new file mode 100644
index 0000000..d695a4d
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/reflect/protoreflect/value_union.go
@@ -0,0 +1,367 @@
+// 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 protoreflect
+
+import (
+	"fmt"
+	"math"
+	"reflect"
+)
+
+// Value is a union where only one Go type may be set at a time.
+// The Value is used to represent all possible values a field may take.
+// The following shows which Go type is used to represent each proto Kind:
+//
+//	╔════════════╤═════════════════════════════════════╗
+//	║ Go type    │ Protobuf kind                       ║
+//	╠════════════╪═════════════════════════════════════╣
+//	║ bool       │ BoolKind                            ║
+//	║ int32      │ Int32Kind, Sint32Kind, Sfixed32Kind ║
+//	║ int64      │ Int64Kind, Sint64Kind, Sfixed64Kind ║
+//	║ uint32     │ Uint32Kind, Fixed32Kind             ║
+//	║ uint64     │ Uint64Kind, Fixed64Kind             ║
+//	║ float32    │ FloatKind                           ║
+//	║ float64    │ DoubleKind                          ║
+//	║ string     │ StringKind                          ║
+//	║ []byte     │ BytesKind                           ║
+//	║ EnumNumber │ EnumKind                            ║
+//	║ Message    │ MessageKind, GroupKind              ║
+//	╚════════════╧═════════════════════════════════════╝
+//
+// Multiple protobuf Kinds may be represented by a single Go type if the type
+// can losslessly represent the information for the proto kind. For example,
+// Int64Kind, Sint64Kind, and Sfixed64Kind are all represented by int64,
+// but use different integer encoding methods.
+//
+// The List or Map types are used if the field cardinality is repeated.
+// A field is a List if FieldDescriptor.IsList reports true.
+// A field is a Map if FieldDescriptor.IsMap reports true.
+//
+// Converting to/from a Value and a concrete Go value panics on type mismatch.
+// For example, ValueOf("hello").Int() panics because this attempts to
+// retrieve an int64 from a string.
+type Value value
+
+// The protoreflect API uses a custom Value union type instead of interface{}
+// to keep the future open for performance optimizations. Using an interface{}
+// always incurs an allocation for primitives (e.g., int64) since it needs to
+// be boxed on the heap (as interfaces can only contain pointers natively).
+// Instead, we represent the Value union as a flat struct that internally keeps
+// track of which type is set. Using unsafe, the Value union can be reduced
+// down to 24B, which is identical in size to a slice.
+//
+// The latest compiler (Go1.11) currently suffers from some limitations:
+//	• With inlining, the compiler should be able to statically prove that
+//	only one of these switch cases are taken and inline one specific case.
+//	See https://golang.org/issue/22310.
+
+// ValueOf returns a Value initialized with the concrete value stored in v.
+// This panics if the type does not match one of the allowed types in the
+// Value union.
+func ValueOf(v interface{}) Value {
+	switch v := v.(type) {
+	case nil:
+		return Value{}
+	case bool:
+		return ValueOfBool(v)
+	case int32:
+		return ValueOfInt32(v)
+	case int64:
+		return ValueOfInt64(v)
+	case uint32:
+		return ValueOfUint32(v)
+	case uint64:
+		return ValueOfUint64(v)
+	case float32:
+		return ValueOfFloat32(v)
+	case float64:
+		return ValueOfFloat64(v)
+	case string:
+		return ValueOfString(v)
+	case []byte:
+		return ValueOfBytes(v)
+	case EnumNumber:
+		return ValueOfEnum(v)
+	case Message, List, Map:
+		return valueOfIface(v)
+	default:
+		panic(fmt.Sprintf("invalid type: %v", reflect.TypeOf(v)))
+	}
+}
+
+// ValueOfBool returns a new boolean value.
+func ValueOfBool(v bool) Value {
+	if v {
+		return Value{typ: boolType, num: 1}
+	} else {
+		return Value{typ: boolType, num: 0}
+	}
+}
+
+// ValueOfInt32 returns a new int32 value.
+func ValueOfInt32(v int32) Value {
+	return Value{typ: int32Type, num: uint64(v)}
+}
+
+// ValueOfInt64 returns a new int64 value.
+func ValueOfInt64(v int64) Value {
+	return Value{typ: int64Type, num: uint64(v)}
+}
+
+// ValueOfUint32 returns a new uint32 value.
+func ValueOfUint32(v uint32) Value {
+	return Value{typ: uint32Type, num: uint64(v)}
+}
+
+// ValueOfUint64 returns a new uint64 value.
+func ValueOfUint64(v uint64) Value {
+	return Value{typ: uint64Type, num: v}
+}
+
+// ValueOfFloat32 returns a new float32 value.
+func ValueOfFloat32(v float32) Value {
+	return Value{typ: float32Type, num: uint64(math.Float64bits(float64(v)))}
+}
+
+// ValueOfFloat64 returns a new float64 value.
+func ValueOfFloat64(v float64) Value {
+	return Value{typ: float64Type, num: uint64(math.Float64bits(float64(v)))}
+}
+
+// ValueOfString returns a new string value.
+func ValueOfString(v string) Value {
+	return valueOfString(v)
+}
+
+// ValueOfBytes returns a new bytes value.
+func ValueOfBytes(v []byte) Value {
+	return valueOfBytes(v[:len(v):len(v)])
+}
+
+// ValueOfEnum returns a new enum value.
+func ValueOfEnum(v EnumNumber) Value {
+	return Value{typ: enumType, num: uint64(v)}
+}
+
+// ValueOfMessage returns a new Message value.
+func ValueOfMessage(v Message) Value {
+	return valueOfIface(v)
+}
+
+// ValueOfList returns a new List value.
+func ValueOfList(v List) Value {
+	return valueOfIface(v)
+}
+
+// ValueOfMap returns a new Map value.
+func ValueOfMap(v Map) Value {
+	return valueOfIface(v)
+}
+
+// IsValid reports whether v is populated with a value.
+func (v Value) IsValid() bool {
+	return v.typ != nilType
+}
+
+// Interface returns v as an interface{}.
+//
+// Invariant: v == ValueOf(v).Interface()
+func (v Value) Interface() interface{} {
+	switch v.typ {
+	case nilType:
+		return nil
+	case boolType:
+		return v.Bool()
+	case int32Type:
+		return int32(v.Int())
+	case int64Type:
+		return int64(v.Int())
+	case uint32Type:
+		return uint32(v.Uint())
+	case uint64Type:
+		return uint64(v.Uint())
+	case float32Type:
+		return float32(v.Float())
+	case float64Type:
+		return float64(v.Float())
+	case stringType:
+		return v.String()
+	case bytesType:
+		return v.Bytes()
+	case enumType:
+		return v.Enum()
+	default:
+		return v.getIface()
+	}
+}
+
+// Bool returns v as a bool and panics if the type is not a bool.
+func (v Value) Bool() bool {
+	switch v.typ {
+	case boolType:
+		return v.num > 0
+	default:
+		panic("proto: value type mismatch")
+	}
+}
+
+// Int returns v as a int64 and panics if the type is not a int32 or int64.
+func (v Value) Int() int64 {
+	switch v.typ {
+	case int32Type, int64Type:
+		return int64(v.num)
+	default:
+		panic("proto: value type mismatch")
+	}
+}
+
+// Uint returns v as a uint64 and panics if the type is not a uint32 or uint64.
+func (v Value) Uint() uint64 {
+	switch v.typ {
+	case uint32Type, uint64Type:
+		return uint64(v.num)
+	default:
+		panic("proto: value type mismatch")
+	}
+}
+
+// Float returns v as a float64 and panics if the type is not a float32 or float64.
+func (v Value) Float() float64 {
+	switch v.typ {
+	case float32Type, float64Type:
+		return math.Float64frombits(uint64(v.num))
+	default:
+		panic("proto: value type mismatch")
+	}
+}
+
+// String returns v as a string. Since this method implements fmt.Stringer,
+// this returns the formatted string value for any non-string type.
+func (v Value) String() string {
+	switch v.typ {
+	case stringType:
+		return v.getString()
+	default:
+		return fmt.Sprint(v.Interface())
+	}
+}
+
+// Bytes returns v as a []byte and panics if the type is not a []byte.
+func (v Value) Bytes() []byte {
+	switch v.typ {
+	case bytesType:
+		return v.getBytes()
+	default:
+		panic("proto: value type mismatch")
+	}
+}
+
+// Enum returns v as a EnumNumber and panics if the type is not a EnumNumber.
+func (v Value) Enum() EnumNumber {
+	switch v.typ {
+	case enumType:
+		return EnumNumber(v.num)
+	default:
+		panic("proto: value type mismatch")
+	}
+}
+
+// Message returns v as a Message and panics if the type is not a Message.
+func (v Value) Message() Message {
+	switch v := v.getIface().(type) {
+	case Message:
+		return v
+	default:
+		panic("proto: value type mismatch")
+	}
+}
+
+// List returns v as a List and panics if the type is not a List.
+func (v Value) List() List {
+	switch v := v.getIface().(type) {
+	case List:
+		return v
+	default:
+		panic("proto: value type mismatch")
+	}
+}
+
+// Map returns v as a Map and panics if the type is not a Map.
+func (v Value) Map() Map {
+	switch v := v.getIface().(type) {
+	case Map:
+		return v
+	default:
+		panic("proto: value type mismatch")
+	}
+}
+
+// MapKey returns v as a MapKey and panics for invalid MapKey types.
+func (v Value) MapKey() MapKey {
+	switch v.typ {
+	case boolType, int32Type, int64Type, uint32Type, uint64Type, stringType:
+		return MapKey(v)
+	}
+	panic("proto: invalid map key type")
+}
+
+// MapKey is used to index maps, where the Go type of the MapKey must match
+// the specified key Kind (see MessageDescriptor.IsMapEntry).
+// The following shows what Go type is used to represent each proto Kind:
+//
+//	╔═════════╤═════════════════════════════════════╗
+//	║ Go type │ Protobuf kind                       ║
+//	╠═════════╪═════════════════════════════════════╣
+//	║ bool    │ BoolKind                            ║
+//	║ int32   │ Int32Kind, Sint32Kind, Sfixed32Kind ║
+//	║ int64   │ Int64Kind, Sint64Kind, Sfixed64Kind ║
+//	║ uint32  │ Uint32Kind, Fixed32Kind             ║
+//	║ uint64  │ Uint64Kind, Fixed64Kind             ║
+//	║ string  │ StringKind                          ║
+//	╚═════════╧═════════════════════════════════════╝
+//
+// A MapKey is constructed and accessed through a Value:
+//	k := ValueOf("hash").MapKey() // convert string to MapKey
+//	s := k.String()               // convert MapKey to string
+//
+// The MapKey is a strict subset of valid types used in Value;
+// converting a Value to a MapKey with an invalid type panics.
+type MapKey value
+
+// IsValid reports whether k is populated with a value.
+func (k MapKey) IsValid() bool {
+	return Value(k).IsValid()
+}
+
+// Interface returns k as an interface{}.
+func (k MapKey) Interface() interface{} {
+	return Value(k).Interface()
+}
+
+// Bool returns k as a bool and panics if the type is not a bool.
+func (k MapKey) Bool() bool {
+	return Value(k).Bool()
+}
+
+// Int returns k as a int64 and panics if the type is not a int32 or int64.
+func (k MapKey) Int() int64 {
+	return Value(k).Int()
+}
+
+// Uint returns k as a uint64 and panics if the type is not a uint32 or uint64.
+func (k MapKey) Uint() uint64 {
+	return Value(k).Uint()
+}
+
+// String returns k as a string. Since this method implements fmt.Stringer,
+// this returns the formatted string value for any non-string type.
+func (k MapKey) String() string {
+	return Value(k).String()
+}
+
+// Value returns k as a Value.
+func (k MapKey) Value() Value {
+	return Value(k)
+}
diff --git a/demo_test/vendor/google.golang.org/protobuf/reflect/protoreflect/value_unsafe.go b/demo_test/vendor/google.golang.org/protobuf/reflect/protoreflect/value_unsafe.go
new file mode 100644
index 0000000..c45debd
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/reflect/protoreflect/value_unsafe.go
@@ -0,0 +1,98 @@
+// 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 protoreflect
+
+import (
+	"unsafe"
+
+	"google.golang.org/protobuf/internal/pragma"
+)
+
+type (
+	stringHeader struct {
+		Data unsafe.Pointer
+		Len  int
+	}
+	sliceHeader struct {
+		Data unsafe.Pointer
+		Len  int
+		Cap  int
+	}
+	ifaceHeader struct {
+		Type unsafe.Pointer
+		Data unsafe.Pointer
+	}
+)
+
+var (
+	nilType     = typeOf(nil)
+	boolType    = typeOf(*new(bool))
+	int32Type   = typeOf(*new(int32))
+	int64Type   = typeOf(*new(int64))
+	uint32Type  = typeOf(*new(uint32))
+	uint64Type  = typeOf(*new(uint64))
+	float32Type = typeOf(*new(float32))
+	float64Type = typeOf(*new(float64))
+	stringType  = typeOf(*new(string))
+	bytesType   = typeOf(*new([]byte))
+	enumType    = typeOf(*new(EnumNumber))
+)
+
+// typeOf returns a pointer to the Go type information.
+// The pointer is comparable and equal if and only if the types are identical.
+func typeOf(t interface{}) unsafe.Pointer {
+	return (*ifaceHeader)(unsafe.Pointer(&t)).Type
+}
+
+// value is a union where only one type can be represented at a time.
+// The struct is 24B large on 64-bit systems and requires the minimum storage
+// necessary to represent each possible type.
+//
+// The Go GC needs to be able to scan variables containing pointers.
+// As such, pointers and non-pointers cannot be intermixed.
+type value struct {
+	pragma.DoNotCompare // 0B
+
+	// typ stores the type of the value as a pointer to the Go type.
+	typ unsafe.Pointer // 8B
+
+	// ptr stores the data pointer for a String, Bytes, or interface value.
+	ptr unsafe.Pointer // 8B
+
+	// num stores a Bool, Int32, Int64, Uint32, Uint64, Float32, Float64, or
+	// Enum value as a raw uint64.
+	//
+	// It is also used to store the length of a String or Bytes value;
+	// the capacity is ignored.
+	num uint64 // 8B
+}
+
+func valueOfString(v string) Value {
+	p := (*stringHeader)(unsafe.Pointer(&v))
+	return Value{typ: stringType, ptr: p.Data, num: uint64(len(v))}
+}
+func valueOfBytes(v []byte) Value {
+	p := (*sliceHeader)(unsafe.Pointer(&v))
+	return Value{typ: bytesType, ptr: p.Data, num: uint64(len(v))}
+}
+func valueOfIface(v interface{}) Value {
+	p := (*ifaceHeader)(unsafe.Pointer(&v))
+	return Value{typ: p.Type, ptr: p.Data}
+}
+
+func (v Value) getString() (x string) {
+	*(*stringHeader)(unsafe.Pointer(&x)) = stringHeader{Data: v.ptr, Len: int(v.num)}
+	return x
+}
+func (v Value) getBytes() (x []byte) {
+	*(*sliceHeader)(unsafe.Pointer(&x)) = sliceHeader{Data: v.ptr, Len: int(v.num), Cap: int(v.num)}
+	return x
+}
+func (v Value) getIface() (x interface{}) {
+	*(*ifaceHeader)(unsafe.Pointer(&x)) = ifaceHeader{Type: v.typ, Data: v.ptr}
+	return x
+}
diff --git a/demo_test/vendor/google.golang.org/protobuf/reflect/protoregistry/registry.go b/demo_test/vendor/google.golang.org/protobuf/reflect/protoregistry/registry.go
new file mode 100644
index 0000000..43f16c6
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/reflect/protoregistry/registry.go
@@ -0,0 +1,768 @@
+// 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 protoregistry provides data structures to register and lookup
+// protobuf descriptor types.
+//
+// The Files registry contains file descriptors and provides the ability
+// to iterate over the files or lookup a specific descriptor within the files.
+// Files only contains protobuf descriptors and has no understanding of Go
+// type information that may be associated with each descriptor.
+//
+// The Types registry contains descriptor types for which there is a known
+// Go type associated with that descriptor. It provides the ability to iterate
+// over the registered types or lookup a type by name.
+package protoregistry
+
+import (
+	"fmt"
+	"log"
+	"strings"
+	"sync"
+
+	"google.golang.org/protobuf/internal/errors"
+	"google.golang.org/protobuf/reflect/protoreflect"
+)
+
+// ignoreConflict reports whether to ignore a registration conflict
+// given the descriptor being registered and the error.
+// It is a variable so that the behavior is easily overridden in another file.
+var ignoreConflict = func(d protoreflect.Descriptor, err error) bool {
+	log.Printf(""+
+		"WARNING: %v\n"+
+		"A future release will panic on registration conflicts. See:\n"+
+		"https://developers.google.com/protocol-buffers/docs/reference/go/faq#namespace-conflict\n"+
+		"\n", err)
+	return true
+}
+
+var globalMutex sync.RWMutex
+
+// GlobalFiles is a global registry of file descriptors.
+var GlobalFiles *Files = new(Files)
+
+// GlobalTypes is the registry used by default for type lookups
+// unless a local registry is provided by the user.
+var GlobalTypes *Types = new(Types)
+
+// NotFound is a sentinel error value to indicate that the type was not found.
+//
+// Since registry lookup can happen in the critical performance path, resolvers
+// must return this exact error value, not an error wrapping it.
+var NotFound = errors.New("not found")
+
+// Files is a registry for looking up or iterating over files and the
+// descriptors contained within them.
+// The Find and Range methods are safe for concurrent use.
+type Files struct {
+	// The map of descsByName contains:
+	//	EnumDescriptor
+	//	EnumValueDescriptor
+	//	MessageDescriptor
+	//	ExtensionDescriptor
+	//	ServiceDescriptor
+	//	*packageDescriptor
+	//
+	// Note that files are stored as a slice, since a package may contain
+	// multiple files. Only top-level declarations are registered.
+	// Note that enum values are in the top-level since that are in the same
+	// scope as the parent enum.
+	descsByName map[protoreflect.FullName]interface{}
+	filesByPath map[string]protoreflect.FileDescriptor
+}
+
+type packageDescriptor struct {
+	files []protoreflect.FileDescriptor
+}
+
+// RegisterFile registers the provided file descriptor.
+//
+// If any descriptor within the file conflicts with the descriptor of any
+// previously registered file (e.g., two enums with the same full name),
+// then the file is not registered and an error is returned.
+//
+// It is permitted for multiple files to have the same file path.
+func (r *Files) RegisterFile(file protoreflect.FileDescriptor) error {
+	if r == GlobalFiles {
+		globalMutex.Lock()
+		defer globalMutex.Unlock()
+	}
+	if r.descsByName == nil {
+		r.descsByName = map[protoreflect.FullName]interface{}{
+			"": &packageDescriptor{},
+		}
+		r.filesByPath = make(map[string]protoreflect.FileDescriptor)
+	}
+	path := file.Path()
+	if prev := r.filesByPath[path]; prev != nil {
+		err := errors.New("file %q is already registered", file.Path())
+		err = amendErrorWithCaller(err, prev, file)
+		if r == GlobalFiles && ignoreConflict(file, err) {
+			err = nil
+		}
+		return err
+	}
+
+	for name := file.Package(); name != ""; name = name.Parent() {
+		switch prev := r.descsByName[name]; prev.(type) {
+		case nil, *packageDescriptor:
+		default:
+			err := errors.New("file %q has a package name conflict over %v", file.Path(), name)
+			err = amendErrorWithCaller(err, prev, file)
+			if r == GlobalFiles && ignoreConflict(file, err) {
+				err = nil
+			}
+			return err
+		}
+	}
+	var err error
+	var hasConflict bool
+	rangeTopLevelDescriptors(file, func(d protoreflect.Descriptor) {
+		if prev := r.descsByName[d.FullName()]; prev != nil {
+			hasConflict = true
+			err = errors.New("file %q has a name conflict over %v", file.Path(), d.FullName())
+			err = amendErrorWithCaller(err, prev, file)
+			if r == GlobalFiles && ignoreConflict(d, err) {
+				err = nil
+			}
+		}
+	})
+	if hasConflict {
+		return err
+	}
+
+	for name := file.Package(); name != ""; name = name.Parent() {
+		if r.descsByName[name] == nil {
+			r.descsByName[name] = &packageDescriptor{}
+		}
+	}
+	p := r.descsByName[file.Package()].(*packageDescriptor)
+	p.files = append(p.files, file)
+	rangeTopLevelDescriptors(file, func(d protoreflect.Descriptor) {
+		r.descsByName[d.FullName()] = d
+	})
+	r.filesByPath[path] = file
+	return nil
+}
+
+// FindDescriptorByName looks up a descriptor by the full name.
+//
+// This returns (nil, NotFound) if not found.
+func (r *Files) FindDescriptorByName(name protoreflect.FullName) (protoreflect.Descriptor, error) {
+	if r == nil {
+		return nil, NotFound
+	}
+	if r == GlobalFiles {
+		globalMutex.RLock()
+		defer globalMutex.RUnlock()
+	}
+	prefix := name
+	suffix := nameSuffix("")
+	for prefix != "" {
+		if d, ok := r.descsByName[prefix]; ok {
+			switch d := d.(type) {
+			case protoreflect.EnumDescriptor:
+				if d.FullName() == name {
+					return d, nil
+				}
+			case protoreflect.EnumValueDescriptor:
+				if d.FullName() == name {
+					return d, nil
+				}
+			case protoreflect.MessageDescriptor:
+				if d.FullName() == name {
+					return d, nil
+				}
+				if d := findDescriptorInMessage(d, suffix); d != nil && d.FullName() == name {
+					return d, nil
+				}
+			case protoreflect.ExtensionDescriptor:
+				if d.FullName() == name {
+					return d, nil
+				}
+			case protoreflect.ServiceDescriptor:
+				if d.FullName() == name {
+					return d, nil
+				}
+				if d := d.Methods().ByName(suffix.Pop()); d != nil && d.FullName() == name {
+					return d, nil
+				}
+			}
+			return nil, NotFound
+		}
+		prefix = prefix.Parent()
+		suffix = nameSuffix(name[len(prefix)+len("."):])
+	}
+	return nil, NotFound
+}
+
+func findDescriptorInMessage(md protoreflect.MessageDescriptor, suffix nameSuffix) protoreflect.Descriptor {
+	name := suffix.Pop()
+	if suffix == "" {
+		if ed := md.Enums().ByName(name); ed != nil {
+			return ed
+		}
+		for i := md.Enums().Len() - 1; i >= 0; i-- {
+			if vd := md.Enums().Get(i).Values().ByName(name); vd != nil {
+				return vd
+			}
+		}
+		if xd := md.Extensions().ByName(name); xd != nil {
+			return xd
+		}
+		if fd := md.Fields().ByName(name); fd != nil {
+			return fd
+		}
+		if od := md.Oneofs().ByName(name); od != nil {
+			return od
+		}
+	}
+	if md := md.Messages().ByName(name); md != nil {
+		if suffix == "" {
+			return md
+		}
+		return findDescriptorInMessage(md, suffix)
+	}
+	return nil
+}
+
+type nameSuffix string
+
+func (s *nameSuffix) Pop() (name protoreflect.Name) {
+	if i := strings.IndexByte(string(*s), '.'); i >= 0 {
+		name, *s = protoreflect.Name((*s)[:i]), (*s)[i+1:]
+	} else {
+		name, *s = protoreflect.Name((*s)), ""
+	}
+	return name
+}
+
+// FindFileByPath looks up a file by the path.
+//
+// This returns (nil, NotFound) if not found.
+func (r *Files) FindFileByPath(path string) (protoreflect.FileDescriptor, error) {
+	if r == nil {
+		return nil, NotFound
+	}
+	if r == GlobalFiles {
+		globalMutex.RLock()
+		defer globalMutex.RUnlock()
+	}
+	if fd, ok := r.filesByPath[path]; ok {
+		return fd, nil
+	}
+	return nil, NotFound
+}
+
+// NumFiles reports the number of registered files.
+func (r *Files) NumFiles() int {
+	if r == nil {
+		return 0
+	}
+	if r == GlobalFiles {
+		globalMutex.RLock()
+		defer globalMutex.RUnlock()
+	}
+	return len(r.filesByPath)
+}
+
+// RangeFiles iterates over all registered files while f returns true.
+// The iteration order is undefined.
+func (r *Files) RangeFiles(f func(protoreflect.FileDescriptor) bool) {
+	if r == nil {
+		return
+	}
+	if r == GlobalFiles {
+		globalMutex.RLock()
+		defer globalMutex.RUnlock()
+	}
+	for _, file := range r.filesByPath {
+		if !f(file) {
+			return
+		}
+	}
+}
+
+// NumFilesByPackage reports the number of registered files in a proto package.
+func (r *Files) NumFilesByPackage(name protoreflect.FullName) int {
+	if r == nil {
+		return 0
+	}
+	if r == GlobalFiles {
+		globalMutex.RLock()
+		defer globalMutex.RUnlock()
+	}
+	p, ok := r.descsByName[name].(*packageDescriptor)
+	if !ok {
+		return 0
+	}
+	return len(p.files)
+}
+
+// RangeFilesByPackage iterates over all registered files in a given proto package
+// while f returns true. The iteration order is undefined.
+func (r *Files) RangeFilesByPackage(name protoreflect.FullName, f func(protoreflect.FileDescriptor) bool) {
+	if r == nil {
+		return
+	}
+	if r == GlobalFiles {
+		globalMutex.RLock()
+		defer globalMutex.RUnlock()
+	}
+	p, ok := r.descsByName[name].(*packageDescriptor)
+	if !ok {
+		return
+	}
+	for _, file := range p.files {
+		if !f(file) {
+			return
+		}
+	}
+}
+
+// rangeTopLevelDescriptors iterates over all top-level descriptors in a file
+// which will be directly entered into the registry.
+func rangeTopLevelDescriptors(fd protoreflect.FileDescriptor, f func(protoreflect.Descriptor)) {
+	eds := fd.Enums()
+	for i := eds.Len() - 1; i >= 0; i-- {
+		f(eds.Get(i))
+		vds := eds.Get(i).Values()
+		for i := vds.Len() - 1; i >= 0; i-- {
+			f(vds.Get(i))
+		}
+	}
+	mds := fd.Messages()
+	for i := mds.Len() - 1; i >= 0; i-- {
+		f(mds.Get(i))
+	}
+	xds := fd.Extensions()
+	for i := xds.Len() - 1; i >= 0; i-- {
+		f(xds.Get(i))
+	}
+	sds := fd.Services()
+	for i := sds.Len() - 1; i >= 0; i-- {
+		f(sds.Get(i))
+	}
+}
+
+// MessageTypeResolver is an interface for looking up messages.
+//
+// A compliant implementation must deterministically return the same type
+// if no error is encountered.
+//
+// The Types type implements this interface.
+type MessageTypeResolver interface {
+	// FindMessageByName looks up a message by its full name.
+	// E.g., "google.protobuf.Any"
+	//
+	// This return (nil, NotFound) if not found.
+	FindMessageByName(message protoreflect.FullName) (protoreflect.MessageType, error)
+
+	// FindMessageByURL looks up a message by a URL identifier.
+	// See documentation on google.protobuf.Any.type_url for the URL format.
+	//
+	// This returns (nil, NotFound) if not found.
+	FindMessageByURL(url string) (protoreflect.MessageType, error)
+}
+
+// ExtensionTypeResolver is an interface for looking up extensions.
+//
+// A compliant implementation must deterministically return the same type
+// if no error is encountered.
+//
+// The Types type implements this interface.
+type ExtensionTypeResolver interface {
+	// FindExtensionByName looks up a extension field by the field's full name.
+	// Note that this is the full name of the field as determined by
+	// where the extension is declared and is unrelated to the full name of the
+	// message being extended.
+	//
+	// This returns (nil, NotFound) if not found.
+	FindExtensionByName(field protoreflect.FullName) (protoreflect.ExtensionType, error)
+
+	// FindExtensionByNumber looks up a extension field by the field number
+	// within some parent message, identified by full name.
+	//
+	// This returns (nil, NotFound) if not found.
+	FindExtensionByNumber(message protoreflect.FullName, field protoreflect.FieldNumber) (protoreflect.ExtensionType, error)
+}
+
+var (
+	_ MessageTypeResolver   = (*Types)(nil)
+	_ ExtensionTypeResolver = (*Types)(nil)
+)
+
+// Types is a registry for looking up or iterating over descriptor types.
+// The Find and Range methods are safe for concurrent use.
+type Types struct {
+	typesByName         typesByName
+	extensionsByMessage extensionsByMessage
+
+	numEnums      int
+	numMessages   int
+	numExtensions int
+}
+
+type (
+	typesByName         map[protoreflect.FullName]interface{}
+	extensionsByMessage map[protoreflect.FullName]extensionsByNumber
+	extensionsByNumber  map[protoreflect.FieldNumber]protoreflect.ExtensionType
+)
+
+// RegisterMessage registers the provided message type.
+//
+// If a naming conflict occurs, the type is not registered and an error is returned.
+func (r *Types) RegisterMessage(mt protoreflect.MessageType) error {
+	// Under rare circumstances getting the descriptor might recursively
+	// examine the registry, so fetch it before locking.
+	md := mt.Descriptor()
+
+	if r == GlobalTypes {
+		globalMutex.Lock()
+		defer globalMutex.Unlock()
+	}
+
+	if err := r.register("message", md, mt); err != nil {
+		return err
+	}
+	r.numMessages++
+	return nil
+}
+
+// RegisterEnum registers the provided enum type.
+//
+// If a naming conflict occurs, the type is not registered and an error is returned.
+func (r *Types) RegisterEnum(et protoreflect.EnumType) error {
+	// Under rare circumstances getting the descriptor might recursively
+	// examine the registry, so fetch it before locking.
+	ed := et.Descriptor()
+
+	if r == GlobalTypes {
+		globalMutex.Lock()
+		defer globalMutex.Unlock()
+	}
+
+	if err := r.register("enum", ed, et); err != nil {
+		return err
+	}
+	r.numEnums++
+	return nil
+}
+
+// RegisterExtension registers the provided extension type.
+//
+// If a naming conflict occurs, the type is not registered and an error is returned.
+func (r *Types) RegisterExtension(xt protoreflect.ExtensionType) error {
+	// Under rare circumstances getting the descriptor might recursively
+	// examine the registry, so fetch it before locking.
+	//
+	// A known case where this can happen: Fetching the TypeDescriptor for a
+	// legacy ExtensionDesc can consult the global registry.
+	xd := xt.TypeDescriptor()
+
+	if r == GlobalTypes {
+		globalMutex.Lock()
+		defer globalMutex.Unlock()
+	}
+
+	field := xd.Number()
+	message := xd.ContainingMessage().FullName()
+	if prev := r.extensionsByMessage[message][field]; prev != nil {
+		err := errors.New("extension number %d is already registered on message %v", field, message)
+		err = amendErrorWithCaller(err, prev, xt)
+		if !(r == GlobalTypes && ignoreConflict(xd, err)) {
+			return err
+		}
+	}
+
+	if err := r.register("extension", xd, xt); err != nil {
+		return err
+	}
+	if r.extensionsByMessage == nil {
+		r.extensionsByMessage = make(extensionsByMessage)
+	}
+	if r.extensionsByMessage[message] == nil {
+		r.extensionsByMessage[message] = make(extensionsByNumber)
+	}
+	r.extensionsByMessage[message][field] = xt
+	r.numExtensions++
+	return nil
+}
+
+func (r *Types) register(kind string, desc protoreflect.Descriptor, typ interface{}) error {
+	name := desc.FullName()
+	prev := r.typesByName[name]
+	if prev != nil {
+		err := errors.New("%v %v is already registered", kind, name)
+		err = amendErrorWithCaller(err, prev, typ)
+		if !(r == GlobalTypes && ignoreConflict(desc, err)) {
+			return err
+		}
+	}
+	if r.typesByName == nil {
+		r.typesByName = make(typesByName)
+	}
+	r.typesByName[name] = typ
+	return nil
+}
+
+// FindEnumByName looks up an enum by its full name.
+// E.g., "google.protobuf.Field.Kind".
+//
+// This returns (nil, NotFound) if not found.
+func (r *Types) FindEnumByName(enum protoreflect.FullName) (protoreflect.EnumType, error) {
+	if r == nil {
+		return nil, NotFound
+	}
+	if r == GlobalTypes {
+		globalMutex.RLock()
+		defer globalMutex.RUnlock()
+	}
+	if v := r.typesByName[enum]; v != nil {
+		if et, _ := v.(protoreflect.EnumType); et != nil {
+			return et, nil
+		}
+		return nil, errors.New("found wrong type: got %v, want enum", typeName(v))
+	}
+	return nil, NotFound
+}
+
+// FindMessageByName looks up a message by its full name.
+// E.g., "google.protobuf.Any"
+//
+// This return (nil, NotFound) if not found.
+func (r *Types) FindMessageByName(message protoreflect.FullName) (protoreflect.MessageType, error) {
+	// The full name by itself is a valid URL.
+	return r.FindMessageByURL(string(message))
+}
+
+// FindMessageByURL looks up a message by a URL identifier.
+// See documentation on google.protobuf.Any.type_url for the URL format.
+//
+// This returns (nil, NotFound) if not found.
+func (r *Types) FindMessageByURL(url string) (protoreflect.MessageType, error) {
+	if r == nil {
+		return nil, NotFound
+	}
+	if r == GlobalTypes {
+		globalMutex.RLock()
+		defer globalMutex.RUnlock()
+	}
+	message := protoreflect.FullName(url)
+	if i := strings.LastIndexByte(url, '/'); i >= 0 {
+		message = message[i+len("/"):]
+	}
+
+	if v := r.typesByName[message]; v != nil {
+		if mt, _ := v.(protoreflect.MessageType); mt != nil {
+			return mt, nil
+		}
+		return nil, errors.New("found wrong type: got %v, want message", typeName(v))
+	}
+	return nil, NotFound
+}
+
+// FindExtensionByName looks up a extension field by the field's full name.
+// Note that this is the full name of the field as determined by
+// where the extension is declared and is unrelated to the full name of the
+// message being extended.
+//
+// This returns (nil, NotFound) if not found.
+func (r *Types) FindExtensionByName(field protoreflect.FullName) (protoreflect.ExtensionType, error) {
+	if r == nil {
+		return nil, NotFound
+	}
+	if r == GlobalTypes {
+		globalMutex.RLock()
+		defer globalMutex.RUnlock()
+	}
+	if v := r.typesByName[field]; v != nil {
+		if xt, _ := v.(protoreflect.ExtensionType); xt != nil {
+			return xt, nil
+		}
+		return nil, errors.New("found wrong type: got %v, want extension", typeName(v))
+	}
+	return nil, NotFound
+}
+
+// FindExtensionByNumber looks up a extension field by the field number
+// within some parent message, identified by full name.
+//
+// This returns (nil, NotFound) if not found.
+func (r *Types) FindExtensionByNumber(message protoreflect.FullName, field protoreflect.FieldNumber) (protoreflect.ExtensionType, error) {
+	if r == nil {
+		return nil, NotFound
+	}
+	if r == GlobalTypes {
+		globalMutex.RLock()
+		defer globalMutex.RUnlock()
+	}
+	if xt, ok := r.extensionsByMessage[message][field]; ok {
+		return xt, nil
+	}
+	return nil, NotFound
+}
+
+// NumEnums reports the number of registered enums.
+func (r *Types) NumEnums() int {
+	if r == nil {
+		return 0
+	}
+	if r == GlobalTypes {
+		globalMutex.RLock()
+		defer globalMutex.RUnlock()
+	}
+	return r.numEnums
+}
+
+// RangeEnums iterates over all registered enums while f returns true.
+// Iteration order is undefined.
+func (r *Types) RangeEnums(f func(protoreflect.EnumType) bool) {
+	if r == nil {
+		return
+	}
+	if r == GlobalTypes {
+		globalMutex.RLock()
+		defer globalMutex.RUnlock()
+	}
+	for _, typ := range r.typesByName {
+		if et, ok := typ.(protoreflect.EnumType); ok {
+			if !f(et) {
+				return
+			}
+		}
+	}
+}
+
+// NumMessages reports the number of registered messages.
+func (r *Types) NumMessages() int {
+	if r == nil {
+		return 0
+	}
+	if r == GlobalTypes {
+		globalMutex.RLock()
+		defer globalMutex.RUnlock()
+	}
+	return r.numMessages
+}
+
+// RangeMessages iterates over all registered messages while f returns true.
+// Iteration order is undefined.
+func (r *Types) RangeMessages(f func(protoreflect.MessageType) bool) {
+	if r == nil {
+		return
+	}
+	if r == GlobalTypes {
+		globalMutex.RLock()
+		defer globalMutex.RUnlock()
+	}
+	for _, typ := range r.typesByName {
+		if mt, ok := typ.(protoreflect.MessageType); ok {
+			if !f(mt) {
+				return
+			}
+		}
+	}
+}
+
+// NumExtensions reports the number of registered extensions.
+func (r *Types) NumExtensions() int {
+	if r == nil {
+		return 0
+	}
+	if r == GlobalTypes {
+		globalMutex.RLock()
+		defer globalMutex.RUnlock()
+	}
+	return r.numExtensions
+}
+
+// RangeExtensions iterates over all registered extensions while f returns true.
+// Iteration order is undefined.
+func (r *Types) RangeExtensions(f func(protoreflect.ExtensionType) bool) {
+	if r == nil {
+		return
+	}
+	if r == GlobalTypes {
+		globalMutex.RLock()
+		defer globalMutex.RUnlock()
+	}
+	for _, typ := range r.typesByName {
+		if xt, ok := typ.(protoreflect.ExtensionType); ok {
+			if !f(xt) {
+				return
+			}
+		}
+	}
+}
+
+// NumExtensionsByMessage reports the number of registered extensions for
+// a given message type.
+func (r *Types) NumExtensionsByMessage(message protoreflect.FullName) int {
+	if r == nil {
+		return 0
+	}
+	if r == GlobalTypes {
+		globalMutex.RLock()
+		defer globalMutex.RUnlock()
+	}
+	return len(r.extensionsByMessage[message])
+}
+
+// RangeExtensionsByMessage iterates over all registered extensions filtered
+// by a given message type while f returns true. Iteration order is undefined.
+func (r *Types) RangeExtensionsByMessage(message protoreflect.FullName, f func(protoreflect.ExtensionType) bool) {
+	if r == nil {
+		return
+	}
+	if r == GlobalTypes {
+		globalMutex.RLock()
+		defer globalMutex.RUnlock()
+	}
+	for _, xt := range r.extensionsByMessage[message] {
+		if !f(xt) {
+			return
+		}
+	}
+}
+
+func typeName(t interface{}) string {
+	switch t.(type) {
+	case protoreflect.EnumType:
+		return "enum"
+	case protoreflect.MessageType:
+		return "message"
+	case protoreflect.ExtensionType:
+		return "extension"
+	default:
+		return fmt.Sprintf("%T", t)
+	}
+}
+
+func amendErrorWithCaller(err error, prev, curr interface{}) error {
+	prevPkg := goPackage(prev)
+	currPkg := goPackage(curr)
+	if prevPkg == "" || currPkg == "" || prevPkg == currPkg {
+		return err
+	}
+	return errors.New("%s\n\tpreviously from: %q\n\tcurrently from:  %q", err, prevPkg, currPkg)
+}
+
+func goPackage(v interface{}) string {
+	switch d := v.(type) {
+	case protoreflect.EnumType:
+		v = d.Descriptor()
+	case protoreflect.MessageType:
+		v = d.Descriptor()
+	case protoreflect.ExtensionType:
+		v = d.TypeDescriptor()
+	}
+	if d, ok := v.(protoreflect.Descriptor); ok {
+		v = d.ParentFile()
+	}
+	if d, ok := v.(interface{ GoPackagePath() string }); ok {
+		return d.GoPackagePath()
+	}
+	return ""
+}
diff --git a/demo_test/vendor/google.golang.org/protobuf/runtime/protoiface/legacy.go b/demo_test/vendor/google.golang.org/protobuf/runtime/protoiface/legacy.go
new file mode 100644
index 0000000..c587276
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/runtime/protoiface/legacy.go
@@ -0,0 +1,15 @@
+// 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 protoiface
+
+type MessageV1 interface {
+	Reset()
+	String() string
+	ProtoMessage()
+}
+
+type ExtensionRangeV1 struct {
+	Start, End int32 // both inclusive
+}
diff --git a/demo_test/vendor/google.golang.org/protobuf/runtime/protoiface/methods.go b/demo_test/vendor/google.golang.org/protobuf/runtime/protoiface/methods.go
new file mode 100644
index 0000000..32c04f6
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/runtime/protoiface/methods.go
@@ -0,0 +1,167 @@
+// 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 protoiface contains types referenced or implemented by messages.
+//
+// WARNING: This package should only be imported by message implementations.
+// The functionality found in this package should be accessed through
+// higher-level abstractions provided by the proto package.
+package protoiface
+
+import (
+	"google.golang.org/protobuf/internal/pragma"
+	"google.golang.org/protobuf/reflect/protoreflect"
+)
+
+// Methods is a set of optional fast-path implementations of various operations.
+type Methods = struct {
+	pragma.NoUnkeyedLiterals
+
+	// Flags indicate support for optional features.
+	Flags SupportFlags
+
+	// Size returns the size in bytes of the wire-format encoding of a message.
+	// Marshal must be provided if a custom Size is provided.
+	Size func(SizeInput) SizeOutput
+
+	// Marshal formats a message in the wire-format encoding to the provided buffer.
+	// Size should be provided if a custom Marshal is provided.
+	// It must not return an error for a partial message.
+	Marshal func(MarshalInput) (MarshalOutput, error)
+
+	// Unmarshal parses the wire-format encoding and merges the result into a message.
+	// It must not reset the target message or return an error for a partial message.
+	Unmarshal func(UnmarshalInput) (UnmarshalOutput, error)
+
+	// Merge merges the contents of a source message into a destination message.
+	Merge func(MergeInput) MergeOutput
+
+	// CheckInitialized returns an error if any required fields in the message are not set.
+	CheckInitialized func(CheckInitializedInput) (CheckInitializedOutput, error)
+}
+
+// SupportFlags indicate support for optional features.
+type SupportFlags = uint64
+
+const (
+	// SupportMarshalDeterministic reports whether MarshalOptions.Deterministic is supported.
+	SupportMarshalDeterministic SupportFlags = 1 << iota
+
+	// SupportUnmarshalDiscardUnknown reports whether UnmarshalOptions.DiscardUnknown is supported.
+	SupportUnmarshalDiscardUnknown
+)
+
+// SizeInput is input to the Size method.
+type SizeInput = struct {
+	pragma.NoUnkeyedLiterals
+
+	Message protoreflect.Message
+	Flags   MarshalInputFlags
+}
+
+// SizeOutput is output from the Size method.
+type SizeOutput = struct {
+	pragma.NoUnkeyedLiterals
+
+	Size int
+}
+
+// MarshalInput is input to the Marshal method.
+type MarshalInput = struct {
+	pragma.NoUnkeyedLiterals
+
+	Message protoreflect.Message
+	Buf     []byte // output is appended to this buffer
+	Flags   MarshalInputFlags
+}
+
+// MarshalOutput is output from the Marshal method.
+type MarshalOutput = struct {
+	pragma.NoUnkeyedLiterals
+
+	Buf []byte // contains marshaled message
+}
+
+// MarshalInputFlags configure the marshaler.
+// Most flags correspond to fields in proto.MarshalOptions.
+type MarshalInputFlags = uint8
+
+const (
+	MarshalDeterministic MarshalInputFlags = 1 << iota
+	MarshalUseCachedSize
+)
+
+// UnmarshalInput is input to the Unmarshal method.
+type UnmarshalInput = struct {
+	pragma.NoUnkeyedLiterals
+
+	Message  protoreflect.Message
+	Buf      []byte // input buffer
+	Flags    UnmarshalInputFlags
+	Resolver interface {
+		FindExtensionByName(field protoreflect.FullName) (protoreflect.ExtensionType, error)
+		FindExtensionByNumber(message protoreflect.FullName, field protoreflect.FieldNumber) (protoreflect.ExtensionType, error)
+	}
+}
+
+// UnmarshalOutput is output from the Unmarshal method.
+type UnmarshalOutput = struct {
+	pragma.NoUnkeyedLiterals
+
+	Flags UnmarshalOutputFlags
+}
+
+// UnmarshalInputFlags configure the unmarshaler.
+// Most flags correspond to fields in proto.UnmarshalOptions.
+type UnmarshalInputFlags = uint8
+
+const (
+	UnmarshalDiscardUnknown UnmarshalInputFlags = 1 << iota
+)
+
+// UnmarshalOutputFlags are output from the Unmarshal method.
+type UnmarshalOutputFlags = uint8
+
+const (
+	// UnmarshalInitialized may be set on return if all required fields are known to be set.
+	// If unset, then it does not necessarily indicate that the message is uninitialized,
+	// only that its status could not be confirmed.
+	UnmarshalInitialized UnmarshalOutputFlags = 1 << iota
+)
+
+// MergeInput is input to the Merge method.
+type MergeInput = struct {
+	pragma.NoUnkeyedLiterals
+
+	Source      protoreflect.Message
+	Destination protoreflect.Message
+}
+
+// MergeOutput is output from the Merge method.
+type MergeOutput = struct {
+	pragma.NoUnkeyedLiterals
+
+	Flags MergeOutputFlags
+}
+
+// MergeOutputFlags are output from the Merge method.
+type MergeOutputFlags = uint8
+
+const (
+	// MergeComplete reports whether the merge was performed.
+	// If unset, the merger must have made no changes to the destination.
+	MergeComplete MergeOutputFlags = 1 << iota
+)
+
+// CheckInitializedInput is input to the CheckInitialized method.
+type CheckInitializedInput = struct {
+	pragma.NoUnkeyedLiterals
+
+	Message protoreflect.Message
+}
+
+// CheckInitializedOutput is output from the CheckInitialized method.
+type CheckInitializedOutput = struct {
+	pragma.NoUnkeyedLiterals
+}
diff --git a/demo_test/vendor/google.golang.org/protobuf/runtime/protoimpl/impl.go b/demo_test/vendor/google.golang.org/protobuf/runtime/protoimpl/impl.go
new file mode 100644
index 0000000..4a1ab7f
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/runtime/protoimpl/impl.go
@@ -0,0 +1,44 @@
+// 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 protoimpl contains the default implementation for messages
+// generated by protoc-gen-go.
+//
+// WARNING: This package should only ever be imported by generated messages.
+// The compatibility agreement covers nothing except for functionality needed
+// to keep existing generated messages operational. Breakages that occur due
+// to unauthorized usages of this package are not the author's responsibility.
+package protoimpl
+
+import (
+	"google.golang.org/protobuf/internal/filedesc"
+	"google.golang.org/protobuf/internal/filetype"
+	"google.golang.org/protobuf/internal/impl"
+)
+
+// UnsafeEnabled specifies whether package unsafe can be used.
+const UnsafeEnabled = impl.UnsafeEnabled
+
+type (
+	// Types used by generated code in init functions.
+	DescBuilder = filedesc.Builder
+	TypeBuilder = filetype.Builder
+
+	// Types used by generated code to implement EnumType, MessageType, and ExtensionType.
+	EnumInfo      = impl.EnumInfo
+	MessageInfo   = impl.MessageInfo
+	ExtensionInfo = impl.ExtensionInfo
+
+	// Types embedded in generated messages.
+	MessageState     = impl.MessageState
+	SizeCache        = impl.SizeCache
+	WeakFields       = impl.WeakFields
+	UnknownFields    = impl.UnknownFields
+	ExtensionFields  = impl.ExtensionFields
+	ExtensionFieldV1 = impl.ExtensionField
+
+	Pointer = impl.Pointer
+)
+
+var X impl.Export
diff --git a/demo_test/vendor/google.golang.org/protobuf/runtime/protoimpl/version.go b/demo_test/vendor/google.golang.org/protobuf/runtime/protoimpl/version.go
new file mode 100644
index 0000000..ff094e1
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/runtime/protoimpl/version.go
@@ -0,0 +1,56 @@
+// 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 protoimpl
+
+import (
+	"google.golang.org/protobuf/internal/version"
+)
+
+const (
+	// MaxVersion is the maximum supported version for generated .pb.go files.
+	// It is always the current version of the module.
+	MaxVersion = version.Minor
+
+	// GenVersion is the runtime version required by generated .pb.go files.
+	// This is incremented when generated code relies on new functionality
+	// in the runtime.
+	GenVersion = 20
+
+	// MinVersion is the minimum supported version for generated .pb.go files.
+	// This is incremented when the runtime drops support for old code.
+	MinVersion = 0
+)
+
+// EnforceVersion is used by code generated by protoc-gen-go
+// to statically enforce minimum and maximum versions of this package.
+// A compilation failure implies either that:
+//	* the runtime package is too old and needs to be updated OR
+//	* the generated code is too old and needs to be regenerated.
+//
+// The runtime package can be upgraded by running:
+//	go get google.golang.org/protobuf
+//
+// The generated code can be regenerated by running:
+//	protoc --go_out=${PROTOC_GEN_GO_ARGS} ${PROTO_FILES}
+//
+// Example usage by generated code:
+//	const (
+//		// Verify that this generated code is sufficiently up-to-date.
+//		_ = protoimpl.EnforceVersion(genVersion - protoimpl.MinVersion)
+//		// Verify that runtime/protoimpl is sufficiently up-to-date.
+//		_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - genVersion)
+//	)
+//
+// The genVersion is the current minor version used to generated the code.
+// This compile-time check relies on negative integer overflow of a uint
+// being a compilation failure (guaranteed by the Go specification).
+type EnforceVersion uint
+
+// This enforces the following invariant:
+//	MinVersion ≤ GenVersion ≤ MaxVersion
+const (
+	_ = EnforceVersion(GenVersion - MinVersion)
+	_ = EnforceVersion(MaxVersion - GenVersion)
+)
diff --git a/demo_test/vendor/google.golang.org/protobuf/types/known/anypb/any.pb.go b/demo_test/vendor/google.golang.org/protobuf/types/known/anypb/any.pb.go
new file mode 100644
index 0000000..5f9498e
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/types/known/anypb/any.pb.go
@@ -0,0 +1,287 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// source: google/protobuf/any.proto
+
+package anypb
+
+import (
+	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+	reflect "reflect"
+	sync "sync"
+)
+
+// `Any` contains an arbitrary serialized protocol buffer message along with a
+// URL that describes the type of the serialized message.
+//
+// Protobuf library provides support to pack/unpack Any values in the form
+// of utility functions or additional generated methods of the Any type.
+//
+// Example 1: Pack and unpack a message in C++.
+//
+//     Foo foo = ...;
+//     Any any;
+//     any.PackFrom(foo);
+//     ...
+//     if (any.UnpackTo(&foo)) {
+//       ...
+//     }
+//
+// Example 2: Pack and unpack a message in Java.
+//
+//     Foo foo = ...;
+//     Any any = Any.pack(foo);
+//     ...
+//     if (any.is(Foo.class)) {
+//       foo = any.unpack(Foo.class);
+//     }
+//
+//  Example 3: Pack and unpack a message in Python.
+//
+//     foo = Foo(...)
+//     any = Any()
+//     any.Pack(foo)
+//     ...
+//     if any.Is(Foo.DESCRIPTOR):
+//       any.Unpack(foo)
+//       ...
+//
+//  Example 4: Pack and unpack a message in Go
+//
+//      foo := &pb.Foo{...}
+//      any, err := ptypes.MarshalAny(foo)
+//      ...
+//      foo := &pb.Foo{}
+//      if err := ptypes.UnmarshalAny(any, foo); err != nil {
+//        ...
+//      }
+//
+// The pack methods provided by protobuf library will by default use
+// 'type.googleapis.com/full.type.name' as the type URL and the unpack
+// methods only use the fully qualified type name after the last '/'
+// in the type URL, for example "foo.bar.com/x/y.z" will yield type
+// name "y.z".
+//
+//
+// JSON
+// ====
+// The JSON representation of an `Any` value uses the regular
+// representation of the deserialized, embedded message, with an
+// additional field `@type` which contains the type URL. Example:
+//
+//     package google.profile;
+//     message Person {
+//       string first_name = 1;
+//       string last_name = 2;
+//     }
+//
+//     {
+//       "@type": "type.googleapis.com/google.profile.Person",
+//       "firstName": <string>,
+//       "lastName": <string>
+//     }
+//
+// If the embedded message type is well-known and has a custom JSON
+// representation, that representation will be embedded adding a field
+// `value` which holds the custom JSON in addition to the `@type`
+// field. Example (for message [google.protobuf.Duration][]):
+//
+//     {
+//       "@type": "type.googleapis.com/google.protobuf.Duration",
+//       "value": "1.212s"
+//     }
+//
+type Any struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// A URL/resource name that uniquely identifies the type of the serialized
+	// protocol buffer message. This string must contain at least
+	// one "/" character. The last segment of the URL's path must represent
+	// the fully qualified name of the type (as in
+	// `path/google.protobuf.Duration`). The name should be in a canonical form
+	// (e.g., leading "." is not accepted).
+	//
+	// In practice, teams usually precompile into the binary all types that they
+	// expect it to use in the context of Any. However, for URLs which use the
+	// scheme `http`, `https`, or no scheme, one can optionally set up a type
+	// server that maps type URLs to message definitions as follows:
+	//
+	// * If no scheme is provided, `https` is assumed.
+	// * An HTTP GET on the URL must yield a [google.protobuf.Type][]
+	//   value in binary format, or produce an error.
+	// * Applications are allowed to cache lookup results based on the
+	//   URL, or have them precompiled into a binary to avoid any
+	//   lookup. Therefore, binary compatibility needs to be preserved
+	//   on changes to types. (Use versioned type names to manage
+	//   breaking changes.)
+	//
+	// Note: this functionality is not currently available in the official
+	// protobuf release, and it is not used for type URLs beginning with
+	// type.googleapis.com.
+	//
+	// Schemes other than `http`, `https` (or the empty scheme) might be
+	// used with implementation specific semantics.
+	//
+	TypeUrl string `protobuf:"bytes,1,opt,name=type_url,json=typeUrl,proto3" json:"type_url,omitempty"`
+	// Must be a valid serialized protocol buffer of the above specified type.
+	Value []byte `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"`
+}
+
+func (x *Any) Reset() {
+	*x = Any{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_google_protobuf_any_proto_msgTypes[0]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *Any) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Any) ProtoMessage() {}
+
+func (x *Any) ProtoReflect() protoreflect.Message {
+	mi := &file_google_protobuf_any_proto_msgTypes[0]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use Any.ProtoReflect.Descriptor instead.
+func (*Any) Descriptor() ([]byte, []int) {
+	return file_google_protobuf_any_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *Any) GetTypeUrl() string {
+	if x != nil {
+		return x.TypeUrl
+	}
+	return ""
+}
+
+func (x *Any) GetValue() []byte {
+	if x != nil {
+		return x.Value
+	}
+	return nil
+}
+
+var File_google_protobuf_any_proto protoreflect.FileDescriptor
+
+var file_google_protobuf_any_proto_rawDesc = []byte{
+	0x0a, 0x19, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75,
+	0x66, 0x2f, 0x61, 0x6e, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0f, 0x67, 0x6f, 0x6f,
+	0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x22, 0x36, 0x0a, 0x03,
+	0x41, 0x6e, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x75, 0x72, 0x6c, 0x18,
+	0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x74, 0x79, 0x70, 0x65, 0x55, 0x72, 0x6c, 0x12, 0x14,
+	0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x76,
+	0x61, 0x6c, 0x75, 0x65, 0x42, 0x6f, 0x0a, 0x13, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x6f, 0x6f, 0x67,
+	0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x42, 0x08, 0x41, 0x6e, 0x79,
+	0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x25, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e,
+	0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+	0x62, 0x75, 0x66, 0x2f, 0x70, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x61, 0x6e, 0x79, 0xa2, 0x02,
+	0x03, 0x47, 0x50, 0x42, 0xaa, 0x02, 0x1e, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x50, 0x72,
+	0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x57, 0x65, 0x6c, 0x6c, 0x4b, 0x6e, 0x6f, 0x77, 0x6e,
+	0x54, 0x79, 0x70, 0x65, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+}
+
+var (
+	file_google_protobuf_any_proto_rawDescOnce sync.Once
+	file_google_protobuf_any_proto_rawDescData = file_google_protobuf_any_proto_rawDesc
+)
+
+func file_google_protobuf_any_proto_rawDescGZIP() []byte {
+	file_google_protobuf_any_proto_rawDescOnce.Do(func() {
+		file_google_protobuf_any_proto_rawDescData = protoimpl.X.CompressGZIP(file_google_protobuf_any_proto_rawDescData)
+	})
+	return file_google_protobuf_any_proto_rawDescData
+}
+
+var file_google_protobuf_any_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
+var file_google_protobuf_any_proto_goTypes = []interface{}{
+	(*Any)(nil), // 0: google.protobuf.Any
+}
+var file_google_protobuf_any_proto_depIdxs = []int32{
+	0, // [0:0] is the sub-list for method output_type
+	0, // [0:0] is the sub-list for method input_type
+	0, // [0:0] is the sub-list for extension type_name
+	0, // [0:0] is the sub-list for extension extendee
+	0, // [0:0] is the sub-list for field type_name
+}
+
+func init() { file_google_protobuf_any_proto_init() }
+func file_google_protobuf_any_proto_init() {
+	if File_google_protobuf_any_proto != nil {
+		return
+	}
+	if !protoimpl.UnsafeEnabled {
+		file_google_protobuf_any_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*Any); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+	}
+	type x struct{}
+	out := protoimpl.TypeBuilder{
+		File: protoimpl.DescBuilder{
+			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+			RawDescriptor: file_google_protobuf_any_proto_rawDesc,
+			NumEnums:      0,
+			NumMessages:   1,
+			NumExtensions: 0,
+			NumServices:   0,
+		},
+		GoTypes:           file_google_protobuf_any_proto_goTypes,
+		DependencyIndexes: file_google_protobuf_any_proto_depIdxs,
+		MessageInfos:      file_google_protobuf_any_proto_msgTypes,
+	}.Build()
+	File_google_protobuf_any_proto = out.File
+	file_google_protobuf_any_proto_rawDesc = nil
+	file_google_protobuf_any_proto_goTypes = nil
+	file_google_protobuf_any_proto_depIdxs = nil
+}
diff --git a/demo_test/vendor/google.golang.org/protobuf/types/known/durationpb/duration.pb.go b/demo_test/vendor/google.golang.org/protobuf/types/known/durationpb/duration.pb.go
new file mode 100644
index 0000000..3997c60
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/types/known/durationpb/duration.pb.go
@@ -0,0 +1,249 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// source: google/protobuf/duration.proto
+
+package durationpb
+
+import (
+	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+	reflect "reflect"
+	sync "sync"
+)
+
+// A Duration represents a signed, fixed-length span of time represented
+// as a count of seconds and fractions of seconds at nanosecond
+// resolution. It is independent of any calendar and concepts like "day"
+// or "month". It is related to Timestamp in that the difference between
+// two Timestamp values is a Duration and it can be added or subtracted
+// from a Timestamp. Range is approximately +-10,000 years.
+//
+// # Examples
+//
+// Example 1: Compute Duration from two Timestamps in pseudo code.
+//
+//     Timestamp start = ...;
+//     Timestamp end = ...;
+//     Duration duration = ...;
+//
+//     duration.seconds = end.seconds - start.seconds;
+//     duration.nanos = end.nanos - start.nanos;
+//
+//     if (duration.seconds < 0 && duration.nanos > 0) {
+//       duration.seconds += 1;
+//       duration.nanos -= 1000000000;
+//     } else if (duration.seconds > 0 && duration.nanos < 0) {
+//       duration.seconds -= 1;
+//       duration.nanos += 1000000000;
+//     }
+//
+// Example 2: Compute Timestamp from Timestamp + Duration in pseudo code.
+//
+//     Timestamp start = ...;
+//     Duration duration = ...;
+//     Timestamp end = ...;
+//
+//     end.seconds = start.seconds + duration.seconds;
+//     end.nanos = start.nanos + duration.nanos;
+//
+//     if (end.nanos < 0) {
+//       end.seconds -= 1;
+//       end.nanos += 1000000000;
+//     } else if (end.nanos >= 1000000000) {
+//       end.seconds += 1;
+//       end.nanos -= 1000000000;
+//     }
+//
+// Example 3: Compute Duration from datetime.timedelta in Python.
+//
+//     td = datetime.timedelta(days=3, minutes=10)
+//     duration = Duration()
+//     duration.FromTimedelta(td)
+//
+// # JSON Mapping
+//
+// In JSON format, the Duration type is encoded as a string rather than an
+// object, where the string ends in the suffix "s" (indicating seconds) and
+// is preceded by the number of seconds, with nanoseconds expressed as
+// fractional seconds. For example, 3 seconds with 0 nanoseconds should be
+// encoded in JSON format as "3s", while 3 seconds and 1 nanosecond should
+// be expressed in JSON format as "3.000000001s", and 3 seconds and 1
+// microsecond should be expressed in JSON format as "3.000001s".
+//
+//
+type Duration struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// Signed seconds of the span of time. Must be from -315,576,000,000
+	// to +315,576,000,000 inclusive. Note: these bounds are computed from:
+	// 60 sec/min * 60 min/hr * 24 hr/day * 365.25 days/year * 10000 years
+	Seconds int64 `protobuf:"varint,1,opt,name=seconds,proto3" json:"seconds,omitempty"`
+	// Signed fractions of a second at nanosecond resolution of the span
+	// of time. Durations less than one second are represented with a 0
+	// `seconds` field and a positive or negative `nanos` field. For durations
+	// of one second or more, a non-zero value for the `nanos` field must be
+	// of the same sign as the `seconds` field. Must be from -999,999,999
+	// to +999,999,999 inclusive.
+	Nanos int32 `protobuf:"varint,2,opt,name=nanos,proto3" json:"nanos,omitempty"`
+}
+
+func (x *Duration) Reset() {
+	*x = Duration{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_google_protobuf_duration_proto_msgTypes[0]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *Duration) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Duration) ProtoMessage() {}
+
+func (x *Duration) ProtoReflect() protoreflect.Message {
+	mi := &file_google_protobuf_duration_proto_msgTypes[0]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use Duration.ProtoReflect.Descriptor instead.
+func (*Duration) Descriptor() ([]byte, []int) {
+	return file_google_protobuf_duration_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *Duration) GetSeconds() int64 {
+	if x != nil {
+		return x.Seconds
+	}
+	return 0
+}
+
+func (x *Duration) GetNanos() int32 {
+	if x != nil {
+		return x.Nanos
+	}
+	return 0
+}
+
+var File_google_protobuf_duration_proto protoreflect.FileDescriptor
+
+var file_google_protobuf_duration_proto_rawDesc = []byte{
+	0x0a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75,
+	0x66, 0x2f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+	0x12, 0x0f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75,
+	0x66, 0x22, 0x3a, 0x0a, 0x08, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a,
+	0x07, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07,
+	0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x6e, 0x61, 0x6e, 0x6f, 0x73,
+	0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x6e, 0x61, 0x6e, 0x6f, 0x73, 0x42, 0x7c, 0x0a,
+	0x13, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74,
+	0x6f, 0x62, 0x75, 0x66, 0x42, 0x0d, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72,
+	0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x2a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f,
+	0x6d, 0x2f, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75,
+	0x66, 0x2f, 0x70, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f,
+	0x6e, 0xf8, 0x01, 0x01, 0xa2, 0x02, 0x03, 0x47, 0x50, 0x42, 0xaa, 0x02, 0x1e, 0x47, 0x6f, 0x6f,
+	0x67, 0x6c, 0x65, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x57, 0x65, 0x6c,
+	0x6c, 0x4b, 0x6e, 0x6f, 0x77, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f,
+	0x74, 0x6f, 0x33,
+}
+
+var (
+	file_google_protobuf_duration_proto_rawDescOnce sync.Once
+	file_google_protobuf_duration_proto_rawDescData = file_google_protobuf_duration_proto_rawDesc
+)
+
+func file_google_protobuf_duration_proto_rawDescGZIP() []byte {
+	file_google_protobuf_duration_proto_rawDescOnce.Do(func() {
+		file_google_protobuf_duration_proto_rawDescData = protoimpl.X.CompressGZIP(file_google_protobuf_duration_proto_rawDescData)
+	})
+	return file_google_protobuf_duration_proto_rawDescData
+}
+
+var file_google_protobuf_duration_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
+var file_google_protobuf_duration_proto_goTypes = []interface{}{
+	(*Duration)(nil), // 0: google.protobuf.Duration
+}
+var file_google_protobuf_duration_proto_depIdxs = []int32{
+	0, // [0:0] is the sub-list for method output_type
+	0, // [0:0] is the sub-list for method input_type
+	0, // [0:0] is the sub-list for extension type_name
+	0, // [0:0] is the sub-list for extension extendee
+	0, // [0:0] is the sub-list for field type_name
+}
+
+func init() { file_google_protobuf_duration_proto_init() }
+func file_google_protobuf_duration_proto_init() {
+	if File_google_protobuf_duration_proto != nil {
+		return
+	}
+	if !protoimpl.UnsafeEnabled {
+		file_google_protobuf_duration_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*Duration); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+	}
+	type x struct{}
+	out := protoimpl.TypeBuilder{
+		File: protoimpl.DescBuilder{
+			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+			RawDescriptor: file_google_protobuf_duration_proto_rawDesc,
+			NumEnums:      0,
+			NumMessages:   1,
+			NumExtensions: 0,
+			NumServices:   0,
+		},
+		GoTypes:           file_google_protobuf_duration_proto_goTypes,
+		DependencyIndexes: file_google_protobuf_duration_proto_depIdxs,
+		MessageInfos:      file_google_protobuf_duration_proto_msgTypes,
+	}.Build()
+	File_google_protobuf_duration_proto = out.File
+	file_google_protobuf_duration_proto_rawDesc = nil
+	file_google_protobuf_duration_proto_goTypes = nil
+	file_google_protobuf_duration_proto_depIdxs = nil
+}
diff --git a/demo_test/vendor/google.golang.org/protobuf/types/known/emptypb/empty.pb.go b/demo_test/vendor/google.golang.org/protobuf/types/known/emptypb/empty.pb.go
new file mode 100644
index 0000000..32a583d
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/types/known/emptypb/empty.pb.go
@@ -0,0 +1,168 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// source: google/protobuf/empty.proto
+
+package emptypb
+
+import (
+	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+	reflect "reflect"
+	sync "sync"
+)
+
+// A generic empty message that you can re-use to avoid defining duplicated
+// empty messages in your APIs. A typical example is to use it as the request
+// or the response type of an API method. For instance:
+//
+//     service Foo {
+//       rpc Bar(google.protobuf.Empty) returns (google.protobuf.Empty);
+//     }
+//
+// The JSON representation for `Empty` is empty JSON object `{}`.
+type Empty struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+}
+
+func (x *Empty) Reset() {
+	*x = Empty{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_google_protobuf_empty_proto_msgTypes[0]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *Empty) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Empty) ProtoMessage() {}
+
+func (x *Empty) ProtoReflect() protoreflect.Message {
+	mi := &file_google_protobuf_empty_proto_msgTypes[0]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use Empty.ProtoReflect.Descriptor instead.
+func (*Empty) Descriptor() ([]byte, []int) {
+	return file_google_protobuf_empty_proto_rawDescGZIP(), []int{0}
+}
+
+var File_google_protobuf_empty_proto protoreflect.FileDescriptor
+
+var file_google_protobuf_empty_proto_rawDesc = []byte{
+	0x0a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75,
+	0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0f, 0x67,
+	0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x22, 0x07,
+	0x0a, 0x05, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x42, 0x76, 0x0a, 0x13, 0x63, 0x6f, 0x6d, 0x2e, 0x67,
+	0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x42, 0x0a,
+	0x45, 0x6d, 0x70, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x27, 0x67, 0x69,
+	0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2f,
+	0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f,
+	0x65, 0x6d, 0x70, 0x74, 0x79, 0xf8, 0x01, 0x01, 0xa2, 0x02, 0x03, 0x47, 0x50, 0x42, 0xaa, 0x02,
+	0x1e, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
+	0x2e, 0x57, 0x65, 0x6c, 0x6c, 0x4b, 0x6e, 0x6f, 0x77, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x73, 0x62,
+	0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+}
+
+var (
+	file_google_protobuf_empty_proto_rawDescOnce sync.Once
+	file_google_protobuf_empty_proto_rawDescData = file_google_protobuf_empty_proto_rawDesc
+)
+
+func file_google_protobuf_empty_proto_rawDescGZIP() []byte {
+	file_google_protobuf_empty_proto_rawDescOnce.Do(func() {
+		file_google_protobuf_empty_proto_rawDescData = protoimpl.X.CompressGZIP(file_google_protobuf_empty_proto_rawDescData)
+	})
+	return file_google_protobuf_empty_proto_rawDescData
+}
+
+var file_google_protobuf_empty_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
+var file_google_protobuf_empty_proto_goTypes = []interface{}{
+	(*Empty)(nil), // 0: google.protobuf.Empty
+}
+var file_google_protobuf_empty_proto_depIdxs = []int32{
+	0, // [0:0] is the sub-list for method output_type
+	0, // [0:0] is the sub-list for method input_type
+	0, // [0:0] is the sub-list for extension type_name
+	0, // [0:0] is the sub-list for extension extendee
+	0, // [0:0] is the sub-list for field type_name
+}
+
+func init() { file_google_protobuf_empty_proto_init() }
+func file_google_protobuf_empty_proto_init() {
+	if File_google_protobuf_empty_proto != nil {
+		return
+	}
+	if !protoimpl.UnsafeEnabled {
+		file_google_protobuf_empty_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*Empty); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+	}
+	type x struct{}
+	out := protoimpl.TypeBuilder{
+		File: protoimpl.DescBuilder{
+			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+			RawDescriptor: file_google_protobuf_empty_proto_rawDesc,
+			NumEnums:      0,
+			NumMessages:   1,
+			NumExtensions: 0,
+			NumServices:   0,
+		},
+		GoTypes:           file_google_protobuf_empty_proto_goTypes,
+		DependencyIndexes: file_google_protobuf_empty_proto_depIdxs,
+		MessageInfos:      file_google_protobuf_empty_proto_msgTypes,
+	}.Build()
+	File_google_protobuf_empty_proto = out.File
+	file_google_protobuf_empty_proto_rawDesc = nil
+	file_google_protobuf_empty_proto_goTypes = nil
+	file_google_protobuf_empty_proto_depIdxs = nil
+}
diff --git a/demo_test/vendor/google.golang.org/protobuf/types/known/timestamppb/timestamp.pb.go b/demo_test/vendor/google.golang.org/protobuf/types/known/timestamppb/timestamp.pb.go
new file mode 100644
index 0000000..6fe6d42
--- /dev/null
+++ b/demo_test/vendor/google.golang.org/protobuf/types/known/timestamppb/timestamp.pb.go
@@ -0,0 +1,271 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// source: google/protobuf/timestamp.proto
+
+package timestamppb
+
+import (
+	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+	reflect "reflect"
+	sync "sync"
+)
+
+// A Timestamp represents a point in time independent of any time zone or local
+// calendar, encoded as a count of seconds and fractions of seconds at
+// nanosecond resolution. The count is relative to an epoch at UTC midnight on
+// January 1, 1970, in the proleptic Gregorian calendar which extends the
+// Gregorian calendar backwards to year one.
+//
+// All minutes are 60 seconds long. Leap seconds are "smeared" so that no leap
+// second table is needed for interpretation, using a [24-hour linear
+// smear](https://developers.google.com/time/smear).
+//
+// The range is from 0001-01-01T00:00:00Z to 9999-12-31T23:59:59.999999999Z. By
+// restricting to that range, we ensure that we can convert to and from [RFC
+// 3339](https://www.ietf.org/rfc/rfc3339.txt) date strings.
+//
+// # Examples
+//
+// Example 1: Compute Timestamp from POSIX `time()`.
+//
+//     Timestamp timestamp;
+//     timestamp.set_seconds(time(NULL));
+//     timestamp.set_nanos(0);
+//
+// Example 2: Compute Timestamp from POSIX `gettimeofday()`.
+//
+//     struct timeval tv;
+//     gettimeofday(&tv, NULL);
+//
+//     Timestamp timestamp;
+//     timestamp.set_seconds(tv.tv_sec);
+//     timestamp.set_nanos(tv.tv_usec * 1000);
+//
+// Example 3: Compute Timestamp from Win32 `GetSystemTimeAsFileTime()`.
+//
+//     FILETIME ft;
+//     GetSystemTimeAsFileTime(&ft);
+//     UINT64 ticks = (((UINT64)ft.dwHighDateTime) << 32) | ft.dwLowDateTime;
+//
+//     // A Windows tick is 100 nanoseconds. Windows epoch 1601-01-01T00:00:00Z
+//     // is 11644473600 seconds before Unix epoch 1970-01-01T00:00:00Z.
+//     Timestamp timestamp;
+//     timestamp.set_seconds((INT64) ((ticks / 10000000) - 11644473600LL));
+//     timestamp.set_nanos((INT32) ((ticks % 10000000) * 100));
+//
+// Example 4: Compute Timestamp from Java `System.currentTimeMillis()`.
+//
+//     long millis = System.currentTimeMillis();
+//
+//     Timestamp timestamp = Timestamp.newBuilder().setSeconds(millis / 1000)
+//         .setNanos((int) ((millis % 1000) * 1000000)).build();
+//
+//
+// Example 5: Compute Timestamp from current time in Python.
+//
+//     timestamp = Timestamp()
+//     timestamp.GetCurrentTime()
+//
+// # JSON Mapping
+//
+// In JSON format, the Timestamp type is encoded as a string in the
+// [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) format. That is, the
+// format is "{year}-{month}-{day}T{hour}:{min}:{sec}[.{frac_sec}]Z"
+// where {year} is always expressed using four digits while {month}, {day},
+// {hour}, {min}, and {sec} are zero-padded to two digits each. The fractional
+// seconds, which can go up to 9 digits (i.e. up to 1 nanosecond resolution),
+// are optional. The "Z" suffix indicates the timezone ("UTC"); the timezone
+// is required. A proto3 JSON serializer should always use UTC (as indicated by
+// "Z") when printing the Timestamp type and a proto3 JSON parser should be
+// able to accept both UTC and other timezones (as indicated by an offset).
+//
+// For example, "2017-01-15T01:30:15.01Z" encodes 15.01 seconds past
+// 01:30 UTC on January 15, 2017.
+//
+// In JavaScript, one can convert a Date object to this format using the
+// standard
+// [toISOString()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString)
+// method. In Python, a standard `datetime.datetime` object can be converted
+// to this format using
+// [`strftime`](https://docs.python.org/2/library/time.html#time.strftime) with
+// the time format spec '%Y-%m-%dT%H:%M:%S.%fZ'. Likewise, in Java, one can use
+// the Joda Time's [`ISODateTimeFormat.dateTime()`](
+// http://www.joda.org/joda-time/apidocs/org/joda/time/format/ISODateTimeFormat.html#dateTime%2D%2D
+// ) to obtain a formatter capable of generating timestamps in this format.
+//
+//
+type Timestamp struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// Represents seconds of UTC time since Unix epoch
+	// 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to
+	// 9999-12-31T23:59:59Z inclusive.
+	Seconds int64 `protobuf:"varint,1,opt,name=seconds,proto3" json:"seconds,omitempty"`
+	// Non-negative fractions of a second at nanosecond resolution. Negative
+	// second values with fractions must still have non-negative nanos values
+	// that count forward in time. Must be from 0 to 999,999,999
+	// inclusive.
+	Nanos int32 `protobuf:"varint,2,opt,name=nanos,proto3" json:"nanos,omitempty"`
+}
+
+func (x *Timestamp) Reset() {
+	*x = Timestamp{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_google_protobuf_timestamp_proto_msgTypes[0]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *Timestamp) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Timestamp) ProtoMessage() {}
+
+func (x *Timestamp) ProtoReflect() protoreflect.Message {
+	mi := &file_google_protobuf_timestamp_proto_msgTypes[0]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use Timestamp.ProtoReflect.Descriptor instead.
+func (*Timestamp) Descriptor() ([]byte, []int) {
+	return file_google_protobuf_timestamp_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *Timestamp) GetSeconds() int64 {
+	if x != nil {
+		return x.Seconds
+	}
+	return 0
+}
+
+func (x *Timestamp) GetNanos() int32 {
+	if x != nil {
+		return x.Nanos
+	}
+	return 0
+}
+
+var File_google_protobuf_timestamp_proto protoreflect.FileDescriptor
+
+var file_google_protobuf_timestamp_proto_rawDesc = []byte{
+	0x0a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75,
+	0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74,
+	0x6f, 0x12, 0x0f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62,
+	0x75, 0x66, 0x22, 0x3b, 0x0a, 0x09, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12,
+	0x18, 0x0a, 0x07, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03,
+	0x52, 0x07, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x6e, 0x61, 0x6e,
+	0x6f, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x6e, 0x61, 0x6e, 0x6f, 0x73, 0x42,
+	0x7e, 0x0a, 0x13, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72,
+	0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x42, 0x0e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d,
+	0x70, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x2b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62,
+	0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74,
+	0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x74, 0x69, 0x6d, 0x65,
+	0x73, 0x74, 0x61, 0x6d, 0x70, 0xf8, 0x01, 0x01, 0xa2, 0x02, 0x03, 0x47, 0x50, 0x42, 0xaa, 0x02,
+	0x1e, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
+	0x2e, 0x57, 0x65, 0x6c, 0x6c, 0x4b, 0x6e, 0x6f, 0x77, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x73, 0x62,
+	0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+}
+
+var (
+	file_google_protobuf_timestamp_proto_rawDescOnce sync.Once
+	file_google_protobuf_timestamp_proto_rawDescData = file_google_protobuf_timestamp_proto_rawDesc
+)
+
+func file_google_protobuf_timestamp_proto_rawDescGZIP() []byte {
+	file_google_protobuf_timestamp_proto_rawDescOnce.Do(func() {
+		file_google_protobuf_timestamp_proto_rawDescData = protoimpl.X.CompressGZIP(file_google_protobuf_timestamp_proto_rawDescData)
+	})
+	return file_google_protobuf_timestamp_proto_rawDescData
+}
+
+var file_google_protobuf_timestamp_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
+var file_google_protobuf_timestamp_proto_goTypes = []interface{}{
+	(*Timestamp)(nil), // 0: google.protobuf.Timestamp
+}
+var file_google_protobuf_timestamp_proto_depIdxs = []int32{
+	0, // [0:0] is the sub-list for method output_type
+	0, // [0:0] is the sub-list for method input_type
+	0, // [0:0] is the sub-list for extension type_name
+	0, // [0:0] is the sub-list for extension extendee
+	0, // [0:0] is the sub-list for field type_name
+}
+
+func init() { file_google_protobuf_timestamp_proto_init() }
+func file_google_protobuf_timestamp_proto_init() {
+	if File_google_protobuf_timestamp_proto != nil {
+		return
+	}
+	if !protoimpl.UnsafeEnabled {
+		file_google_protobuf_timestamp_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*Timestamp); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+	}
+	type x struct{}
+	out := protoimpl.TypeBuilder{
+		File: protoimpl.DescBuilder{
+			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+			RawDescriptor: file_google_protobuf_timestamp_proto_rawDesc,
+			NumEnums:      0,
+			NumMessages:   1,
+			NumExtensions: 0,
+			NumServices:   0,
+		},
+		GoTypes:           file_google_protobuf_timestamp_proto_goTypes,
+		DependencyIndexes: file_google_protobuf_timestamp_proto_depIdxs,
+		MessageInfos:      file_google_protobuf_timestamp_proto_msgTypes,
+	}.Build()
+	File_google_protobuf_timestamp_proto = out.File
+	file_google_protobuf_timestamp_proto_rawDesc = nil
+	file_google_protobuf_timestamp_proto_goTypes = nil
+	file_google_protobuf_timestamp_proto_depIdxs = nil
+}
