diff --git a/demo_test/vendor/github.com/golang/protobuf/proto/extensions.go b/demo_test/vendor/github.com/golang/protobuf/proto/extensions.go
new file mode 100644
index 0000000..5ed131c
--- /dev/null
+++ b/demo_test/vendor/github.com/golang/protobuf/proto/extensions.go
@@ -0,0 +1,356 @@
+// Copyright 2010 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 (
+	"errors"
+	"fmt"
+	"reflect"
+
+	"google.golang.org/protobuf/encoding/protowire"
+	"google.golang.org/protobuf/proto"
+	"google.golang.org/protobuf/reflect/protoreflect"
+	"google.golang.org/protobuf/reflect/protoregistry"
+	"google.golang.org/protobuf/runtime/protoiface"
+	"google.golang.org/protobuf/runtime/protoimpl"
+)
+
+type (
+	// ExtensionDesc represents an extension descriptor and
+	// is used to interact with an extension field in a message.
+	//
+	// Variables of this type are generated in code by protoc-gen-go.
+	ExtensionDesc = protoimpl.ExtensionInfo
+
+	// ExtensionRange represents a range of message extensions.
+	// Used in code generated by protoc-gen-go.
+	ExtensionRange = protoiface.ExtensionRangeV1
+
+	// Deprecated: Do not use; this is an internal type.
+	Extension = protoimpl.ExtensionFieldV1
+
+	// Deprecated: Do not use; this is an internal type.
+	XXX_InternalExtensions = protoimpl.ExtensionFields
+)
+
+// ErrMissingExtension reports whether the extension was not present.
+var ErrMissingExtension = errors.New("proto: missing extension")
+
+var errNotExtendable = errors.New("proto: not an extendable proto.Message")
+
+// HasExtension reports whether the extension field is present in m
+// either as an explicitly populated field or as an unknown field.
+func HasExtension(m Message, xt *ExtensionDesc) (has bool) {
+	mr := MessageReflect(m)
+	if mr == nil || !mr.IsValid() {
+		return false
+	}
+
+	// Check whether any populated known field matches the field number.
+	xtd := xt.TypeDescriptor()
+	if isValidExtension(mr.Descriptor(), xtd) {
+		has = mr.Has(xtd)
+	} else {
+		mr.Range(func(fd protoreflect.FieldDescriptor, _ protoreflect.Value) bool {
+			has = int32(fd.Number()) == xt.Field
+			return !has
+		})
+	}
+
+	// Check whether any unknown field matches the field number.
+	for b := mr.GetUnknown(); !has && len(b) > 0; {
+		num, _, n := protowire.ConsumeField(b)
+		has = int32(num) == xt.Field
+		b = b[n:]
+	}
+	return has
+}
+
+// ClearExtension removes the the exntesion field from m
+// either as an explicitly populated field or as an unknown field.
+func ClearExtension(m Message, xt *ExtensionDesc) {
+	mr := MessageReflect(m)
+	if mr == nil || !mr.IsValid() {
+		return
+	}
+
+	xtd := xt.TypeDescriptor()
+	if isValidExtension(mr.Descriptor(), xtd) {
+		mr.Clear(xtd)
+	} else {
+		mr.Range(func(fd protoreflect.FieldDescriptor, _ protoreflect.Value) bool {
+			if int32(fd.Number()) == xt.Field {
+				mr.Clear(fd)
+				return false
+			}
+			return true
+		})
+	}
+	clearUnknown(mr, fieldNum(xt.Field))
+}
+
+// ClearAllExtensions clears all extensions from m.
+// This includes populated fields and unknown fields in the extension range.
+func ClearAllExtensions(m Message) {
+	mr := MessageReflect(m)
+	if mr == nil || !mr.IsValid() {
+		return
+	}
+
+	mr.Range(func(fd protoreflect.FieldDescriptor, _ protoreflect.Value) bool {
+		if fd.IsExtension() {
+			mr.Clear(fd)
+		}
+		return true
+	})
+	clearUnknown(mr, mr.Descriptor().ExtensionRanges())
+}
+
+// GetExtension retrieves a proto2 extended field from pb.
+//
+// If the descriptor is type complete (i.e., ExtensionDesc.ExtensionType is non-nil),
+// then GetExtension parses the encoded field and returns a Go value of the specified type.
+// If the field is not present, then the default value is returned (if one is specified),
+// otherwise ErrMissingExtension is reported.
+//
+// If the descriptor is type incomplete (i.e., ExtensionDesc.ExtensionType is nil),
+// then GetExtension returns the raw encoded bytes for the extension field.
+func GetExtension(m Message, xt *ExtensionDesc) (interface{}, error) {
+	mr := MessageReflect(m)
+	if mr == nil || !mr.IsValid() || mr.Descriptor().ExtensionRanges().Len() == 0 {
+		return nil, errNotExtendable
+	}
+
+	// Retrieve the unknown fields for this extension field.
+	var bo protoreflect.RawFields
+	for bi := mr.GetUnknown(); len(bi) > 0; {
+		num, _, n := protowire.ConsumeField(bi)
+		if int32(num) == xt.Field {
+			bo = append(bo, bi[:n]...)
+		}
+		bi = bi[n:]
+	}
+
+	// For type incomplete descriptors, only retrieve the unknown fields.
+	if xt.ExtensionType == nil {
+		return []byte(bo), nil
+	}
+
+	// If the extension field only exists as unknown fields, unmarshal it.
+	// This is rarely done since proto.Unmarshal eagerly unmarshals extensions.
+	xtd := xt.TypeDescriptor()
+	if !isValidExtension(mr.Descriptor(), xtd) {
+		return nil, fmt.Errorf("proto: bad extended type; %T does not extend %T", xt.ExtendedType, m)
+	}
+	if !mr.Has(xtd) && len(bo) > 0 {
+		m2 := mr.New()
+		if err := (proto.UnmarshalOptions{
+			Resolver: extensionResolver{xt},
+		}.Unmarshal(bo, m2.Interface())); err != nil {
+			return nil, err
+		}
+		if m2.Has(xtd) {
+			mr.Set(xtd, m2.Get(xtd))
+			clearUnknown(mr, fieldNum(xt.Field))
+		}
+	}
+
+	// Check whether the message has the extension field set or a default.
+	var pv protoreflect.Value
+	switch {
+	case mr.Has(xtd):
+		pv = mr.Get(xtd)
+	case xtd.HasDefault():
+		pv = xtd.Default()
+	default:
+		return nil, ErrMissingExtension
+	}
+
+	v := xt.InterfaceOf(pv)
+	rv := reflect.ValueOf(v)
+	if isScalarKind(rv.Kind()) {
+		rv2 := reflect.New(rv.Type())
+		rv2.Elem().Set(rv)
+		v = rv2.Interface()
+	}
+	return v, nil
+}
+
+// extensionResolver is a custom extension resolver that stores a single
+// extension type that takes precedence over the global registry.
+type extensionResolver struct{ xt protoreflect.ExtensionType }
+
+func (r extensionResolver) FindExtensionByName(field protoreflect.FullName) (protoreflect.ExtensionType, error) {
+	if xtd := r.xt.TypeDescriptor(); xtd.FullName() == field {
+		return r.xt, nil
+	}
+	return protoregistry.GlobalTypes.FindExtensionByName(field)
+}
+
+func (r extensionResolver) FindExtensionByNumber(message protoreflect.FullName, field protoreflect.FieldNumber) (protoreflect.ExtensionType, error) {
+	if xtd := r.xt.TypeDescriptor(); xtd.ContainingMessage().FullName() == message && xtd.Number() == field {
+		return r.xt, nil
+	}
+	return protoregistry.GlobalTypes.FindExtensionByNumber(message, field)
+}
+
+// GetExtensions returns a list of the extensions values present in m,
+// corresponding with the provided list of extension descriptors, xts.
+// If an extension is missing in m, the corresponding value is nil.
+func GetExtensions(m Message, xts []*ExtensionDesc) ([]interface{}, error) {
+	mr := MessageReflect(m)
+	if mr == nil || !mr.IsValid() {
+		return nil, errNotExtendable
+	}
+
+	vs := make([]interface{}, len(xts))
+	for i, xt := range xts {
+		v, err := GetExtension(m, xt)
+		if err != nil {
+			if err == ErrMissingExtension {
+				continue
+			}
+			return vs, err
+		}
+		vs[i] = v
+	}
+	return vs, nil
+}
+
+// SetExtension sets an extension field in m to the provided value.
+func SetExtension(m Message, xt *ExtensionDesc, v interface{}) error {
+	mr := MessageReflect(m)
+	if mr == nil || !mr.IsValid() || mr.Descriptor().ExtensionRanges().Len() == 0 {
+		return errNotExtendable
+	}
+
+	rv := reflect.ValueOf(v)
+	if reflect.TypeOf(v) != reflect.TypeOf(xt.ExtensionType) {
+		return fmt.Errorf("proto: bad extension value type. got: %T, want: %T", v, xt.ExtensionType)
+	}
+	if rv.Kind() == reflect.Ptr {
+		if rv.IsNil() {
+			return fmt.Errorf("proto: SetExtension called with nil value of type %T", v)
+		}
+		if isScalarKind(rv.Elem().Kind()) {
+			v = rv.Elem().Interface()
+		}
+	}
+
+	xtd := xt.TypeDescriptor()
+	if !isValidExtension(mr.Descriptor(), xtd) {
+		return fmt.Errorf("proto: bad extended type; %T does not extend %T", xt.ExtendedType, m)
+	}
+	mr.Set(xtd, xt.ValueOf(v))
+	clearUnknown(mr, fieldNum(xt.Field))
+	return nil
+}
+
+// SetRawExtension inserts b into the unknown fields of m.
+//
+// Deprecated: Use Message.ProtoReflect.SetUnknown instead.
+func SetRawExtension(m Message, fnum int32, b []byte) {
+	mr := MessageReflect(m)
+	if mr == nil || !mr.IsValid() {
+		return
+	}
+
+	// Verify that the raw field is valid.
+	for b0 := b; len(b0) > 0; {
+		num, _, n := protowire.ConsumeField(b0)
+		if int32(num) != fnum {
+			panic(fmt.Sprintf("mismatching field number: got %d, want %d", num, fnum))
+		}
+		b0 = b0[n:]
+	}
+
+	ClearExtension(m, &ExtensionDesc{Field: fnum})
+	mr.SetUnknown(append(mr.GetUnknown(), b...))
+}
+
+// ExtensionDescs returns a list of extension descriptors found in m,
+// containing descriptors for both populated extension fields in m and
+// also unknown fields of m that are in the extension range.
+// For the later case, an type incomplete descriptor is provided where only
+// the ExtensionDesc.Field field is populated.
+// The order of the extension descriptors is undefined.
+func ExtensionDescs(m Message) ([]*ExtensionDesc, error) {
+	mr := MessageReflect(m)
+	if mr == nil || !mr.IsValid() || mr.Descriptor().ExtensionRanges().Len() == 0 {
+		return nil, errNotExtendable
+	}
+
+	// Collect a set of known extension descriptors.
+	extDescs := make(map[protoreflect.FieldNumber]*ExtensionDesc)
+	mr.Range(func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool {
+		if fd.IsExtension() {
+			xt := fd.(protoreflect.ExtensionTypeDescriptor)
+			if xd, ok := xt.Type().(*ExtensionDesc); ok {
+				extDescs[fd.Number()] = xd
+			}
+		}
+		return true
+	})
+
+	// Collect a set of unknown extension descriptors.
+	extRanges := mr.Descriptor().ExtensionRanges()
+	for b := mr.GetUnknown(); len(b) > 0; {
+		num, _, n := protowire.ConsumeField(b)
+		if extRanges.Has(num) && extDescs[num] == nil {
+			extDescs[num] = nil
+		}
+		b = b[n:]
+	}
+
+	// Transpose the set of descriptors into a list.
+	var xts []*ExtensionDesc
+	for num, xt := range extDescs {
+		if xt == nil {
+			xt = &ExtensionDesc{Field: int32(num)}
+		}
+		xts = append(xts, xt)
+	}
+	return xts, nil
+}
+
+// isValidExtension reports whether xtd is a valid extension descriptor for md.
+func isValidExtension(md protoreflect.MessageDescriptor, xtd protoreflect.ExtensionTypeDescriptor) bool {
+	return xtd.ContainingMessage() == md && md.ExtensionRanges().Has(xtd.Number())
+}
+
+// isScalarKind reports whether k is a protobuf scalar kind (except bytes).
+// This function exists for historical reasons since the representation of
+// scalars differs between v1 and v2, where v1 uses *T and v2 uses T.
+func isScalarKind(k reflect.Kind) bool {
+	switch k {
+	case reflect.Bool, reflect.Int32, reflect.Int64, reflect.Uint32, reflect.Uint64, reflect.Float32, reflect.Float64, reflect.String:
+		return true
+	default:
+		return false
+	}
+}
+
+// clearUnknown removes unknown fields from m where remover.Has reports true.
+func clearUnknown(m protoreflect.Message, remover interface {
+	Has(protoreflect.FieldNumber) bool
+}) {
+	var bo protoreflect.RawFields
+	for bi := m.GetUnknown(); len(bi) > 0; {
+		num, _, n := protowire.ConsumeField(bi)
+		if !remover.Has(num) {
+			bo = append(bo, bi[:n]...)
+		}
+		bi = bi[n:]
+	}
+	if bi := m.GetUnknown(); len(bi) != len(bo) {
+		m.SetUnknown(bo)
+	}
+}
+
+type fieldNum protoreflect.FieldNumber
+
+func (n1 fieldNum) Has(n2 protoreflect.FieldNumber) bool {
+	return protoreflect.FieldNumber(n1) == n2
+}
