diff --git a/vendor/google.golang.org/protobuf/internal/filedesc/build.go b/vendor/google.golang.org/protobuf/internal/filedesc/build.go
new file mode 100644
index 0000000..b293b69
--- /dev/null
+++ b/vendor/google.golang.org/protobuf/internal/filedesc/build.go
@@ -0,0 +1,158 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package filedesc provides functionality for constructing descriptors.
+//
+// The types in this package implement interfaces in the protoreflect package
+// related to protobuf descripriptors.
+package filedesc
+
+import (
+	"google.golang.org/protobuf/encoding/protowire"
+	"google.golang.org/protobuf/internal/genid"
+	"google.golang.org/protobuf/reflect/protoreflect"
+	pref "google.golang.org/protobuf/reflect/protoreflect"
+	preg "google.golang.org/protobuf/reflect/protoregistry"
+)
+
+// Builder construct a protoreflect.FileDescriptor from the raw descriptor.
+type Builder struct {
+	// GoPackagePath is the Go package path that is invoking this builder.
+	GoPackagePath string
+
+	// RawDescriptor is the wire-encoded bytes of FileDescriptorProto
+	// and must be populated.
+	RawDescriptor []byte
+
+	// NumEnums is the total number of enums declared in the file.
+	NumEnums int32
+	// NumMessages is the total number of messages declared in the file.
+	// It includes the implicit message declarations for map entries.
+	NumMessages int32
+	// NumExtensions is the total number of extensions declared in the file.
+	NumExtensions int32
+	// NumServices is the total number of services declared in the file.
+	NumServices int32
+
+	// TypeResolver resolves extension field types for descriptor options.
+	// If nil, it uses protoregistry.GlobalTypes.
+	TypeResolver interface {
+		preg.ExtensionTypeResolver
+	}
+
+	// FileRegistry is use to lookup file, enum, and message dependencies.
+	// Once constructed, the file descriptor is registered here.
+	// If nil, it uses protoregistry.GlobalFiles.
+	FileRegistry interface {
+		FindFileByPath(string) (protoreflect.FileDescriptor, error)
+		FindDescriptorByName(pref.FullName) (pref.Descriptor, error)
+		RegisterFile(pref.FileDescriptor) error
+	}
+}
+
+// resolverByIndex is an interface Builder.FileRegistry may implement.
+// If so, it permits looking up an enum or message dependency based on the
+// sub-list and element index into filetype.Builder.DependencyIndexes.
+type resolverByIndex interface {
+	FindEnumByIndex(int32, int32, []Enum, []Message) pref.EnumDescriptor
+	FindMessageByIndex(int32, int32, []Enum, []Message) pref.MessageDescriptor
+}
+
+// Indexes of each sub-list in filetype.Builder.DependencyIndexes.
+const (
+	listFieldDeps int32 = iota
+	listExtTargets
+	listExtDeps
+	listMethInDeps
+	listMethOutDeps
+)
+
+// Out is the output of the Builder.
+type Out struct {
+	File pref.FileDescriptor
+
+	// Enums is all enum descriptors in "flattened ordering".
+	Enums []Enum
+	// Messages is all message descriptors in "flattened ordering".
+	// It includes the implicit message declarations for map entries.
+	Messages []Message
+	// Extensions is all extension descriptors in "flattened ordering".
+	Extensions []Extension
+	// Service is all service descriptors in "flattened ordering".
+	Services []Service
+}
+
+// Build constructs a FileDescriptor given the parameters set in Builder.
+// It assumes that the inputs are well-formed and panics if any inconsistencies
+// are encountered.
+//
+// If NumEnums+NumMessages+NumExtensions+NumServices is zero,
+// then Build automatically derives them from the raw descriptor.
+func (db Builder) Build() (out Out) {
+	// Populate the counts if uninitialized.
+	if db.NumEnums+db.NumMessages+db.NumExtensions+db.NumServices == 0 {
+		db.unmarshalCounts(db.RawDescriptor, true)
+	}
+
+	// Initialize resolvers and registries if unpopulated.
+	if db.TypeResolver == nil {
+		db.TypeResolver = preg.GlobalTypes
+	}
+	if db.FileRegistry == nil {
+		db.FileRegistry = preg.GlobalFiles
+	}
+
+	fd := newRawFile(db)
+	out.File = fd
+	out.Enums = fd.allEnums
+	out.Messages = fd.allMessages
+	out.Extensions = fd.allExtensions
+	out.Services = fd.allServices
+
+	if err := db.FileRegistry.RegisterFile(fd); err != nil {
+		panic(err)
+	}
+	return out
+}
+
+// unmarshalCounts counts the number of enum, message, extension, and service
+// declarations in the raw message, which is either a FileDescriptorProto
+// or a MessageDescriptorProto depending on whether isFile is set.
+func (db *Builder) unmarshalCounts(b []byte, isFile bool) {
+	for len(b) > 0 {
+		num, typ, n := protowire.ConsumeTag(b)
+		b = b[n:]
+		switch typ {
+		case protowire.BytesType:
+			v, m := protowire.ConsumeBytes(b)
+			b = b[m:]
+			if isFile {
+				switch num {
+				case genid.FileDescriptorProto_EnumType_field_number:
+					db.NumEnums++
+				case genid.FileDescriptorProto_MessageType_field_number:
+					db.unmarshalCounts(v, false)
+					db.NumMessages++
+				case genid.FileDescriptorProto_Extension_field_number:
+					db.NumExtensions++
+				case genid.FileDescriptorProto_Service_field_number:
+					db.NumServices++
+				}
+			} else {
+				switch num {
+				case genid.DescriptorProto_EnumType_field_number:
+					db.NumEnums++
+				case genid.DescriptorProto_NestedType_field_number:
+					db.unmarshalCounts(v, false)
+					db.NumMessages++
+				case genid.DescriptorProto_Extension_field_number:
+					db.NumExtensions++
+				}
+			}
+		default:
+			m := protowire.ConsumeFieldValue(num, typ, b)
+			b = b[m:]
+		}
+	}
+}
diff --git a/vendor/google.golang.org/protobuf/internal/filedesc/desc.go b/vendor/google.golang.org/protobuf/internal/filedesc/desc.go
new file mode 100644
index 0000000..98ab142
--- /dev/null
+++ b/vendor/google.golang.org/protobuf/internal/filedesc/desc.go
@@ -0,0 +1,631 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package filedesc
+
+import (
+	"bytes"
+	"fmt"
+	"sync"
+	"sync/atomic"
+
+	"google.golang.org/protobuf/internal/descfmt"
+	"google.golang.org/protobuf/internal/descopts"
+	"google.golang.org/protobuf/internal/encoding/defval"
+	"google.golang.org/protobuf/internal/encoding/messageset"
+	"google.golang.org/protobuf/internal/genid"
+	"google.golang.org/protobuf/internal/pragma"
+	"google.golang.org/protobuf/internal/strs"
+	pref "google.golang.org/protobuf/reflect/protoreflect"
+	"google.golang.org/protobuf/reflect/protoregistry"
+)
+
+// The types in this file may have a suffix:
+//	• L0: Contains fields common to all descriptors (except File) and
+//	must be initialized up front.
+//	• L1: Contains fields specific to a descriptor and
+//	must be initialized up front.
+//	• L2: Contains fields that are lazily initialized when constructing
+//	from the raw file descriptor. When constructing as a literal, the L2
+//	fields must be initialized up front.
+//
+// The types are exported so that packages like reflect/protodesc can
+// directly construct descriptors.
+
+type (
+	File struct {
+		fileRaw
+		L1 FileL1
+
+		once uint32     // atomically set if L2 is valid
+		mu   sync.Mutex // protects L2
+		L2   *FileL2
+	}
+	FileL1 struct {
+		Syntax  pref.Syntax
+		Path    string
+		Package pref.FullName
+
+		Enums      Enums
+		Messages   Messages
+		Extensions Extensions
+		Services   Services
+	}
+	FileL2 struct {
+		Options   func() pref.ProtoMessage
+		Imports   FileImports
+		Locations SourceLocations
+	}
+)
+
+func (fd *File) ParentFile() pref.FileDescriptor { return fd }
+func (fd *File) Parent() pref.Descriptor         { return nil }
+func (fd *File) Index() int                      { return 0 }
+func (fd *File) Syntax() pref.Syntax             { return fd.L1.Syntax }
+func (fd *File) Name() pref.Name                 { return fd.L1.Package.Name() }
+func (fd *File) FullName() pref.FullName         { return fd.L1.Package }
+func (fd *File) IsPlaceholder() bool             { return false }
+func (fd *File) Options() pref.ProtoMessage {
+	if f := fd.lazyInit().Options; f != nil {
+		return f()
+	}
+	return descopts.File
+}
+func (fd *File) Path() string                          { return fd.L1.Path }
+func (fd *File) Package() pref.FullName                { return fd.L1.Package }
+func (fd *File) Imports() pref.FileImports             { return &fd.lazyInit().Imports }
+func (fd *File) Enums() pref.EnumDescriptors           { return &fd.L1.Enums }
+func (fd *File) Messages() pref.MessageDescriptors     { return &fd.L1.Messages }
+func (fd *File) Extensions() pref.ExtensionDescriptors { return &fd.L1.Extensions }
+func (fd *File) Services() pref.ServiceDescriptors     { return &fd.L1.Services }
+func (fd *File) SourceLocations() pref.SourceLocations { return &fd.lazyInit().Locations }
+func (fd *File) Format(s fmt.State, r rune)            { descfmt.FormatDesc(s, r, fd) }
+func (fd *File) ProtoType(pref.FileDescriptor)         {}
+func (fd *File) ProtoInternal(pragma.DoNotImplement)   {}
+
+func (fd *File) lazyInit() *FileL2 {
+	if atomic.LoadUint32(&fd.once) == 0 {
+		fd.lazyInitOnce()
+	}
+	return fd.L2
+}
+
+func (fd *File) lazyInitOnce() {
+	fd.mu.Lock()
+	if fd.L2 == nil {
+		fd.lazyRawInit() // recursively initializes all L2 structures
+	}
+	atomic.StoreUint32(&fd.once, 1)
+	fd.mu.Unlock()
+}
+
+// GoPackagePath is a pseudo-internal API for determining the Go package path
+// that this file descriptor is declared in.
+//
+// WARNING: This method is exempt from the compatibility promise and may be
+// removed in the future without warning.
+func (fd *File) GoPackagePath() string {
+	return fd.builder.GoPackagePath
+}
+
+type (
+	Enum struct {
+		Base
+		L1 EnumL1
+		L2 *EnumL2 // protected by fileDesc.once
+	}
+	EnumL1 struct {
+		eagerValues bool // controls whether EnumL2.Values is already populated
+	}
+	EnumL2 struct {
+		Options        func() pref.ProtoMessage
+		Values         EnumValues
+		ReservedNames  Names
+		ReservedRanges EnumRanges
+	}
+
+	EnumValue struct {
+		Base
+		L1 EnumValueL1
+	}
+	EnumValueL1 struct {
+		Options func() pref.ProtoMessage
+		Number  pref.EnumNumber
+	}
+)
+
+func (ed *Enum) Options() pref.ProtoMessage {
+	if f := ed.lazyInit().Options; f != nil {
+		return f()
+	}
+	return descopts.Enum
+}
+func (ed *Enum) Values() pref.EnumValueDescriptors {
+	if ed.L1.eagerValues {
+		return &ed.L2.Values
+	}
+	return &ed.lazyInit().Values
+}
+func (ed *Enum) ReservedNames() pref.Names       { return &ed.lazyInit().ReservedNames }
+func (ed *Enum) ReservedRanges() pref.EnumRanges { return &ed.lazyInit().ReservedRanges }
+func (ed *Enum) Format(s fmt.State, r rune)      { descfmt.FormatDesc(s, r, ed) }
+func (ed *Enum) ProtoType(pref.EnumDescriptor)   {}
+func (ed *Enum) lazyInit() *EnumL2 {
+	ed.L0.ParentFile.lazyInit() // implicitly initializes L2
+	return ed.L2
+}
+
+func (ed *EnumValue) Options() pref.ProtoMessage {
+	if f := ed.L1.Options; f != nil {
+		return f()
+	}
+	return descopts.EnumValue
+}
+func (ed *EnumValue) Number() pref.EnumNumber            { return ed.L1.Number }
+func (ed *EnumValue) Format(s fmt.State, r rune)         { descfmt.FormatDesc(s, r, ed) }
+func (ed *EnumValue) ProtoType(pref.EnumValueDescriptor) {}
+
+type (
+	Message struct {
+		Base
+		L1 MessageL1
+		L2 *MessageL2 // protected by fileDesc.once
+	}
+	MessageL1 struct {
+		Enums        Enums
+		Messages     Messages
+		Extensions   Extensions
+		IsMapEntry   bool // promoted from google.protobuf.MessageOptions
+		IsMessageSet bool // promoted from google.protobuf.MessageOptions
+	}
+	MessageL2 struct {
+		Options               func() pref.ProtoMessage
+		Fields                Fields
+		Oneofs                Oneofs
+		ReservedNames         Names
+		ReservedRanges        FieldRanges
+		RequiredNumbers       FieldNumbers // must be consistent with Fields.Cardinality
+		ExtensionRanges       FieldRanges
+		ExtensionRangeOptions []func() pref.ProtoMessage // must be same length as ExtensionRanges
+	}
+
+	Field struct {
+		Base
+		L1 FieldL1
+	}
+	FieldL1 struct {
+		Options          func() pref.ProtoMessage
+		Number           pref.FieldNumber
+		Cardinality      pref.Cardinality // must be consistent with Message.RequiredNumbers
+		Kind             pref.Kind
+		StringName       stringName
+		IsProto3Optional bool // promoted from google.protobuf.FieldDescriptorProto
+		IsWeak           bool // promoted from google.protobuf.FieldOptions
+		HasPacked        bool // promoted from google.protobuf.FieldOptions
+		IsPacked         bool // promoted from google.protobuf.FieldOptions
+		HasEnforceUTF8   bool // promoted from google.protobuf.FieldOptions
+		EnforceUTF8      bool // promoted from google.protobuf.FieldOptions
+		Default          defaultValue
+		ContainingOneof  pref.OneofDescriptor // must be consistent with Message.Oneofs.Fields
+		Enum             pref.EnumDescriptor
+		Message          pref.MessageDescriptor
+	}
+
+	Oneof struct {
+		Base
+		L1 OneofL1
+	}
+	OneofL1 struct {
+		Options func() pref.ProtoMessage
+		Fields  OneofFields // must be consistent with Message.Fields.ContainingOneof
+	}
+)
+
+func (md *Message) Options() pref.ProtoMessage {
+	if f := md.lazyInit().Options; f != nil {
+		return f()
+	}
+	return descopts.Message
+}
+func (md *Message) IsMapEntry() bool                   { return md.L1.IsMapEntry }
+func (md *Message) Fields() pref.FieldDescriptors      { return &md.lazyInit().Fields }
+func (md *Message) Oneofs() pref.OneofDescriptors      { return &md.lazyInit().Oneofs }
+func (md *Message) ReservedNames() pref.Names          { return &md.lazyInit().ReservedNames }
+func (md *Message) ReservedRanges() pref.FieldRanges   { return &md.lazyInit().ReservedRanges }
+func (md *Message) RequiredNumbers() pref.FieldNumbers { return &md.lazyInit().RequiredNumbers }
+func (md *Message) ExtensionRanges() pref.FieldRanges  { return &md.lazyInit().ExtensionRanges }
+func (md *Message) ExtensionRangeOptions(i int) pref.ProtoMessage {
+	if f := md.lazyInit().ExtensionRangeOptions[i]; f != nil {
+		return f()
+	}
+	return descopts.ExtensionRange
+}
+func (md *Message) Enums() pref.EnumDescriptors           { return &md.L1.Enums }
+func (md *Message) Messages() pref.MessageDescriptors     { return &md.L1.Messages }
+func (md *Message) Extensions() pref.ExtensionDescriptors { return &md.L1.Extensions }
+func (md *Message) ProtoType(pref.MessageDescriptor)      {}
+func (md *Message) Format(s fmt.State, r rune)            { descfmt.FormatDesc(s, r, md) }
+func (md *Message) lazyInit() *MessageL2 {
+	md.L0.ParentFile.lazyInit() // implicitly initializes L2
+	return md.L2
+}
+
+// IsMessageSet is a pseudo-internal API for checking whether a message
+// should serialize in the proto1 message format.
+//
+// WARNING: This method is exempt from the compatibility promise and may be
+// removed in the future without warning.
+func (md *Message) IsMessageSet() bool {
+	return md.L1.IsMessageSet
+}
+
+func (fd *Field) Options() pref.ProtoMessage {
+	if f := fd.L1.Options; f != nil {
+		return f()
+	}
+	return descopts.Field
+}
+func (fd *Field) Number() pref.FieldNumber      { return fd.L1.Number }
+func (fd *Field) Cardinality() pref.Cardinality { return fd.L1.Cardinality }
+func (fd *Field) Kind() pref.Kind               { return fd.L1.Kind }
+func (fd *Field) HasJSONName() bool             { return fd.L1.StringName.hasJSON }
+func (fd *Field) JSONName() string              { return fd.L1.StringName.getJSON(fd) }
+func (fd *Field) TextName() string              { return fd.L1.StringName.getText(fd) }
+func (fd *Field) HasPresence() bool {
+	return fd.L1.Cardinality != pref.Repeated && (fd.L0.ParentFile.L1.Syntax == pref.Proto2 || fd.L1.Message != nil || fd.L1.ContainingOneof != nil)
+}
+func (fd *Field) HasOptionalKeyword() bool {
+	return (fd.L0.ParentFile.L1.Syntax == pref.Proto2 && fd.L1.Cardinality == pref.Optional && fd.L1.ContainingOneof == nil) || fd.L1.IsProto3Optional
+}
+func (fd *Field) IsPacked() bool {
+	if !fd.L1.HasPacked && fd.L0.ParentFile.L1.Syntax != pref.Proto2 && fd.L1.Cardinality == pref.Repeated {
+		switch fd.L1.Kind {
+		case pref.StringKind, pref.BytesKind, pref.MessageKind, pref.GroupKind:
+		default:
+			return true
+		}
+	}
+	return fd.L1.IsPacked
+}
+func (fd *Field) IsExtension() bool { return false }
+func (fd *Field) IsWeak() bool      { return fd.L1.IsWeak }
+func (fd *Field) IsList() bool      { return fd.Cardinality() == pref.Repeated && !fd.IsMap() }
+func (fd *Field) IsMap() bool       { return fd.Message() != nil && fd.Message().IsMapEntry() }
+func (fd *Field) MapKey() pref.FieldDescriptor {
+	if !fd.IsMap() {
+		return nil
+	}
+	return fd.Message().Fields().ByNumber(genid.MapEntry_Key_field_number)
+}
+func (fd *Field) MapValue() pref.FieldDescriptor {
+	if !fd.IsMap() {
+		return nil
+	}
+	return fd.Message().Fields().ByNumber(genid.MapEntry_Value_field_number)
+}
+func (fd *Field) HasDefault() bool                           { return fd.L1.Default.has }
+func (fd *Field) Default() pref.Value                        { return fd.L1.Default.get(fd) }
+func (fd *Field) DefaultEnumValue() pref.EnumValueDescriptor { return fd.L1.Default.enum }
+func (fd *Field) ContainingOneof() pref.OneofDescriptor      { return fd.L1.ContainingOneof }
+func (fd *Field) ContainingMessage() pref.MessageDescriptor {
+	return fd.L0.Parent.(pref.MessageDescriptor)
+}
+func (fd *Field) Enum() pref.EnumDescriptor {
+	return fd.L1.Enum
+}
+func (fd *Field) Message() pref.MessageDescriptor {
+	if fd.L1.IsWeak {
+		if d, _ := protoregistry.GlobalFiles.FindDescriptorByName(fd.L1.Message.FullName()); d != nil {
+			return d.(pref.MessageDescriptor)
+		}
+	}
+	return fd.L1.Message
+}
+func (fd *Field) Format(s fmt.State, r rune)     { descfmt.FormatDesc(s, r, fd) }
+func (fd *Field) ProtoType(pref.FieldDescriptor) {}
+
+// EnforceUTF8 is a pseudo-internal API to determine whether to enforce UTF-8
+// validation for the string field. This exists for Google-internal use only
+// since proto3 did not enforce UTF-8 validity prior to the open-source release.
+// If this method does not exist, the default is to enforce valid UTF-8.
+//
+// WARNING: This method is exempt from the compatibility promise and may be
+// removed in the future without warning.
+func (fd *Field) EnforceUTF8() bool {
+	if fd.L1.HasEnforceUTF8 {
+		return fd.L1.EnforceUTF8
+	}
+	return fd.L0.ParentFile.L1.Syntax == pref.Proto3
+}
+
+func (od *Oneof) IsSynthetic() bool {
+	return od.L0.ParentFile.L1.Syntax == pref.Proto3 && len(od.L1.Fields.List) == 1 && od.L1.Fields.List[0].HasOptionalKeyword()
+}
+func (od *Oneof) Options() pref.ProtoMessage {
+	if f := od.L1.Options; f != nil {
+		return f()
+	}
+	return descopts.Oneof
+}
+func (od *Oneof) Fields() pref.FieldDescriptors  { return &od.L1.Fields }
+func (od *Oneof) Format(s fmt.State, r rune)     { descfmt.FormatDesc(s, r, od) }
+func (od *Oneof) ProtoType(pref.OneofDescriptor) {}
+
+type (
+	Extension struct {
+		Base
+		L1 ExtensionL1
+		L2 *ExtensionL2 // protected by fileDesc.once
+	}
+	ExtensionL1 struct {
+		Number      pref.FieldNumber
+		Extendee    pref.MessageDescriptor
+		Cardinality pref.Cardinality
+		Kind        pref.Kind
+	}
+	ExtensionL2 struct {
+		Options          func() pref.ProtoMessage
+		StringName       stringName
+		IsProto3Optional bool // promoted from google.protobuf.FieldDescriptorProto
+		IsPacked         bool // promoted from google.protobuf.FieldOptions
+		Default          defaultValue
+		Enum             pref.EnumDescriptor
+		Message          pref.MessageDescriptor
+	}
+)
+
+func (xd *Extension) Options() pref.ProtoMessage {
+	if f := xd.lazyInit().Options; f != nil {
+		return f()
+	}
+	return descopts.Field
+}
+func (xd *Extension) Number() pref.FieldNumber      { return xd.L1.Number }
+func (xd *Extension) Cardinality() pref.Cardinality { return xd.L1.Cardinality }
+func (xd *Extension) Kind() pref.Kind               { return xd.L1.Kind }
+func (xd *Extension) HasJSONName() bool             { return xd.lazyInit().StringName.hasJSON }
+func (xd *Extension) JSONName() string              { return xd.lazyInit().StringName.getJSON(xd) }
+func (xd *Extension) TextName() string              { return xd.lazyInit().StringName.getText(xd) }
+func (xd *Extension) HasPresence() bool             { return xd.L1.Cardinality != pref.Repeated }
+func (xd *Extension) HasOptionalKeyword() bool {
+	return (xd.L0.ParentFile.L1.Syntax == pref.Proto2 && xd.L1.Cardinality == pref.Optional) || xd.lazyInit().IsProto3Optional
+}
+func (xd *Extension) IsPacked() bool                             { return xd.lazyInit().IsPacked }
+func (xd *Extension) IsExtension() bool                          { return true }
+func (xd *Extension) IsWeak() bool                               { return false }
+func (xd *Extension) IsList() bool                               { return xd.Cardinality() == pref.Repeated }
+func (xd *Extension) IsMap() bool                                { return false }
+func (xd *Extension) MapKey() pref.FieldDescriptor               { return nil }
+func (xd *Extension) MapValue() pref.FieldDescriptor             { return nil }
+func (xd *Extension) HasDefault() bool                           { return xd.lazyInit().Default.has }
+func (xd *Extension) Default() pref.Value                        { return xd.lazyInit().Default.get(xd) }
+func (xd *Extension) DefaultEnumValue() pref.EnumValueDescriptor { return xd.lazyInit().Default.enum }
+func (xd *Extension) ContainingOneof() pref.OneofDescriptor      { return nil }
+func (xd *Extension) ContainingMessage() pref.MessageDescriptor  { return xd.L1.Extendee }
+func (xd *Extension) Enum() pref.EnumDescriptor                  { return xd.lazyInit().Enum }
+func (xd *Extension) Message() pref.MessageDescriptor            { return xd.lazyInit().Message }
+func (xd *Extension) Format(s fmt.State, r rune)                 { descfmt.FormatDesc(s, r, xd) }
+func (xd *Extension) ProtoType(pref.FieldDescriptor)             {}
+func (xd *Extension) ProtoInternal(pragma.DoNotImplement)        {}
+func (xd *Extension) lazyInit() *ExtensionL2 {
+	xd.L0.ParentFile.lazyInit() // implicitly initializes L2
+	return xd.L2
+}
+
+type (
+	Service struct {
+		Base
+		L1 ServiceL1
+		L2 *ServiceL2 // protected by fileDesc.once
+	}
+	ServiceL1 struct{}
+	ServiceL2 struct {
+		Options func() pref.ProtoMessage
+		Methods Methods
+	}
+
+	Method struct {
+		Base
+		L1 MethodL1
+	}
+	MethodL1 struct {
+		Options           func() pref.ProtoMessage
+		Input             pref.MessageDescriptor
+		Output            pref.MessageDescriptor
+		IsStreamingClient bool
+		IsStreamingServer bool
+	}
+)
+
+func (sd *Service) Options() pref.ProtoMessage {
+	if f := sd.lazyInit().Options; f != nil {
+		return f()
+	}
+	return descopts.Service
+}
+func (sd *Service) Methods() pref.MethodDescriptors     { return &sd.lazyInit().Methods }
+func (sd *Service) Format(s fmt.State, r rune)          { descfmt.FormatDesc(s, r, sd) }
+func (sd *Service) ProtoType(pref.ServiceDescriptor)    {}
+func (sd *Service) ProtoInternal(pragma.DoNotImplement) {}
+func (sd *Service) lazyInit() *ServiceL2 {
+	sd.L0.ParentFile.lazyInit() // implicitly initializes L2
+	return sd.L2
+}
+
+func (md *Method) Options() pref.ProtoMessage {
+	if f := md.L1.Options; f != nil {
+		return f()
+	}
+	return descopts.Method
+}
+func (md *Method) Input() pref.MessageDescriptor       { return md.L1.Input }
+func (md *Method) Output() pref.MessageDescriptor      { return md.L1.Output }
+func (md *Method) IsStreamingClient() bool             { return md.L1.IsStreamingClient }
+func (md *Method) IsStreamingServer() bool             { return md.L1.IsStreamingServer }
+func (md *Method) Format(s fmt.State, r rune)          { descfmt.FormatDesc(s, r, md) }
+func (md *Method) ProtoType(pref.MethodDescriptor)     {}
+func (md *Method) ProtoInternal(pragma.DoNotImplement) {}
+
+// Surrogate files are can be used to create standalone descriptors
+// where the syntax is only information derived from the parent file.
+var (
+	SurrogateProto2 = &File{L1: FileL1{Syntax: pref.Proto2}, L2: &FileL2{}}
+	SurrogateProto3 = &File{L1: FileL1{Syntax: pref.Proto3}, L2: &FileL2{}}
+)
+
+type (
+	Base struct {
+		L0 BaseL0
+	}
+	BaseL0 struct {
+		FullName   pref.FullName // must be populated
+		ParentFile *File         // must be populated
+		Parent     pref.Descriptor
+		Index      int
+	}
+)
+
+func (d *Base) Name() pref.Name         { return d.L0.FullName.Name() }
+func (d *Base) FullName() pref.FullName { return d.L0.FullName }
+func (d *Base) ParentFile() pref.FileDescriptor {
+	if d.L0.ParentFile == SurrogateProto2 || d.L0.ParentFile == SurrogateProto3 {
+		return nil // surrogate files are not real parents
+	}
+	return d.L0.ParentFile
+}
+func (d *Base) Parent() pref.Descriptor             { return d.L0.Parent }
+func (d *Base) Index() int                          { return d.L0.Index }
+func (d *Base) Syntax() pref.Syntax                 { return d.L0.ParentFile.Syntax() }
+func (d *Base) IsPlaceholder() bool                 { return false }
+func (d *Base) ProtoInternal(pragma.DoNotImplement) {}
+
+type stringName struct {
+	hasJSON  bool
+	once     sync.Once
+	nameJSON string
+	nameText string
+}
+
+// InitJSON initializes the name. It is exported for use by other internal packages.
+func (s *stringName) InitJSON(name string) {
+	s.hasJSON = true
+	s.nameJSON = name
+}
+
+func (s *stringName) lazyInit(fd pref.FieldDescriptor) *stringName {
+	s.once.Do(func() {
+		if fd.IsExtension() {
+			// For extensions, JSON and text are formatted the same way.
+			var name string
+			if messageset.IsMessageSetExtension(fd) {
+				name = string("[" + fd.FullName().Parent() + "]")
+			} else {
+				name = string("[" + fd.FullName() + "]")
+			}
+			s.nameJSON = name
+			s.nameText = name
+		} else {
+			// Format the JSON name.
+			if !s.hasJSON {
+				s.nameJSON = strs.JSONCamelCase(string(fd.Name()))
+			}
+
+			// Format the text name.
+			s.nameText = string(fd.Name())
+			if fd.Kind() == pref.GroupKind {
+				s.nameText = string(fd.Message().Name())
+			}
+		}
+	})
+	return s
+}
+
+func (s *stringName) getJSON(fd pref.FieldDescriptor) string { return s.lazyInit(fd).nameJSON }
+func (s *stringName) getText(fd pref.FieldDescriptor) string { return s.lazyInit(fd).nameText }
+
+func DefaultValue(v pref.Value, ev pref.EnumValueDescriptor) defaultValue {
+	dv := defaultValue{has: v.IsValid(), val: v, enum: ev}
+	if b, ok := v.Interface().([]byte); ok {
+		// Store a copy of the default bytes, so that we can detect
+		// accidental mutations of the original value.
+		dv.bytes = append([]byte(nil), b...)
+	}
+	return dv
+}
+
+func unmarshalDefault(b []byte, k pref.Kind, pf *File, ed pref.EnumDescriptor) defaultValue {
+	var evs pref.EnumValueDescriptors
+	if k == pref.EnumKind {
+		// If the enum is declared within the same file, be careful not to
+		// blindly call the Values method, lest we bind ourselves in a deadlock.
+		if e, ok := ed.(*Enum); ok && e.L0.ParentFile == pf {
+			evs = &e.L2.Values
+		} else {
+			evs = ed.Values()
+		}
+
+		// If we are unable to resolve the enum dependency, use a placeholder
+		// enum value since we will not be able to parse the default value.
+		if ed.IsPlaceholder() && pref.Name(b).IsValid() {
+			v := pref.ValueOfEnum(0)
+			ev := PlaceholderEnumValue(ed.FullName().Parent().Append(pref.Name(b)))
+			return DefaultValue(v, ev)
+		}
+	}
+
+	v, ev, err := defval.Unmarshal(string(b), k, evs, defval.Descriptor)
+	if err != nil {
+		panic(err)
+	}
+	return DefaultValue(v, ev)
+}
+
+type defaultValue struct {
+	has   bool
+	val   pref.Value
+	enum  pref.EnumValueDescriptor
+	bytes []byte
+}
+
+func (dv *defaultValue) get(fd pref.FieldDescriptor) pref.Value {
+	// Return the zero value as the default if unpopulated.
+	if !dv.has {
+		if fd.Cardinality() == pref.Repeated {
+			return pref.Value{}
+		}
+		switch fd.Kind() {
+		case pref.BoolKind:
+			return pref.ValueOfBool(false)
+		case pref.Int32Kind, pref.Sint32Kind, pref.Sfixed32Kind:
+			return pref.ValueOfInt32(0)
+		case pref.Int64Kind, pref.Sint64Kind, pref.Sfixed64Kind:
+			return pref.ValueOfInt64(0)
+		case pref.Uint32Kind, pref.Fixed32Kind:
+			return pref.ValueOfUint32(0)
+		case pref.Uint64Kind, pref.Fixed64Kind:
+			return pref.ValueOfUint64(0)
+		case pref.FloatKind:
+			return pref.ValueOfFloat32(0)
+		case pref.DoubleKind:
+			return pref.ValueOfFloat64(0)
+		case pref.StringKind:
+			return pref.ValueOfString("")
+		case pref.BytesKind:
+			return pref.ValueOfBytes(nil)
+		case pref.EnumKind:
+			if evs := fd.Enum().Values(); evs.Len() > 0 {
+				return pref.ValueOfEnum(evs.Get(0).Number())
+			}
+			return pref.ValueOfEnum(0)
+		}
+	}
+
+	if len(dv.bytes) > 0 && !bytes.Equal(dv.bytes, dv.val.Bytes()) {
+		// TODO: Avoid panic if we're running with the race detector
+		// and instead spawn a goroutine that periodically resets
+		// this value back to the original to induce a race.
+		panic(fmt.Sprintf("detected mutation on the default bytes for %v", fd.FullName()))
+	}
+	return dv.val
+}
diff --git a/vendor/google.golang.org/protobuf/internal/filedesc/desc_init.go b/vendor/google.golang.org/protobuf/internal/filedesc/desc_init.go
new file mode 100644
index 0000000..66e1fee
--- /dev/null
+++ b/vendor/google.golang.org/protobuf/internal/filedesc/desc_init.go
@@ -0,0 +1,471 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package filedesc
+
+import (
+	"sync"
+
+	"google.golang.org/protobuf/encoding/protowire"
+	"google.golang.org/protobuf/internal/genid"
+	"google.golang.org/protobuf/internal/strs"
+	pref "google.golang.org/protobuf/reflect/protoreflect"
+)
+
+// fileRaw is a data struct used when initializing a file descriptor from
+// a raw FileDescriptorProto.
+type fileRaw struct {
+	builder       Builder
+	allEnums      []Enum
+	allMessages   []Message
+	allExtensions []Extension
+	allServices   []Service
+}
+
+func newRawFile(db Builder) *File {
+	fd := &File{fileRaw: fileRaw{builder: db}}
+	fd.initDecls(db.NumEnums, db.NumMessages, db.NumExtensions, db.NumServices)
+	fd.unmarshalSeed(db.RawDescriptor)
+
+	// Extended message targets are eagerly resolved since registration
+	// needs this information at program init time.
+	for i := range fd.allExtensions {
+		xd := &fd.allExtensions[i]
+		xd.L1.Extendee = fd.resolveMessageDependency(xd.L1.Extendee, listExtTargets, int32(i))
+	}
+
+	fd.checkDecls()
+	return fd
+}
+
+// initDecls pre-allocates slices for the exact number of enums, messages
+// (including map entries), extensions, and services declared in the proto file.
+// This is done to avoid regrowing the slice, which would change the address
+// for any previously seen declaration.
+//
+// The alloc methods "allocates" slices by pulling from the capacity.
+func (fd *File) initDecls(numEnums, numMessages, numExtensions, numServices int32) {
+	fd.allEnums = make([]Enum, 0, numEnums)
+	fd.allMessages = make([]Message, 0, numMessages)
+	fd.allExtensions = make([]Extension, 0, numExtensions)
+	fd.allServices = make([]Service, 0, numServices)
+}
+
+func (fd *File) allocEnums(n int) []Enum {
+	total := len(fd.allEnums)
+	es := fd.allEnums[total : total+n]
+	fd.allEnums = fd.allEnums[:total+n]
+	return es
+}
+func (fd *File) allocMessages(n int) []Message {
+	total := len(fd.allMessages)
+	ms := fd.allMessages[total : total+n]
+	fd.allMessages = fd.allMessages[:total+n]
+	return ms
+}
+func (fd *File) allocExtensions(n int) []Extension {
+	total := len(fd.allExtensions)
+	xs := fd.allExtensions[total : total+n]
+	fd.allExtensions = fd.allExtensions[:total+n]
+	return xs
+}
+func (fd *File) allocServices(n int) []Service {
+	total := len(fd.allServices)
+	xs := fd.allServices[total : total+n]
+	fd.allServices = fd.allServices[:total+n]
+	return xs
+}
+
+// checkDecls performs a sanity check that the expected number of expected
+// declarations matches the number that were found in the descriptor proto.
+func (fd *File) checkDecls() {
+	switch {
+	case len(fd.allEnums) != cap(fd.allEnums):
+	case len(fd.allMessages) != cap(fd.allMessages):
+	case len(fd.allExtensions) != cap(fd.allExtensions):
+	case len(fd.allServices) != cap(fd.allServices):
+	default:
+		return
+	}
+	panic("mismatching cardinality")
+}
+
+func (fd *File) unmarshalSeed(b []byte) {
+	sb := getBuilder()
+	defer putBuilder(sb)
+
+	var prevField pref.FieldNumber
+	var numEnums, numMessages, numExtensions, numServices int
+	var posEnums, posMessages, posExtensions, posServices int
+	b0 := b
+	for len(b) > 0 {
+		num, typ, n := protowire.ConsumeTag(b)
+		b = b[n:]
+		switch typ {
+		case protowire.BytesType:
+			v, m := protowire.ConsumeBytes(b)
+			b = b[m:]
+			switch num {
+			case genid.FileDescriptorProto_Syntax_field_number:
+				switch string(v) {
+				case "proto2":
+					fd.L1.Syntax = pref.Proto2
+				case "proto3":
+					fd.L1.Syntax = pref.Proto3
+				default:
+					panic("invalid syntax")
+				}
+			case genid.FileDescriptorProto_Name_field_number:
+				fd.L1.Path = sb.MakeString(v)
+			case genid.FileDescriptorProto_Package_field_number:
+				fd.L1.Package = pref.FullName(sb.MakeString(v))
+			case genid.FileDescriptorProto_EnumType_field_number:
+				if prevField != genid.FileDescriptorProto_EnumType_field_number {
+					if numEnums > 0 {
+						panic("non-contiguous repeated field")
+					}
+					posEnums = len(b0) - len(b) - n - m
+				}
+				numEnums++
+			case genid.FileDescriptorProto_MessageType_field_number:
+				if prevField != genid.FileDescriptorProto_MessageType_field_number {
+					if numMessages > 0 {
+						panic("non-contiguous repeated field")
+					}
+					posMessages = len(b0) - len(b) - n - m
+				}
+				numMessages++
+			case genid.FileDescriptorProto_Extension_field_number:
+				if prevField != genid.FileDescriptorProto_Extension_field_number {
+					if numExtensions > 0 {
+						panic("non-contiguous repeated field")
+					}
+					posExtensions = len(b0) - len(b) - n - m
+				}
+				numExtensions++
+			case genid.FileDescriptorProto_Service_field_number:
+				if prevField != genid.FileDescriptorProto_Service_field_number {
+					if numServices > 0 {
+						panic("non-contiguous repeated field")
+					}
+					posServices = len(b0) - len(b) - n - m
+				}
+				numServices++
+			}
+			prevField = num
+		default:
+			m := protowire.ConsumeFieldValue(num, typ, b)
+			b = b[m:]
+			prevField = -1 // ignore known field numbers of unknown wire type
+		}
+	}
+
+	// If syntax is missing, it is assumed to be proto2.
+	if fd.L1.Syntax == 0 {
+		fd.L1.Syntax = pref.Proto2
+	}
+
+	// Must allocate all declarations before parsing each descriptor type
+	// to ensure we handled all descriptors in "flattened ordering".
+	if numEnums > 0 {
+		fd.L1.Enums.List = fd.allocEnums(numEnums)
+	}
+	if numMessages > 0 {
+		fd.L1.Messages.List = fd.allocMessages(numMessages)
+	}
+	if numExtensions > 0 {
+		fd.L1.Extensions.List = fd.allocExtensions(numExtensions)
+	}
+	if numServices > 0 {
+		fd.L1.Services.List = fd.allocServices(numServices)
+	}
+
+	if numEnums > 0 {
+		b := b0[posEnums:]
+		for i := range fd.L1.Enums.List {
+			_, n := protowire.ConsumeVarint(b)
+			v, m := protowire.ConsumeBytes(b[n:])
+			fd.L1.Enums.List[i].unmarshalSeed(v, sb, fd, fd, i)
+			b = b[n+m:]
+		}
+	}
+	if numMessages > 0 {
+		b := b0[posMessages:]
+		for i := range fd.L1.Messages.List {
+			_, n := protowire.ConsumeVarint(b)
+			v, m := protowire.ConsumeBytes(b[n:])
+			fd.L1.Messages.List[i].unmarshalSeed(v, sb, fd, fd, i)
+			b = b[n+m:]
+		}
+	}
+	if numExtensions > 0 {
+		b := b0[posExtensions:]
+		for i := range fd.L1.Extensions.List {
+			_, n := protowire.ConsumeVarint(b)
+			v, m := protowire.ConsumeBytes(b[n:])
+			fd.L1.Extensions.List[i].unmarshalSeed(v, sb, fd, fd, i)
+			b = b[n+m:]
+		}
+	}
+	if numServices > 0 {
+		b := b0[posServices:]
+		for i := range fd.L1.Services.List {
+			_, n := protowire.ConsumeVarint(b)
+			v, m := protowire.ConsumeBytes(b[n:])
+			fd.L1.Services.List[i].unmarshalSeed(v, sb, fd, fd, i)
+			b = b[n+m:]
+		}
+	}
+}
+
+func (ed *Enum) unmarshalSeed(b []byte, sb *strs.Builder, pf *File, pd pref.Descriptor, i int) {
+	ed.L0.ParentFile = pf
+	ed.L0.Parent = pd
+	ed.L0.Index = i
+
+	var numValues int
+	for b := b; len(b) > 0; {
+		num, typ, n := protowire.ConsumeTag(b)
+		b = b[n:]
+		switch typ {
+		case protowire.BytesType:
+			v, m := protowire.ConsumeBytes(b)
+			b = b[m:]
+			switch num {
+			case genid.EnumDescriptorProto_Name_field_number:
+				ed.L0.FullName = appendFullName(sb, pd.FullName(), v)
+			case genid.EnumDescriptorProto_Value_field_number:
+				numValues++
+			}
+		default:
+			m := protowire.ConsumeFieldValue(num, typ, b)
+			b = b[m:]
+		}
+	}
+
+	// Only construct enum value descriptors for top-level enums since
+	// they are needed for registration.
+	if pd != pf {
+		return
+	}
+	ed.L1.eagerValues = true
+	ed.L2 = new(EnumL2)
+	ed.L2.Values.List = make([]EnumValue, numValues)
+	for i := 0; len(b) > 0; {
+		num, typ, n := protowire.ConsumeTag(b)
+		b = b[n:]
+		switch typ {
+		case protowire.BytesType:
+			v, m := protowire.ConsumeBytes(b)
+			b = b[m:]
+			switch num {
+			case genid.EnumDescriptorProto_Value_field_number:
+				ed.L2.Values.List[i].unmarshalFull(v, sb, pf, ed, i)
+				i++
+			}
+		default:
+			m := protowire.ConsumeFieldValue(num, typ, b)
+			b = b[m:]
+		}
+	}
+}
+
+func (md *Message) unmarshalSeed(b []byte, sb *strs.Builder, pf *File, pd pref.Descriptor, i int) {
+	md.L0.ParentFile = pf
+	md.L0.Parent = pd
+	md.L0.Index = i
+
+	var prevField pref.FieldNumber
+	var numEnums, numMessages, numExtensions int
+	var posEnums, posMessages, posExtensions int
+	b0 := b
+	for len(b) > 0 {
+		num, typ, n := protowire.ConsumeTag(b)
+		b = b[n:]
+		switch typ {
+		case protowire.BytesType:
+			v, m := protowire.ConsumeBytes(b)
+			b = b[m:]
+			switch num {
+			case genid.DescriptorProto_Name_field_number:
+				md.L0.FullName = appendFullName(sb, pd.FullName(), v)
+			case genid.DescriptorProto_EnumType_field_number:
+				if prevField != genid.DescriptorProto_EnumType_field_number {
+					if numEnums > 0 {
+						panic("non-contiguous repeated field")
+					}
+					posEnums = len(b0) - len(b) - n - m
+				}
+				numEnums++
+			case genid.DescriptorProto_NestedType_field_number:
+				if prevField != genid.DescriptorProto_NestedType_field_number {
+					if numMessages > 0 {
+						panic("non-contiguous repeated field")
+					}
+					posMessages = len(b0) - len(b) - n - m
+				}
+				numMessages++
+			case genid.DescriptorProto_Extension_field_number:
+				if prevField != genid.DescriptorProto_Extension_field_number {
+					if numExtensions > 0 {
+						panic("non-contiguous repeated field")
+					}
+					posExtensions = len(b0) - len(b) - n - m
+				}
+				numExtensions++
+			case genid.DescriptorProto_Options_field_number:
+				md.unmarshalSeedOptions(v)
+			}
+			prevField = num
+		default:
+			m := protowire.ConsumeFieldValue(num, typ, b)
+			b = b[m:]
+			prevField = -1 // ignore known field numbers of unknown wire type
+		}
+	}
+
+	// Must allocate all declarations before parsing each descriptor type
+	// to ensure we handled all descriptors in "flattened ordering".
+	if numEnums > 0 {
+		md.L1.Enums.List = pf.allocEnums(numEnums)
+	}
+	if numMessages > 0 {
+		md.L1.Messages.List = pf.allocMessages(numMessages)
+	}
+	if numExtensions > 0 {
+		md.L1.Extensions.List = pf.allocExtensions(numExtensions)
+	}
+
+	if numEnums > 0 {
+		b := b0[posEnums:]
+		for i := range md.L1.Enums.List {
+			_, n := protowire.ConsumeVarint(b)
+			v, m := protowire.ConsumeBytes(b[n:])
+			md.L1.Enums.List[i].unmarshalSeed(v, sb, pf, md, i)
+			b = b[n+m:]
+		}
+	}
+	if numMessages > 0 {
+		b := b0[posMessages:]
+		for i := range md.L1.Messages.List {
+			_, n := protowire.ConsumeVarint(b)
+			v, m := protowire.ConsumeBytes(b[n:])
+			md.L1.Messages.List[i].unmarshalSeed(v, sb, pf, md, i)
+			b = b[n+m:]
+		}
+	}
+	if numExtensions > 0 {
+		b := b0[posExtensions:]
+		for i := range md.L1.Extensions.List {
+			_, n := protowire.ConsumeVarint(b)
+			v, m := protowire.ConsumeBytes(b[n:])
+			md.L1.Extensions.List[i].unmarshalSeed(v, sb, pf, md, i)
+			b = b[n+m:]
+		}
+	}
+}
+
+func (md *Message) unmarshalSeedOptions(b []byte) {
+	for len(b) > 0 {
+		num, typ, n := protowire.ConsumeTag(b)
+		b = b[n:]
+		switch typ {
+		case protowire.VarintType:
+			v, m := protowire.ConsumeVarint(b)
+			b = b[m:]
+			switch num {
+			case genid.MessageOptions_MapEntry_field_number:
+				md.L1.IsMapEntry = protowire.DecodeBool(v)
+			case genid.MessageOptions_MessageSetWireFormat_field_number:
+				md.L1.IsMessageSet = protowire.DecodeBool(v)
+			}
+		default:
+			m := protowire.ConsumeFieldValue(num, typ, b)
+			b = b[m:]
+		}
+	}
+}
+
+func (xd *Extension) unmarshalSeed(b []byte, sb *strs.Builder, pf *File, pd pref.Descriptor, i int) {
+	xd.L0.ParentFile = pf
+	xd.L0.Parent = pd
+	xd.L0.Index = i
+
+	for len(b) > 0 {
+		num, typ, n := protowire.ConsumeTag(b)
+		b = b[n:]
+		switch typ {
+		case protowire.VarintType:
+			v, m := protowire.ConsumeVarint(b)
+			b = b[m:]
+			switch num {
+			case genid.FieldDescriptorProto_Number_field_number:
+				xd.L1.Number = pref.FieldNumber(v)
+			case genid.FieldDescriptorProto_Label_field_number:
+				xd.L1.Cardinality = pref.Cardinality(v)
+			case genid.FieldDescriptorProto_Type_field_number:
+				xd.L1.Kind = pref.Kind(v)
+			}
+		case protowire.BytesType:
+			v, m := protowire.ConsumeBytes(b)
+			b = b[m:]
+			switch num {
+			case genid.FieldDescriptorProto_Name_field_number:
+				xd.L0.FullName = appendFullName(sb, pd.FullName(), v)
+			case genid.FieldDescriptorProto_Extendee_field_number:
+				xd.L1.Extendee = PlaceholderMessage(makeFullName(sb, v))
+			}
+		default:
+			m := protowire.ConsumeFieldValue(num, typ, b)
+			b = b[m:]
+		}
+	}
+}
+
+func (sd *Service) unmarshalSeed(b []byte, sb *strs.Builder, pf *File, pd pref.Descriptor, i int) {
+	sd.L0.ParentFile = pf
+	sd.L0.Parent = pd
+	sd.L0.Index = i
+
+	for len(b) > 0 {
+		num, typ, n := protowire.ConsumeTag(b)
+		b = b[n:]
+		switch typ {
+		case protowire.BytesType:
+			v, m := protowire.ConsumeBytes(b)
+			b = b[m:]
+			switch num {
+			case genid.ServiceDescriptorProto_Name_field_number:
+				sd.L0.FullName = appendFullName(sb, pd.FullName(), v)
+			}
+		default:
+			m := protowire.ConsumeFieldValue(num, typ, b)
+			b = b[m:]
+		}
+	}
+}
+
+var nameBuilderPool = sync.Pool{
+	New: func() interface{} { return new(strs.Builder) },
+}
+
+func getBuilder() *strs.Builder {
+	return nameBuilderPool.Get().(*strs.Builder)
+}
+func putBuilder(b *strs.Builder) {
+	nameBuilderPool.Put(b)
+}
+
+// makeFullName converts b to a protoreflect.FullName,
+// where b must start with a leading dot.
+func makeFullName(sb *strs.Builder, b []byte) pref.FullName {
+	if len(b) == 0 || b[0] != '.' {
+		panic("name reference must be fully qualified")
+	}
+	return pref.FullName(sb.MakeString(b[1:]))
+}
+
+func appendFullName(sb *strs.Builder, prefix pref.FullName, suffix []byte) pref.FullName {
+	return sb.AppendFullName(prefix, pref.Name(strs.UnsafeString(suffix)))
+}
diff --git a/vendor/google.golang.org/protobuf/internal/filedesc/desc_lazy.go b/vendor/google.golang.org/protobuf/internal/filedesc/desc_lazy.go
new file mode 100644
index 0000000..198451e
--- /dev/null
+++ b/vendor/google.golang.org/protobuf/internal/filedesc/desc_lazy.go
@@ -0,0 +1,704 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package filedesc
+
+import (
+	"reflect"
+	"sync"
+
+	"google.golang.org/protobuf/encoding/protowire"
+	"google.golang.org/protobuf/internal/descopts"
+	"google.golang.org/protobuf/internal/genid"
+	"google.golang.org/protobuf/internal/strs"
+	"google.golang.org/protobuf/proto"
+	pref "google.golang.org/protobuf/reflect/protoreflect"
+)
+
+func (fd *File) lazyRawInit() {
+	fd.unmarshalFull(fd.builder.RawDescriptor)
+	fd.resolveMessages()
+	fd.resolveExtensions()
+	fd.resolveServices()
+}
+
+func (file *File) resolveMessages() {
+	var depIdx int32
+	for i := range file.allMessages {
+		md := &file.allMessages[i]
+
+		// Resolve message field dependencies.
+		for j := range md.L2.Fields.List {
+			fd := &md.L2.Fields.List[j]
+
+			// Weak fields are resolved upon actual use.
+			if fd.L1.IsWeak {
+				continue
+			}
+
+			// Resolve message field dependency.
+			switch fd.L1.Kind {
+			case pref.EnumKind:
+				fd.L1.Enum = file.resolveEnumDependency(fd.L1.Enum, listFieldDeps, depIdx)
+				depIdx++
+			case pref.MessageKind, pref.GroupKind:
+				fd.L1.Message = file.resolveMessageDependency(fd.L1.Message, listFieldDeps, depIdx)
+				depIdx++
+			}
+
+			// Default is resolved here since it depends on Enum being resolved.
+			if v := fd.L1.Default.val; v.IsValid() {
+				fd.L1.Default = unmarshalDefault(v.Bytes(), fd.L1.Kind, file, fd.L1.Enum)
+			}
+		}
+	}
+}
+
+func (file *File) resolveExtensions() {
+	var depIdx int32
+	for i := range file.allExtensions {
+		xd := &file.allExtensions[i]
+
+		// Resolve extension field dependency.
+		switch xd.L1.Kind {
+		case pref.EnumKind:
+			xd.L2.Enum = file.resolveEnumDependency(xd.L2.Enum, listExtDeps, depIdx)
+			depIdx++
+		case pref.MessageKind, pref.GroupKind:
+			xd.L2.Message = file.resolveMessageDependency(xd.L2.Message, listExtDeps, depIdx)
+			depIdx++
+		}
+
+		// Default is resolved here since it depends on Enum being resolved.
+		if v := xd.L2.Default.val; v.IsValid() {
+			xd.L2.Default = unmarshalDefault(v.Bytes(), xd.L1.Kind, file, xd.L2.Enum)
+		}
+	}
+}
+
+func (file *File) resolveServices() {
+	var depIdx int32
+	for i := range file.allServices {
+		sd := &file.allServices[i]
+
+		// Resolve method dependencies.
+		for j := range sd.L2.Methods.List {
+			md := &sd.L2.Methods.List[j]
+			md.L1.Input = file.resolveMessageDependency(md.L1.Input, listMethInDeps, depIdx)
+			md.L1.Output = file.resolveMessageDependency(md.L1.Output, listMethOutDeps, depIdx)
+			depIdx++
+		}
+	}
+}
+
+func (file *File) resolveEnumDependency(ed pref.EnumDescriptor, i, j int32) pref.EnumDescriptor {
+	r := file.builder.FileRegistry
+	if r, ok := r.(resolverByIndex); ok {
+		if ed2 := r.FindEnumByIndex(i, j, file.allEnums, file.allMessages); ed2 != nil {
+			return ed2
+		}
+	}
+	for i := range file.allEnums {
+		if ed2 := &file.allEnums[i]; ed2.L0.FullName == ed.FullName() {
+			return ed2
+		}
+	}
+	if d, _ := r.FindDescriptorByName(ed.FullName()); d != nil {
+		return d.(pref.EnumDescriptor)
+	}
+	return ed
+}
+
+func (file *File) resolveMessageDependency(md pref.MessageDescriptor, i, j int32) pref.MessageDescriptor {
+	r := file.builder.FileRegistry
+	if r, ok := r.(resolverByIndex); ok {
+		if md2 := r.FindMessageByIndex(i, j, file.allEnums, file.allMessages); md2 != nil {
+			return md2
+		}
+	}
+	for i := range file.allMessages {
+		if md2 := &file.allMessages[i]; md2.L0.FullName == md.FullName() {
+			return md2
+		}
+	}
+	if d, _ := r.FindDescriptorByName(md.FullName()); d != nil {
+		return d.(pref.MessageDescriptor)
+	}
+	return md
+}
+
+func (fd *File) unmarshalFull(b []byte) {
+	sb := getBuilder()
+	defer putBuilder(sb)
+
+	var enumIdx, messageIdx, extensionIdx, serviceIdx int
+	var rawOptions []byte
+	fd.L2 = new(FileL2)
+	for len(b) > 0 {
+		num, typ, n := protowire.ConsumeTag(b)
+		b = b[n:]
+		switch typ {
+		case protowire.VarintType:
+			v, m := protowire.ConsumeVarint(b)
+			b = b[m:]
+			switch num {
+			case genid.FileDescriptorProto_PublicDependency_field_number:
+				fd.L2.Imports[v].IsPublic = true
+			case genid.FileDescriptorProto_WeakDependency_field_number:
+				fd.L2.Imports[v].IsWeak = true
+			}
+		case protowire.BytesType:
+			v, m := protowire.ConsumeBytes(b)
+			b = b[m:]
+			switch num {
+			case genid.FileDescriptorProto_Dependency_field_number:
+				path := sb.MakeString(v)
+				imp, _ := fd.builder.FileRegistry.FindFileByPath(path)
+				if imp == nil {
+					imp = PlaceholderFile(path)
+				}
+				fd.L2.Imports = append(fd.L2.Imports, pref.FileImport{FileDescriptor: imp})
+			case genid.FileDescriptorProto_EnumType_field_number:
+				fd.L1.Enums.List[enumIdx].unmarshalFull(v, sb)
+				enumIdx++
+			case genid.FileDescriptorProto_MessageType_field_number:
+				fd.L1.Messages.List[messageIdx].unmarshalFull(v, sb)
+				messageIdx++
+			case genid.FileDescriptorProto_Extension_field_number:
+				fd.L1.Extensions.List[extensionIdx].unmarshalFull(v, sb)
+				extensionIdx++
+			case genid.FileDescriptorProto_Service_field_number:
+				fd.L1.Services.List[serviceIdx].unmarshalFull(v, sb)
+				serviceIdx++
+			case genid.FileDescriptorProto_Options_field_number:
+				rawOptions = appendOptions(rawOptions, v)
+			}
+		default:
+			m := protowire.ConsumeFieldValue(num, typ, b)
+			b = b[m:]
+		}
+	}
+	fd.L2.Options = fd.builder.optionsUnmarshaler(&descopts.File, rawOptions)
+}
+
+func (ed *Enum) unmarshalFull(b []byte, sb *strs.Builder) {
+	var rawValues [][]byte
+	var rawOptions []byte
+	if !ed.L1.eagerValues {
+		ed.L2 = new(EnumL2)
+	}
+	for len(b) > 0 {
+		num, typ, n := protowire.ConsumeTag(b)
+		b = b[n:]
+		switch typ {
+		case protowire.BytesType:
+			v, m := protowire.ConsumeBytes(b)
+			b = b[m:]
+			switch num {
+			case genid.EnumDescriptorProto_Value_field_number:
+				rawValues = append(rawValues, v)
+			case genid.EnumDescriptorProto_ReservedName_field_number:
+				ed.L2.ReservedNames.List = append(ed.L2.ReservedNames.List, pref.Name(sb.MakeString(v)))
+			case genid.EnumDescriptorProto_ReservedRange_field_number:
+				ed.L2.ReservedRanges.List = append(ed.L2.ReservedRanges.List, unmarshalEnumReservedRange(v))
+			case genid.EnumDescriptorProto_Options_field_number:
+				rawOptions = appendOptions(rawOptions, v)
+			}
+		default:
+			m := protowire.ConsumeFieldValue(num, typ, b)
+			b = b[m:]
+		}
+	}
+	if !ed.L1.eagerValues && len(rawValues) > 0 {
+		ed.L2.Values.List = make([]EnumValue, len(rawValues))
+		for i, b := range rawValues {
+			ed.L2.Values.List[i].unmarshalFull(b, sb, ed.L0.ParentFile, ed, i)
+		}
+	}
+	ed.L2.Options = ed.L0.ParentFile.builder.optionsUnmarshaler(&descopts.Enum, rawOptions)
+}
+
+func unmarshalEnumReservedRange(b []byte) (r [2]pref.EnumNumber) {
+	for len(b) > 0 {
+		num, typ, n := protowire.ConsumeTag(b)
+		b = b[n:]
+		switch typ {
+		case protowire.VarintType:
+			v, m := protowire.ConsumeVarint(b)
+			b = b[m:]
+			switch num {
+			case genid.EnumDescriptorProto_EnumReservedRange_Start_field_number:
+				r[0] = pref.EnumNumber(v)
+			case genid.EnumDescriptorProto_EnumReservedRange_End_field_number:
+				r[1] = pref.EnumNumber(v)
+			}
+		default:
+			m := protowire.ConsumeFieldValue(num, typ, b)
+			b = b[m:]
+		}
+	}
+	return r
+}
+
+func (vd *EnumValue) unmarshalFull(b []byte, sb *strs.Builder, pf *File, pd pref.Descriptor, i int) {
+	vd.L0.ParentFile = pf
+	vd.L0.Parent = pd
+	vd.L0.Index = i
+
+	var rawOptions []byte
+	for len(b) > 0 {
+		num, typ, n := protowire.ConsumeTag(b)
+		b = b[n:]
+		switch typ {
+		case protowire.VarintType:
+			v, m := protowire.ConsumeVarint(b)
+			b = b[m:]
+			switch num {
+			case genid.EnumValueDescriptorProto_Number_field_number:
+				vd.L1.Number = pref.EnumNumber(v)
+			}
+		case protowire.BytesType:
+			v, m := protowire.ConsumeBytes(b)
+			b = b[m:]
+			switch num {
+			case genid.EnumValueDescriptorProto_Name_field_number:
+				// NOTE: Enum values are in the same scope as the enum parent.
+				vd.L0.FullName = appendFullName(sb, pd.Parent().FullName(), v)
+			case genid.EnumValueDescriptorProto_Options_field_number:
+				rawOptions = appendOptions(rawOptions, v)
+			}
+		default:
+			m := protowire.ConsumeFieldValue(num, typ, b)
+			b = b[m:]
+		}
+	}
+	vd.L1.Options = pf.builder.optionsUnmarshaler(&descopts.EnumValue, rawOptions)
+}
+
+func (md *Message) unmarshalFull(b []byte, sb *strs.Builder) {
+	var rawFields, rawOneofs [][]byte
+	var enumIdx, messageIdx, extensionIdx int
+	var rawOptions []byte
+	md.L2 = new(MessageL2)
+	for len(b) > 0 {
+		num, typ, n := protowire.ConsumeTag(b)
+		b = b[n:]
+		switch typ {
+		case protowire.BytesType:
+			v, m := protowire.ConsumeBytes(b)
+			b = b[m:]
+			switch num {
+			case genid.DescriptorProto_Field_field_number:
+				rawFields = append(rawFields, v)
+			case genid.DescriptorProto_OneofDecl_field_number:
+				rawOneofs = append(rawOneofs, v)
+			case genid.DescriptorProto_ReservedName_field_number:
+				md.L2.ReservedNames.List = append(md.L2.ReservedNames.List, pref.Name(sb.MakeString(v)))
+			case genid.DescriptorProto_ReservedRange_field_number:
+				md.L2.ReservedRanges.List = append(md.L2.ReservedRanges.List, unmarshalMessageReservedRange(v))
+			case genid.DescriptorProto_ExtensionRange_field_number:
+				r, rawOptions := unmarshalMessageExtensionRange(v)
+				opts := md.L0.ParentFile.builder.optionsUnmarshaler(&descopts.ExtensionRange, rawOptions)
+				md.L2.ExtensionRanges.List = append(md.L2.ExtensionRanges.List, r)
+				md.L2.ExtensionRangeOptions = append(md.L2.ExtensionRangeOptions, opts)
+			case genid.DescriptorProto_EnumType_field_number:
+				md.L1.Enums.List[enumIdx].unmarshalFull(v, sb)
+				enumIdx++
+			case genid.DescriptorProto_NestedType_field_number:
+				md.L1.Messages.List[messageIdx].unmarshalFull(v, sb)
+				messageIdx++
+			case genid.DescriptorProto_Extension_field_number:
+				md.L1.Extensions.List[extensionIdx].unmarshalFull(v, sb)
+				extensionIdx++
+			case genid.DescriptorProto_Options_field_number:
+				md.unmarshalOptions(v)
+				rawOptions = appendOptions(rawOptions, v)
+			}
+		default:
+			m := protowire.ConsumeFieldValue(num, typ, b)
+			b = b[m:]
+		}
+	}
+	if len(rawFields) > 0 || len(rawOneofs) > 0 {
+		md.L2.Fields.List = make([]Field, len(rawFields))
+		md.L2.Oneofs.List = make([]Oneof, len(rawOneofs))
+		for i, b := range rawFields {
+			fd := &md.L2.Fields.List[i]
+			fd.unmarshalFull(b, sb, md.L0.ParentFile, md, i)
+			if fd.L1.Cardinality == pref.Required {
+				md.L2.RequiredNumbers.List = append(md.L2.RequiredNumbers.List, fd.L1.Number)
+			}
+		}
+		for i, b := range rawOneofs {
+			od := &md.L2.Oneofs.List[i]
+			od.unmarshalFull(b, sb, md.L0.ParentFile, md, i)
+		}
+	}
+	md.L2.Options = md.L0.ParentFile.builder.optionsUnmarshaler(&descopts.Message, rawOptions)
+}
+
+func (md *Message) unmarshalOptions(b []byte) {
+	for len(b) > 0 {
+		num, typ, n := protowire.ConsumeTag(b)
+		b = b[n:]
+		switch typ {
+		case protowire.VarintType:
+			v, m := protowire.ConsumeVarint(b)
+			b = b[m:]
+			switch num {
+			case genid.MessageOptions_MapEntry_field_number:
+				md.L1.IsMapEntry = protowire.DecodeBool(v)
+			case genid.MessageOptions_MessageSetWireFormat_field_number:
+				md.L1.IsMessageSet = protowire.DecodeBool(v)
+			}
+		default:
+			m := protowire.ConsumeFieldValue(num, typ, b)
+			b = b[m:]
+		}
+	}
+}
+
+func unmarshalMessageReservedRange(b []byte) (r [2]pref.FieldNumber) {
+	for len(b) > 0 {
+		num, typ, n := protowire.ConsumeTag(b)
+		b = b[n:]
+		switch typ {
+		case protowire.VarintType:
+			v, m := protowire.ConsumeVarint(b)
+			b = b[m:]
+			switch num {
+			case genid.DescriptorProto_ReservedRange_Start_field_number:
+				r[0] = pref.FieldNumber(v)
+			case genid.DescriptorProto_ReservedRange_End_field_number:
+				r[1] = pref.FieldNumber(v)
+			}
+		default:
+			m := protowire.ConsumeFieldValue(num, typ, b)
+			b = b[m:]
+		}
+	}
+	return r
+}
+
+func unmarshalMessageExtensionRange(b []byte) (r [2]pref.FieldNumber, rawOptions []byte) {
+	for len(b) > 0 {
+		num, typ, n := protowire.ConsumeTag(b)
+		b = b[n:]
+		switch typ {
+		case protowire.VarintType:
+			v, m := protowire.ConsumeVarint(b)
+			b = b[m:]
+			switch num {
+			case genid.DescriptorProto_ExtensionRange_Start_field_number:
+				r[0] = pref.FieldNumber(v)
+			case genid.DescriptorProto_ExtensionRange_End_field_number:
+				r[1] = pref.FieldNumber(v)
+			}
+		case protowire.BytesType:
+			v, m := protowire.ConsumeBytes(b)
+			b = b[m:]
+			switch num {
+			case genid.DescriptorProto_ExtensionRange_Options_field_number:
+				rawOptions = appendOptions(rawOptions, v)
+			}
+		default:
+			m := protowire.ConsumeFieldValue(num, typ, b)
+			b = b[m:]
+		}
+	}
+	return r, rawOptions
+}
+
+func (fd *Field) unmarshalFull(b []byte, sb *strs.Builder, pf *File, pd pref.Descriptor, i int) {
+	fd.L0.ParentFile = pf
+	fd.L0.Parent = pd
+	fd.L0.Index = i
+
+	var rawTypeName []byte
+	var rawOptions []byte
+	for len(b) > 0 {
+		num, typ, n := protowire.ConsumeTag(b)
+		b = b[n:]
+		switch typ {
+		case protowire.VarintType:
+			v, m := protowire.ConsumeVarint(b)
+			b = b[m:]
+			switch num {
+			case genid.FieldDescriptorProto_Number_field_number:
+				fd.L1.Number = pref.FieldNumber(v)
+			case genid.FieldDescriptorProto_Label_field_number:
+				fd.L1.Cardinality = pref.Cardinality(v)
+			case genid.FieldDescriptorProto_Type_field_number:
+				fd.L1.Kind = pref.Kind(v)
+			case genid.FieldDescriptorProto_OneofIndex_field_number:
+				// In Message.unmarshalFull, we allocate slices for both
+				// the field and oneof descriptors before unmarshaling either
+				// of them. This ensures pointers to slice elements are stable.
+				od := &pd.(*Message).L2.Oneofs.List[v]
+				od.L1.Fields.List = append(od.L1.Fields.List, fd)
+				if fd.L1.ContainingOneof != nil {
+					panic("oneof type already set")
+				}
+				fd.L1.ContainingOneof = od
+			case genid.FieldDescriptorProto_Proto3Optional_field_number:
+				fd.L1.IsProto3Optional = protowire.DecodeBool(v)
+			}
+		case protowire.BytesType:
+			v, m := protowire.ConsumeBytes(b)
+			b = b[m:]
+			switch num {
+			case genid.FieldDescriptorProto_Name_field_number:
+				fd.L0.FullName = appendFullName(sb, pd.FullName(), v)
+			case genid.FieldDescriptorProto_JsonName_field_number:
+				fd.L1.StringName.InitJSON(sb.MakeString(v))
+			case genid.FieldDescriptorProto_DefaultValue_field_number:
+				fd.L1.Default.val = pref.ValueOfBytes(v) // temporarily store as bytes; later resolved in resolveMessages
+			case genid.FieldDescriptorProto_TypeName_field_number:
+				rawTypeName = v
+			case genid.FieldDescriptorProto_Options_field_number:
+				fd.unmarshalOptions(v)
+				rawOptions = appendOptions(rawOptions, v)
+			}
+		default:
+			m := protowire.ConsumeFieldValue(num, typ, b)
+			b = b[m:]
+		}
+	}
+	if rawTypeName != nil {
+		name := makeFullName(sb, rawTypeName)
+		switch fd.L1.Kind {
+		case pref.EnumKind:
+			fd.L1.Enum = PlaceholderEnum(name)
+		case pref.MessageKind, pref.GroupKind:
+			fd.L1.Message = PlaceholderMessage(name)
+		}
+	}
+	fd.L1.Options = pf.builder.optionsUnmarshaler(&descopts.Field, rawOptions)
+}
+
+func (fd *Field) unmarshalOptions(b []byte) {
+	const FieldOptions_EnforceUTF8 = 13
+
+	for len(b) > 0 {
+		num, typ, n := protowire.ConsumeTag(b)
+		b = b[n:]
+		switch typ {
+		case protowire.VarintType:
+			v, m := protowire.ConsumeVarint(b)
+			b = b[m:]
+			switch num {
+			case genid.FieldOptions_Packed_field_number:
+				fd.L1.HasPacked = true
+				fd.L1.IsPacked = protowire.DecodeBool(v)
+			case genid.FieldOptions_Weak_field_number:
+				fd.L1.IsWeak = protowire.DecodeBool(v)
+			case FieldOptions_EnforceUTF8:
+				fd.L1.HasEnforceUTF8 = true
+				fd.L1.EnforceUTF8 = protowire.DecodeBool(v)
+			}
+		default:
+			m := protowire.ConsumeFieldValue(num, typ, b)
+			b = b[m:]
+		}
+	}
+}
+
+func (od *Oneof) unmarshalFull(b []byte, sb *strs.Builder, pf *File, pd pref.Descriptor, i int) {
+	od.L0.ParentFile = pf
+	od.L0.Parent = pd
+	od.L0.Index = i
+
+	var rawOptions []byte
+	for len(b) > 0 {
+		num, typ, n := protowire.ConsumeTag(b)
+		b = b[n:]
+		switch typ {
+		case protowire.BytesType:
+			v, m := protowire.ConsumeBytes(b)
+			b = b[m:]
+			switch num {
+			case genid.OneofDescriptorProto_Name_field_number:
+				od.L0.FullName = appendFullName(sb, pd.FullName(), v)
+			case genid.OneofDescriptorProto_Options_field_number:
+				rawOptions = appendOptions(rawOptions, v)
+			}
+		default:
+			m := protowire.ConsumeFieldValue(num, typ, b)
+			b = b[m:]
+		}
+	}
+	od.L1.Options = pf.builder.optionsUnmarshaler(&descopts.Oneof, rawOptions)
+}
+
+func (xd *Extension) unmarshalFull(b []byte, sb *strs.Builder) {
+	var rawTypeName []byte
+	var rawOptions []byte
+	xd.L2 = new(ExtensionL2)
+	for len(b) > 0 {
+		num, typ, n := protowire.ConsumeTag(b)
+		b = b[n:]
+		switch typ {
+		case protowire.VarintType:
+			v, m := protowire.ConsumeVarint(b)
+			b = b[m:]
+			switch num {
+			case genid.FieldDescriptorProto_Proto3Optional_field_number:
+				xd.L2.IsProto3Optional = protowire.DecodeBool(v)
+			}
+		case protowire.BytesType:
+			v, m := protowire.ConsumeBytes(b)
+			b = b[m:]
+			switch num {
+			case genid.FieldDescriptorProto_JsonName_field_number:
+				xd.L2.StringName.InitJSON(sb.MakeString(v))
+			case genid.FieldDescriptorProto_DefaultValue_field_number:
+				xd.L2.Default.val = pref.ValueOfBytes(v) // temporarily store as bytes; later resolved in resolveExtensions
+			case genid.FieldDescriptorProto_TypeName_field_number:
+				rawTypeName = v
+			case genid.FieldDescriptorProto_Options_field_number:
+				xd.unmarshalOptions(v)
+				rawOptions = appendOptions(rawOptions, v)
+			}
+		default:
+			m := protowire.ConsumeFieldValue(num, typ, b)
+			b = b[m:]
+		}
+	}
+	if rawTypeName != nil {
+		name := makeFullName(sb, rawTypeName)
+		switch xd.L1.Kind {
+		case pref.EnumKind:
+			xd.L2.Enum = PlaceholderEnum(name)
+		case pref.MessageKind, pref.GroupKind:
+			xd.L2.Message = PlaceholderMessage(name)
+		}
+	}
+	xd.L2.Options = xd.L0.ParentFile.builder.optionsUnmarshaler(&descopts.Field, rawOptions)
+}
+
+func (xd *Extension) unmarshalOptions(b []byte) {
+	for len(b) > 0 {
+		num, typ, n := protowire.ConsumeTag(b)
+		b = b[n:]
+		switch typ {
+		case protowire.VarintType:
+			v, m := protowire.ConsumeVarint(b)
+			b = b[m:]
+			switch num {
+			case genid.FieldOptions_Packed_field_number:
+				xd.L2.IsPacked = protowire.DecodeBool(v)
+			}
+		default:
+			m := protowire.ConsumeFieldValue(num, typ, b)
+			b = b[m:]
+		}
+	}
+}
+
+func (sd *Service) unmarshalFull(b []byte, sb *strs.Builder) {
+	var rawMethods [][]byte
+	var rawOptions []byte
+	sd.L2 = new(ServiceL2)
+	for len(b) > 0 {
+		num, typ, n := protowire.ConsumeTag(b)
+		b = b[n:]
+		switch typ {
+		case protowire.BytesType:
+			v, m := protowire.ConsumeBytes(b)
+			b = b[m:]
+			switch num {
+			case genid.ServiceDescriptorProto_Method_field_number:
+				rawMethods = append(rawMethods, v)
+			case genid.ServiceDescriptorProto_Options_field_number:
+				rawOptions = appendOptions(rawOptions, v)
+			}
+		default:
+			m := protowire.ConsumeFieldValue(num, typ, b)
+			b = b[m:]
+		}
+	}
+	if len(rawMethods) > 0 {
+		sd.L2.Methods.List = make([]Method, len(rawMethods))
+		for i, b := range rawMethods {
+			sd.L2.Methods.List[i].unmarshalFull(b, sb, sd.L0.ParentFile, sd, i)
+		}
+	}
+	sd.L2.Options = sd.L0.ParentFile.builder.optionsUnmarshaler(&descopts.Service, rawOptions)
+}
+
+func (md *Method) unmarshalFull(b []byte, sb *strs.Builder, pf *File, pd pref.Descriptor, i int) {
+	md.L0.ParentFile = pf
+	md.L0.Parent = pd
+	md.L0.Index = i
+
+	var rawOptions []byte
+	for len(b) > 0 {
+		num, typ, n := protowire.ConsumeTag(b)
+		b = b[n:]
+		switch typ {
+		case protowire.VarintType:
+			v, m := protowire.ConsumeVarint(b)
+			b = b[m:]
+			switch num {
+			case genid.MethodDescriptorProto_ClientStreaming_field_number:
+				md.L1.IsStreamingClient = protowire.DecodeBool(v)
+			case genid.MethodDescriptorProto_ServerStreaming_field_number:
+				md.L1.IsStreamingServer = protowire.DecodeBool(v)
+			}
+		case protowire.BytesType:
+			v, m := protowire.ConsumeBytes(b)
+			b = b[m:]
+			switch num {
+			case genid.MethodDescriptorProto_Name_field_number:
+				md.L0.FullName = appendFullName(sb, pd.FullName(), v)
+			case genid.MethodDescriptorProto_InputType_field_number:
+				md.L1.Input = PlaceholderMessage(makeFullName(sb, v))
+			case genid.MethodDescriptorProto_OutputType_field_number:
+				md.L1.Output = PlaceholderMessage(makeFullName(sb, v))
+			case genid.MethodDescriptorProto_Options_field_number:
+				rawOptions = appendOptions(rawOptions, v)
+			}
+		default:
+			m := protowire.ConsumeFieldValue(num, typ, b)
+			b = b[m:]
+		}
+	}
+	md.L1.Options = pf.builder.optionsUnmarshaler(&descopts.Method, rawOptions)
+}
+
+// appendOptions appends src to dst, where the returned slice is never nil.
+// This is necessary to distinguish between empty and unpopulated options.
+func appendOptions(dst, src []byte) []byte {
+	if dst == nil {
+		dst = []byte{}
+	}
+	return append(dst, src...)
+}
+
+// optionsUnmarshaler constructs a lazy unmarshal function for an options message.
+//
+// The type of message to unmarshal to is passed as a pointer since the
+// vars in descopts may not yet be populated at the time this function is called.
+func (db *Builder) optionsUnmarshaler(p *pref.ProtoMessage, b []byte) func() pref.ProtoMessage {
+	if b == nil {
+		return nil
+	}
+	var opts pref.ProtoMessage
+	var once sync.Once
+	return func() pref.ProtoMessage {
+		once.Do(func() {
+			if *p == nil {
+				panic("Descriptor.Options called without importing the descriptor package")
+			}
+			opts = reflect.New(reflect.TypeOf(*p).Elem()).Interface().(pref.ProtoMessage)
+			if err := (proto.UnmarshalOptions{
+				AllowPartial: true,
+				Resolver:     db.TypeResolver,
+			}).Unmarshal(b, opts); err != nil {
+				panic(err)
+			}
+		})
+		return opts
+	}
+}
diff --git a/vendor/google.golang.org/protobuf/internal/filedesc/desc_list.go b/vendor/google.golang.org/protobuf/internal/filedesc/desc_list.go
new file mode 100644
index 0000000..aa294ff
--- /dev/null
+++ b/vendor/google.golang.org/protobuf/internal/filedesc/desc_list.go
@@ -0,0 +1,450 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package filedesc
+
+import (
+	"fmt"
+	"math"
+	"sort"
+	"sync"
+
+	"google.golang.org/protobuf/internal/genid"
+
+	"google.golang.org/protobuf/encoding/protowire"
+	"google.golang.org/protobuf/internal/descfmt"
+	"google.golang.org/protobuf/internal/errors"
+	"google.golang.org/protobuf/internal/pragma"
+	"google.golang.org/protobuf/reflect/protoreflect"
+	pref "google.golang.org/protobuf/reflect/protoreflect"
+)
+
+type FileImports []pref.FileImport
+
+func (p *FileImports) Len() int                            { return len(*p) }
+func (p *FileImports) Get(i int) pref.FileImport           { return (*p)[i] }
+func (p *FileImports) Format(s fmt.State, r rune)          { descfmt.FormatList(s, r, p) }
+func (p *FileImports) ProtoInternal(pragma.DoNotImplement) {}
+
+type Names struct {
+	List []pref.Name
+	once sync.Once
+	has  map[pref.Name]int // protected by once
+}
+
+func (p *Names) Len() int                            { return len(p.List) }
+func (p *Names) Get(i int) pref.Name                 { return p.List[i] }
+func (p *Names) Has(s pref.Name) bool                { return p.lazyInit().has[s] > 0 }
+func (p *Names) Format(s fmt.State, r rune)          { descfmt.FormatList(s, r, p) }
+func (p *Names) ProtoInternal(pragma.DoNotImplement) {}
+func (p *Names) lazyInit() *Names {
+	p.once.Do(func() {
+		if len(p.List) > 0 {
+			p.has = make(map[pref.Name]int, len(p.List))
+			for _, s := range p.List {
+				p.has[s] = p.has[s] + 1
+			}
+		}
+	})
+	return p
+}
+
+// CheckValid reports any errors with the set of names with an error message
+// that completes the sentence: "ranges is invalid because it has ..."
+func (p *Names) CheckValid() error {
+	for s, n := range p.lazyInit().has {
+		switch {
+		case n > 1:
+			return errors.New("duplicate name: %q", s)
+		case false && !s.IsValid():
+			// NOTE: The C++ implementation does not validate the identifier.
+			// See https://github.com/protocolbuffers/protobuf/issues/6335.
+			return errors.New("invalid name: %q", s)
+		}
+	}
+	return nil
+}
+
+type EnumRanges struct {
+	List   [][2]pref.EnumNumber // start inclusive; end inclusive
+	once   sync.Once
+	sorted [][2]pref.EnumNumber // protected by once
+}
+
+func (p *EnumRanges) Len() int                     { return len(p.List) }
+func (p *EnumRanges) Get(i int) [2]pref.EnumNumber { return p.List[i] }
+func (p *EnumRanges) Has(n pref.EnumNumber) bool {
+	for ls := p.lazyInit().sorted; len(ls) > 0; {
+		i := len(ls) / 2
+		switch r := enumRange(ls[i]); {
+		case n < r.Start():
+			ls = ls[:i] // search lower
+		case n > r.End():
+			ls = ls[i+1:] // search upper
+		default:
+			return true
+		}
+	}
+	return false
+}
+func (p *EnumRanges) Format(s fmt.State, r rune)          { descfmt.FormatList(s, r, p) }
+func (p *EnumRanges) ProtoInternal(pragma.DoNotImplement) {}
+func (p *EnumRanges) lazyInit() *EnumRanges {
+	p.once.Do(func() {
+		p.sorted = append(p.sorted, p.List...)
+		sort.Slice(p.sorted, func(i, j int) bool {
+			return p.sorted[i][0] < p.sorted[j][0]
+		})
+	})
+	return p
+}
+
+// CheckValid reports any errors with the set of names with an error message
+// that completes the sentence: "ranges is invalid because it has ..."
+func (p *EnumRanges) CheckValid() error {
+	var rp enumRange
+	for i, r := range p.lazyInit().sorted {
+		r := enumRange(r)
+		switch {
+		case !(r.Start() <= r.End()):
+			return errors.New("invalid range: %v", r)
+		case !(rp.End() < r.Start()) && i > 0:
+			return errors.New("overlapping ranges: %v with %v", rp, r)
+		}
+		rp = r
+	}
+	return nil
+}
+
+type enumRange [2]protoreflect.EnumNumber
+
+func (r enumRange) Start() protoreflect.EnumNumber { return r[0] } // inclusive
+func (r enumRange) End() protoreflect.EnumNumber   { return r[1] } // inclusive
+func (r enumRange) String() string {
+	if r.Start() == r.End() {
+		return fmt.Sprintf("%d", r.Start())
+	}
+	return fmt.Sprintf("%d to %d", r.Start(), r.End())
+}
+
+type FieldRanges struct {
+	List   [][2]pref.FieldNumber // start inclusive; end exclusive
+	once   sync.Once
+	sorted [][2]pref.FieldNumber // protected by once
+}
+
+func (p *FieldRanges) Len() int                      { return len(p.List) }
+func (p *FieldRanges) Get(i int) [2]pref.FieldNumber { return p.List[i] }
+func (p *FieldRanges) Has(n pref.FieldNumber) bool {
+	for ls := p.lazyInit().sorted; len(ls) > 0; {
+		i := len(ls) / 2
+		switch r := fieldRange(ls[i]); {
+		case n < r.Start():
+			ls = ls[:i] // search lower
+		case n > r.End():
+			ls = ls[i+1:] // search upper
+		default:
+			return true
+		}
+	}
+	return false
+}
+func (p *FieldRanges) Format(s fmt.State, r rune)          { descfmt.FormatList(s, r, p) }
+func (p *FieldRanges) ProtoInternal(pragma.DoNotImplement) {}
+func (p *FieldRanges) lazyInit() *FieldRanges {
+	p.once.Do(func() {
+		p.sorted = append(p.sorted, p.List...)
+		sort.Slice(p.sorted, func(i, j int) bool {
+			return p.sorted[i][0] < p.sorted[j][0]
+		})
+	})
+	return p
+}
+
+// CheckValid reports any errors with the set of ranges with an error message
+// that completes the sentence: "ranges is invalid because it has ..."
+func (p *FieldRanges) CheckValid(isMessageSet bool) error {
+	var rp fieldRange
+	for i, r := range p.lazyInit().sorted {
+		r := fieldRange(r)
+		switch {
+		case !isValidFieldNumber(r.Start(), isMessageSet):
+			return errors.New("invalid field number: %d", r.Start())
+		case !isValidFieldNumber(r.End(), isMessageSet):
+			return errors.New("invalid field number: %d", r.End())
+		case !(r.Start() <= r.End()):
+			return errors.New("invalid range: %v", r)
+		case !(rp.End() < r.Start()) && i > 0:
+			return errors.New("overlapping ranges: %v with %v", rp, r)
+		}
+		rp = r
+	}
+	return nil
+}
+
+// isValidFieldNumber reports whether the field number is valid.
+// Unlike the FieldNumber.IsValid method, it allows ranges that cover the
+// reserved number range.
+func isValidFieldNumber(n protoreflect.FieldNumber, isMessageSet bool) bool {
+	return protowire.MinValidNumber <= n && (n <= protowire.MaxValidNumber || isMessageSet)
+}
+
+// CheckOverlap reports an error if p and q overlap.
+func (p *FieldRanges) CheckOverlap(q *FieldRanges) error {
+	rps := p.lazyInit().sorted
+	rqs := q.lazyInit().sorted
+	for pi, qi := 0, 0; pi < len(rps) && qi < len(rqs); {
+		rp := fieldRange(rps[pi])
+		rq := fieldRange(rqs[qi])
+		if !(rp.End() < rq.Start() || rq.End() < rp.Start()) {
+			return errors.New("overlapping ranges: %v with %v", rp, rq)
+		}
+		if rp.Start() < rq.Start() {
+			pi++
+		} else {
+			qi++
+		}
+	}
+	return nil
+}
+
+type fieldRange [2]protoreflect.FieldNumber
+
+func (r fieldRange) Start() protoreflect.FieldNumber { return r[0] }     // inclusive
+func (r fieldRange) End() protoreflect.FieldNumber   { return r[1] - 1 } // inclusive
+func (r fieldRange) String() string {
+	if r.Start() == r.End() {
+		return fmt.Sprintf("%d", r.Start())
+	}
+	return fmt.Sprintf("%d to %d", r.Start(), r.End())
+}
+
+type FieldNumbers struct {
+	List []pref.FieldNumber
+	once sync.Once
+	has  map[pref.FieldNumber]struct{} // protected by once
+}
+
+func (p *FieldNumbers) Len() int                   { return len(p.List) }
+func (p *FieldNumbers) Get(i int) pref.FieldNumber { return p.List[i] }
+func (p *FieldNumbers) Has(n pref.FieldNumber) bool {
+	p.once.Do(func() {
+		if len(p.List) > 0 {
+			p.has = make(map[pref.FieldNumber]struct{}, len(p.List))
+			for _, n := range p.List {
+				p.has[n] = struct{}{}
+			}
+		}
+	})
+	_, ok := p.has[n]
+	return ok
+}
+func (p *FieldNumbers) Format(s fmt.State, r rune)          { descfmt.FormatList(s, r, p) }
+func (p *FieldNumbers) ProtoInternal(pragma.DoNotImplement) {}
+
+type OneofFields struct {
+	List   []pref.FieldDescriptor
+	once   sync.Once
+	byName map[pref.Name]pref.FieldDescriptor        // protected by once
+	byJSON map[string]pref.FieldDescriptor           // protected by once
+	byText map[string]pref.FieldDescriptor           // protected by once
+	byNum  map[pref.FieldNumber]pref.FieldDescriptor // protected by once
+}
+
+func (p *OneofFields) Len() int                                         { return len(p.List) }
+func (p *OneofFields) Get(i int) pref.FieldDescriptor                   { return p.List[i] }
+func (p *OneofFields) ByName(s pref.Name) pref.FieldDescriptor          { return p.lazyInit().byName[s] }
+func (p *OneofFields) ByJSONName(s string) pref.FieldDescriptor         { return p.lazyInit().byJSON[s] }
+func (p *OneofFields) ByTextName(s string) pref.FieldDescriptor         { return p.lazyInit().byText[s] }
+func (p *OneofFields) ByNumber(n pref.FieldNumber) pref.FieldDescriptor { return p.lazyInit().byNum[n] }
+func (p *OneofFields) Format(s fmt.State, r rune)                       { descfmt.FormatList(s, r, p) }
+func (p *OneofFields) ProtoInternal(pragma.DoNotImplement)              {}
+
+func (p *OneofFields) lazyInit() *OneofFields {
+	p.once.Do(func() {
+		if len(p.List) > 0 {
+			p.byName = make(map[pref.Name]pref.FieldDescriptor, len(p.List))
+			p.byJSON = make(map[string]pref.FieldDescriptor, len(p.List))
+			p.byText = make(map[string]pref.FieldDescriptor, len(p.List))
+			p.byNum = make(map[pref.FieldNumber]pref.FieldDescriptor, len(p.List))
+			for _, f := range p.List {
+				// Field names and numbers are guaranteed to be unique.
+				p.byName[f.Name()] = f
+				p.byJSON[f.JSONName()] = f
+				p.byText[f.TextName()] = f
+				p.byNum[f.Number()] = f
+			}
+		}
+	})
+	return p
+}
+
+type SourceLocations struct {
+	// List is a list of SourceLocations.
+	// The SourceLocation.Next field does not need to be populated
+	// as it will be lazily populated upon first need.
+	List []pref.SourceLocation
+
+	// File is the parent file descriptor that these locations are relative to.
+	// If non-nil, ByDescriptor verifies that the provided descriptor
+	// is a child of this file descriptor.
+	File pref.FileDescriptor
+
+	once   sync.Once
+	byPath map[pathKey]int
+}
+
+func (p *SourceLocations) Len() int                      { return len(p.List) }
+func (p *SourceLocations) Get(i int) pref.SourceLocation { return p.lazyInit().List[i] }
+func (p *SourceLocations) byKey(k pathKey) pref.SourceLocation {
+	if i, ok := p.lazyInit().byPath[k]; ok {
+		return p.List[i]
+	}
+	return pref.SourceLocation{}
+}
+func (p *SourceLocations) ByPath(path pref.SourcePath) pref.SourceLocation {
+	return p.byKey(newPathKey(path))
+}
+func (p *SourceLocations) ByDescriptor(desc pref.Descriptor) pref.SourceLocation {
+	if p.File != nil && desc != nil && p.File != desc.ParentFile() {
+		return pref.SourceLocation{} // mismatching parent files
+	}
+	var pathArr [16]int32
+	path := pathArr[:0]
+	for {
+		switch desc.(type) {
+		case pref.FileDescriptor:
+			// Reverse the path since it was constructed in reverse.
+			for i, j := 0, len(path)-1; i < j; i, j = i+1, j-1 {
+				path[i], path[j] = path[j], path[i]
+			}
+			return p.byKey(newPathKey(path))
+		case pref.MessageDescriptor:
+			path = append(path, int32(desc.Index()))
+			desc = desc.Parent()
+			switch desc.(type) {
+			case pref.FileDescriptor:
+				path = append(path, int32(genid.FileDescriptorProto_MessageType_field_number))
+			case pref.MessageDescriptor:
+				path = append(path, int32(genid.DescriptorProto_NestedType_field_number))
+			default:
+				return pref.SourceLocation{}
+			}
+		case pref.FieldDescriptor:
+			isExtension := desc.(pref.FieldDescriptor).IsExtension()
+			path = append(path, int32(desc.Index()))
+			desc = desc.Parent()
+			if isExtension {
+				switch desc.(type) {
+				case pref.FileDescriptor:
+					path = append(path, int32(genid.FileDescriptorProto_Extension_field_number))
+				case pref.MessageDescriptor:
+					path = append(path, int32(genid.DescriptorProto_Extension_field_number))
+				default:
+					return pref.SourceLocation{}
+				}
+			} else {
+				switch desc.(type) {
+				case pref.MessageDescriptor:
+					path = append(path, int32(genid.DescriptorProto_Field_field_number))
+				default:
+					return pref.SourceLocation{}
+				}
+			}
+		case pref.OneofDescriptor:
+			path = append(path, int32(desc.Index()))
+			desc = desc.Parent()
+			switch desc.(type) {
+			case pref.MessageDescriptor:
+				path = append(path, int32(genid.DescriptorProto_OneofDecl_field_number))
+			default:
+				return pref.SourceLocation{}
+			}
+		case pref.EnumDescriptor:
+			path = append(path, int32(desc.Index()))
+			desc = desc.Parent()
+			switch desc.(type) {
+			case pref.FileDescriptor:
+				path = append(path, int32(genid.FileDescriptorProto_EnumType_field_number))
+			case pref.MessageDescriptor:
+				path = append(path, int32(genid.DescriptorProto_EnumType_field_number))
+			default:
+				return pref.SourceLocation{}
+			}
+		case pref.EnumValueDescriptor:
+			path = append(path, int32(desc.Index()))
+			desc = desc.Parent()
+			switch desc.(type) {
+			case pref.EnumDescriptor:
+				path = append(path, int32(genid.EnumDescriptorProto_Value_field_number))
+			default:
+				return pref.SourceLocation{}
+			}
+		case pref.ServiceDescriptor:
+			path = append(path, int32(desc.Index()))
+			desc = desc.Parent()
+			switch desc.(type) {
+			case pref.FileDescriptor:
+				path = append(path, int32(genid.FileDescriptorProto_Service_field_number))
+			default:
+				return pref.SourceLocation{}
+			}
+		case pref.MethodDescriptor:
+			path = append(path, int32(desc.Index()))
+			desc = desc.Parent()
+			switch desc.(type) {
+			case pref.ServiceDescriptor:
+				path = append(path, int32(genid.ServiceDescriptorProto_Method_field_number))
+			default:
+				return pref.SourceLocation{}
+			}
+		default:
+			return pref.SourceLocation{}
+		}
+	}
+}
+func (p *SourceLocations) lazyInit() *SourceLocations {
+	p.once.Do(func() {
+		if len(p.List) > 0 {
+			// Collect all the indexes for a given path.
+			pathIdxs := make(map[pathKey][]int, len(p.List))
+			for i, l := range p.List {
+				k := newPathKey(l.Path)
+				pathIdxs[k] = append(pathIdxs[k], i)
+			}
+
+			// Update the next index for all locations.
+			p.byPath = make(map[pathKey]int, len(p.List))
+			for k, idxs := range pathIdxs {
+				for i := 0; i < len(idxs)-1; i++ {
+					p.List[idxs[i]].Next = idxs[i+1]
+				}
+				p.List[idxs[len(idxs)-1]].Next = 0
+				p.byPath[k] = idxs[0] // record the first location for this path
+			}
+		}
+	})
+	return p
+}
+func (p *SourceLocations) ProtoInternal(pragma.DoNotImplement) {}
+
+// pathKey is a comparable representation of protoreflect.SourcePath.
+type pathKey struct {
+	arr [16]uint8 // first n-1 path segments; last element is the length
+	str string    // used if the path does not fit in arr
+}
+
+func newPathKey(p pref.SourcePath) (k pathKey) {
+	if len(p) < len(k.arr) {
+		for i, ps := range p {
+			if ps < 0 || math.MaxUint8 <= ps {
+				return pathKey{str: p.String()}
+			}
+			k.arr[i] = uint8(ps)
+		}
+		k.arr[len(k.arr)-1] = uint8(len(p))
+		return k
+	}
+	return pathKey{str: p.String()}
+}
diff --git a/vendor/google.golang.org/protobuf/internal/filedesc/desc_list_gen.go b/vendor/google.golang.org/protobuf/internal/filedesc/desc_list_gen.go
new file mode 100644
index 0000000..30db19f
--- /dev/null
+++ b/vendor/google.golang.org/protobuf/internal/filedesc/desc_list_gen.go
@@ -0,0 +1,356 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Code generated by generate-types. DO NOT EDIT.
+
+package filedesc
+
+import (
+	"fmt"
+	"sync"
+
+	"google.golang.org/protobuf/internal/descfmt"
+	"google.golang.org/protobuf/internal/pragma"
+	"google.golang.org/protobuf/reflect/protoreflect"
+)
+
+type Enums struct {
+	List   []Enum
+	once   sync.Once
+	byName map[protoreflect.Name]*Enum // protected by once
+}
+
+func (p *Enums) Len() int {
+	return len(p.List)
+}
+func (p *Enums) Get(i int) protoreflect.EnumDescriptor {
+	return &p.List[i]
+}
+func (p *Enums) ByName(s protoreflect.Name) protoreflect.EnumDescriptor {
+	if d := p.lazyInit().byName[s]; d != nil {
+		return d
+	}
+	return nil
+}
+func (p *Enums) Format(s fmt.State, r rune) {
+	descfmt.FormatList(s, r, p)
+}
+func (p *Enums) ProtoInternal(pragma.DoNotImplement) {}
+func (p *Enums) lazyInit() *Enums {
+	p.once.Do(func() {
+		if len(p.List) > 0 {
+			p.byName = make(map[protoreflect.Name]*Enum, len(p.List))
+			for i := range p.List {
+				d := &p.List[i]
+				if _, ok := p.byName[d.Name()]; !ok {
+					p.byName[d.Name()] = d
+				}
+			}
+		}
+	})
+	return p
+}
+
+type EnumValues struct {
+	List   []EnumValue
+	once   sync.Once
+	byName map[protoreflect.Name]*EnumValue       // protected by once
+	byNum  map[protoreflect.EnumNumber]*EnumValue // protected by once
+}
+
+func (p *EnumValues) Len() int {
+	return len(p.List)
+}
+func (p *EnumValues) Get(i int) protoreflect.EnumValueDescriptor {
+	return &p.List[i]
+}
+func (p *EnumValues) ByName(s protoreflect.Name) protoreflect.EnumValueDescriptor {
+	if d := p.lazyInit().byName[s]; d != nil {
+		return d
+	}
+	return nil
+}
+func (p *EnumValues) ByNumber(n protoreflect.EnumNumber) protoreflect.EnumValueDescriptor {
+	if d := p.lazyInit().byNum[n]; d != nil {
+		return d
+	}
+	return nil
+}
+func (p *EnumValues) Format(s fmt.State, r rune) {
+	descfmt.FormatList(s, r, p)
+}
+func (p *EnumValues) ProtoInternal(pragma.DoNotImplement) {}
+func (p *EnumValues) lazyInit() *EnumValues {
+	p.once.Do(func() {
+		if len(p.List) > 0 {
+			p.byName = make(map[protoreflect.Name]*EnumValue, len(p.List))
+			p.byNum = make(map[protoreflect.EnumNumber]*EnumValue, len(p.List))
+			for i := range p.List {
+				d := &p.List[i]
+				if _, ok := p.byName[d.Name()]; !ok {
+					p.byName[d.Name()] = d
+				}
+				if _, ok := p.byNum[d.Number()]; !ok {
+					p.byNum[d.Number()] = d
+				}
+			}
+		}
+	})
+	return p
+}
+
+type Messages struct {
+	List   []Message
+	once   sync.Once
+	byName map[protoreflect.Name]*Message // protected by once
+}
+
+func (p *Messages) Len() int {
+	return len(p.List)
+}
+func (p *Messages) Get(i int) protoreflect.MessageDescriptor {
+	return &p.List[i]
+}
+func (p *Messages) ByName(s protoreflect.Name) protoreflect.MessageDescriptor {
+	if d := p.lazyInit().byName[s]; d != nil {
+		return d
+	}
+	return nil
+}
+func (p *Messages) Format(s fmt.State, r rune) {
+	descfmt.FormatList(s, r, p)
+}
+func (p *Messages) ProtoInternal(pragma.DoNotImplement) {}
+func (p *Messages) lazyInit() *Messages {
+	p.once.Do(func() {
+		if len(p.List) > 0 {
+			p.byName = make(map[protoreflect.Name]*Message, len(p.List))
+			for i := range p.List {
+				d := &p.List[i]
+				if _, ok := p.byName[d.Name()]; !ok {
+					p.byName[d.Name()] = d
+				}
+			}
+		}
+	})
+	return p
+}
+
+type Fields struct {
+	List   []Field
+	once   sync.Once
+	byName map[protoreflect.Name]*Field        // protected by once
+	byJSON map[string]*Field                   // protected by once
+	byText map[string]*Field                   // protected by once
+	byNum  map[protoreflect.FieldNumber]*Field // protected by once
+}
+
+func (p *Fields) Len() int {
+	return len(p.List)
+}
+func (p *Fields) Get(i int) protoreflect.FieldDescriptor {
+	return &p.List[i]
+}
+func (p *Fields) ByName(s protoreflect.Name) protoreflect.FieldDescriptor {
+	if d := p.lazyInit().byName[s]; d != nil {
+		return d
+	}
+	return nil
+}
+func (p *Fields) ByJSONName(s string) protoreflect.FieldDescriptor {
+	if d := p.lazyInit().byJSON[s]; d != nil {
+		return d
+	}
+	return nil
+}
+func (p *Fields) ByTextName(s string) protoreflect.FieldDescriptor {
+	if d := p.lazyInit().byText[s]; d != nil {
+		return d
+	}
+	return nil
+}
+func (p *Fields) ByNumber(n protoreflect.FieldNumber) protoreflect.FieldDescriptor {
+	if d := p.lazyInit().byNum[n]; d != nil {
+		return d
+	}
+	return nil
+}
+func (p *Fields) Format(s fmt.State, r rune) {
+	descfmt.FormatList(s, r, p)
+}
+func (p *Fields) ProtoInternal(pragma.DoNotImplement) {}
+func (p *Fields) lazyInit() *Fields {
+	p.once.Do(func() {
+		if len(p.List) > 0 {
+			p.byName = make(map[protoreflect.Name]*Field, len(p.List))
+			p.byJSON = make(map[string]*Field, len(p.List))
+			p.byText = make(map[string]*Field, len(p.List))
+			p.byNum = make(map[protoreflect.FieldNumber]*Field, len(p.List))
+			for i := range p.List {
+				d := &p.List[i]
+				if _, ok := p.byName[d.Name()]; !ok {
+					p.byName[d.Name()] = d
+				}
+				if _, ok := p.byJSON[d.JSONName()]; !ok {
+					p.byJSON[d.JSONName()] = d
+				}
+				if _, ok := p.byText[d.TextName()]; !ok {
+					p.byText[d.TextName()] = d
+				}
+				if _, ok := p.byNum[d.Number()]; !ok {
+					p.byNum[d.Number()] = d
+				}
+			}
+		}
+	})
+	return p
+}
+
+type Oneofs struct {
+	List   []Oneof
+	once   sync.Once
+	byName map[protoreflect.Name]*Oneof // protected by once
+}
+
+func (p *Oneofs) Len() int {
+	return len(p.List)
+}
+func (p *Oneofs) Get(i int) protoreflect.OneofDescriptor {
+	return &p.List[i]
+}
+func (p *Oneofs) ByName(s protoreflect.Name) protoreflect.OneofDescriptor {
+	if d := p.lazyInit().byName[s]; d != nil {
+		return d
+	}
+	return nil
+}
+func (p *Oneofs) Format(s fmt.State, r rune) {
+	descfmt.FormatList(s, r, p)
+}
+func (p *Oneofs) ProtoInternal(pragma.DoNotImplement) {}
+func (p *Oneofs) lazyInit() *Oneofs {
+	p.once.Do(func() {
+		if len(p.List) > 0 {
+			p.byName = make(map[protoreflect.Name]*Oneof, len(p.List))
+			for i := range p.List {
+				d := &p.List[i]
+				if _, ok := p.byName[d.Name()]; !ok {
+					p.byName[d.Name()] = d
+				}
+			}
+		}
+	})
+	return p
+}
+
+type Extensions struct {
+	List   []Extension
+	once   sync.Once
+	byName map[protoreflect.Name]*Extension // protected by once
+}
+
+func (p *Extensions) Len() int {
+	return len(p.List)
+}
+func (p *Extensions) Get(i int) protoreflect.ExtensionDescriptor {
+	return &p.List[i]
+}
+func (p *Extensions) ByName(s protoreflect.Name) protoreflect.ExtensionDescriptor {
+	if d := p.lazyInit().byName[s]; d != nil {
+		return d
+	}
+	return nil
+}
+func (p *Extensions) Format(s fmt.State, r rune) {
+	descfmt.FormatList(s, r, p)
+}
+func (p *Extensions) ProtoInternal(pragma.DoNotImplement) {}
+func (p *Extensions) lazyInit() *Extensions {
+	p.once.Do(func() {
+		if len(p.List) > 0 {
+			p.byName = make(map[protoreflect.Name]*Extension, len(p.List))
+			for i := range p.List {
+				d := &p.List[i]
+				if _, ok := p.byName[d.Name()]; !ok {
+					p.byName[d.Name()] = d
+				}
+			}
+		}
+	})
+	return p
+}
+
+type Services struct {
+	List   []Service
+	once   sync.Once
+	byName map[protoreflect.Name]*Service // protected by once
+}
+
+func (p *Services) Len() int {
+	return len(p.List)
+}
+func (p *Services) Get(i int) protoreflect.ServiceDescriptor {
+	return &p.List[i]
+}
+func (p *Services) ByName(s protoreflect.Name) protoreflect.ServiceDescriptor {
+	if d := p.lazyInit().byName[s]; d != nil {
+		return d
+	}
+	return nil
+}
+func (p *Services) Format(s fmt.State, r rune) {
+	descfmt.FormatList(s, r, p)
+}
+func (p *Services) ProtoInternal(pragma.DoNotImplement) {}
+func (p *Services) lazyInit() *Services {
+	p.once.Do(func() {
+		if len(p.List) > 0 {
+			p.byName = make(map[protoreflect.Name]*Service, len(p.List))
+			for i := range p.List {
+				d := &p.List[i]
+				if _, ok := p.byName[d.Name()]; !ok {
+					p.byName[d.Name()] = d
+				}
+			}
+		}
+	})
+	return p
+}
+
+type Methods struct {
+	List   []Method
+	once   sync.Once
+	byName map[protoreflect.Name]*Method // protected by once
+}
+
+func (p *Methods) Len() int {
+	return len(p.List)
+}
+func (p *Methods) Get(i int) protoreflect.MethodDescriptor {
+	return &p.List[i]
+}
+func (p *Methods) ByName(s protoreflect.Name) protoreflect.MethodDescriptor {
+	if d := p.lazyInit().byName[s]; d != nil {
+		return d
+	}
+	return nil
+}
+func (p *Methods) Format(s fmt.State, r rune) {
+	descfmt.FormatList(s, r, p)
+}
+func (p *Methods) ProtoInternal(pragma.DoNotImplement) {}
+func (p *Methods) lazyInit() *Methods {
+	p.once.Do(func() {
+		if len(p.List) > 0 {
+			p.byName = make(map[protoreflect.Name]*Method, len(p.List))
+			for i := range p.List {
+				d := &p.List[i]
+				if _, ok := p.byName[d.Name()]; !ok {
+					p.byName[d.Name()] = d
+				}
+			}
+		}
+	})
+	return p
+}
diff --git a/vendor/google.golang.org/protobuf/internal/filedesc/placeholder.go b/vendor/google.golang.org/protobuf/internal/filedesc/placeholder.go
new file mode 100644
index 0000000..dbf2c60
--- /dev/null
+++ b/vendor/google.golang.org/protobuf/internal/filedesc/placeholder.go
@@ -0,0 +1,107 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package filedesc
+
+import (
+	"google.golang.org/protobuf/internal/descopts"
+	"google.golang.org/protobuf/internal/pragma"
+	pref "google.golang.org/protobuf/reflect/protoreflect"
+)
+
+var (
+	emptyNames           = new(Names)
+	emptyEnumRanges      = new(EnumRanges)
+	emptyFieldRanges     = new(FieldRanges)
+	emptyFieldNumbers    = new(FieldNumbers)
+	emptySourceLocations = new(SourceLocations)
+
+	emptyFiles      = new(FileImports)
+	emptyMessages   = new(Messages)
+	emptyFields     = new(Fields)
+	emptyOneofs     = new(Oneofs)
+	emptyEnums      = new(Enums)
+	emptyEnumValues = new(EnumValues)
+	emptyExtensions = new(Extensions)
+	emptyServices   = new(Services)
+)
+
+// PlaceholderFile is a placeholder, representing only the file path.
+type PlaceholderFile string
+
+func (f PlaceholderFile) ParentFile() pref.FileDescriptor       { return f }
+func (f PlaceholderFile) Parent() pref.Descriptor               { return nil }
+func (f PlaceholderFile) Index() int                            { return 0 }
+func (f PlaceholderFile) Syntax() pref.Syntax                   { return 0 }
+func (f PlaceholderFile) Name() pref.Name                       { return "" }
+func (f PlaceholderFile) FullName() pref.FullName               { return "" }
+func (f PlaceholderFile) IsPlaceholder() bool                   { return true }
+func (f PlaceholderFile) Options() pref.ProtoMessage            { return descopts.File }
+func (f PlaceholderFile) Path() string                          { return string(f) }
+func (f PlaceholderFile) Package() pref.FullName                { return "" }
+func (f PlaceholderFile) Imports() pref.FileImports             { return emptyFiles }
+func (f PlaceholderFile) Messages() pref.MessageDescriptors     { return emptyMessages }
+func (f PlaceholderFile) Enums() pref.EnumDescriptors           { return emptyEnums }
+func (f PlaceholderFile) Extensions() pref.ExtensionDescriptors { return emptyExtensions }
+func (f PlaceholderFile) Services() pref.ServiceDescriptors     { return emptyServices }
+func (f PlaceholderFile) SourceLocations() pref.SourceLocations { return emptySourceLocations }
+func (f PlaceholderFile) ProtoType(pref.FileDescriptor)         { return }
+func (f PlaceholderFile) ProtoInternal(pragma.DoNotImplement)   { return }
+
+// PlaceholderEnum is a placeholder, representing only the full name.
+type PlaceholderEnum pref.FullName
+
+func (e PlaceholderEnum) ParentFile() pref.FileDescriptor     { return nil }
+func (e PlaceholderEnum) Parent() pref.Descriptor             { return nil }
+func (e PlaceholderEnum) Index() int                          { return 0 }
+func (e PlaceholderEnum) Syntax() pref.Syntax                 { return 0 }
+func (e PlaceholderEnum) Name() pref.Name                     { return pref.FullName(e).Name() }
+func (e PlaceholderEnum) FullName() pref.FullName             { return pref.FullName(e) }
+func (e PlaceholderEnum) IsPlaceholder() bool                 { return true }
+func (e PlaceholderEnum) Options() pref.ProtoMessage          { return descopts.Enum }
+func (e PlaceholderEnum) Values() pref.EnumValueDescriptors   { return emptyEnumValues }
+func (e PlaceholderEnum) ReservedNames() pref.Names           { return emptyNames }
+func (e PlaceholderEnum) ReservedRanges() pref.EnumRanges     { return emptyEnumRanges }
+func (e PlaceholderEnum) ProtoType(pref.EnumDescriptor)       { return }
+func (e PlaceholderEnum) ProtoInternal(pragma.DoNotImplement) { return }
+
+// PlaceholderEnumValue is a placeholder, representing only the full name.
+type PlaceholderEnumValue pref.FullName
+
+func (e PlaceholderEnumValue) ParentFile() pref.FileDescriptor     { return nil }
+func (e PlaceholderEnumValue) Parent() pref.Descriptor             { return nil }
+func (e PlaceholderEnumValue) Index() int                          { return 0 }
+func (e PlaceholderEnumValue) Syntax() pref.Syntax                 { return 0 }
+func (e PlaceholderEnumValue) Name() pref.Name                     { return pref.FullName(e).Name() }
+func (e PlaceholderEnumValue) FullName() pref.FullName             { return pref.FullName(e) }
+func (e PlaceholderEnumValue) IsPlaceholder() bool                 { return true }
+func (e PlaceholderEnumValue) Options() pref.ProtoMessage          { return descopts.EnumValue }
+func (e PlaceholderEnumValue) Number() pref.EnumNumber             { return 0 }
+func (e PlaceholderEnumValue) ProtoType(pref.EnumValueDescriptor)  { return }
+func (e PlaceholderEnumValue) ProtoInternal(pragma.DoNotImplement) { return }
+
+// PlaceholderMessage is a placeholder, representing only the full name.
+type PlaceholderMessage pref.FullName
+
+func (m PlaceholderMessage) ParentFile() pref.FileDescriptor             { return nil }
+func (m PlaceholderMessage) Parent() pref.Descriptor                     { return nil }
+func (m PlaceholderMessage) Index() int                                  { return 0 }
+func (m PlaceholderMessage) Syntax() pref.Syntax                         { return 0 }
+func (m PlaceholderMessage) Name() pref.Name                             { return pref.FullName(m).Name() }
+func (m PlaceholderMessage) FullName() pref.FullName                     { return pref.FullName(m) }
+func (m PlaceholderMessage) IsPlaceholder() bool                         { return true }
+func (m PlaceholderMessage) Options() pref.ProtoMessage                  { return descopts.Message }
+func (m PlaceholderMessage) IsMapEntry() bool                            { return false }
+func (m PlaceholderMessage) Fields() pref.FieldDescriptors               { return emptyFields }
+func (m PlaceholderMessage) Oneofs() pref.OneofDescriptors               { return emptyOneofs }
+func (m PlaceholderMessage) ReservedNames() pref.Names                   { return emptyNames }
+func (m PlaceholderMessage) ReservedRanges() pref.FieldRanges            { return emptyFieldRanges }
+func (m PlaceholderMessage) RequiredNumbers() pref.FieldNumbers          { return emptyFieldNumbers }
+func (m PlaceholderMessage) ExtensionRanges() pref.FieldRanges           { return emptyFieldRanges }
+func (m PlaceholderMessage) ExtensionRangeOptions(int) pref.ProtoMessage { panic("index out of range") }
+func (m PlaceholderMessage) Messages() pref.MessageDescriptors           { return emptyMessages }
+func (m PlaceholderMessage) Enums() pref.EnumDescriptors                 { return emptyEnums }
+func (m PlaceholderMessage) Extensions() pref.ExtensionDescriptors       { return emptyExtensions }
+func (m PlaceholderMessage) ProtoType(pref.MessageDescriptor)            { return }
+func (m PlaceholderMessage) ProtoInternal(pragma.DoNotImplement)         { return }
