diff --git a/vendor/google.golang.org/protobuf/reflect/protodesc/desc.go b/vendor/google.golang.org/protobuf/reflect/protodesc/desc.go
new file mode 100644
index 0000000..37f254d
--- /dev/null
+++ b/vendor/google.golang.org/protobuf/reflect/protodesc/desc.go
@@ -0,0 +1,275 @@
+// 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 protodesc provides functionality for converting
+// FileDescriptorProto messages to/from protoreflect.FileDescriptor values.
+//
+// The google.protobuf.FileDescriptorProto is a protobuf message that describes
+// the type information for a .proto file in a form that is easily serializable.
+// The protoreflect.FileDescriptor is a more structured representation of
+// the FileDescriptorProto message where references and remote dependencies
+// can be directly followed.
+package protodesc
+
+import (
+	"google.golang.org/protobuf/internal/errors"
+	"google.golang.org/protobuf/internal/filedesc"
+	"google.golang.org/protobuf/internal/pragma"
+	"google.golang.org/protobuf/internal/strs"
+	"google.golang.org/protobuf/proto"
+	"google.golang.org/protobuf/reflect/protoreflect"
+	"google.golang.org/protobuf/reflect/protoregistry"
+
+	"google.golang.org/protobuf/types/descriptorpb"
+)
+
+// Resolver is the resolver used by NewFile to resolve dependencies.
+// The enums and messages provided must belong to some parent file,
+// which is also registered.
+//
+// It is implemented by protoregistry.Files.
+type Resolver interface {
+	FindFileByPath(string) (protoreflect.FileDescriptor, error)
+	FindDescriptorByName(protoreflect.FullName) (protoreflect.Descriptor, error)
+}
+
+// FileOptions configures the construction of file descriptors.
+type FileOptions struct {
+	pragma.NoUnkeyedLiterals
+
+	// AllowUnresolvable configures New to permissively allow unresolvable
+	// file, enum, or message dependencies. Unresolved dependencies are replaced
+	// by placeholder equivalents.
+	//
+	// The following dependencies may be left unresolved:
+	//	• Resolving an imported file.
+	//	• Resolving the type for a message field or extension field.
+	//	If the kind of the field is unknown, then a placeholder is used for both
+	//	the Enum and Message accessors on the protoreflect.FieldDescriptor.
+	//	• Resolving an enum value set as the default for an optional enum field.
+	//	If unresolvable, the protoreflect.FieldDescriptor.Default is set to the
+	//	first value in the associated enum (or zero if the also enum dependency
+	//	is also unresolvable). The protoreflect.FieldDescriptor.DefaultEnumValue
+	//	is populated with a placeholder.
+	//	• Resolving the extended message type for an extension field.
+	//	• Resolving the input or output message type for a service method.
+	//
+	// If the unresolved dependency uses a relative name,
+	// then the placeholder will contain an invalid FullName with a "*." prefix,
+	// indicating that the starting prefix of the full name is unknown.
+	AllowUnresolvable bool
+}
+
+// NewFile creates a new protoreflect.FileDescriptor from the provided
+// file descriptor message. See FileOptions.New for more information.
+func NewFile(fd *descriptorpb.FileDescriptorProto, r Resolver) (protoreflect.FileDescriptor, error) {
+	return FileOptions{}.New(fd, r)
+}
+
+// NewFiles creates a new protoregistry.Files from the provided
+// FileDescriptorSet message. See FileOptions.NewFiles for more information.
+func NewFiles(fd *descriptorpb.FileDescriptorSet) (*protoregistry.Files, error) {
+	return FileOptions{}.NewFiles(fd)
+}
+
+// New creates a new protoreflect.FileDescriptor from the provided
+// file descriptor message. The file must represent a valid proto file according
+// to protobuf semantics. The returned descriptor is a deep copy of the input.
+//
+// Any imported files, enum types, or message types referenced in the file are
+// resolved using the provided registry. When looking up an import file path,
+// the path must be unique. The newly created file descriptor is not registered
+// back into the provided file registry.
+func (o FileOptions) New(fd *descriptorpb.FileDescriptorProto, r Resolver) (protoreflect.FileDescriptor, error) {
+	if r == nil {
+		r = (*protoregistry.Files)(nil) // empty resolver
+	}
+
+	// Handle the file descriptor content.
+	f := &filedesc.File{L2: &filedesc.FileL2{}}
+	switch fd.GetSyntax() {
+	case "proto2", "":
+		f.L1.Syntax = protoreflect.Proto2
+	case "proto3":
+		f.L1.Syntax = protoreflect.Proto3
+	default:
+		return nil, errors.New("invalid syntax: %q", fd.GetSyntax())
+	}
+	f.L1.Path = fd.GetName()
+	if f.L1.Path == "" {
+		return nil, errors.New("file path must be populated")
+	}
+	f.L1.Package = protoreflect.FullName(fd.GetPackage())
+	if !f.L1.Package.IsValid() && f.L1.Package != "" {
+		return nil, errors.New("invalid package: %q", f.L1.Package)
+	}
+	if opts := fd.GetOptions(); opts != nil {
+		opts = proto.Clone(opts).(*descriptorpb.FileOptions)
+		f.L2.Options = func() protoreflect.ProtoMessage { return opts }
+	}
+
+	f.L2.Imports = make(filedesc.FileImports, len(fd.GetDependency()))
+	for _, i := range fd.GetPublicDependency() {
+		if !(0 <= i && int(i) < len(f.L2.Imports)) || f.L2.Imports[i].IsPublic {
+			return nil, errors.New("invalid or duplicate public import index: %d", i)
+		}
+		f.L2.Imports[i].IsPublic = true
+	}
+	for _, i := range fd.GetWeakDependency() {
+		if !(0 <= i && int(i) < len(f.L2.Imports)) || f.L2.Imports[i].IsWeak {
+			return nil, errors.New("invalid or duplicate weak import index: %d", i)
+		}
+		f.L2.Imports[i].IsWeak = true
+	}
+	imps := importSet{f.Path(): true}
+	for i, path := range fd.GetDependency() {
+		imp := &f.L2.Imports[i]
+		f, err := r.FindFileByPath(path)
+		if err == protoregistry.NotFound && (o.AllowUnresolvable || imp.IsWeak) {
+			f = filedesc.PlaceholderFile(path)
+		} else if err != nil {
+			return nil, errors.New("could not resolve import %q: %v", path, err)
+		}
+		imp.FileDescriptor = f
+
+		if imps[imp.Path()] {
+			return nil, errors.New("already imported %q", path)
+		}
+		imps[imp.Path()] = true
+	}
+	for i := range fd.GetDependency() {
+		imp := &f.L2.Imports[i]
+		imps.importPublic(imp.Imports())
+	}
+
+	// Handle source locations.
+	for _, loc := range fd.GetSourceCodeInfo().GetLocation() {
+		var l protoreflect.SourceLocation
+		// TODO: Validate that the path points to an actual declaration?
+		l.Path = protoreflect.SourcePath(loc.GetPath())
+		s := loc.GetSpan()
+		switch len(s) {
+		case 3:
+			l.StartLine, l.StartColumn, l.EndLine, l.EndColumn = int(s[0]), int(s[1]), int(s[0]), int(s[2])
+		case 4:
+			l.StartLine, l.StartColumn, l.EndLine, l.EndColumn = int(s[0]), int(s[1]), int(s[2]), int(s[3])
+		default:
+			return nil, errors.New("invalid span: %v", s)
+		}
+		// TODO: Validate that the span information is sensible?
+		// See https://github.com/protocolbuffers/protobuf/issues/6378.
+		if false && (l.EndLine < l.StartLine || l.StartLine < 0 || l.StartColumn < 0 || l.EndColumn < 0 ||
+			(l.StartLine == l.EndLine && l.EndColumn <= l.StartColumn)) {
+			return nil, errors.New("invalid span: %v", s)
+		}
+		l.LeadingDetachedComments = loc.GetLeadingDetachedComments()
+		l.LeadingComments = loc.GetLeadingComments()
+		l.TrailingComments = loc.GetTrailingComments()
+		f.L2.Locations.List = append(f.L2.Locations.List, l)
+	}
+
+	// Step 1: Allocate and derive the names for all declarations.
+	// This copies all fields from the descriptor proto except:
+	//	google.protobuf.FieldDescriptorProto.type_name
+	//	google.protobuf.FieldDescriptorProto.default_value
+	//	google.protobuf.FieldDescriptorProto.oneof_index
+	//	google.protobuf.FieldDescriptorProto.extendee
+	//	google.protobuf.MethodDescriptorProto.input
+	//	google.protobuf.MethodDescriptorProto.output
+	var err error
+	sb := new(strs.Builder)
+	r1 := make(descsByName)
+	if f.L1.Enums.List, err = r1.initEnumDeclarations(fd.GetEnumType(), f, sb); err != nil {
+		return nil, err
+	}
+	if f.L1.Messages.List, err = r1.initMessagesDeclarations(fd.GetMessageType(), f, sb); err != nil {
+		return nil, err
+	}
+	if f.L1.Extensions.List, err = r1.initExtensionDeclarations(fd.GetExtension(), f, sb); err != nil {
+		return nil, err
+	}
+	if f.L1.Services.List, err = r1.initServiceDeclarations(fd.GetService(), f, sb); err != nil {
+		return nil, err
+	}
+
+	// Step 2: Resolve every dependency reference not handled by step 1.
+	r2 := &resolver{local: r1, remote: r, imports: imps, allowUnresolvable: o.AllowUnresolvable}
+	if err := r2.resolveMessageDependencies(f.L1.Messages.List, fd.GetMessageType()); err != nil {
+		return nil, err
+	}
+	if err := r2.resolveExtensionDependencies(f.L1.Extensions.List, fd.GetExtension()); err != nil {
+		return nil, err
+	}
+	if err := r2.resolveServiceDependencies(f.L1.Services.List, fd.GetService()); err != nil {
+		return nil, err
+	}
+
+	// Step 3: Validate every enum, message, and extension declaration.
+	if err := validateEnumDeclarations(f.L1.Enums.List, fd.GetEnumType()); err != nil {
+		return nil, err
+	}
+	if err := validateMessageDeclarations(f.L1.Messages.List, fd.GetMessageType()); err != nil {
+		return nil, err
+	}
+	if err := validateExtensionDeclarations(f.L1.Extensions.List, fd.GetExtension()); err != nil {
+		return nil, err
+	}
+
+	return f, nil
+}
+
+type importSet map[string]bool
+
+func (is importSet) importPublic(imps protoreflect.FileImports) {
+	for i := 0; i < imps.Len(); i++ {
+		if imp := imps.Get(i); imp.IsPublic {
+			is[imp.Path()] = true
+			is.importPublic(imp.Imports())
+		}
+	}
+}
+
+// NewFiles creates a new protoregistry.Files from the provided
+// FileDescriptorSet message. The descriptor set must include only
+// valid files according to protobuf semantics. The returned descriptors
+// are a deep copy of the input.
+func (o FileOptions) NewFiles(fds *descriptorpb.FileDescriptorSet) (*protoregistry.Files, error) {
+	files := make(map[string]*descriptorpb.FileDescriptorProto)
+	for _, fd := range fds.File {
+		if _, ok := files[fd.GetName()]; ok {
+			return nil, errors.New("file appears multiple times: %q", fd.GetName())
+		}
+		files[fd.GetName()] = fd
+	}
+	r := &protoregistry.Files{}
+	for _, fd := range files {
+		if err := o.addFileDeps(r, fd, files); err != nil {
+			return nil, err
+		}
+	}
+	return r, nil
+}
+func (o FileOptions) addFileDeps(r *protoregistry.Files, fd *descriptorpb.FileDescriptorProto, files map[string]*descriptorpb.FileDescriptorProto) error {
+	// Set the entry to nil while descending into a file's dependencies to detect cycles.
+	files[fd.GetName()] = nil
+	for _, dep := range fd.Dependency {
+		depfd, ok := files[dep]
+		if depfd == nil {
+			if ok {
+				return errors.New("import cycle in file: %q", dep)
+			}
+			continue
+		}
+		if err := o.addFileDeps(r, depfd, files); err != nil {
+			return err
+		}
+	}
+	// Delete the entry once dependencies are processed.
+	delete(files, fd.GetName())
+	f, err := o.New(fd, r)
+	if err != nil {
+		return err
+	}
+	return r.RegisterFile(f)
+}
diff --git a/vendor/google.golang.org/protobuf/reflect/protodesc/desc_init.go b/vendor/google.golang.org/protobuf/reflect/protodesc/desc_init.go
new file mode 100644
index 0000000..673a230
--- /dev/null
+++ b/vendor/google.golang.org/protobuf/reflect/protodesc/desc_init.go
@@ -0,0 +1,248 @@
+// 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 protodesc
+
+import (
+	"google.golang.org/protobuf/internal/errors"
+	"google.golang.org/protobuf/internal/filedesc"
+	"google.golang.org/protobuf/internal/strs"
+	"google.golang.org/protobuf/proto"
+	"google.golang.org/protobuf/reflect/protoreflect"
+
+	"google.golang.org/protobuf/types/descriptorpb"
+)
+
+type descsByName map[protoreflect.FullName]protoreflect.Descriptor
+
+func (r descsByName) initEnumDeclarations(eds []*descriptorpb.EnumDescriptorProto, parent protoreflect.Descriptor, sb *strs.Builder) (es []filedesc.Enum, err error) {
+	es = make([]filedesc.Enum, len(eds)) // allocate up-front to ensure stable pointers
+	for i, ed := range eds {
+		e := &es[i]
+		e.L2 = new(filedesc.EnumL2)
+		if e.L0, err = r.makeBase(e, parent, ed.GetName(), i, sb); err != nil {
+			return nil, err
+		}
+		if opts := ed.GetOptions(); opts != nil {
+			opts = proto.Clone(opts).(*descriptorpb.EnumOptions)
+			e.L2.Options = func() protoreflect.ProtoMessage { return opts }
+		}
+		for _, s := range ed.GetReservedName() {
+			e.L2.ReservedNames.List = append(e.L2.ReservedNames.List, protoreflect.Name(s))
+		}
+		for _, rr := range ed.GetReservedRange() {
+			e.L2.ReservedRanges.List = append(e.L2.ReservedRanges.List, [2]protoreflect.EnumNumber{
+				protoreflect.EnumNumber(rr.GetStart()),
+				protoreflect.EnumNumber(rr.GetEnd()),
+			})
+		}
+		if e.L2.Values.List, err = r.initEnumValuesFromDescriptorProto(ed.GetValue(), e, sb); err != nil {
+			return nil, err
+		}
+	}
+	return es, nil
+}
+
+func (r descsByName) initEnumValuesFromDescriptorProto(vds []*descriptorpb.EnumValueDescriptorProto, parent protoreflect.Descriptor, sb *strs.Builder) (vs []filedesc.EnumValue, err error) {
+	vs = make([]filedesc.EnumValue, len(vds)) // allocate up-front to ensure stable pointers
+	for i, vd := range vds {
+		v := &vs[i]
+		if v.L0, err = r.makeBase(v, parent, vd.GetName(), i, sb); err != nil {
+			return nil, err
+		}
+		if opts := vd.GetOptions(); opts != nil {
+			opts = proto.Clone(opts).(*descriptorpb.EnumValueOptions)
+			v.L1.Options = func() protoreflect.ProtoMessage { return opts }
+		}
+		v.L1.Number = protoreflect.EnumNumber(vd.GetNumber())
+	}
+	return vs, nil
+}
+
+func (r descsByName) initMessagesDeclarations(mds []*descriptorpb.DescriptorProto, parent protoreflect.Descriptor, sb *strs.Builder) (ms []filedesc.Message, err error) {
+	ms = make([]filedesc.Message, len(mds)) // allocate up-front to ensure stable pointers
+	for i, md := range mds {
+		m := &ms[i]
+		m.L2 = new(filedesc.MessageL2)
+		if m.L0, err = r.makeBase(m, parent, md.GetName(), i, sb); err != nil {
+			return nil, err
+		}
+		if opts := md.GetOptions(); opts != nil {
+			opts = proto.Clone(opts).(*descriptorpb.MessageOptions)
+			m.L2.Options = func() protoreflect.ProtoMessage { return opts }
+			m.L1.IsMapEntry = opts.GetMapEntry()
+			m.L1.IsMessageSet = opts.GetMessageSetWireFormat()
+		}
+		for _, s := range md.GetReservedName() {
+			m.L2.ReservedNames.List = append(m.L2.ReservedNames.List, protoreflect.Name(s))
+		}
+		for _, rr := range md.GetReservedRange() {
+			m.L2.ReservedRanges.List = append(m.L2.ReservedRanges.List, [2]protoreflect.FieldNumber{
+				protoreflect.FieldNumber(rr.GetStart()),
+				protoreflect.FieldNumber(rr.GetEnd()),
+			})
+		}
+		for _, xr := range md.GetExtensionRange() {
+			m.L2.ExtensionRanges.List = append(m.L2.ExtensionRanges.List, [2]protoreflect.FieldNumber{
+				protoreflect.FieldNumber(xr.GetStart()),
+				protoreflect.FieldNumber(xr.GetEnd()),
+			})
+			var optsFunc func() protoreflect.ProtoMessage
+			if opts := xr.GetOptions(); opts != nil {
+				opts = proto.Clone(opts).(*descriptorpb.ExtensionRangeOptions)
+				optsFunc = func() protoreflect.ProtoMessage { return opts }
+			}
+			m.L2.ExtensionRangeOptions = append(m.L2.ExtensionRangeOptions, optsFunc)
+		}
+		if m.L2.Fields.List, err = r.initFieldsFromDescriptorProto(md.GetField(), m, sb); err != nil {
+			return nil, err
+		}
+		if m.L2.Oneofs.List, err = r.initOneofsFromDescriptorProto(md.GetOneofDecl(), m, sb); err != nil {
+			return nil, err
+		}
+		if m.L1.Enums.List, err = r.initEnumDeclarations(md.GetEnumType(), m, sb); err != nil {
+			return nil, err
+		}
+		if m.L1.Messages.List, err = r.initMessagesDeclarations(md.GetNestedType(), m, sb); err != nil {
+			return nil, err
+		}
+		if m.L1.Extensions.List, err = r.initExtensionDeclarations(md.GetExtension(), m, sb); err != nil {
+			return nil, err
+		}
+	}
+	return ms, nil
+}
+
+func (r descsByName) initFieldsFromDescriptorProto(fds []*descriptorpb.FieldDescriptorProto, parent protoreflect.Descriptor, sb *strs.Builder) (fs []filedesc.Field, err error) {
+	fs = make([]filedesc.Field, len(fds)) // allocate up-front to ensure stable pointers
+	for i, fd := range fds {
+		f := &fs[i]
+		if f.L0, err = r.makeBase(f, parent, fd.GetName(), i, sb); err != nil {
+			return nil, err
+		}
+		f.L1.IsProto3Optional = fd.GetProto3Optional()
+		if opts := fd.GetOptions(); opts != nil {
+			opts = proto.Clone(opts).(*descriptorpb.FieldOptions)
+			f.L1.Options = func() protoreflect.ProtoMessage { return opts }
+			f.L1.IsWeak = opts.GetWeak()
+			f.L1.HasPacked = opts.Packed != nil
+			f.L1.IsPacked = opts.GetPacked()
+		}
+		f.L1.Number = protoreflect.FieldNumber(fd.GetNumber())
+		f.L1.Cardinality = protoreflect.Cardinality(fd.GetLabel())
+		if fd.Type != nil {
+			f.L1.Kind = protoreflect.Kind(fd.GetType())
+		}
+		if fd.JsonName != nil {
+			f.L1.JSONName.Init(fd.GetJsonName())
+		}
+	}
+	return fs, nil
+}
+
+func (r descsByName) initOneofsFromDescriptorProto(ods []*descriptorpb.OneofDescriptorProto, parent protoreflect.Descriptor, sb *strs.Builder) (os []filedesc.Oneof, err error) {
+	os = make([]filedesc.Oneof, len(ods)) // allocate up-front to ensure stable pointers
+	for i, od := range ods {
+		o := &os[i]
+		if o.L0, err = r.makeBase(o, parent, od.GetName(), i, sb); err != nil {
+			return nil, err
+		}
+		if opts := od.GetOptions(); opts != nil {
+			opts = proto.Clone(opts).(*descriptorpb.OneofOptions)
+			o.L1.Options = func() protoreflect.ProtoMessage { return opts }
+		}
+	}
+	return os, nil
+}
+
+func (r descsByName) initExtensionDeclarations(xds []*descriptorpb.FieldDescriptorProto, parent protoreflect.Descriptor, sb *strs.Builder) (xs []filedesc.Extension, err error) {
+	xs = make([]filedesc.Extension, len(xds)) // allocate up-front to ensure stable pointers
+	for i, xd := range xds {
+		x := &xs[i]
+		x.L2 = new(filedesc.ExtensionL2)
+		if x.L0, err = r.makeBase(x, parent, xd.GetName(), i, sb); err != nil {
+			return nil, err
+		}
+		if opts := xd.GetOptions(); opts != nil {
+			opts = proto.Clone(opts).(*descriptorpb.FieldOptions)
+			x.L2.Options = func() protoreflect.ProtoMessage { return opts }
+			x.L2.IsPacked = opts.GetPacked()
+		}
+		x.L1.Number = protoreflect.FieldNumber(xd.GetNumber())
+		x.L1.Cardinality = protoreflect.Cardinality(xd.GetLabel())
+		if xd.Type != nil {
+			x.L1.Kind = protoreflect.Kind(xd.GetType())
+		}
+		if xd.JsonName != nil {
+			x.L2.JSONName.Init(xd.GetJsonName())
+		}
+	}
+	return xs, nil
+}
+
+func (r descsByName) initServiceDeclarations(sds []*descriptorpb.ServiceDescriptorProto, parent protoreflect.Descriptor, sb *strs.Builder) (ss []filedesc.Service, err error) {
+	ss = make([]filedesc.Service, len(sds)) // allocate up-front to ensure stable pointers
+	for i, sd := range sds {
+		s := &ss[i]
+		s.L2 = new(filedesc.ServiceL2)
+		if s.L0, err = r.makeBase(s, parent, sd.GetName(), i, sb); err != nil {
+			return nil, err
+		}
+		if opts := sd.GetOptions(); opts != nil {
+			opts = proto.Clone(opts).(*descriptorpb.ServiceOptions)
+			s.L2.Options = func() protoreflect.ProtoMessage { return opts }
+		}
+		if s.L2.Methods.List, err = r.initMethodsFromDescriptorProto(sd.GetMethod(), s, sb); err != nil {
+			return nil, err
+		}
+	}
+	return ss, nil
+}
+
+func (r descsByName) initMethodsFromDescriptorProto(mds []*descriptorpb.MethodDescriptorProto, parent protoreflect.Descriptor, sb *strs.Builder) (ms []filedesc.Method, err error) {
+	ms = make([]filedesc.Method, len(mds)) // allocate up-front to ensure stable pointers
+	for i, md := range mds {
+		m := &ms[i]
+		if m.L0, err = r.makeBase(m, parent, md.GetName(), i, sb); err != nil {
+			return nil, err
+		}
+		if opts := md.GetOptions(); opts != nil {
+			opts = proto.Clone(opts).(*descriptorpb.MethodOptions)
+			m.L1.Options = func() protoreflect.ProtoMessage { return opts }
+		}
+		m.L1.IsStreamingClient = md.GetClientStreaming()
+		m.L1.IsStreamingServer = md.GetServerStreaming()
+	}
+	return ms, nil
+}
+
+func (r descsByName) makeBase(child, parent protoreflect.Descriptor, name string, idx int, sb *strs.Builder) (filedesc.BaseL0, error) {
+	if !protoreflect.Name(name).IsValid() {
+		return filedesc.BaseL0{}, errors.New("descriptor %q has an invalid nested name: %q", parent.FullName(), name)
+	}
+
+	// Derive the full name of the child.
+	// Note that enum values are a sibling to the enum parent in the namespace.
+	var fullName protoreflect.FullName
+	if _, ok := parent.(protoreflect.EnumDescriptor); ok {
+		fullName = sb.AppendFullName(parent.FullName().Parent(), protoreflect.Name(name))
+	} else {
+		fullName = sb.AppendFullName(parent.FullName(), protoreflect.Name(name))
+	}
+	if _, ok := r[fullName]; ok {
+		return filedesc.BaseL0{}, errors.New("descriptor %q already declared", fullName)
+	}
+	r[fullName] = child
+
+	// TODO: Verify that the full name does not already exist in the resolver?
+	// This is not as critical since most usages of NewFile will register
+	// the created file back into the registry, which will perform this check.
+
+	return filedesc.BaseL0{
+		FullName:   fullName,
+		ParentFile: parent.ParentFile().(*filedesc.File),
+		Parent:     parent,
+		Index:      idx,
+	}, nil
+}
diff --git a/vendor/google.golang.org/protobuf/reflect/protodesc/desc_resolve.go b/vendor/google.golang.org/protobuf/reflect/protodesc/desc_resolve.go
new file mode 100644
index 0000000..cebb36c
--- /dev/null
+++ b/vendor/google.golang.org/protobuf/reflect/protodesc/desc_resolve.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 protodesc
+
+import (
+	"google.golang.org/protobuf/internal/encoding/defval"
+	"google.golang.org/protobuf/internal/errors"
+	"google.golang.org/protobuf/internal/filedesc"
+	"google.golang.org/protobuf/reflect/protoreflect"
+	"google.golang.org/protobuf/reflect/protoregistry"
+
+	"google.golang.org/protobuf/types/descriptorpb"
+)
+
+// resolver is a wrapper around a local registry of declarations within the file
+// and the remote resolver. The remote resolver is restricted to only return
+// descriptors that have been imported.
+type resolver struct {
+	local   descsByName
+	remote  Resolver
+	imports importSet
+
+	allowUnresolvable bool
+}
+
+func (r *resolver) resolveMessageDependencies(ms []filedesc.Message, mds []*descriptorpb.DescriptorProto) (err error) {
+	for i, md := range mds {
+		m := &ms[i]
+		for j, fd := range md.GetField() {
+			f := &m.L2.Fields.List[j]
+			if f.L1.Cardinality == protoreflect.Required {
+				m.L2.RequiredNumbers.List = append(m.L2.RequiredNumbers.List, f.L1.Number)
+			}
+			if fd.OneofIndex != nil {
+				k := int(fd.GetOneofIndex())
+				if !(0 <= k && k < len(md.GetOneofDecl())) {
+					return errors.New("message field %q has an invalid oneof index: %d", f.FullName(), k)
+				}
+				o := &m.L2.Oneofs.List[k]
+				f.L1.ContainingOneof = o
+				o.L1.Fields.List = append(o.L1.Fields.List, f)
+			}
+
+			if f.L1.Kind, f.L1.Enum, f.L1.Message, err = r.findTarget(f.Kind(), f.Parent().FullName(), partialName(fd.GetTypeName()), f.IsWeak()); err != nil {
+				return errors.New("message field %q cannot resolve type: %v", f.FullName(), err)
+			}
+			if fd.DefaultValue != nil {
+				v, ev, err := unmarshalDefault(fd.GetDefaultValue(), f, r.allowUnresolvable)
+				if err != nil {
+					return errors.New("message field %q has invalid default: %v", f.FullName(), err)
+				}
+				f.L1.Default = filedesc.DefaultValue(v, ev)
+			}
+		}
+
+		if err := r.resolveMessageDependencies(m.L1.Messages.List, md.GetNestedType()); err != nil {
+			return err
+		}
+		if err := r.resolveExtensionDependencies(m.L1.Extensions.List, md.GetExtension()); err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+func (r *resolver) resolveExtensionDependencies(xs []filedesc.Extension, xds []*descriptorpb.FieldDescriptorProto) (err error) {
+	for i, xd := range xds {
+		x := &xs[i]
+		if x.L1.Extendee, err = r.findMessageDescriptor(x.Parent().FullName(), partialName(xd.GetExtendee()), false); err != nil {
+			return errors.New("extension field %q cannot resolve extendee: %v", x.FullName(), err)
+		}
+		if x.L1.Kind, x.L2.Enum, x.L2.Message, err = r.findTarget(x.Kind(), x.Parent().FullName(), partialName(xd.GetTypeName()), false); err != nil {
+			return errors.New("extension field %q cannot resolve type: %v", x.FullName(), err)
+		}
+		if xd.DefaultValue != nil {
+			v, ev, err := unmarshalDefault(xd.GetDefaultValue(), x, r.allowUnresolvable)
+			if err != nil {
+				return errors.New("extension field %q has invalid default: %v", x.FullName(), err)
+			}
+			x.L2.Default = filedesc.DefaultValue(v, ev)
+		}
+	}
+	return nil
+}
+
+func (r *resolver) resolveServiceDependencies(ss []filedesc.Service, sds []*descriptorpb.ServiceDescriptorProto) (err error) {
+	for i, sd := range sds {
+		s := &ss[i]
+		for j, md := range sd.GetMethod() {
+			m := &s.L2.Methods.List[j]
+			m.L1.Input, err = r.findMessageDescriptor(m.Parent().FullName(), partialName(md.GetInputType()), false)
+			if err != nil {
+				return errors.New("service method %q cannot resolve input: %v", m.FullName(), err)
+			}
+			m.L1.Output, err = r.findMessageDescriptor(s.FullName(), partialName(md.GetOutputType()), false)
+			if err != nil {
+				return errors.New("service method %q cannot resolve output: %v", m.FullName(), err)
+			}
+		}
+	}
+	return nil
+}
+
+// findTarget finds an enum or message descriptor if k is an enum, message,
+// group, or unknown. If unknown, and the name could be resolved, the kind
+// returned kind is set based on the type of the resolved descriptor.
+func (r *resolver) findTarget(k protoreflect.Kind, scope protoreflect.FullName, ref partialName, isWeak bool) (protoreflect.Kind, protoreflect.EnumDescriptor, protoreflect.MessageDescriptor, error) {
+	switch k {
+	case protoreflect.EnumKind:
+		ed, err := r.findEnumDescriptor(scope, ref, isWeak)
+		if err != nil {
+			return 0, nil, nil, err
+		}
+		return k, ed, nil, nil
+	case protoreflect.MessageKind, protoreflect.GroupKind:
+		md, err := r.findMessageDescriptor(scope, ref, isWeak)
+		if err != nil {
+			return 0, nil, nil, err
+		}
+		return k, nil, md, nil
+	case 0:
+		// Handle unspecified kinds (possible with parsers that operate
+		// on a per-file basis without knowledge of dependencies).
+		d, err := r.findDescriptor(scope, ref)
+		if err == protoregistry.NotFound && (r.allowUnresolvable || isWeak) {
+			return k, filedesc.PlaceholderEnum(ref.FullName()), filedesc.PlaceholderMessage(ref.FullName()), nil
+		} else if err == protoregistry.NotFound {
+			return 0, nil, nil, errors.New("%q not found", ref.FullName())
+		} else if err != nil {
+			return 0, nil, nil, err
+		}
+		switch d := d.(type) {
+		case protoreflect.EnumDescriptor:
+			return protoreflect.EnumKind, d, nil, nil
+		case protoreflect.MessageDescriptor:
+			return protoreflect.MessageKind, nil, d, nil
+		default:
+			return 0, nil, nil, errors.New("unknown kind")
+		}
+	default:
+		if ref != "" {
+			return 0, nil, nil, errors.New("target name cannot be specified for %v", k)
+		}
+		if !k.IsValid() {
+			return 0, nil, nil, errors.New("invalid kind: %d", k)
+		}
+		return k, nil, nil, nil
+	}
+}
+
+// findDescriptor finds the descriptor by name,
+// which may be a relative name within some scope.
+//
+// Suppose the scope was "fizz.buzz" and the reference was "Foo.Bar",
+// then the following full names are searched:
+//	* fizz.buzz.Foo.Bar
+//	* fizz.Foo.Bar
+//	* Foo.Bar
+func (r *resolver) findDescriptor(scope protoreflect.FullName, ref partialName) (protoreflect.Descriptor, error) {
+	if !ref.IsValid() {
+		return nil, errors.New("invalid name reference: %q", ref)
+	}
+	if ref.IsFull() {
+		scope, ref = "", ref[1:]
+	}
+	var foundButNotImported protoreflect.Descriptor
+	for {
+		// Derive the full name to search.
+		s := protoreflect.FullName(ref)
+		if scope != "" {
+			s = scope + "." + s
+		}
+
+		// Check the current file for the descriptor.
+		if d, ok := r.local[s]; ok {
+			return d, nil
+		}
+
+		// Check the remote registry for the descriptor.
+		d, err := r.remote.FindDescriptorByName(s)
+		if err == nil {
+			// Only allow descriptors covered by one of the imports.
+			if r.imports[d.ParentFile().Path()] {
+				return d, nil
+			}
+			foundButNotImported = d
+		} else if err != protoregistry.NotFound {
+			return nil, errors.Wrap(err, "%q", s)
+		}
+
+		// Continue on at a higher level of scoping.
+		if scope == "" {
+			if d := foundButNotImported; d != nil {
+				return nil, errors.New("resolved %q, but %q is not imported", d.FullName(), d.ParentFile().Path())
+			}
+			return nil, protoregistry.NotFound
+		}
+		scope = scope.Parent()
+	}
+}
+
+func (r *resolver) findEnumDescriptor(scope protoreflect.FullName, ref partialName, isWeak bool) (protoreflect.EnumDescriptor, error) {
+	d, err := r.findDescriptor(scope, ref)
+	if err == protoregistry.NotFound && (r.allowUnresolvable || isWeak) {
+		return filedesc.PlaceholderEnum(ref.FullName()), nil
+	} else if err == protoregistry.NotFound {
+		return nil, errors.New("%q not found", ref.FullName())
+	} else if err != nil {
+		return nil, err
+	}
+	ed, ok := d.(protoreflect.EnumDescriptor)
+	if !ok {
+		return nil, errors.New("resolved %q, but it is not an enum", d.FullName())
+	}
+	return ed, nil
+}
+
+func (r *resolver) findMessageDescriptor(scope protoreflect.FullName, ref partialName, isWeak bool) (protoreflect.MessageDescriptor, error) {
+	d, err := r.findDescriptor(scope, ref)
+	if err == protoregistry.NotFound && (r.allowUnresolvable || isWeak) {
+		return filedesc.PlaceholderMessage(ref.FullName()), nil
+	} else if err == protoregistry.NotFound {
+		return nil, errors.New("%q not found", ref.FullName())
+	} else if err != nil {
+		return nil, err
+	}
+	md, ok := d.(protoreflect.MessageDescriptor)
+	if !ok {
+		return nil, errors.New("resolved %q, but it is not an message", d.FullName())
+	}
+	return md, nil
+}
+
+// partialName is the partial name. A leading dot means that the name is full,
+// otherwise the name is relative to some current scope.
+// See google.protobuf.FieldDescriptorProto.type_name.
+type partialName string
+
+func (s partialName) IsFull() bool {
+	return len(s) > 0 && s[0] == '.'
+}
+
+func (s partialName) IsValid() bool {
+	if s.IsFull() {
+		return protoreflect.FullName(s[1:]).IsValid()
+	}
+	return protoreflect.FullName(s).IsValid()
+}
+
+const unknownPrefix = "*."
+
+// FullName converts the partial name to a full name on a best-effort basis.
+// If relative, it creates an invalid full name, using a "*." prefix
+// to indicate that the start of the full name is unknown.
+func (s partialName) FullName() protoreflect.FullName {
+	if s.IsFull() {
+		return protoreflect.FullName(s[1:])
+	}
+	return protoreflect.FullName(unknownPrefix + s)
+}
+
+func unmarshalDefault(s string, fd protoreflect.FieldDescriptor, allowUnresolvable bool) (protoreflect.Value, protoreflect.EnumValueDescriptor, error) {
+	var evs protoreflect.EnumValueDescriptors
+	if fd.Enum() != nil {
+		evs = fd.Enum().Values()
+	}
+	v, ev, err := defval.Unmarshal(s, fd.Kind(), evs, defval.Descriptor)
+	if err != nil && allowUnresolvable && evs != nil && protoreflect.Name(s).IsValid() {
+		v = protoreflect.ValueOfEnum(0)
+		if evs.Len() > 0 {
+			v = protoreflect.ValueOfEnum(evs.Get(0).Number())
+		}
+		ev = filedesc.PlaceholderEnumValue(fd.Enum().FullName().Parent().Append(protoreflect.Name(s)))
+	} else if err != nil {
+		return v, ev, err
+	}
+	if fd.Syntax() == protoreflect.Proto3 {
+		return v, ev, errors.New("cannot be specified under proto3 semantics")
+	}
+	if fd.Kind() == protoreflect.MessageKind || fd.Kind() == protoreflect.GroupKind || fd.Cardinality() == protoreflect.Repeated {
+		return v, ev, errors.New("cannot be specified on composite types")
+	}
+	return v, ev, nil
+}
diff --git a/vendor/google.golang.org/protobuf/reflect/protodesc/desc_validate.go b/vendor/google.golang.org/protobuf/reflect/protodesc/desc_validate.go
new file mode 100644
index 0000000..cf9641a
--- /dev/null
+++ b/vendor/google.golang.org/protobuf/reflect/protodesc/desc_validate.go
@@ -0,0 +1,370 @@
+// 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 protodesc
+
+import (
+	"strings"
+	"unicode"
+
+	"google.golang.org/protobuf/encoding/protowire"
+	"google.golang.org/protobuf/internal/errors"
+	"google.golang.org/protobuf/internal/filedesc"
+	"google.golang.org/protobuf/internal/flags"
+	"google.golang.org/protobuf/internal/strs"
+	"google.golang.org/protobuf/reflect/protoreflect"
+
+	"google.golang.org/protobuf/types/descriptorpb"
+)
+
+func validateEnumDeclarations(es []filedesc.Enum, eds []*descriptorpb.EnumDescriptorProto) error {
+	for i, ed := range eds {
+		e := &es[i]
+		if err := e.L2.ReservedNames.CheckValid(); err != nil {
+			return errors.New("enum %q reserved names has %v", e.FullName(), err)
+		}
+		if err := e.L2.ReservedRanges.CheckValid(); err != nil {
+			return errors.New("enum %q reserved ranges has %v", e.FullName(), err)
+		}
+		if len(ed.GetValue()) == 0 {
+			return errors.New("enum %q must contain at least one value declaration", e.FullName())
+		}
+		allowAlias := ed.GetOptions().GetAllowAlias()
+		foundAlias := false
+		for i := 0; i < e.Values().Len(); i++ {
+			v1 := e.Values().Get(i)
+			if v2 := e.Values().ByNumber(v1.Number()); v1 != v2 {
+				foundAlias = true
+				if !allowAlias {
+					return errors.New("enum %q has conflicting non-aliased values on number %d: %q with %q", e.FullName(), v1.Number(), v1.Name(), v2.Name())
+				}
+			}
+		}
+		if allowAlias && !foundAlias {
+			return errors.New("enum %q allows aliases, but none were found", e.FullName())
+		}
+		if e.Syntax() == protoreflect.Proto3 {
+			if v := e.Values().Get(0); v.Number() != 0 {
+				return errors.New("enum %q using proto3 semantics must have zero number for the first value", v.FullName())
+			}
+			// Verify that value names in proto3 do not conflict if the
+			// case-insensitive prefix is removed.
+			// See protoc v3.8.0: src/google/protobuf/descriptor.cc:4991-5055
+			names := map[string]protoreflect.EnumValueDescriptor{}
+			prefix := strings.Replace(strings.ToLower(string(e.Name())), "_", "", -1)
+			for i := 0; i < e.Values().Len(); i++ {
+				v1 := e.Values().Get(i)
+				s := strs.EnumValueName(strs.TrimEnumPrefix(string(v1.Name()), prefix))
+				if v2, ok := names[s]; ok && v1.Number() != v2.Number() {
+					return errors.New("enum %q using proto3 semantics has conflict: %q with %q", e.FullName(), v1.Name(), v2.Name())
+				}
+				names[s] = v1
+			}
+		}
+
+		for j, vd := range ed.GetValue() {
+			v := &e.L2.Values.List[j]
+			if vd.Number == nil {
+				return errors.New("enum value %q must have a specified number", v.FullName())
+			}
+			if e.L2.ReservedNames.Has(v.Name()) {
+				return errors.New("enum value %q must not use reserved name", v.FullName())
+			}
+			if e.L2.ReservedRanges.Has(v.Number()) {
+				return errors.New("enum value %q must not use reserved number %d", v.FullName(), v.Number())
+			}
+		}
+	}
+	return nil
+}
+
+func validateMessageDeclarations(ms []filedesc.Message, mds []*descriptorpb.DescriptorProto) error {
+	for i, md := range mds {
+		m := &ms[i]
+
+		// Handle the message descriptor itself.
+		isMessageSet := md.GetOptions().GetMessageSetWireFormat()
+		if err := m.L2.ReservedNames.CheckValid(); err != nil {
+			return errors.New("message %q reserved names has %v", m.FullName(), err)
+		}
+		if err := m.L2.ReservedRanges.CheckValid(isMessageSet); err != nil {
+			return errors.New("message %q reserved ranges has %v", m.FullName(), err)
+		}
+		if err := m.L2.ExtensionRanges.CheckValid(isMessageSet); err != nil {
+			return errors.New("message %q extension ranges has %v", m.FullName(), err)
+		}
+		if err := (*filedesc.FieldRanges).CheckOverlap(&m.L2.ReservedRanges, &m.L2.ExtensionRanges); err != nil {
+			return errors.New("message %q reserved and extension ranges has %v", m.FullName(), err)
+		}
+		for i := 0; i < m.Fields().Len(); i++ {
+			f1 := m.Fields().Get(i)
+			if f2 := m.Fields().ByNumber(f1.Number()); f1 != f2 {
+				return errors.New("message %q has conflicting fields: %q with %q", m.FullName(), f1.Name(), f2.Name())
+			}
+		}
+		if isMessageSet && !flags.ProtoLegacy {
+			return errors.New("message %q is a MessageSet, which is a legacy proto1 feature that is no longer supported", m.FullName())
+		}
+		if isMessageSet && (m.Syntax() != protoreflect.Proto2 || m.Fields().Len() > 0 || m.ExtensionRanges().Len() == 0) {
+			return errors.New("message %q is an invalid proto1 MessageSet", m.FullName())
+		}
+		if m.Syntax() == protoreflect.Proto3 {
+			if m.ExtensionRanges().Len() > 0 {
+				return errors.New("message %q using proto3 semantics cannot have extension ranges", m.FullName())
+			}
+			// Verify that field names in proto3 do not conflict if lowercased
+			// with all underscores removed.
+			// See protoc v3.8.0: src/google/protobuf/descriptor.cc:5830-5847
+			names := map[string]protoreflect.FieldDescriptor{}
+			for i := 0; i < m.Fields().Len(); i++ {
+				f1 := m.Fields().Get(i)
+				s := strings.Replace(strings.ToLower(string(f1.Name())), "_", "", -1)
+				if f2, ok := names[s]; ok {
+					return errors.New("message %q using proto3 semantics has conflict: %q with %q", m.FullName(), f1.Name(), f2.Name())
+				}
+				names[s] = f1
+			}
+		}
+
+		for j, fd := range md.GetField() {
+			f := &m.L2.Fields.List[j]
+			if m.L2.ReservedNames.Has(f.Name()) {
+				return errors.New("message field %q must not use reserved name", f.FullName())
+			}
+			if !f.Number().IsValid() {
+				return errors.New("message field %q has an invalid number: %d", f.FullName(), f.Number())
+			}
+			if !f.Cardinality().IsValid() {
+				return errors.New("message field %q has an invalid cardinality: %d", f.FullName(), f.Cardinality())
+			}
+			if m.L2.ReservedRanges.Has(f.Number()) {
+				return errors.New("message field %q must not use reserved number %d", f.FullName(), f.Number())
+			}
+			if m.L2.ExtensionRanges.Has(f.Number()) {
+				return errors.New("message field %q with number %d in extension range", f.FullName(), f.Number())
+			}
+			if fd.Extendee != nil {
+				return errors.New("message field %q may not have extendee: %q", f.FullName(), fd.GetExtendee())
+			}
+			if f.L1.IsProto3Optional {
+				if f.Syntax() != protoreflect.Proto3 {
+					return errors.New("message field %q under proto3 optional semantics must be specified in the proto3 syntax", f.FullName())
+				}
+				if f.Cardinality() != protoreflect.Optional {
+					return errors.New("message field %q under proto3 optional semantics must have optional cardinality", f.FullName())
+				}
+				if f.ContainingOneof() != nil && f.ContainingOneof().Fields().Len() != 1 {
+					return errors.New("message field %q under proto3 optional semantics must be within a single element oneof", f.FullName())
+				}
+			}
+			if f.IsWeak() && !flags.ProtoLegacy {
+				return errors.New("message field %q is a weak field, which is a legacy proto1 feature that is no longer supported", f.FullName())
+			}
+			if f.IsWeak() && (f.Syntax() != protoreflect.Proto2 || !isOptionalMessage(f) || f.ContainingOneof() != nil) {
+				return errors.New("message field %q may only be weak for an optional message", f.FullName())
+			}
+			if f.IsPacked() && !isPackable(f) {
+				return errors.New("message field %q is not packable", f.FullName())
+			}
+			if err := checkValidGroup(f); err != nil {
+				return errors.New("message field %q is an invalid group: %v", f.FullName(), err)
+			}
+			if err := checkValidMap(f); err != nil {
+				return errors.New("message field %q is an invalid map: %v", f.FullName(), err)
+			}
+			if f.Syntax() == protoreflect.Proto3 {
+				if f.Cardinality() == protoreflect.Required {
+					return errors.New("message field %q using proto3 semantics cannot be required", f.FullName())
+				}
+				if f.Enum() != nil && !f.Enum().IsPlaceholder() && f.Enum().Syntax() != protoreflect.Proto3 {
+					return errors.New("message field %q using proto3 semantics may only depend on a proto3 enum", f.FullName())
+				}
+			}
+		}
+		seenSynthetic := false // synthetic oneofs for proto3 optional must come after real oneofs
+		for j := range md.GetOneofDecl() {
+			o := &m.L2.Oneofs.List[j]
+			if o.Fields().Len() == 0 {
+				return errors.New("message oneof %q must contain at least one field declaration", o.FullName())
+			}
+			if n := o.Fields().Len(); n-1 != (o.Fields().Get(n-1).Index() - o.Fields().Get(0).Index()) {
+				return errors.New("message oneof %q must have consecutively declared fields", o.FullName())
+			}
+
+			if o.IsSynthetic() {
+				seenSynthetic = true
+				continue
+			}
+			if !o.IsSynthetic() && seenSynthetic {
+				return errors.New("message oneof %q must be declared before synthetic oneofs", o.FullName())
+			}
+
+			for i := 0; i < o.Fields().Len(); i++ {
+				f := o.Fields().Get(i)
+				if f.Cardinality() != protoreflect.Optional {
+					return errors.New("message field %q belongs in a oneof and must be optional", f.FullName())
+				}
+				if f.IsWeak() {
+					return errors.New("message field %q belongs in a oneof and must not be a weak reference", f.FullName())
+				}
+			}
+		}
+
+		if err := validateEnumDeclarations(m.L1.Enums.List, md.GetEnumType()); err != nil {
+			return err
+		}
+		if err := validateMessageDeclarations(m.L1.Messages.List, md.GetNestedType()); err != nil {
+			return err
+		}
+		if err := validateExtensionDeclarations(m.L1.Extensions.List, md.GetExtension()); err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+func validateExtensionDeclarations(xs []filedesc.Extension, xds []*descriptorpb.FieldDescriptorProto) error {
+	for i, xd := range xds {
+		x := &xs[i]
+		// NOTE: Avoid using the IsValid method since extensions to MessageSet
+		// may have a field number higher than normal. This check only verifies
+		// that the number is not negative or reserved. We check again later
+		// if we know that the extendee is definitely not a MessageSet.
+		if n := x.Number(); n < 0 || (protowire.FirstReservedNumber <= n && n <= protowire.LastReservedNumber) {
+			return errors.New("extension field %q has an invalid number: %d", x.FullName(), x.Number())
+		}
+		if !x.Cardinality().IsValid() || x.Cardinality() == protoreflect.Required {
+			return errors.New("extension field %q has an invalid cardinality: %d", x.FullName(), x.Cardinality())
+		}
+		if xd.JsonName != nil {
+			if xd.GetJsonName() != strs.JSONCamelCase(string(x.Name())) {
+				return errors.New("extension field %q may not have an explicitly set JSON name: %q", x.FullName(), xd.GetJsonName())
+			}
+		}
+		if xd.OneofIndex != nil {
+			return errors.New("extension field %q may not be part of a oneof", x.FullName())
+		}
+		if md := x.ContainingMessage(); !md.IsPlaceholder() {
+			if !md.ExtensionRanges().Has(x.Number()) {
+				return errors.New("extension field %q extends %q with non-extension field number: %d", x.FullName(), md.FullName(), x.Number())
+			}
+			isMessageSet := md.Options().(*descriptorpb.MessageOptions).GetMessageSetWireFormat()
+			if isMessageSet && !isOptionalMessage(x) {
+				return errors.New("extension field %q extends MessageSet and must be an optional message", x.FullName())
+			}
+			if !isMessageSet && !x.Number().IsValid() {
+				return errors.New("extension field %q has an invalid number: %d", x.FullName(), x.Number())
+			}
+		}
+		if xd.GetOptions().GetWeak() {
+			return errors.New("extension field %q cannot be a weak reference", x.FullName())
+		}
+		if x.IsPacked() && !isPackable(x) {
+			return errors.New("extension field %q is not packable", x.FullName())
+		}
+		if err := checkValidGroup(x); err != nil {
+			return errors.New("extension field %q is an invalid group: %v", x.FullName(), err)
+		}
+		if md := x.Message(); md != nil && md.IsMapEntry() {
+			return errors.New("extension field %q cannot be a map entry", x.FullName())
+		}
+		if x.Syntax() == protoreflect.Proto3 {
+			switch x.ContainingMessage().FullName() {
+			case (*descriptorpb.FileOptions)(nil).ProtoReflect().Descriptor().FullName():
+			case (*descriptorpb.EnumOptions)(nil).ProtoReflect().Descriptor().FullName():
+			case (*descriptorpb.EnumValueOptions)(nil).ProtoReflect().Descriptor().FullName():
+			case (*descriptorpb.MessageOptions)(nil).ProtoReflect().Descriptor().FullName():
+			case (*descriptorpb.FieldOptions)(nil).ProtoReflect().Descriptor().FullName():
+			case (*descriptorpb.OneofOptions)(nil).ProtoReflect().Descriptor().FullName():
+			case (*descriptorpb.ExtensionRangeOptions)(nil).ProtoReflect().Descriptor().FullName():
+			case (*descriptorpb.ServiceOptions)(nil).ProtoReflect().Descriptor().FullName():
+			case (*descriptorpb.MethodOptions)(nil).ProtoReflect().Descriptor().FullName():
+			default:
+				return errors.New("extension field %q cannot be declared in proto3 unless extended descriptor options", x.FullName())
+			}
+		}
+	}
+	return nil
+}
+
+// isOptionalMessage reports whether this is an optional message.
+// If the kind is unknown, it is assumed to be a message.
+func isOptionalMessage(fd protoreflect.FieldDescriptor) bool {
+	return (fd.Kind() == 0 || fd.Kind() == protoreflect.MessageKind) && fd.Cardinality() == protoreflect.Optional
+}
+
+// isPackable checks whether the pack option can be specified.
+func isPackable(fd protoreflect.FieldDescriptor) bool {
+	switch fd.Kind() {
+	case protoreflect.StringKind, protoreflect.BytesKind, protoreflect.MessageKind, protoreflect.GroupKind:
+		return false
+	}
+	return fd.IsList()
+}
+
+// checkValidGroup reports whether fd is a valid group according to the same
+// rules that protoc imposes.
+func checkValidGroup(fd protoreflect.FieldDescriptor) error {
+	md := fd.Message()
+	switch {
+	case fd.Kind() != protoreflect.GroupKind:
+		return nil
+	case fd.Syntax() != protoreflect.Proto2:
+		return errors.New("invalid under proto2 semantics")
+	case md == nil || md.IsPlaceholder():
+		return errors.New("message must be resolvable")
+	case fd.FullName().Parent() != md.FullName().Parent():
+		return errors.New("message and field must be declared in the same scope")
+	case !unicode.IsUpper(rune(md.Name()[0])):
+		return errors.New("message name must start with an uppercase")
+	case fd.Name() != protoreflect.Name(strings.ToLower(string(md.Name()))):
+		return errors.New("field name must be lowercased form of the message name")
+	}
+	return nil
+}
+
+// checkValidMap checks whether the field is a valid map according to the same
+// rules that protoc imposes.
+// See protoc v3.8.0: src/google/protobuf/descriptor.cc:6045-6115
+func checkValidMap(fd protoreflect.FieldDescriptor) error {
+	md := fd.Message()
+	switch {
+	case md == nil || !md.IsMapEntry():
+		return nil
+	case fd.FullName().Parent() != md.FullName().Parent():
+		return errors.New("message and field must be declared in the same scope")
+	case md.Name() != protoreflect.Name(strs.MapEntryName(string(fd.Name()))):
+		return errors.New("incorrect implicit map entry name")
+	case fd.Cardinality() != protoreflect.Repeated:
+		return errors.New("field must be repeated")
+	case md.Fields().Len() != 2:
+		return errors.New("message must have exactly two fields")
+	case md.ExtensionRanges().Len() > 0:
+		return errors.New("message must not have any extension ranges")
+	case md.Enums().Len()+md.Messages().Len()+md.Extensions().Len() > 0:
+		return errors.New("message must not have any nested declarations")
+	}
+	kf := md.Fields().Get(0)
+	vf := md.Fields().Get(1)
+	switch {
+	case kf.Name() != "key" || kf.Number() != 1 || kf.Cardinality() != protoreflect.Optional || kf.ContainingOneof() != nil || kf.HasDefault():
+		return errors.New("invalid key field")
+	case vf.Name() != "value" || vf.Number() != 2 || vf.Cardinality() != protoreflect.Optional || vf.ContainingOneof() != nil || vf.HasDefault():
+		return errors.New("invalid value field")
+	}
+	switch kf.Kind() {
+	case protoreflect.BoolKind: // bool
+	case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind: // int32
+	case protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind: // int64
+	case protoreflect.Uint32Kind, protoreflect.Fixed32Kind: // uint32
+	case protoreflect.Uint64Kind, protoreflect.Fixed64Kind: // uint64
+	case protoreflect.StringKind: // string
+	default:
+		return errors.New("invalid key kind: %v", kf.Kind())
+	}
+	if e := vf.Enum(); e != nil && e.Values().Len() > 0 && e.Values().Get(0).Number() != 0 {
+		return errors.New("map enum value must have zero number for the first value")
+	}
+	return nil
+}
diff --git a/vendor/google.golang.org/protobuf/reflect/protodesc/proto.go b/vendor/google.golang.org/protobuf/reflect/protodesc/proto.go
new file mode 100644
index 0000000..00d35e0
--- /dev/null
+++ b/vendor/google.golang.org/protobuf/reflect/protodesc/proto.go
@@ -0,0 +1,242 @@
+// 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 protodesc
+
+import (
+	"fmt"
+	"strings"
+
+	"google.golang.org/protobuf/internal/encoding/defval"
+	"google.golang.org/protobuf/proto"
+	"google.golang.org/protobuf/reflect/protoreflect"
+
+	"google.golang.org/protobuf/types/descriptorpb"
+)
+
+// ToFileDescriptorProto copies a protoreflect.FileDescriptor into a
+// google.protobuf.FileDescriptorProto message.
+func ToFileDescriptorProto(file protoreflect.FileDescriptor) *descriptorpb.FileDescriptorProto {
+	p := &descriptorpb.FileDescriptorProto{
+		Name:    proto.String(file.Path()),
+		Package: proto.String(string(file.Package())),
+		Options: proto.Clone(file.Options()).(*descriptorpb.FileOptions),
+	}
+	for i, imports := 0, file.Imports(); i < imports.Len(); i++ {
+		imp := imports.Get(i)
+		p.Dependency = append(p.Dependency, imp.Path())
+		if imp.IsPublic {
+			p.PublicDependency = append(p.PublicDependency, int32(i))
+		}
+		if imp.IsWeak {
+			p.WeakDependency = append(p.WeakDependency, int32(i))
+		}
+	}
+	for i, locs := 0, file.SourceLocations(); i < locs.Len(); i++ {
+		loc := locs.Get(i)
+		l := &descriptorpb.SourceCodeInfo_Location{}
+		l.Path = append(l.Path, loc.Path...)
+		if loc.StartLine == loc.EndLine {
+			l.Span = []int32{int32(loc.StartLine), int32(loc.StartColumn), int32(loc.EndColumn)}
+		} else {
+			l.Span = []int32{int32(loc.StartLine), int32(loc.StartColumn), int32(loc.EndLine), int32(loc.EndColumn)}
+		}
+		l.LeadingDetachedComments = append([]string(nil), loc.LeadingDetachedComments...)
+		if loc.LeadingComments != "" {
+			l.LeadingComments = proto.String(loc.LeadingComments)
+		}
+		if loc.TrailingComments != "" {
+			l.TrailingComments = proto.String(loc.TrailingComments)
+		}
+		if p.SourceCodeInfo == nil {
+			p.SourceCodeInfo = &descriptorpb.SourceCodeInfo{}
+		}
+		p.SourceCodeInfo.Location = append(p.SourceCodeInfo.Location, l)
+
+	}
+	for i, messages := 0, file.Messages(); i < messages.Len(); i++ {
+		p.MessageType = append(p.MessageType, ToDescriptorProto(messages.Get(i)))
+	}
+	for i, enums := 0, file.Enums(); i < enums.Len(); i++ {
+		p.EnumType = append(p.EnumType, ToEnumDescriptorProto(enums.Get(i)))
+	}
+	for i, services := 0, file.Services(); i < services.Len(); i++ {
+		p.Service = append(p.Service, ToServiceDescriptorProto(services.Get(i)))
+	}
+	for i, exts := 0, file.Extensions(); i < exts.Len(); i++ {
+		p.Extension = append(p.Extension, ToFieldDescriptorProto(exts.Get(i)))
+	}
+	if syntax := file.Syntax(); syntax != protoreflect.Proto2 {
+		p.Syntax = proto.String(file.Syntax().String())
+	}
+	return p
+}
+
+// ToDescriptorProto copies a protoreflect.MessageDescriptor into a
+// google.protobuf.DescriptorProto message.
+func ToDescriptorProto(message protoreflect.MessageDescriptor) *descriptorpb.DescriptorProto {
+	p := &descriptorpb.DescriptorProto{
+		Name:    proto.String(string(message.Name())),
+		Options: proto.Clone(message.Options()).(*descriptorpb.MessageOptions),
+	}
+	for i, fields := 0, message.Fields(); i < fields.Len(); i++ {
+		p.Field = append(p.Field, ToFieldDescriptorProto(fields.Get(i)))
+	}
+	for i, exts := 0, message.Extensions(); i < exts.Len(); i++ {
+		p.Extension = append(p.Extension, ToFieldDescriptorProto(exts.Get(i)))
+	}
+	for i, messages := 0, message.Messages(); i < messages.Len(); i++ {
+		p.NestedType = append(p.NestedType, ToDescriptorProto(messages.Get(i)))
+	}
+	for i, enums := 0, message.Enums(); i < enums.Len(); i++ {
+		p.EnumType = append(p.EnumType, ToEnumDescriptorProto(enums.Get(i)))
+	}
+	for i, xranges := 0, message.ExtensionRanges(); i < xranges.Len(); i++ {
+		xrange := xranges.Get(i)
+		p.ExtensionRange = append(p.ExtensionRange, &descriptorpb.DescriptorProto_ExtensionRange{
+			Start:   proto.Int32(int32(xrange[0])),
+			End:     proto.Int32(int32(xrange[1])),
+			Options: proto.Clone(message.ExtensionRangeOptions(i)).(*descriptorpb.ExtensionRangeOptions),
+		})
+	}
+	for i, oneofs := 0, message.Oneofs(); i < oneofs.Len(); i++ {
+		p.OneofDecl = append(p.OneofDecl, ToOneofDescriptorProto(oneofs.Get(i)))
+	}
+	for i, ranges := 0, message.ReservedRanges(); i < ranges.Len(); i++ {
+		rrange := ranges.Get(i)
+		p.ReservedRange = append(p.ReservedRange, &descriptorpb.DescriptorProto_ReservedRange{
+			Start: proto.Int32(int32(rrange[0])),
+			End:   proto.Int32(int32(rrange[1])),
+		})
+	}
+	for i, names := 0, message.ReservedNames(); i < names.Len(); i++ {
+		p.ReservedName = append(p.ReservedName, string(names.Get(i)))
+	}
+	return p
+}
+
+// ToFieldDescriptorProto copies a protoreflect.FieldDescriptor into a
+// google.protobuf.FieldDescriptorProto message.
+func ToFieldDescriptorProto(field protoreflect.FieldDescriptor) *descriptorpb.FieldDescriptorProto {
+	p := &descriptorpb.FieldDescriptorProto{
+		Name:    proto.String(string(field.Name())),
+		Number:  proto.Int32(int32(field.Number())),
+		Label:   descriptorpb.FieldDescriptorProto_Label(field.Cardinality()).Enum(),
+		Options: proto.Clone(field.Options()).(*descriptorpb.FieldOptions),
+	}
+	if field.IsExtension() {
+		p.Extendee = fullNameOf(field.ContainingMessage())
+	}
+	if field.Kind().IsValid() {
+		p.Type = descriptorpb.FieldDescriptorProto_Type(field.Kind()).Enum()
+	}
+	if field.Enum() != nil {
+		p.TypeName = fullNameOf(field.Enum())
+	}
+	if field.Message() != nil {
+		p.TypeName = fullNameOf(field.Message())
+	}
+	if field.HasJSONName() {
+		p.JsonName = proto.String(field.JSONName())
+	}
+	if field.Syntax() == protoreflect.Proto3 && field.HasOptionalKeyword() {
+		p.Proto3Optional = proto.Bool(true)
+	}
+	if field.HasDefault() {
+		def, err := defval.Marshal(field.Default(), field.DefaultEnumValue(), field.Kind(), defval.Descriptor)
+		if err != nil && field.DefaultEnumValue() != nil {
+			def = string(field.DefaultEnumValue().Name()) // occurs for unresolved enum values
+		} else if err != nil {
+			panic(fmt.Sprintf("%v: %v", field.FullName(), err))
+		}
+		p.DefaultValue = proto.String(def)
+	}
+	if oneof := field.ContainingOneof(); oneof != nil {
+		p.OneofIndex = proto.Int32(int32(oneof.Index()))
+	}
+	return p
+}
+
+// ToOneofDescriptorProto copies a protoreflect.OneofDescriptor into a
+// google.protobuf.OneofDescriptorProto message.
+func ToOneofDescriptorProto(oneof protoreflect.OneofDescriptor) *descriptorpb.OneofDescriptorProto {
+	return &descriptorpb.OneofDescriptorProto{
+		Name:    proto.String(string(oneof.Name())),
+		Options: proto.Clone(oneof.Options()).(*descriptorpb.OneofOptions),
+	}
+}
+
+// ToEnumDescriptorProto copies a protoreflect.EnumDescriptor into a
+// google.protobuf.EnumDescriptorProto message.
+func ToEnumDescriptorProto(enum protoreflect.EnumDescriptor) *descriptorpb.EnumDescriptorProto {
+	p := &descriptorpb.EnumDescriptorProto{
+		Name:    proto.String(string(enum.Name())),
+		Options: proto.Clone(enum.Options()).(*descriptorpb.EnumOptions),
+	}
+	for i, values := 0, enum.Values(); i < values.Len(); i++ {
+		p.Value = append(p.Value, ToEnumValueDescriptorProto(values.Get(i)))
+	}
+	for i, ranges := 0, enum.ReservedRanges(); i < ranges.Len(); i++ {
+		rrange := ranges.Get(i)
+		p.ReservedRange = append(p.ReservedRange, &descriptorpb.EnumDescriptorProto_EnumReservedRange{
+			Start: proto.Int32(int32(rrange[0])),
+			End:   proto.Int32(int32(rrange[1])),
+		})
+	}
+	for i, names := 0, enum.ReservedNames(); i < names.Len(); i++ {
+		p.ReservedName = append(p.ReservedName, string(names.Get(i)))
+	}
+	return p
+}
+
+// ToEnumValueDescriptorProto copies a protoreflect.EnumValueDescriptor into a
+// google.protobuf.EnumValueDescriptorProto message.
+func ToEnumValueDescriptorProto(value protoreflect.EnumValueDescriptor) *descriptorpb.EnumValueDescriptorProto {
+	return &descriptorpb.EnumValueDescriptorProto{
+		Name:    proto.String(string(value.Name())),
+		Number:  proto.Int32(int32(value.Number())),
+		Options: proto.Clone(value.Options()).(*descriptorpb.EnumValueOptions),
+	}
+}
+
+// ToServiceDescriptorProto copies a protoreflect.ServiceDescriptor into a
+// google.protobuf.ServiceDescriptorProto message.
+func ToServiceDescriptorProto(service protoreflect.ServiceDescriptor) *descriptorpb.ServiceDescriptorProto {
+	p := &descriptorpb.ServiceDescriptorProto{
+		Name:    proto.String(string(service.Name())),
+		Options: proto.Clone(service.Options()).(*descriptorpb.ServiceOptions),
+	}
+	for i, methods := 0, service.Methods(); i < methods.Len(); i++ {
+		p.Method = append(p.Method, ToMethodDescriptorProto(methods.Get(i)))
+	}
+	return p
+}
+
+// ToMethodDescriptorProto copies a protoreflect.MethodDescriptor into a
+// google.protobuf.MethodDescriptorProto message.
+func ToMethodDescriptorProto(method protoreflect.MethodDescriptor) *descriptorpb.MethodDescriptorProto {
+	p := &descriptorpb.MethodDescriptorProto{
+		Name:       proto.String(string(method.Name())),
+		InputType:  fullNameOf(method.Input()),
+		OutputType: fullNameOf(method.Output()),
+		Options:    proto.Clone(method.Options()).(*descriptorpb.MethodOptions),
+	}
+	if method.IsStreamingClient() {
+		p.ClientStreaming = proto.Bool(true)
+	}
+	if method.IsStreamingServer() {
+		p.ServerStreaming = proto.Bool(true)
+	}
+	return p
+}
+
+func fullNameOf(d protoreflect.Descriptor) *string {
+	if d == nil {
+		return nil
+	}
+	if strings.HasPrefix(string(d.FullName()), unknownPrefix) {
+		return proto.String(string(d.FullName()[len(unknownPrefix):]))
+	}
+	return proto.String("." + string(d.FullName()))
+}
diff --git a/vendor/google.golang.org/protobuf/reflect/protoreflect/methods.go b/vendor/google.golang.org/protobuf/reflect/protoreflect/methods.go
new file mode 100644
index 0000000..6be5d16
--- /dev/null
+++ b/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/vendor/google.golang.org/protobuf/reflect/protoreflect/proto.go b/vendor/google.golang.org/protobuf/reflect/protoreflect/proto.go
new file mode 100644
index 0000000..b669a4e
--- /dev/null
+++ b/vendor/google.golang.org/protobuf/reflect/protoreflect/proto.go
@@ -0,0 +1,478 @@
+// 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.
+// The "google.golang.org/protobuf/reflect/protodesc" package converts between
+// google.protobuf.DescriptorProto messages and protobuf descriptors.
+//
+//
+// 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/vendor/google.golang.org/protobuf/reflect/protoreflect/source.go b/vendor/google.golang.org/protobuf/reflect/protoreflect/source.go
new file mode 100644
index 0000000..32ea3d9
--- /dev/null
+++ b/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/vendor/google.golang.org/protobuf/reflect/protoreflect/type.go b/vendor/google.golang.org/protobuf/reflect/protoreflect/type.go
new file mode 100644
index 0000000..5be14a7
--- /dev/null
+++ b/vendor/google.golang.org/protobuf/reflect/protoreflect/type.go
@@ -0,0 +1,631 @@
+// 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
+
+	// HasPresence reports whether the field distinguishes between unpopulated
+	// and default values.
+	HasPresence() bool
+
+	// 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
+
+	// HasOptionalKeyword reports whether the "optional" keyword was explicitly
+	// specified in the source .proto file.
+	HasOptionalKeyword() 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
+
+	// IsSynthetic reports whether this is a synthetic oneof created to support
+	// proto3 optional semantics. If true, Fields contains exactly one field
+	// with HasOptionalKeyword specified.
+	IsSynthetic() bool
+
+	// 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/vendor/google.golang.org/protobuf/reflect/protoreflect/value.go b/vendor/google.golang.org/protobuf/reflect/protoreflect/value.go
new file mode 100644
index 0000000..f319810
--- /dev/null
+++ b/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 that is assignable to the field
+	// for the 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/vendor/google.golang.org/protobuf/reflect/protoreflect/value_pure.go b/vendor/google.golang.org/protobuf/reflect/protoreflect/value_pure.go
new file mode 100644
index 0000000..918e685
--- /dev/null
+++ b/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/vendor/google.golang.org/protobuf/reflect/protoreflect/value_union.go b/vendor/google.golang.org/protobuf/reflect/protoreflect/value_union.go
new file mode 100644
index 0000000..f334f71
--- /dev/null
+++ b/vendor/google.golang.org/protobuf/reflect/protoreflect/value_union.go
@@ -0,0 +1,409 @@
+// 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"
+)
+
+// 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: %T", 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()
+	}
+}
+
+func (v Value) typeName() string {
+	switch v.typ {
+	case nilType:
+		return "nil"
+	case boolType:
+		return "bool"
+	case int32Type:
+		return "int32"
+	case int64Type:
+		return "int64"
+	case uint32Type:
+		return "uint32"
+	case uint64Type:
+		return "uint64"
+	case float32Type:
+		return "float32"
+	case float64Type:
+		return "float64"
+	case stringType:
+		return "string"
+	case bytesType:
+		return "bytes"
+	case enumType:
+		return "enum"
+	default:
+		switch v := v.getIface().(type) {
+		case Message:
+			return "message"
+		case List:
+			return "list"
+		case Map:
+			return "map"
+		default:
+			return fmt.Sprintf("<unknown: %T>", v)
+		}
+	}
+}
+
+func (v Value) panicMessage(what string) string {
+	return fmt.Sprintf("type mismatch: cannot convert %v to %s", v.typeName(), what)
+}
+
+// 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(v.panicMessage("bool"))
+	}
+}
+
+// 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(v.panicMessage("int"))
+	}
+}
+
+// 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(v.panicMessage("uint"))
+	}
+}
+
+// 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(v.panicMessage("float"))
+	}
+}
+
+// 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(v.panicMessage("bytes"))
+	}
+}
+
+// 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(v.panicMessage("enum"))
+	}
+}
+
+// Message returns v as a Message and panics if the type is not a Message.
+func (v Value) Message() Message {
+	switch vi := v.getIface().(type) {
+	case Message:
+		return vi
+	default:
+		panic(v.panicMessage("message"))
+	}
+}
+
+// List returns v as a List and panics if the type is not a List.
+func (v Value) List() List {
+	switch vi := v.getIface().(type) {
+	case List:
+		return vi
+	default:
+		panic(v.panicMessage("list"))
+	}
+}
+
+// Map returns v as a Map and panics if the type is not a Map.
+func (v Value) Map() Map {
+	switch vi := v.getIface().(type) {
+	case Map:
+		return vi
+	default:
+		panic(v.panicMessage("map"))
+	}
+}
+
+// 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)
+	default:
+		panic(v.panicMessage("map key"))
+	}
+}
+
+// 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/vendor/google.golang.org/protobuf/reflect/protoreflect/value_unsafe.go b/vendor/google.golang.org/protobuf/reflect/protoreflect/value_unsafe.go
new file mode 100644
index 0000000..c45debd
--- /dev/null
+++ b/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/vendor/google.golang.org/protobuf/reflect/protoregistry/registry.go b/vendor/google.golang.org/protobuf/reflect/protoregistry/registry.go
new file mode 100644
index 0000000..43f16c6
--- /dev/null
+++ b/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 ""
+}
