diff --git a/go.mod b/go.mod
index fa8fe8b..d34df4b 100644
--- a/go.mod
+++ b/go.mod
@@ -13,7 +13,6 @@
 	github.com/grpc-ecosystem/grpc-gateway v1.12.2
 	github.com/imdario/mergo v0.3.11
 	github.com/jessevdk/go-flags v1.4.0
-	github.com/jhump/protoreflect v1.5.0
 	github.com/jpillora/backoff v1.0.0
 	github.com/looplab/fsm v0.1.0
 	github.com/olekukonko/tablewriter v0.0.4
diff --git a/go.sum b/go.sum
index 2d39ec3..b8ac6d3 100644
--- a/go.sum
+++ b/go.sum
@@ -33,7 +33,6 @@
 github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
 github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
 github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
-github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
 github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
 github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
 github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
@@ -57,8 +56,6 @@
 github.com/jcmturner/gofork v1.0.0/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o=
 github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGARJA=
 github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
-github.com/jhump/protoreflect v1.5.0 h1:NgpVT+dX71c8hZnxHof2M7QDK7QtohIJ7DYycjnkyfc=
-github.com/jhump/protoreflect v1.5.0/go.mod h1:eaTn3RZAmMBcV0fifFvlm6VHNz3wSkYyXYWUh7ymB74=
 github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA=
 github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
 github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
@@ -110,7 +107,6 @@
 golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
 golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
 golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
-golang.org/x/net v0.0.0-20180530234432-1e491301e022/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -146,13 +142,11 @@
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
 google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
-google.golang.org/genproto v0.0.0-20170818010345-ee236bd376b0/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
 google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8 h1:Nw54tB0rB7hY/N0NQvRW8DG4Yk3Q6T9cu9RcFQDu1tc=
 google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
 google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
 google.golang.org/genproto v0.0.0-20190927181202-20e1ac93f88c h1:hrpEMCZ2O7DR5gC1n2AJGVhrwiEjOi35+jxtIuZpTMo=
 google.golang.org/genproto v0.0.0-20190927181202-20e1ac93f88c/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
-google.golang.org/grpc v1.8.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
 google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
 google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
 google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
diff --git a/internal/bbsimctl/commands/handler.go b/internal/bbsimctl/commands/handler.go
deleted file mode 100644
index 6b05534..0000000
--- a/internal/bbsimctl/commands/handler.go
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright 2019-present Ciena Corporation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package commands
-
-import (
-	"io"
-
-	"github.com/golang/protobuf/proto"
-	"github.com/jhump/protoreflect/desc"
-	"github.com/jhump/protoreflect/dynamic"
-	"google.golang.org/grpc/metadata"
-	"google.golang.org/grpc/status"
-)
-
-type RpcEventHandler struct {
-	Response proto.Message
-	Status   *status.Status
-	Data     []byte
-	Fields   map[string]map[string]interface{}
-}
-
-func (h *RpcEventHandler) OnResolveMethod(*desc.MethodDescriptor) {
-}
-
-func (h *RpcEventHandler) OnSendHeaders(metadata.MD) {
-}
-
-func (h *RpcEventHandler) OnReceiveHeaders(metadata.MD) {
-}
-
-func (h *RpcEventHandler) OnReceiveResponse(m proto.Message) {
-	h.Response = m
-}
-
-func (h *RpcEventHandler) OnReceiveTrailers(s *status.Status, m metadata.MD) {
-	h.Status = s
-}
-
-func (h *RpcEventHandler) GetParams(msg proto.Message) error {
-	dmsg, err := dynamic.AsDynamicMessage(msg)
-	if err != nil {
-		return err
-	}
-
-	if h.Fields == nil || len(h.Fields) == 0 {
-		return io.EOF
-	}
-
-	fields, ok := h.Fields[dmsg.XXX_MessageName()]
-	if !ok {
-		return nil
-	}
-
-	for k, v := range fields {
-		err := dmsg.TrySetFieldByName(k, v)
-		if err != nil {
-			return err
-		}
-	}
-	delete(h.Fields, dmsg.XXX_MessageName())
-
-	return nil
-}
diff --git a/vendor/github.com/golang/protobuf/ptypes/empty/empty.pb.go b/vendor/github.com/golang/protobuf/ptypes/empty/empty.pb.go
deleted file mode 100644
index b4eb03e..0000000
--- a/vendor/github.com/golang/protobuf/ptypes/empty/empty.pb.go
+++ /dev/null
@@ -1,83 +0,0 @@
-// Code generated by protoc-gen-go. DO NOT EDIT.
-// source: google/protobuf/empty.proto
-
-package empty
-
-import (
-	fmt "fmt"
-	proto "github.com/golang/protobuf/proto"
-	math "math"
-)
-
-// Reference imports to suppress errors if they are not otherwise used.
-var _ = proto.Marshal
-var _ = fmt.Errorf
-var _ = math.Inf
-
-// This is a compile-time assertion to ensure that this generated file
-// is compatible with the proto package it is being compiled against.
-// A compilation error at this line likely means your copy of the
-// proto package needs to be updated.
-const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
-
-// A generic empty message that you can re-use to avoid defining duplicated
-// empty messages in your APIs. A typical example is to use it as the request
-// or the response type of an API method. For instance:
-//
-//     service Foo {
-//       rpc Bar(google.protobuf.Empty) returns (google.protobuf.Empty);
-//     }
-//
-// The JSON representation for `Empty` is empty JSON object `{}`.
-type Empty struct {
-	XXX_NoUnkeyedLiteral struct{} `json:"-"`
-	XXX_unrecognized     []byte   `json:"-"`
-	XXX_sizecache        int32    `json:"-"`
-}
-
-func (m *Empty) Reset()         { *m = Empty{} }
-func (m *Empty) String() string { return proto.CompactTextString(m) }
-func (*Empty) ProtoMessage()    {}
-func (*Empty) Descriptor() ([]byte, []int) {
-	return fileDescriptor_900544acb223d5b8, []int{0}
-}
-
-func (*Empty) XXX_WellKnownType() string { return "Empty" }
-
-func (m *Empty) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_Empty.Unmarshal(m, b)
-}
-func (m *Empty) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_Empty.Marshal(b, m, deterministic)
-}
-func (m *Empty) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_Empty.Merge(m, src)
-}
-func (m *Empty) XXX_Size() int {
-	return xxx_messageInfo_Empty.Size(m)
-}
-func (m *Empty) XXX_DiscardUnknown() {
-	xxx_messageInfo_Empty.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_Empty proto.InternalMessageInfo
-
-func init() {
-	proto.RegisterType((*Empty)(nil), "google.protobuf.Empty")
-}
-
-func init() { proto.RegisterFile("google/protobuf/empty.proto", fileDescriptor_900544acb223d5b8) }
-
-var fileDescriptor_900544acb223d5b8 = []byte{
-	// 148 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x4e, 0xcf, 0xcf, 0x4f,
-	0xcf, 0x49, 0xd5, 0x2f, 0x28, 0xca, 0x2f, 0xc9, 0x4f, 0x2a, 0x4d, 0xd3, 0x4f, 0xcd, 0x2d, 0x28,
-	0xa9, 0xd4, 0x03, 0x73, 0x85, 0xf8, 0x21, 0x92, 0x7a, 0x30, 0x49, 0x25, 0x76, 0x2e, 0x56, 0x57,
-	0x90, 0xbc, 0x53, 0x19, 0x97, 0x70, 0x72, 0x7e, 0xae, 0x1e, 0x9a, 0xbc, 0x13, 0x17, 0x58, 0x36,
-	0x00, 0xc4, 0x0d, 0x60, 0x8c, 0x52, 0x4f, 0xcf, 0x2c, 0xc9, 0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf,
-	0xd5, 0x4f, 0xcf, 0xcf, 0x49, 0xcc, 0x4b, 0x47, 0x58, 0x53, 0x50, 0x52, 0x59, 0x90, 0x5a, 0x0c,
-	0xb1, 0xed, 0x07, 0x23, 0xe3, 0x22, 0x26, 0x66, 0xf7, 0x00, 0xa7, 0x55, 0x4c, 0x72, 0xee, 0x10,
-	0x13, 0x03, 0xa0, 0xea, 0xf4, 0xc2, 0x53, 0x73, 0x72, 0xbc, 0xf3, 0xf2, 0xcb, 0xf3, 0x42, 0x40,
-	0xea, 0x93, 0xd8, 0xc0, 0x06, 0x18, 0x03, 0x02, 0x00, 0x00, 0xff, 0xff, 0x64, 0xd4, 0xb3, 0xa6,
-	0xb7, 0x00, 0x00, 0x00,
-}
diff --git a/vendor/github.com/golang/protobuf/ptypes/empty/empty.proto b/vendor/github.com/golang/protobuf/ptypes/empty/empty.proto
deleted file mode 100644
index 03cacd2..0000000
--- a/vendor/github.com/golang/protobuf/ptypes/empty/empty.proto
+++ /dev/null
@@ -1,52 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-syntax = "proto3";
-
-package google.protobuf;
-
-option csharp_namespace = "Google.Protobuf.WellKnownTypes";
-option go_package = "github.com/golang/protobuf/ptypes/empty";
-option java_package = "com.google.protobuf";
-option java_outer_classname = "EmptyProto";
-option java_multiple_files = true;
-option objc_class_prefix = "GPB";
-option cc_enable_arenas = true;
-
-// A generic empty message that you can re-use to avoid defining duplicated
-// empty messages in your APIs. A typical example is to use it as the request
-// or the response type of an API method. For instance:
-//
-//     service Foo {
-//       rpc Bar(google.protobuf.Empty) returns (google.protobuf.Empty);
-//     }
-//
-// The JSON representation for `Empty` is empty JSON object `{}`.
-message Empty {}
diff --git a/vendor/github.com/jhump/protoreflect/LICENSE b/vendor/github.com/jhump/protoreflect/LICENSE
deleted file mode 100644
index d645695..0000000
--- a/vendor/github.com/jhump/protoreflect/LICENSE
+++ /dev/null
@@ -1,202 +0,0 @@
-
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
-   APPENDIX: How to apply the Apache License to your work.
-
-      To apply the Apache License to your work, attach the following
-      boilerplate notice, with the fields enclosed by brackets "[]"
-      replaced with your own identifying information. (Don't include
-      the brackets!)  The text should be enclosed in the appropriate
-      comment syntax for the file format. We also recommend that a
-      file or class name and description of purpose be included on the
-      same "printed page" as the copyright notice for easier
-      identification within third-party archives.
-
-   Copyright [yyyy] [name of copyright owner]
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-   You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
diff --git a/vendor/github.com/jhump/protoreflect/codec/buffer.go b/vendor/github.com/jhump/protoreflect/codec/buffer.go
deleted file mode 100644
index b9de99c..0000000
--- a/vendor/github.com/jhump/protoreflect/codec/buffer.go
+++ /dev/null
@@ -1,112 +0,0 @@
-package codec
-
-import (
-	"fmt"
-	"io"
-)
-
-// Buffer is a reader and a writer that wraps a slice of bytes and also
-// provides API for decoding and encoding the protobuf binary format.
-//
-// Its operation is similar to that of a bytes.Buffer: writing pushes
-// data to the end of the buffer while reading pops data from the head
-// of the buffer. So the same buffer can be used to both read and write.
-type Buffer struct {
-	buf   []byte
-	index int
-
-	// tmp is used when another byte slice is needed, such as when
-	// serializing messages, since we need to know the length before
-	// we can write the length prefix; by caching this, including
-	// after it is grown by serialization operations, we reduce the
-	// number of allocations needed
-	tmp []byte
-
-	deterministic bool
-}
-
-// NewBuffer creates a new buffer with the given slice of bytes as the
-// buffer's initial contents.
-func NewBuffer(buf []byte) *Buffer {
-	return &Buffer{buf: buf}
-}
-
-// SetDeterministic sets this buffer to encode messages deterministically. This
-// is useful for tests. But the overhead is non-zero, so it should not likely be
-// used outside of tests. When true, map fields in a message must have their
-// keys sorted before serialization to ensure deterministic output. Otherwise,
-// values in a map field will be serialized in map iteration order.
-func (cb *Buffer) SetDeterministic(deterministic bool) {
-	cb.deterministic = deterministic
-}
-
-// Reset resets this buffer back to empty. Any subsequent writes/encodes
-// to the buffer will allocate a new backing slice of bytes.
-func (cb *Buffer) Reset() {
-	cb.buf = []byte(nil)
-	cb.index = 0
-}
-
-// Bytes returns the slice of bytes remaining in the buffer. Note that
-// this does not perform a copy: if the contents of the returned slice
-// are modified, the modifications will be visible to subsequent reads
-// via the buffer.
-func (cb *Buffer) Bytes() []byte {
-	return cb.buf[cb.index:]
-}
-
-// String returns the remaining bytes in the buffer as a string.
-func (cb *Buffer) String() string {
-	return string(cb.Bytes())
-}
-
-// EOF returns true if there are no more bytes remaining to read.
-func (cb *Buffer) EOF() bool {
-	return cb.index >= len(cb.buf)
-}
-
-// Skip attempts to skip the given number of bytes in the input. If
-// the input has fewer bytes than the given count, false is returned
-// and the buffer is unchanged. Otherwise, the given number of bytes
-// are skipped and true is returned.
-func (cb *Buffer) Skip(count int) error {
-	if count < 0 {
-		return fmt.Errorf("proto: bad byte length %d", count)
-	}
-	newIndex := cb.index + count
-	if newIndex < cb.index || newIndex > len(cb.buf) {
-		return io.ErrUnexpectedEOF
-	}
-	cb.index = newIndex
-	return nil
-}
-
-// Len returns the remaining number of bytes in the buffer.
-func (cb *Buffer) Len() int {
-	return len(cb.buf) - cb.index
-}
-
-// Read implements the io.Reader interface. If there are no bytes
-// remaining in the buffer, it will return 0, io.EOF. Otherwise,
-// it reads max(len(dest), cb.Len()) bytes from input and copies
-// them into dest. It returns the number of bytes copied and a nil
-// error in this case.
-func (cb *Buffer) Read(dest []byte) (int, error) {
-	if cb.index == len(cb.buf) {
-		return 0, io.EOF
-	}
-	copied := copy(dest, cb.buf[cb.index:])
-	cb.index += copied
-	return copied, nil
-}
-
-var _ io.Reader = (*Buffer)(nil)
-
-// Write implements the io.Writer interface. It always returns
-// len(data), nil.
-func (cb *Buffer) Write(data []byte) (int, error) {
-	cb.buf = append(cb.buf, data...)
-	return len(data), nil
-}
-
-var _ io.Writer = (*Buffer)(nil)
diff --git a/vendor/github.com/jhump/protoreflect/codec/decode.go b/vendor/github.com/jhump/protoreflect/codec/decode.go
deleted file mode 100644
index 2a7e59f..0000000
--- a/vendor/github.com/jhump/protoreflect/codec/decode.go
+++ /dev/null
@@ -1,372 +0,0 @@
-package codec
-
-import (
-	"errors"
-	"fmt"
-	"io"
-	"math"
-
-	"github.com/golang/protobuf/proto"
-	"github.com/golang/protobuf/protoc-gen-go/descriptor"
-)
-
-// ErrOverflow is returned when an integer is too large to be represented.
-var ErrOverflow = errors.New("proto: integer overflow")
-
-// ErrBadWireType is returned when decoding a wire-type from a buffer that
-// is not valid.
-var ErrBadWireType = errors.New("proto: bad wiretype")
-
-var varintTypes = map[descriptor.FieldDescriptorProto_Type]bool{}
-var fixed32Types = map[descriptor.FieldDescriptorProto_Type]bool{}
-var fixed64Types = map[descriptor.FieldDescriptorProto_Type]bool{}
-
-func init() {
-	varintTypes[descriptor.FieldDescriptorProto_TYPE_BOOL] = true
-	varintTypes[descriptor.FieldDescriptorProto_TYPE_INT32] = true
-	varintTypes[descriptor.FieldDescriptorProto_TYPE_INT64] = true
-	varintTypes[descriptor.FieldDescriptorProto_TYPE_UINT32] = true
-	varintTypes[descriptor.FieldDescriptorProto_TYPE_UINT64] = true
-	varintTypes[descriptor.FieldDescriptorProto_TYPE_SINT32] = true
-	varintTypes[descriptor.FieldDescriptorProto_TYPE_SINT64] = true
-	varintTypes[descriptor.FieldDescriptorProto_TYPE_ENUM] = true
-
-	fixed32Types[descriptor.FieldDescriptorProto_TYPE_FIXED32] = true
-	fixed32Types[descriptor.FieldDescriptorProto_TYPE_SFIXED32] = true
-	fixed32Types[descriptor.FieldDescriptorProto_TYPE_FLOAT] = true
-
-	fixed64Types[descriptor.FieldDescriptorProto_TYPE_FIXED64] = true
-	fixed64Types[descriptor.FieldDescriptorProto_TYPE_SFIXED64] = true
-	fixed64Types[descriptor.FieldDescriptorProto_TYPE_DOUBLE] = true
-}
-
-func (cb *Buffer) decodeVarintSlow() (x uint64, err error) {
-	i := cb.index
-	l := len(cb.buf)
-
-	for shift := uint(0); shift < 64; shift += 7 {
-		if i >= l {
-			err = io.ErrUnexpectedEOF
-			return
-		}
-		b := cb.buf[i]
-		i++
-		x |= (uint64(b) & 0x7F) << shift
-		if b < 0x80 {
-			cb.index = i
-			return
-		}
-	}
-
-	// The number is too large to represent in a 64-bit value.
-	err = ErrOverflow
-	return
-}
-
-// DecodeVarint reads a varint-encoded integer from the Buffer.
-// This is the format for the
-// int32, int64, uint32, uint64, bool, and enum
-// protocol buffer types.
-func (cb *Buffer) DecodeVarint() (uint64, error) {
-	i := cb.index
-	buf := cb.buf
-
-	if i >= len(buf) {
-		return 0, io.ErrUnexpectedEOF
-	} else if buf[i] < 0x80 {
-		cb.index++
-		return uint64(buf[i]), nil
-	} else if len(buf)-i < 10 {
-		return cb.decodeVarintSlow()
-	}
-
-	var b uint64
-	// we already checked the first byte
-	x := uint64(buf[i]) - 0x80
-	i++
-
-	b = uint64(buf[i])
-	i++
-	x += b << 7
-	if b&0x80 == 0 {
-		goto done
-	}
-	x -= 0x80 << 7
-
-	b = uint64(buf[i])
-	i++
-	x += b << 14
-	if b&0x80 == 0 {
-		goto done
-	}
-	x -= 0x80 << 14
-
-	b = uint64(buf[i])
-	i++
-	x += b << 21
-	if b&0x80 == 0 {
-		goto done
-	}
-	x -= 0x80 << 21
-
-	b = uint64(buf[i])
-	i++
-	x += b << 28
-	if b&0x80 == 0 {
-		goto done
-	}
-	x -= 0x80 << 28
-
-	b = uint64(buf[i])
-	i++
-	x += b << 35
-	if b&0x80 == 0 {
-		goto done
-	}
-	x -= 0x80 << 35
-
-	b = uint64(buf[i])
-	i++
-	x += b << 42
-	if b&0x80 == 0 {
-		goto done
-	}
-	x -= 0x80 << 42
-
-	b = uint64(buf[i])
-	i++
-	x += b << 49
-	if b&0x80 == 0 {
-		goto done
-	}
-	x -= 0x80 << 49
-
-	b = uint64(buf[i])
-	i++
-	x += b << 56
-	if b&0x80 == 0 {
-		goto done
-	}
-	x -= 0x80 << 56
-
-	b = uint64(buf[i])
-	i++
-	x += b << 63
-	if b&0x80 == 0 {
-		goto done
-	}
-	// x -= 0x80 << 63 // Always zero.
-
-	return 0, ErrOverflow
-
-done:
-	cb.index = i
-	return x, nil
-}
-
-// DecodeTagAndWireType decodes a field tag and wire type from input.
-// This reads a varint and then extracts the two fields from the varint
-// value read.
-func (cb *Buffer) DecodeTagAndWireType() (tag int32, wireType int8, err error) {
-	var v uint64
-	v, err = cb.DecodeVarint()
-	if err != nil {
-		return
-	}
-	// low 7 bits is wire type
-	wireType = int8(v & 7)
-	// rest is int32 tag number
-	v = v >> 3
-	if v > math.MaxInt32 {
-		err = fmt.Errorf("tag number out of range: %d", v)
-		return
-	}
-	tag = int32(v)
-	return
-}
-
-// DecodeFixed64 reads a 64-bit integer from the Buffer.
-// This is the format for the
-// fixed64, sfixed64, and double protocol buffer types.
-func (cb *Buffer) DecodeFixed64() (x uint64, err error) {
-	// x, err already 0
-	i := cb.index + 8
-	if i < 0 || i > len(cb.buf) {
-		err = io.ErrUnexpectedEOF
-		return
-	}
-	cb.index = i
-
-	x = uint64(cb.buf[i-8])
-	x |= uint64(cb.buf[i-7]) << 8
-	x |= uint64(cb.buf[i-6]) << 16
-	x |= uint64(cb.buf[i-5]) << 24
-	x |= uint64(cb.buf[i-4]) << 32
-	x |= uint64(cb.buf[i-3]) << 40
-	x |= uint64(cb.buf[i-2]) << 48
-	x |= uint64(cb.buf[i-1]) << 56
-	return
-}
-
-// DecodeFixed32 reads a 32-bit integer from the Buffer.
-// This is the format for the
-// fixed32, sfixed32, and float protocol buffer types.
-func (cb *Buffer) DecodeFixed32() (x uint64, err error) {
-	// x, err already 0
-	i := cb.index + 4
-	if i < 0 || i > len(cb.buf) {
-		err = io.ErrUnexpectedEOF
-		return
-	}
-	cb.index = i
-
-	x = uint64(cb.buf[i-4])
-	x |= uint64(cb.buf[i-3]) << 8
-	x |= uint64(cb.buf[i-2]) << 16
-	x |= uint64(cb.buf[i-1]) << 24
-	return
-}
-
-// DecodeZigZag32 decodes a signed 32-bit integer from the given
-// zig-zag encoded value.
-func DecodeZigZag32(v uint64) int32 {
-	return int32((uint32(v) >> 1) ^ uint32((int32(v&1)<<31)>>31))
-}
-
-// DecodeZigZag64 decodes a signed 64-bit integer from the given
-// zig-zag encoded value.
-func DecodeZigZag64(v uint64) int64 {
-	return int64((v >> 1) ^ uint64((int64(v&1)<<63)>>63))
-}
-
-// DecodeRawBytes reads a count-delimited byte buffer from the Buffer.
-// This is the format used for the bytes protocol buffer
-// type and for embedded messages.
-func (cb *Buffer) DecodeRawBytes(alloc bool) (buf []byte, err error) {
-	n, err := cb.DecodeVarint()
-	if err != nil {
-		return nil, err
-	}
-
-	nb := int(n)
-	if nb < 0 {
-		return nil, fmt.Errorf("proto: bad byte length %d", nb)
-	}
-	end := cb.index + nb
-	if end < cb.index || end > len(cb.buf) {
-		return nil, io.ErrUnexpectedEOF
-	}
-
-	if !alloc {
-		buf = cb.buf[cb.index:end]
-		cb.index = end
-		return
-	}
-
-	buf = make([]byte, nb)
-	copy(buf, cb.buf[cb.index:])
-	cb.index = end
-	return
-}
-
-// ReadGroup reads the input until a "group end" tag is found
-// and returns the data up to that point. Subsequent reads from
-// the buffer will read data after the group end tag. If alloc
-// is true, the data is copied to a new slice before being returned.
-// Otherwise, the returned slice is a view into the buffer's
-// underlying byte slice.
-//
-// This function correctly handles nested groups: if a "group start"
-// tag is found, then that group's end tag will be included in the
-// returned data.
-func (cb *Buffer) ReadGroup(alloc bool) ([]byte, error) {
-	var groupEnd, dataEnd int
-	groupEnd, dataEnd, err := cb.findGroupEnd()
-	if err != nil {
-		return nil, err
-	}
-	var results []byte
-	if !alloc {
-		results = cb.buf[cb.index:dataEnd]
-	} else {
-		results = make([]byte, dataEnd-cb.index)
-		copy(results, cb.buf[cb.index:])
-	}
-	cb.index = groupEnd
-	return results, nil
-}
-
-// SkipGroup is like ReadGroup, except that it discards the
-// data and just advances the buffer to point to the input
-// right *after* the "group end" tag.
-func (cb *Buffer) SkipGroup() error {
-	groupEnd, _, err := cb.findGroupEnd()
-	if err != nil {
-		return err
-	}
-	cb.index = groupEnd
-	return nil
-}
-
-func (cb *Buffer) findGroupEnd() (groupEnd int, dataEnd int, err error) {
-	bs := cb.buf
-	start := cb.index
-	defer func() {
-		cb.index = start
-	}()
-	for {
-		fieldStart := cb.index
-		// read a field tag
-		_, wireType, err := cb.DecodeTagAndWireType()
-		if err != nil {
-			return 0, 0, err
-		}
-		// skip past the field's data
-		switch wireType {
-		case proto.WireFixed32:
-			if err := cb.Skip(4); err != nil {
-				return 0, 0, err
-			}
-		case proto.WireFixed64:
-			if err := cb.Skip(8); err != nil {
-				return 0, 0, err
-			}
-		case proto.WireVarint:
-			// skip varint by finding last byte (has high bit unset)
-			i := cb.index
-			limit := i + 10 // varint cannot be >10 bytes
-			for {
-				if i >= limit {
-					return 0, 0, ErrOverflow
-				}
-				if i >= len(bs) {
-					return 0, 0, io.ErrUnexpectedEOF
-				}
-				if bs[i]&0x80 == 0 {
-					break
-				}
-				i++
-			}
-			// TODO: This would only overflow if buffer length was MaxInt and we
-			// read the last byte. This is not a real/feasible concern on 64-bit
-			// systems. Something to worry about for 32-bit systems? Do we care?
-			cb.index = i + 1
-		case proto.WireBytes:
-			l, err := cb.DecodeVarint()
-			if err != nil {
-				return 0, 0, err
-			}
-			if err := cb.Skip(int(l)); err != nil {
-				return 0, 0, err
-			}
-		case proto.WireStartGroup:
-			if err := cb.SkipGroup(); err != nil {
-				return 0, 0, err
-			}
-		case proto.WireEndGroup:
-			return cb.index, fieldStart, nil
-		default:
-			return 0, 0, ErrBadWireType
-		}
-	}
-}
diff --git a/vendor/github.com/jhump/protoreflect/codec/decode_fields.go b/vendor/github.com/jhump/protoreflect/codec/decode_fields.go
deleted file mode 100644
index 938b4d9..0000000
--- a/vendor/github.com/jhump/protoreflect/codec/decode_fields.go
+++ /dev/null
@@ -1,283 +0,0 @@
-package codec
-
-import (
-	"errors"
-	"fmt"
-	"io"
-	"math"
-
-	"github.com/golang/protobuf/proto"
-	"github.com/golang/protobuf/protoc-gen-go/descriptor"
-
-	"github.com/jhump/protoreflect/desc"
-)
-
-// ErrWireTypeEndGroup is returned from DecodeFieldValue if the tag and wire-type
-// it reads indicates an end-group marker.
-var ErrWireTypeEndGroup = errors.New("unexpected wire type: end group")
-
-// MessageFactory is used to instantiate messages when DecodeFieldValue needs to
-// decode a message value.
-//
-// Also see MessageFactory in "github.com/jhump/protoreflect/dynamic", which
-// implements this interface.
-type MessageFactory interface {
-	NewMessage(md *desc.MessageDescriptor) proto.Message
-}
-
-// UnknownField represents a field that was parsed from the binary wire
-// format for a message, but was not a recognized field number. Enough
-// information is preserved so that re-serializing the message won't lose
-// any of the unrecognized data.
-type UnknownField struct {
-	// The tag number for the unrecognized field.
-	Tag int32
-
-	// Encoding indicates how the unknown field was encoded on the wire. If it
-	// is proto.WireBytes or proto.WireGroupStart then Contents will be set to
-	// the raw bytes. If it is proto.WireTypeFixed32 then the data is in the least
-	// significant 32 bits of Value. Otherwise, the data is in all 64 bits of
-	// Value.
-	Encoding int8
-	Contents []byte
-	Value    uint64
-}
-
-// DecodeFieldValue will read a field value from the buffer and return its
-// value and the corresponding field descriptor. The given function is used
-// to lookup a field descriptor by tag number. The given factory is used to
-// instantiate a message if the field value is (or contains) a message value.
-//
-// On error, the field descriptor and value are typically nil. However, if the
-// error returned is ErrWireTypeEndGroup, the returned value will indicate any
-// tag number encoded in the end-group marker.
-//
-// If the field descriptor returned is nil, that means that the given function
-// returned nil. This is expected to happen for unrecognized tag numbers. In
-// that case, no error is returned, and the value will be an UnknownField.
-func (cb *Buffer) DecodeFieldValue(fieldFinder func(int32) *desc.FieldDescriptor, fact MessageFactory) (*desc.FieldDescriptor, interface{}, error) {
-	if cb.EOF() {
-		return nil, nil, io.EOF
-	}
-	tagNumber, wireType, err := cb.DecodeTagAndWireType()
-	if err != nil {
-		return nil, nil, err
-	}
-	if wireType == proto.WireEndGroup {
-		return nil, tagNumber, ErrWireTypeEndGroup
-	}
-	fd := fieldFinder(tagNumber)
-	if fd == nil {
-		val, err := cb.decodeUnknownField(tagNumber, wireType)
-		return nil, val, err
-	}
-	val, err := cb.decodeKnownField(fd, wireType, fact)
-	return fd, val, err
-}
-
-// DecodeScalarField extracts a properly-typed value from v. The returned value's
-// type depends on the given field descriptor type. It will be the same type as
-// generated structs use for the field descriptor's type. Enum types will return
-// an int32. If the given field type uses length-delimited encoding (nested
-// messages, bytes, and strings), an error is returned.
-func DecodeScalarField(fd *desc.FieldDescriptor, v uint64) (interface{}, error) {
-	switch fd.GetType() {
-	case descriptor.FieldDescriptorProto_TYPE_BOOL:
-		return v != 0, nil
-	case descriptor.FieldDescriptorProto_TYPE_UINT32,
-		descriptor.FieldDescriptorProto_TYPE_FIXED32:
-		if v > math.MaxUint32 {
-			return nil, ErrOverflow
-		}
-		return uint32(v), nil
-
-	case descriptor.FieldDescriptorProto_TYPE_INT32,
-		descriptor.FieldDescriptorProto_TYPE_ENUM:
-		s := int64(v)
-		if s > math.MaxInt32 || s < math.MinInt32 {
-			return nil, ErrOverflow
-		}
-		return int32(s), nil
-
-	case descriptor.FieldDescriptorProto_TYPE_SFIXED32:
-		if v > math.MaxUint32 {
-			return nil, ErrOverflow
-		}
-		return int32(v), nil
-
-	case descriptor.FieldDescriptorProto_TYPE_SINT32:
-		if v > math.MaxUint32 {
-			return nil, ErrOverflow
-		}
-		return DecodeZigZag32(v), nil
-
-	case descriptor.FieldDescriptorProto_TYPE_UINT64,
-		descriptor.FieldDescriptorProto_TYPE_FIXED64:
-		return v, nil
-
-	case descriptor.FieldDescriptorProto_TYPE_INT64,
-		descriptor.FieldDescriptorProto_TYPE_SFIXED64:
-		return int64(v), nil
-
-	case descriptor.FieldDescriptorProto_TYPE_SINT64:
-		return DecodeZigZag64(v), nil
-
-	case descriptor.FieldDescriptorProto_TYPE_FLOAT:
-		if v > math.MaxUint32 {
-			return nil, ErrOverflow
-		}
-		return math.Float32frombits(uint32(v)), nil
-
-	case descriptor.FieldDescriptorProto_TYPE_DOUBLE:
-		return math.Float64frombits(v), nil
-
-	default:
-		// bytes, string, message, and group cannot be represented as a simple numeric value
-		return nil, fmt.Errorf("bad input; field %s requires length-delimited wire type", fd.GetFullyQualifiedName())
-	}
-}
-
-// DecodeLengthDelimitedField extracts a properly-typed value from bytes. The
-// returned value's type will usually be []byte, string, or, for nested messages,
-// the type returned from the given message factory. However, since repeated
-// scalar fields can be length-delimited, when they used packed encoding, it can
-// also return an []interface{}, where each element is a scalar value. Furthermore,
-// it could return a scalar type, not in a slice, if the given field descriptor is
-// not repeated. This is to support cases where a field is changed from optional
-// to repeated. New code may emit a packed repeated representation, but old code
-// still expects a single scalar value. In this case, if the actual data in bytes
-// contains multiple values, only the last value is returned.
-func DecodeLengthDelimitedField(fd *desc.FieldDescriptor, bytes []byte, mf MessageFactory) (interface{}, error) {
-	switch {
-	case fd.GetType() == descriptor.FieldDescriptorProto_TYPE_BYTES:
-		return bytes, nil
-
-	case fd.GetType() == descriptor.FieldDescriptorProto_TYPE_STRING:
-		return string(bytes), nil
-
-	case fd.GetType() == descriptor.FieldDescriptorProto_TYPE_MESSAGE ||
-		fd.GetType() == descriptor.FieldDescriptorProto_TYPE_GROUP:
-		msg := mf.NewMessage(fd.GetMessageType())
-		err := proto.Unmarshal(bytes, msg)
-		if err != nil {
-			return nil, err
-		} else {
-			return msg, nil
-		}
-
-	default:
-		// even if the field is not repeated or not packed, we still parse it as such for
-		// backwards compatibility (e.g. message we are de-serializing could have been both
-		// repeated and packed at the time of serialization)
-		packedBuf := NewBuffer(bytes)
-		var slice []interface{}
-		var val interface{}
-		for !packedBuf.EOF() {
-			var v uint64
-			var err error
-			if varintTypes[fd.GetType()] {
-				v, err = packedBuf.DecodeVarint()
-			} else if fixed32Types[fd.GetType()] {
-				v, err = packedBuf.DecodeFixed32()
-			} else if fixed64Types[fd.GetType()] {
-				v, err = packedBuf.DecodeFixed64()
-			} else {
-				return nil, fmt.Errorf("bad input; cannot parse length-delimited wire type for field %s", fd.GetFullyQualifiedName())
-			}
-			if err != nil {
-				return nil, err
-			}
-			val, err = DecodeScalarField(fd, v)
-			if err != nil {
-				return nil, err
-			}
-			if fd.IsRepeated() {
-				slice = append(slice, val)
-			}
-		}
-		if fd.IsRepeated() {
-			return slice, nil
-		} else {
-			// if not a repeated field, last value wins
-			return val, nil
-		}
-	}
-}
-
-func (b *Buffer) decodeKnownField(fd *desc.FieldDescriptor, encoding int8, fact MessageFactory) (interface{}, error) {
-	var val interface{}
-	var err error
-	switch encoding {
-	case proto.WireFixed32:
-		var num uint64
-		num, err = b.DecodeFixed32()
-		if err == nil {
-			val, err = DecodeScalarField(fd, num)
-		}
-	case proto.WireFixed64:
-		var num uint64
-		num, err = b.DecodeFixed64()
-		if err == nil {
-			val, err = DecodeScalarField(fd, num)
-		}
-	case proto.WireVarint:
-		var num uint64
-		num, err = b.DecodeVarint()
-		if err == nil {
-			val, err = DecodeScalarField(fd, num)
-		}
-
-	case proto.WireBytes:
-		alloc := fd.GetType() == descriptor.FieldDescriptorProto_TYPE_BYTES
-		var raw []byte
-		raw, err = b.DecodeRawBytes(alloc)
-		if err == nil {
-			val, err = DecodeLengthDelimitedField(fd, raw, fact)
-		}
-
-	case proto.WireStartGroup:
-		if fd.GetMessageType() == nil {
-			return nil, fmt.Errorf("cannot parse field %s from group-encoded wire type", fd.GetFullyQualifiedName())
-		}
-		msg := fact.NewMessage(fd.GetMessageType())
-		var data []byte
-		data, err = b.ReadGroup(false)
-		if err == nil {
-			err = proto.Unmarshal(data, msg)
-			if err == nil {
-				val = msg
-			}
-		}
-
-	default:
-		return nil, ErrBadWireType
-	}
-	if err != nil {
-		return nil, err
-	}
-
-	return val, nil
-}
-
-func (b *Buffer) decodeUnknownField(tagNumber int32, encoding int8) (interface{}, error) {
-	u := UnknownField{Tag: tagNumber, Encoding: encoding}
-	var err error
-	switch encoding {
-	case proto.WireFixed32:
-		u.Value, err = b.DecodeFixed32()
-	case proto.WireFixed64:
-		u.Value, err = b.DecodeFixed64()
-	case proto.WireVarint:
-		u.Value, err = b.DecodeVarint()
-	case proto.WireBytes:
-		u.Contents, err = b.DecodeRawBytes(true)
-	case proto.WireStartGroup:
-		u.Contents, err = b.ReadGroup(true)
-	default:
-		err = ErrBadWireType
-	}
-	if err != nil {
-		return nil, err
-	}
-	return u, nil
-}
diff --git a/vendor/github.com/jhump/protoreflect/codec/doc.go b/vendor/github.com/jhump/protoreflect/codec/doc.go
deleted file mode 100644
index f76499f..0000000
--- a/vendor/github.com/jhump/protoreflect/codec/doc.go
+++ /dev/null
@@ -1,7 +0,0 @@
-// Package codec contains a reader/write type that assists with encoding
-// and decoding protobuf's binary representation.
-//
-// The code in this package began as a fork of proto.Buffer but provides
-// additional API to make it more useful to code that needs to dynamically
-// process or produce the protobuf binary format.
-package codec
diff --git a/vendor/github.com/jhump/protoreflect/codec/encode.go b/vendor/github.com/jhump/protoreflect/codec/encode.go
deleted file mode 100644
index c84523f..0000000
--- a/vendor/github.com/jhump/protoreflect/codec/encode.go
+++ /dev/null
@@ -1,163 +0,0 @@
-package codec
-
-import "github.com/golang/protobuf/proto"
-
-// EncodeVarint writes a varint-encoded integer to the Buffer.
-// This is the format for the
-// int32, int64, uint32, uint64, bool, and enum
-// protocol buffer types.
-func (cb *Buffer) EncodeVarint(x uint64) error {
-	for x >= 1<<7 {
-		cb.buf = append(cb.buf, uint8(x&0x7f|0x80))
-		x >>= 7
-	}
-	cb.buf = append(cb.buf, uint8(x))
-	return nil
-}
-
-// EncodeTagAndWireType encodes the given field tag and wire type to the
-// buffer. This combines the two values and then writes them as a varint.
-func (cb *Buffer) EncodeTagAndWireType(tag int32, wireType int8) error {
-	v := uint64((int64(tag) << 3) | int64(wireType))
-	return cb.EncodeVarint(v)
-}
-
-// EncodeFixed64 writes a 64-bit integer to the Buffer.
-// This is the format for the
-// fixed64, sfixed64, and double protocol buffer types.
-func (cb *Buffer) EncodeFixed64(x uint64) error {
-	cb.buf = append(cb.buf,
-		uint8(x),
-		uint8(x>>8),
-		uint8(x>>16),
-		uint8(x>>24),
-		uint8(x>>32),
-		uint8(x>>40),
-		uint8(x>>48),
-		uint8(x>>56))
-	return nil
-}
-
-// EncodeFixed32 writes a 32-bit integer to the Buffer.
-// This is the format for the
-// fixed32, sfixed32, and float protocol buffer types.
-func (cb *Buffer) EncodeFixed32(x uint64) error {
-	cb.buf = append(cb.buf,
-		uint8(x),
-		uint8(x>>8),
-		uint8(x>>16),
-		uint8(x>>24))
-	return nil
-}
-
-// EncodeZigZag64 does zig-zag encoding to convert the given
-// signed 64-bit integer into a form that can be expressed
-// efficiently as a varint, even for negative values.
-func EncodeZigZag64(v int64) uint64 {
-	return (uint64(v) << 1) ^ uint64(v>>63)
-}
-
-// EncodeZigZag32 does zig-zag encoding to convert the given
-// signed 32-bit integer into a form that can be expressed
-// efficiently as a varint, even for negative values.
-func EncodeZigZag32(v int32) uint64 {
-	return uint64((uint32(v) << 1) ^ uint32((v >> 31)))
-}
-
-// EncodeRawBytes writes a count-delimited byte buffer to the Buffer.
-// This is the format used for the bytes protocol buffer
-// type and for embedded messages.
-func (cb *Buffer) EncodeRawBytes(b []byte) error {
-	if err := cb.EncodeVarint(uint64(len(b))); err != nil {
-		return err
-	}
-	cb.buf = append(cb.buf, b...)
-	return nil
-}
-
-// EncodeMessage writes the given message to the buffer.
-func (cb *Buffer) EncodeMessage(pm proto.Message) error {
-	bytes, err := marshalMessage(cb.buf, pm, cb.deterministic)
-	if err != nil {
-		return err
-	}
-	cb.buf = bytes
-	return nil
-}
-
-// EncodeDelimitedMessage writes the given message to the buffer with a
-// varint-encoded length prefix (the delimiter).
-func (cb *Buffer) EncodeDelimitedMessage(pm proto.Message) error {
-	bytes, err := marshalMessage(cb.tmp, pm, cb.deterministic)
-	if err != nil {
-		return err
-	}
-	// save truncated buffer if it was grown (so we can re-use it and
-	// curtail future allocations)
-	if cap(bytes) > cap(cb.tmp) {
-		cb.tmp = bytes[:0]
-	}
-	return cb.EncodeRawBytes(bytes)
-}
-
-func marshalMessage(b []byte, pm proto.Message, deterministic bool) ([]byte, error) {
-	// we try to use the most efficient way to marshal to existing slice
-	nm, ok := pm.(interface {
-		// this interface is implemented by generated messages
-		XXX_Size() int
-		XXX_Marshal(b []byte, deterministic bool) ([]byte, error)
-	})
-	if ok {
-		sz := nm.XXX_Size()
-		if cap(b) < len(b)+sz {
-			// re-allocate to fit
-			bytes := make([]byte, len(b), len(b)+sz)
-			copy(bytes, b)
-			b = bytes
-		}
-		return nm.XXX_Marshal(b, deterministic)
-	}
-
-	if deterministic {
-		// see if the message has custom deterministic methods, preferring an
-		// "append" method over one that must always re-allocate
-		madm, ok := pm.(interface {
-			MarshalAppendDeterministic(b []byte) ([]byte, error)
-		})
-		if ok {
-			return madm.MarshalAppendDeterministic(b)
-		}
-
-		mdm, ok := pm.(interface {
-			MarshalDeterministic() ([]byte, error)
-		})
-		if ok {
-			bytes, err := mdm.MarshalDeterministic()
-			if err != nil {
-				return nil, err
-			}
-			if len(b) == 0 {
-				return bytes, nil
-			}
-			return append(b, bytes...), nil
-		}
-	}
-
-	mam, ok := pm.(interface {
-		// see if we can append the message, vs. having to re-allocate
-		MarshalAppend(b []byte) ([]byte, error)
-	})
-	if ok {
-		return mam.MarshalAppend(b)
-	}
-
-	// lowest common denominator
-	bytes, err := proto.Marshal(pm)
-	if err != nil {
-		return nil, err
-	}
-	if len(b) == 0 {
-		return bytes, nil
-	}
-	return append(b, bytes...), nil
-}
diff --git a/vendor/github.com/jhump/protoreflect/codec/encode_fields.go b/vendor/github.com/jhump/protoreflect/codec/encode_fields.go
deleted file mode 100644
index cda7299..0000000
--- a/vendor/github.com/jhump/protoreflect/codec/encode_fields.go
+++ /dev/null
@@ -1,267 +0,0 @@
-package codec
-
-import (
-	"fmt"
-	"math"
-	"reflect"
-	"sort"
-
-	"github.com/golang/protobuf/proto"
-	"github.com/golang/protobuf/protoc-gen-go/descriptor"
-
-	"github.com/jhump/protoreflect/desc"
-)
-
-func (cb *Buffer) EncodeFieldValue(fd *desc.FieldDescriptor, val interface{}) error {
-	if fd.IsMap() {
-		mp := val.(map[interface{}]interface{})
-		entryType := fd.GetMessageType()
-		keyType := entryType.FindFieldByNumber(1)
-		valType := entryType.FindFieldByNumber(2)
-		var entryBuffer Buffer
-		if cb.deterministic {
-			keys := make([]interface{}, 0, len(mp))
-			for k := range mp {
-				keys = append(keys, k)
-			}
-			sort.Sort(sortable(keys))
-			for _, k := range keys {
-				v := mp[k]
-				entryBuffer.Reset()
-				if err := entryBuffer.encodeFieldElement(keyType, k); err != nil {
-					return err
-				}
-				if err := entryBuffer.encodeFieldElement(valType, v); err != nil {
-					return err
-				}
-				if err := cb.EncodeTagAndWireType(fd.GetNumber(), proto.WireBytes); err != nil {
-					return err
-				}
-				if err := cb.EncodeRawBytes(entryBuffer.Bytes()); err != nil {
-					return err
-				}
-			}
-		} else {
-			for k, v := range mp {
-				entryBuffer.Reset()
-				if err := entryBuffer.encodeFieldElement(keyType, k); err != nil {
-					return err
-				}
-				if err := entryBuffer.encodeFieldElement(valType, v); err != nil {
-					return err
-				}
-				if err := cb.EncodeTagAndWireType(fd.GetNumber(), proto.WireBytes); err != nil {
-					return err
-				}
-				if err := cb.EncodeRawBytes(entryBuffer.Bytes()); err != nil {
-					return err
-				}
-			}
-		}
-		return nil
-	} else if fd.IsRepeated() {
-		sl := val.([]interface{})
-		wt, err := getWireType(fd.GetType())
-		if err != nil {
-			return err
-		}
-		if isPacked(fd) && len(sl) > 1 &&
-			(wt == proto.WireVarint || wt == proto.WireFixed32 || wt == proto.WireFixed64) {
-			// packed repeated field
-			var packedBuffer Buffer
-			for _, v := range sl {
-				if err := packedBuffer.encodeFieldValue(fd, v); err != nil {
-					return err
-				}
-			}
-			if err := cb.EncodeTagAndWireType(fd.GetNumber(), proto.WireBytes); err != nil {
-				return err
-			}
-			return cb.EncodeRawBytes(packedBuffer.Bytes())
-		} else {
-			// non-packed repeated field
-			for _, v := range sl {
-				if err := cb.encodeFieldElement(fd, v); err != nil {
-					return err
-				}
-			}
-			return nil
-		}
-	} else {
-		return cb.encodeFieldElement(fd, val)
-	}
-}
-
-func isPacked(fd *desc.FieldDescriptor) bool {
-	opts := fd.AsFieldDescriptorProto().GetOptions()
-	// if set, use that value
-	if opts != nil && opts.Packed != nil {
-		return opts.GetPacked()
-	}
-	// if unset: proto2 defaults to false, proto3 to true
-	return fd.GetFile().IsProto3()
-}
-
-// sortable is used to sort map keys. Values will be integers (int32, int64, uint32, and uint64),
-// bools, or strings.
-type sortable []interface{}
-
-func (s sortable) Len() int {
-	return len(s)
-}
-
-func (s sortable) Less(i, j int) bool {
-	vi := s[i]
-	vj := s[j]
-	switch reflect.TypeOf(vi).Kind() {
-	case reflect.Int32:
-		return vi.(int32) < vj.(int32)
-	case reflect.Int64:
-		return vi.(int64) < vj.(int64)
-	case reflect.Uint32:
-		return vi.(uint32) < vj.(uint32)
-	case reflect.Uint64:
-		return vi.(uint64) < vj.(uint64)
-	case reflect.String:
-		return vi.(string) < vj.(string)
-	case reflect.Bool:
-		return !vi.(bool) && vj.(bool)
-	default:
-		panic(fmt.Sprintf("cannot compare keys of type %v", reflect.TypeOf(vi)))
-	}
-}
-
-func (s sortable) Swap(i, j int) {
-	s[i], s[j] = s[j], s[i]
-}
-
-func (b *Buffer) encodeFieldElement(fd *desc.FieldDescriptor, val interface{}) error {
-	wt, err := getWireType(fd.GetType())
-	if err != nil {
-		return err
-	}
-	if err := b.EncodeTagAndWireType(fd.GetNumber(), wt); err != nil {
-		return err
-	}
-	if err := b.encodeFieldValue(fd, val); err != nil {
-		return err
-	}
-	if wt == proto.WireStartGroup {
-		return b.EncodeTagAndWireType(fd.GetNumber(), proto.WireEndGroup)
-	}
-	return nil
-}
-
-func (b *Buffer) encodeFieldValue(fd *desc.FieldDescriptor, val interface{}) error {
-	switch fd.GetType() {
-	case descriptor.FieldDescriptorProto_TYPE_BOOL:
-		v := val.(bool)
-		if v {
-			return b.EncodeVarint(1)
-		}
-		return b.EncodeVarint(0)
-
-	case descriptor.FieldDescriptorProto_TYPE_ENUM,
-		descriptor.FieldDescriptorProto_TYPE_INT32:
-		v := val.(int32)
-		return b.EncodeVarint(uint64(v))
-
-	case descriptor.FieldDescriptorProto_TYPE_SFIXED32:
-		v := val.(int32)
-		return b.EncodeFixed32(uint64(v))
-
-	case descriptor.FieldDescriptorProto_TYPE_SINT32:
-		v := val.(int32)
-		return b.EncodeVarint(EncodeZigZag32(v))
-
-	case descriptor.FieldDescriptorProto_TYPE_UINT32:
-		v := val.(uint32)
-		return b.EncodeVarint(uint64(v))
-
-	case descriptor.FieldDescriptorProto_TYPE_FIXED32:
-		v := val.(uint32)
-		return b.EncodeFixed32(uint64(v))
-
-	case descriptor.FieldDescriptorProto_TYPE_INT64:
-		v := val.(int64)
-		return b.EncodeVarint(uint64(v))
-
-	case descriptor.FieldDescriptorProto_TYPE_SFIXED64:
-		v := val.(int64)
-		return b.EncodeFixed64(uint64(v))
-
-	case descriptor.FieldDescriptorProto_TYPE_SINT64:
-		v := val.(int64)
-		return b.EncodeVarint(EncodeZigZag64(v))
-
-	case descriptor.FieldDescriptorProto_TYPE_UINT64:
-		v := val.(uint64)
-		return b.EncodeVarint(v)
-
-	case descriptor.FieldDescriptorProto_TYPE_FIXED64:
-		v := val.(uint64)
-		return b.EncodeFixed64(v)
-
-	case descriptor.FieldDescriptorProto_TYPE_DOUBLE:
-		v := val.(float64)
-		return b.EncodeFixed64(math.Float64bits(v))
-
-	case descriptor.FieldDescriptorProto_TYPE_FLOAT:
-		v := val.(float32)
-		return b.EncodeFixed32(uint64(math.Float32bits(v)))
-
-	case descriptor.FieldDescriptorProto_TYPE_BYTES:
-		v := val.([]byte)
-		return b.EncodeRawBytes(v)
-
-	case descriptor.FieldDescriptorProto_TYPE_STRING:
-		v := val.(string)
-		return b.EncodeRawBytes(([]byte)(v))
-
-	case descriptor.FieldDescriptorProto_TYPE_MESSAGE:
-		return b.EncodeDelimitedMessage(val.(proto.Message))
-
-	case descriptor.FieldDescriptorProto_TYPE_GROUP:
-		// just append the nested message to this buffer
-		return b.EncodeMessage(val.(proto.Message))
-		// whosoever writeth start-group tag (e.g. caller) is responsible for writing end-group tag
-
-	default:
-		return fmt.Errorf("unrecognized field type: %v", fd.GetType())
-	}
-}
-
-func getWireType(t descriptor.FieldDescriptorProto_Type) (int8, error) {
-	switch t {
-	case descriptor.FieldDescriptorProto_TYPE_ENUM,
-		descriptor.FieldDescriptorProto_TYPE_BOOL,
-		descriptor.FieldDescriptorProto_TYPE_INT32,
-		descriptor.FieldDescriptorProto_TYPE_SINT32,
-		descriptor.FieldDescriptorProto_TYPE_UINT32,
-		descriptor.FieldDescriptorProto_TYPE_INT64,
-		descriptor.FieldDescriptorProto_TYPE_SINT64,
-		descriptor.FieldDescriptorProto_TYPE_UINT64:
-		return proto.WireVarint, nil
-
-	case descriptor.FieldDescriptorProto_TYPE_FIXED32,
-		descriptor.FieldDescriptorProto_TYPE_SFIXED32,
-		descriptor.FieldDescriptorProto_TYPE_FLOAT:
-		return proto.WireFixed32, nil
-
-	case descriptor.FieldDescriptorProto_TYPE_FIXED64,
-		descriptor.FieldDescriptorProto_TYPE_SFIXED64,
-		descriptor.FieldDescriptorProto_TYPE_DOUBLE:
-		return proto.WireFixed64, nil
-
-	case descriptor.FieldDescriptorProto_TYPE_BYTES,
-		descriptor.FieldDescriptorProto_TYPE_STRING,
-		descriptor.FieldDescriptorProto_TYPE_MESSAGE:
-		return proto.WireBytes, nil
-
-	case descriptor.FieldDescriptorProto_TYPE_GROUP:
-		return proto.WireStartGroup, nil
-
-	default:
-		return 0, ErrBadWireType
-	}
-}
diff --git a/vendor/github.com/jhump/protoreflect/desc/convert.go b/vendor/github.com/jhump/protoreflect/desc/convert.go
deleted file mode 100644
index 538820c..0000000
--- a/vendor/github.com/jhump/protoreflect/desc/convert.go
+++ /dev/null
@@ -1,231 +0,0 @@
-package desc
-
-import (
-	"errors"
-	"fmt"
-	"strings"
-
-	dpb "github.com/golang/protobuf/protoc-gen-go/descriptor"
-
-	"github.com/jhump/protoreflect/desc/internal"
-	intn "github.com/jhump/protoreflect/internal"
-)
-
-// CreateFileDescriptor instantiates a new file descriptor for the given descriptor proto.
-// The file's direct dependencies must be provided. If the given dependencies do not include
-// all of the file's dependencies or if the contents of the descriptors are internally
-// inconsistent (e.g. contain unresolvable symbols) then an error is returned.
-func CreateFileDescriptor(fd *dpb.FileDescriptorProto, deps ...*FileDescriptor) (*FileDescriptor, error) {
-	return createFileDescriptor(fd, deps, nil)
-}
-
-func createFileDescriptor(fd *dpb.FileDescriptorProto, deps []*FileDescriptor, r *ImportResolver) (*FileDescriptor, error) {
-	ret := &FileDescriptor{
-		proto:      fd,
-		symbols:    map[string]Descriptor{},
-		fieldIndex: map[string]map[int32]*FieldDescriptor{},
-	}
-	pkg := fd.GetPackage()
-
-	// populate references to file descriptor dependencies
-	files := map[string]*FileDescriptor{}
-	for _, f := range deps {
-		files[f.proto.GetName()] = f
-	}
-	ret.deps = make([]*FileDescriptor, len(fd.GetDependency()))
-	for i, d := range fd.GetDependency() {
-		resolved := r.ResolveImport(fd.GetName(), d)
-		ret.deps[i] = files[resolved]
-		if ret.deps[i] == nil {
-			if resolved != d {
-				ret.deps[i] = files[d]
-			}
-			if ret.deps[i] == nil {
-				return nil, intn.ErrNoSuchFile(d)
-			}
-		}
-	}
-	ret.publicDeps = make([]*FileDescriptor, len(fd.GetPublicDependency()))
-	for i, pd := range fd.GetPublicDependency() {
-		ret.publicDeps[i] = ret.deps[pd]
-	}
-	ret.weakDeps = make([]*FileDescriptor, len(fd.GetWeakDependency()))
-	for i, wd := range fd.GetWeakDependency() {
-		ret.weakDeps[i] = ret.deps[wd]
-	}
-	ret.isProto3 = fd.GetSyntax() == "proto3"
-
-	// populate all tables of child descriptors
-	for _, m := range fd.GetMessageType() {
-		md, n := createMessageDescriptor(ret, ret, pkg, m, ret.symbols)
-		ret.symbols[n] = md
-		ret.messages = append(ret.messages, md)
-	}
-	for _, e := range fd.GetEnumType() {
-		ed, n := createEnumDescriptor(ret, ret, pkg, e, ret.symbols)
-		ret.symbols[n] = ed
-		ret.enums = append(ret.enums, ed)
-	}
-	for _, ex := range fd.GetExtension() {
-		exd, n := createFieldDescriptor(ret, ret, pkg, ex)
-		ret.symbols[n] = exd
-		ret.extensions = append(ret.extensions, exd)
-	}
-	for _, s := range fd.GetService() {
-		sd, n := createServiceDescriptor(ret, pkg, s, ret.symbols)
-		ret.symbols[n] = sd
-		ret.services = append(ret.services, sd)
-	}
-
-	ret.sourceInfo = internal.CreateSourceInfoMap(fd)
-	ret.sourceInfoRecomputeFunc = ret.recomputeSourceInfo
-
-	// now we can resolve all type references and source code info
-	scopes := []scope{fileScope(ret)}
-	path := make([]int32, 1, 8)
-	path[0] = internal.File_messagesTag
-	for i, md := range ret.messages {
-		if err := md.resolve(append(path, int32(i)), scopes); err != nil {
-			return nil, err
-		}
-	}
-	path[0] = internal.File_enumsTag
-	for i, ed := range ret.enums {
-		ed.resolve(append(path, int32(i)))
-	}
-	path[0] = internal.File_extensionsTag
-	for i, exd := range ret.extensions {
-		if err := exd.resolve(append(path, int32(i)), scopes); err != nil {
-			return nil, err
-		}
-	}
-	path[0] = internal.File_servicesTag
-	for i, sd := range ret.services {
-		if err := sd.resolve(append(path, int32(i)), scopes); err != nil {
-			return nil, err
-		}
-	}
-
-	return ret, nil
-}
-
-// CreateFileDescriptors constructs a set of descriptors, one for each of the
-// given descriptor protos. The given set of descriptor protos must include all
-// transitive dependencies for every file.
-func CreateFileDescriptors(fds []*dpb.FileDescriptorProto) (map[string]*FileDescriptor, error) {
-	return createFileDescriptors(fds, nil)
-}
-
-func createFileDescriptors(fds []*dpb.FileDescriptorProto, r *ImportResolver) (map[string]*FileDescriptor, error) {
-	if len(fds) == 0 {
-		return nil, nil
-	}
-	files := map[string]*dpb.FileDescriptorProto{}
-	resolved := map[string]*FileDescriptor{}
-	var name string
-	for _, fd := range fds {
-		name = fd.GetName()
-		files[name] = fd
-	}
-	for _, fd := range fds {
-		_, err := createFromSet(fd.GetName(), r, nil, files, resolved)
-		if err != nil {
-			return nil, err
-		}
-	}
-	return resolved, nil
-}
-
-// ToFileDescriptorSet creates a FileDescriptorSet proto that contains all of the given
-// file descriptors and their transitive dependencies. The files are topologically sorted
-// so that a file will always appear after its dependencies.
-func ToFileDescriptorSet(fds ...*FileDescriptor) *dpb.FileDescriptorSet {
-	var fdps []*dpb.FileDescriptorProto
-	addAllFiles(fds, &fdps, map[string]struct{}{})
-	return &dpb.FileDescriptorSet{File: fdps}
-}
-
-func addAllFiles(src []*FileDescriptor, results *[]*dpb.FileDescriptorProto, seen map[string]struct{}) {
-	for _, fd := range src {
-		if _, ok := seen[fd.GetName()]; ok {
-			continue
-		}
-		seen[fd.GetName()] = struct{}{}
-		addAllFiles(fd.GetDependencies(), results, seen)
-		*results = append(*results, fd.AsFileDescriptorProto())
-	}
-}
-
-// CreateFileDescriptorFromSet creates a descriptor from the given file descriptor set. The
-// set's *last* file will be the returned descriptor. The set's remaining files must comprise
-// the full set of transitive dependencies of that last file. This is the same format and
-// order used by protoc when emitting a FileDescriptorSet file with an invocation like so:
-//    protoc --descriptor_set_out=./test.protoset --include_imports -I. test.proto
-func CreateFileDescriptorFromSet(fds *dpb.FileDescriptorSet) (*FileDescriptor, error) {
-	return createFileDescriptorFromSet(fds, nil)
-}
-
-func createFileDescriptorFromSet(fds *dpb.FileDescriptorSet, r *ImportResolver) (*FileDescriptor, error) {
-	result, err := createFileDescriptorsFromSet(fds, r)
-	if err != nil {
-		return nil, err
-	}
-	files := fds.GetFile()
-	lastFilename := files[len(files)-1].GetName()
-	return result[lastFilename], nil
-}
-
-// CreateFileDescriptorsFromSet creates file descriptors from the given file descriptor set.
-// The returned map includes all files in the set, keyed b name. The set must include the
-// full set of transitive dependencies for all files therein or else a link error will occur
-// and be returned instead of the slice of descriptors. This is the same format used by
-// protoc when a FileDescriptorSet file with an invocation like so:
-//    protoc --descriptor_set_out=./test.protoset --include_imports -I. test.proto
-func CreateFileDescriptorsFromSet(fds *dpb.FileDescriptorSet) (map[string]*FileDescriptor, error) {
-	return createFileDescriptorsFromSet(fds, nil)
-}
-
-func createFileDescriptorsFromSet(fds *dpb.FileDescriptorSet, r *ImportResolver) (map[string]*FileDescriptor, error) {
-	files := fds.GetFile()
-	if len(files) == 0 {
-		return nil, errors.New("file descriptor set is empty")
-	}
-	return createFileDescriptors(files, r)
-}
-
-// createFromSet creates a descriptor for the given filename. It recursively
-// creates descriptors for the given file's dependencies.
-func createFromSet(filename string, r *ImportResolver, seen []string, files map[string]*dpb.FileDescriptorProto, resolved map[string]*FileDescriptor) (*FileDescriptor, error) {
-	for _, s := range seen {
-		if filename == s {
-			return nil, fmt.Errorf("cycle in imports: %s", strings.Join(append(seen, filename), " -> "))
-		}
-	}
-	seen = append(seen, filename)
-
-	if d, ok := resolved[filename]; ok {
-		return d, nil
-	}
-	fdp := files[filename]
-	if fdp == nil {
-		return nil, intn.ErrNoSuchFile(filename)
-	}
-	deps := make([]*FileDescriptor, len(fdp.GetDependency()))
-	for i, depName := range fdp.GetDependency() {
-		resolvedDep := r.ResolveImport(filename, depName)
-		dep, err := createFromSet(resolvedDep, r, seen, files, resolved)
-		if _, ok := err.(intn.ErrNoSuchFile); ok && resolvedDep != depName {
-			dep, err = createFromSet(depName, r, seen, files, resolved)
-		}
-		if err != nil {
-			return nil, err
-		}
-		deps[i] = dep
-	}
-	d, err := createFileDescriptor(fdp, deps, r)
-	if err != nil {
-		return nil, err
-	}
-	resolved[filename] = d
-	return d, nil
-}
diff --git a/vendor/github.com/jhump/protoreflect/desc/descriptor.go b/vendor/github.com/jhump/protoreflect/desc/descriptor.go
deleted file mode 100644
index ab235a3..0000000
--- a/vendor/github.com/jhump/protoreflect/desc/descriptor.go
+++ /dev/null
@@ -1,1666 +0,0 @@
-package desc
-
-import (
-	"bytes"
-	"fmt"
-	"sort"
-	"strconv"
-	"strings"
-	"unicode/utf8"
-
-	"github.com/golang/protobuf/proto"
-	dpb "github.com/golang/protobuf/protoc-gen-go/descriptor"
-
-	"github.com/jhump/protoreflect/desc/internal"
-)
-
-// Descriptor is the common interface implemented by all descriptor objects.
-type Descriptor interface {
-	// GetName returns the name of the object described by the descriptor. This will
-	// be a base name that does not include enclosing message names or the package name.
-	// For file descriptors, this indicates the path and name to the described file.
-	GetName() string
-	// GetFullyQualifiedName returns the fully-qualified name of the object described by
-	// the descriptor. This will include the package name and any enclosing message names.
-	// For file descriptors, this returns the path and name to the described file (same as
-	// GetName).
-	GetFullyQualifiedName() string
-	// GetParent returns the enclosing element in a proto source file. If the described
-	// object is a top-level object, this returns the file descriptor. Otherwise, it returns
-	// the element in which the described object was declared. File descriptors have no
-	// parent and return nil.
-	GetParent() Descriptor
-	// GetFile returns the file descriptor in which this element was declared. File
-	// descriptors return themselves.
-	GetFile() *FileDescriptor
-	// GetOptions returns the options proto containing options for the described element.
-	GetOptions() proto.Message
-	// GetSourceInfo returns any source code information that was present in the file
-	// descriptor. Source code info is optional. If no source code info is available for
-	// the element (including if there is none at all in the file descriptor) then this
-	// returns nil
-	GetSourceInfo() *dpb.SourceCodeInfo_Location
-	// AsProto returns the underlying descriptor proto for this descriptor.
-	AsProto() proto.Message
-}
-
-type sourceInfoRecomputeFunc = internal.SourceInfoComputeFunc
-
-// FileDescriptor describes a proto source file.
-type FileDescriptor struct {
-	proto      *dpb.FileDescriptorProto
-	symbols    map[string]Descriptor
-	deps       []*FileDescriptor
-	publicDeps []*FileDescriptor
-	weakDeps   []*FileDescriptor
-	messages   []*MessageDescriptor
-	enums      []*EnumDescriptor
-	extensions []*FieldDescriptor
-	services   []*ServiceDescriptor
-	fieldIndex map[string]map[int32]*FieldDescriptor
-	isProto3   bool
-	sourceInfo internal.SourceInfoMap
-	sourceInfoRecomputeFunc
-}
-
-func (fd *FileDescriptor) recomputeSourceInfo() {
-	internal.PopulateSourceInfoMap(fd.proto, fd.sourceInfo)
-}
-
-func (fd *FileDescriptor) registerField(field *FieldDescriptor) {
-	fields := fd.fieldIndex[field.owner.GetFullyQualifiedName()]
-	if fields == nil {
-		fields = map[int32]*FieldDescriptor{}
-		fd.fieldIndex[field.owner.GetFullyQualifiedName()] = fields
-	}
-	fields[field.GetNumber()] = field
-}
-
-// GetName returns the name of the file, as it was given to the protoc invocation
-// to compile it, possibly including path (relative to a directory in the proto
-// import path).
-func (fd *FileDescriptor) GetName() string {
-	return fd.proto.GetName()
-}
-
-// GetFullyQualifiedName returns the name of the file, same as GetName. It is
-// present to satisfy the Descriptor interface.
-func (fd *FileDescriptor) GetFullyQualifiedName() string {
-	return fd.proto.GetName()
-}
-
-// GetPackage returns the name of the package declared in the file.
-func (fd *FileDescriptor) GetPackage() string {
-	return fd.proto.GetPackage()
-}
-
-// GetParent always returns nil: files are the root of descriptor hierarchies.
-// Is it present to satisfy the Descriptor interface.
-func (fd *FileDescriptor) GetParent() Descriptor {
-	return nil
-}
-
-// GetFile returns the receiver, which is a file descriptor. This is present
-// to satisfy the Descriptor interface.
-func (fd *FileDescriptor) GetFile() *FileDescriptor {
-	return fd
-}
-
-// GetOptions returns the file's options. Most usages will be more interested
-// in GetFileOptions, which has a concrete return type. This generic version
-// is present to satisfy the Descriptor interface.
-func (fd *FileDescriptor) GetOptions() proto.Message {
-	return fd.proto.GetOptions()
-}
-
-// GetFileOptions returns the file's options.
-func (fd *FileDescriptor) GetFileOptions() *dpb.FileOptions {
-	return fd.proto.GetOptions()
-}
-
-// GetSourceInfo returns nil for files. It is present to satisfy the Descriptor
-// interface.
-func (fd *FileDescriptor) GetSourceInfo() *dpb.SourceCodeInfo_Location {
-	return nil
-}
-
-// AsProto returns the underlying descriptor proto. Most usages will be more
-// interested in AsFileDescriptorProto, which has a concrete return type. This
-// generic version is present to satisfy the Descriptor interface.
-func (fd *FileDescriptor) AsProto() proto.Message {
-	return fd.proto
-}
-
-// AsFileDescriptorProto returns the underlying descriptor proto.
-func (fd *FileDescriptor) AsFileDescriptorProto() *dpb.FileDescriptorProto {
-	return fd.proto
-}
-
-// String returns the underlying descriptor proto, in compact text format.
-func (fd *FileDescriptor) String() string {
-	return fd.proto.String()
-}
-
-// IsProto3 returns true if the file declares a syntax of "proto3".
-func (fd *FileDescriptor) IsProto3() bool {
-	return fd.isProto3
-}
-
-// GetDependencies returns all of this file's dependencies. These correspond to
-// import statements in the file.
-func (fd *FileDescriptor) GetDependencies() []*FileDescriptor {
-	return fd.deps
-}
-
-// GetPublicDependencies returns all of this file's public dependencies. These
-// correspond to public import statements in the file.
-func (fd *FileDescriptor) GetPublicDependencies() []*FileDescriptor {
-	return fd.publicDeps
-}
-
-// GetWeakDependencies returns all of this file's weak dependencies. These
-// correspond to weak import statements in the file.
-func (fd *FileDescriptor) GetWeakDependencies() []*FileDescriptor {
-	return fd.weakDeps
-}
-
-// GetMessageTypes returns all top-level messages declared in this file.
-func (fd *FileDescriptor) GetMessageTypes() []*MessageDescriptor {
-	return fd.messages
-}
-
-// GetEnumTypes returns all top-level enums declared in this file.
-func (fd *FileDescriptor) GetEnumTypes() []*EnumDescriptor {
-	return fd.enums
-}
-
-// GetExtensions returns all top-level extensions declared in this file.
-func (fd *FileDescriptor) GetExtensions() []*FieldDescriptor {
-	return fd.extensions
-}
-
-// GetServices returns all services declared in this file.
-func (fd *FileDescriptor) GetServices() []*ServiceDescriptor {
-	return fd.services
-}
-
-// FindSymbol returns the descriptor contained within this file for the
-// element with the given fully-qualified symbol name. If no such element
-// exists then this method returns nil.
-func (fd *FileDescriptor) FindSymbol(symbol string) Descriptor {
-	if symbol[0] == '.' {
-		symbol = symbol[1:]
-	}
-	return fd.symbols[symbol]
-}
-
-// FindMessage finds the message with the given fully-qualified name. If no
-// such element exists in this file then nil is returned.
-func (fd *FileDescriptor) FindMessage(msgName string) *MessageDescriptor {
-	if md, ok := fd.symbols[msgName].(*MessageDescriptor); ok {
-		return md
-	} else {
-		return nil
-	}
-}
-
-// FindEnum finds the enum with the given fully-qualified name. If no such
-// element exists in this file then nil is returned.
-func (fd *FileDescriptor) FindEnum(enumName string) *EnumDescriptor {
-	if ed, ok := fd.symbols[enumName].(*EnumDescriptor); ok {
-		return ed
-	} else {
-		return nil
-	}
-}
-
-// FindService finds the service with the given fully-qualified name. If no
-// such element exists in this file then nil is returned.
-func (fd *FileDescriptor) FindService(serviceName string) *ServiceDescriptor {
-	if sd, ok := fd.symbols[serviceName].(*ServiceDescriptor); ok {
-		return sd
-	} else {
-		return nil
-	}
-}
-
-// FindExtension finds the extension field for the given extended type name and
-// tag number. If no such element exists in this file then nil is returned.
-func (fd *FileDescriptor) FindExtension(extendeeName string, tagNumber int32) *FieldDescriptor {
-	if exd, ok := fd.fieldIndex[extendeeName][tagNumber]; ok && exd.IsExtension() {
-		return exd
-	} else {
-		return nil
-	}
-}
-
-// FindExtensionByName finds the extension field with the given fully-qualified
-// name. If no such element exists in this file then nil is returned.
-func (fd *FileDescriptor) FindExtensionByName(extName string) *FieldDescriptor {
-	if exd, ok := fd.symbols[extName].(*FieldDescriptor); ok && exd.IsExtension() {
-		return exd
-	} else {
-		return nil
-	}
-}
-
-// MessageDescriptor describes a protocol buffer message.
-type MessageDescriptor struct {
-	proto          *dpb.DescriptorProto
-	parent         Descriptor
-	file           *FileDescriptor
-	fields         []*FieldDescriptor
-	nested         []*MessageDescriptor
-	enums          []*EnumDescriptor
-	extensions     []*FieldDescriptor
-	oneOfs         []*OneOfDescriptor
-	extRanges      extRanges
-	fqn            string
-	sourceInfoPath []int32
-	jsonNames      jsonNameMap
-	isProto3       bool
-	isMapEntry     bool
-}
-
-func createMessageDescriptor(fd *FileDescriptor, parent Descriptor, enclosing string, md *dpb.DescriptorProto, symbols map[string]Descriptor) (*MessageDescriptor, string) {
-	msgName := merge(enclosing, md.GetName())
-	ret := &MessageDescriptor{proto: md, parent: parent, file: fd, fqn: msgName}
-	for _, f := range md.GetField() {
-		fld, n := createFieldDescriptor(fd, ret, msgName, f)
-		symbols[n] = fld
-		ret.fields = append(ret.fields, fld)
-	}
-	for _, nm := range md.NestedType {
-		nmd, n := createMessageDescriptor(fd, ret, msgName, nm, symbols)
-		symbols[n] = nmd
-		ret.nested = append(ret.nested, nmd)
-	}
-	for _, e := range md.EnumType {
-		ed, n := createEnumDescriptor(fd, ret, msgName, e, symbols)
-		symbols[n] = ed
-		ret.enums = append(ret.enums, ed)
-	}
-	for _, ex := range md.GetExtension() {
-		exd, n := createFieldDescriptor(fd, ret, msgName, ex)
-		symbols[n] = exd
-		ret.extensions = append(ret.extensions, exd)
-	}
-	for i, o := range md.GetOneofDecl() {
-		od, n := createOneOfDescriptor(fd, ret, i, msgName, o)
-		symbols[n] = od
-		ret.oneOfs = append(ret.oneOfs, od)
-	}
-	for _, r := range md.GetExtensionRange() {
-		// proto.ExtensionRange is inclusive (and that's how extension ranges are defined in code).
-		// but protoc converts range to exclusive end in descriptor, so we must convert back
-		end := r.GetEnd() - 1
-		ret.extRanges = append(ret.extRanges, proto.ExtensionRange{
-			Start: r.GetStart(),
-			End:   end})
-	}
-	sort.Sort(ret.extRanges)
-	ret.isProto3 = fd.isProto3
-	ret.isMapEntry = md.GetOptions().GetMapEntry() &&
-		len(ret.fields) == 2 &&
-		ret.fields[0].GetNumber() == 1 &&
-		ret.fields[1].GetNumber() == 2
-
-	return ret, msgName
-}
-
-func (md *MessageDescriptor) resolve(path []int32, scopes []scope) error {
-	md.sourceInfoPath = append([]int32(nil), path...) // defensive copy
-	path = append(path, internal.Message_nestedMessagesTag)
-	scopes = append(scopes, messageScope(md))
-	for i, nmd := range md.nested {
-		if err := nmd.resolve(append(path, int32(i)), scopes); err != nil {
-			return err
-		}
-	}
-	path[len(path)-1] = internal.Message_enumsTag
-	for i, ed := range md.enums {
-		ed.resolve(append(path, int32(i)))
-	}
-	path[len(path)-1] = internal.Message_fieldsTag
-	for i, fld := range md.fields {
-		if err := fld.resolve(append(path, int32(i)), scopes); err != nil {
-			return err
-		}
-	}
-	path[len(path)-1] = internal.Message_extensionsTag
-	for i, exd := range md.extensions {
-		if err := exd.resolve(append(path, int32(i)), scopes); err != nil {
-			return err
-		}
-	}
-	path[len(path)-1] = internal.Message_oneOfsTag
-	for i, od := range md.oneOfs {
-		od.resolve(append(path, int32(i)))
-	}
-	return nil
-}
-
-// GetName returns the simple (unqualified) name of the message.
-func (md *MessageDescriptor) GetName() string {
-	return md.proto.GetName()
-}
-
-// GetFullyQualifiedName returns the fully qualified name of the message. This
-// includes the package name (if there is one) as well as the names of any
-// enclosing messages.
-func (md *MessageDescriptor) GetFullyQualifiedName() string {
-	return md.fqn
-}
-
-// GetParent returns the message's enclosing descriptor. For top-level messages,
-// this will be a file descriptor. Otherwise it will be the descriptor for the
-// enclosing message.
-func (md *MessageDescriptor) GetParent() Descriptor {
-	return md.parent
-}
-
-// GetFile returns the descriptor for the file in which this message is defined.
-func (md *MessageDescriptor) GetFile() *FileDescriptor {
-	return md.file
-}
-
-// GetOptions returns the message's options. Most usages will be more interested
-// in GetMessageOptions, which has a concrete return type. This generic version
-// is present to satisfy the Descriptor interface.
-func (md *MessageDescriptor) GetOptions() proto.Message {
-	return md.proto.GetOptions()
-}
-
-// GetMessageOptions returns the message's options.
-func (md *MessageDescriptor) GetMessageOptions() *dpb.MessageOptions {
-	return md.proto.GetOptions()
-}
-
-// GetSourceInfo returns source info for the message, if present in the
-// descriptor. Not all descriptors will contain source info. If non-nil, the
-// returned info contains information about the location in the file where the
-// message was defined and also contains comments associated with the message
-// definition.
-func (md *MessageDescriptor) GetSourceInfo() *dpb.SourceCodeInfo_Location {
-	return md.file.sourceInfo.Get(md.sourceInfoPath)
-}
-
-// AsProto returns the underlying descriptor proto. Most usages will be more
-// interested in AsDescriptorProto, which has a concrete return type. This
-// generic version is present to satisfy the Descriptor interface.
-func (md *MessageDescriptor) AsProto() proto.Message {
-	return md.proto
-}
-
-// AsDescriptorProto returns the underlying descriptor proto.
-func (md *MessageDescriptor) AsDescriptorProto() *dpb.DescriptorProto {
-	return md.proto
-}
-
-// String returns the underlying descriptor proto, in compact text format.
-func (md *MessageDescriptor) String() string {
-	return md.proto.String()
-}
-
-// IsMapEntry returns true if this is a synthetic message type that represents an entry
-// in a map field.
-func (md *MessageDescriptor) IsMapEntry() bool {
-	return md.isMapEntry
-}
-
-// GetFields returns all of the fields for this message.
-func (md *MessageDescriptor) GetFields() []*FieldDescriptor {
-	return md.fields
-}
-
-// GetNestedMessageTypes returns all of the message types declared inside this message.
-func (md *MessageDescriptor) GetNestedMessageTypes() []*MessageDescriptor {
-	return md.nested
-}
-
-// GetNestedEnumTypes returns all of the enums declared inside this message.
-func (md *MessageDescriptor) GetNestedEnumTypes() []*EnumDescriptor {
-	return md.enums
-}
-
-// GetNestedExtensions returns all of the extensions declared inside this message.
-func (md *MessageDescriptor) GetNestedExtensions() []*FieldDescriptor {
-	return md.extensions
-}
-
-// GetOneOfs returns all of the one-of field sets declared inside this message.
-func (md *MessageDescriptor) GetOneOfs() []*OneOfDescriptor {
-	return md.oneOfs
-}
-
-// IsProto3 returns true if the file in which this message is defined declares a syntax of "proto3".
-func (md *MessageDescriptor) IsProto3() bool {
-	return md.isProto3
-}
-
-// GetExtensionRanges returns the ranges of extension field numbers for this message.
-func (md *MessageDescriptor) GetExtensionRanges() []proto.ExtensionRange {
-	return md.extRanges
-}
-
-// IsExtendable returns true if this message has any extension ranges.
-func (md *MessageDescriptor) IsExtendable() bool {
-	return len(md.extRanges) > 0
-}
-
-// IsExtension returns true if the given tag number is within any of this message's
-// extension ranges.
-func (md *MessageDescriptor) IsExtension(tagNumber int32) bool {
-	return md.extRanges.IsExtension(tagNumber)
-}
-
-type extRanges []proto.ExtensionRange
-
-func (er extRanges) String() string {
-	var buf bytes.Buffer
-	first := true
-	for _, r := range er {
-		if first {
-			first = false
-		} else {
-			buf.WriteString(",")
-		}
-		fmt.Fprintf(&buf, "%d..%d", r.Start, r.End)
-	}
-	return buf.String()
-}
-
-func (er extRanges) IsExtension(tagNumber int32) bool {
-	i := sort.Search(len(er), func(i int) bool { return er[i].End >= tagNumber })
-	return i < len(er) && tagNumber >= er[i].Start
-}
-
-func (er extRanges) Len() int {
-	return len(er)
-}
-
-func (er extRanges) Less(i, j int) bool {
-	return er[i].Start < er[j].Start
-}
-
-func (er extRanges) Swap(i, j int) {
-	er[i], er[j] = er[j], er[i]
-}
-
-// FindFieldByName finds the field with the given name. If no such field exists
-// then nil is returned. Only regular fields are returned, not extensions.
-func (md *MessageDescriptor) FindFieldByName(fieldName string) *FieldDescriptor {
-	fqn := fmt.Sprintf("%s.%s", md.fqn, fieldName)
-	if fd, ok := md.file.symbols[fqn].(*FieldDescriptor); ok && !fd.IsExtension() {
-		return fd
-	} else {
-		return nil
-	}
-}
-
-// FindFieldByNumber finds the field with the given tag number. If no such field
-// exists then nil is returned. Only regular fields are returned, not extensions.
-func (md *MessageDescriptor) FindFieldByNumber(tagNumber int32) *FieldDescriptor {
-	if fd, ok := md.file.fieldIndex[md.fqn][tagNumber]; ok && !fd.IsExtension() {
-		return fd
-	} else {
-		return nil
-	}
-}
-
-// FieldDescriptor describes a field of a protocol buffer message.
-type FieldDescriptor struct {
-	proto          *dpb.FieldDescriptorProto
-	parent         Descriptor
-	owner          *MessageDescriptor
-	file           *FileDescriptor
-	oneOf          *OneOfDescriptor
-	msgType        *MessageDescriptor
-	enumType       *EnumDescriptor
-	fqn            string
-	sourceInfoPath []int32
-	def            memoizedDefault
-	isMap          bool
-}
-
-func createFieldDescriptor(fd *FileDescriptor, parent Descriptor, enclosing string, fld *dpb.FieldDescriptorProto) (*FieldDescriptor, string) {
-	fldName := merge(enclosing, fld.GetName())
-	ret := &FieldDescriptor{proto: fld, parent: parent, file: fd, fqn: fldName}
-	if fld.GetExtendee() == "" {
-		ret.owner = parent.(*MessageDescriptor)
-	}
-	// owner for extensions, field type (be it message or enum), and one-ofs get resolved later
-	return ret, fldName
-}
-
-func (fd *FieldDescriptor) resolve(path []int32, scopes []scope) error {
-	if fd.proto.OneofIndex != nil && fd.oneOf == nil {
-		return fmt.Errorf("could not link field %s to one-of index %d", fd.fqn, *fd.proto.OneofIndex)
-	}
-	fd.sourceInfoPath = append([]int32(nil), path...) // defensive copy
-	if fd.proto.GetType() == dpb.FieldDescriptorProto_TYPE_ENUM {
-		if desc, err := resolve(fd.file, fd.proto.GetTypeName(), scopes); err != nil {
-			return err
-		} else {
-			fd.enumType = desc.(*EnumDescriptor)
-		}
-	}
-	if fd.proto.GetType() == dpb.FieldDescriptorProto_TYPE_MESSAGE || fd.proto.GetType() == dpb.FieldDescriptorProto_TYPE_GROUP {
-		if desc, err := resolve(fd.file, fd.proto.GetTypeName(), scopes); err != nil {
-			return err
-		} else {
-			fd.msgType = desc.(*MessageDescriptor)
-		}
-	}
-	if fd.proto.GetExtendee() != "" {
-		if desc, err := resolve(fd.file, fd.proto.GetExtendee(), scopes); err != nil {
-			return err
-		} else {
-			fd.owner = desc.(*MessageDescriptor)
-		}
-	}
-	fd.file.registerField(fd)
-	fd.isMap = fd.proto.GetLabel() == dpb.FieldDescriptorProto_LABEL_REPEATED &&
-		fd.proto.GetType() == dpb.FieldDescriptorProto_TYPE_MESSAGE &&
-		fd.GetMessageType().IsMapEntry()
-	return nil
-}
-
-func (fd *FieldDescriptor) determineDefault() interface{} {
-	if fd.IsMap() {
-		return map[interface{}]interface{}(nil)
-	} else if fd.IsRepeated() {
-		return []interface{}(nil)
-	} else if fd.msgType != nil {
-		return nil
-	}
-
-	proto3 := fd.file.isProto3
-	if !proto3 {
-		def := fd.AsFieldDescriptorProto().GetDefaultValue()
-		if def != "" {
-			ret := parseDefaultValue(fd, def)
-			if ret != nil {
-				return ret
-			}
-			// if we can't parse default value, fall-through to return normal default...
-		}
-	}
-
-	switch fd.GetType() {
-	case dpb.FieldDescriptorProto_TYPE_FIXED32,
-		dpb.FieldDescriptorProto_TYPE_UINT32:
-		return uint32(0)
-	case dpb.FieldDescriptorProto_TYPE_SFIXED32,
-		dpb.FieldDescriptorProto_TYPE_INT32,
-		dpb.FieldDescriptorProto_TYPE_SINT32:
-		return int32(0)
-	case dpb.FieldDescriptorProto_TYPE_FIXED64,
-		dpb.FieldDescriptorProto_TYPE_UINT64:
-		return uint64(0)
-	case dpb.FieldDescriptorProto_TYPE_SFIXED64,
-		dpb.FieldDescriptorProto_TYPE_INT64,
-		dpb.FieldDescriptorProto_TYPE_SINT64:
-		return int64(0)
-	case dpb.FieldDescriptorProto_TYPE_FLOAT:
-		return float32(0.0)
-	case dpb.FieldDescriptorProto_TYPE_DOUBLE:
-		return float64(0.0)
-	case dpb.FieldDescriptorProto_TYPE_BOOL:
-		return false
-	case dpb.FieldDescriptorProto_TYPE_BYTES:
-		return []byte(nil)
-	case dpb.FieldDescriptorProto_TYPE_STRING:
-		return ""
-	case dpb.FieldDescriptorProto_TYPE_ENUM:
-		if proto3 {
-			return int32(0)
-		}
-		enumVals := fd.GetEnumType().GetValues()
-		if len(enumVals) > 0 {
-			return enumVals[0].GetNumber()
-		} else {
-			return int32(0) // WTF?
-		}
-	default:
-		panic(fmt.Sprintf("Unknown field type: %v", fd.GetType()))
-	}
-}
-
-func parseDefaultValue(fd *FieldDescriptor, val string) interface{} {
-	switch fd.GetType() {
-	case dpb.FieldDescriptorProto_TYPE_ENUM:
-		vd := fd.GetEnumType().FindValueByName(val)
-		if vd != nil {
-			return vd.GetNumber()
-		}
-		return nil
-	case dpb.FieldDescriptorProto_TYPE_BOOL:
-		if val == "true" {
-			return true
-		} else if val == "false" {
-			return false
-		}
-		return nil
-	case dpb.FieldDescriptorProto_TYPE_BYTES:
-		return []byte(unescape(val))
-	case dpb.FieldDescriptorProto_TYPE_STRING:
-		return val
-	case dpb.FieldDescriptorProto_TYPE_FLOAT:
-		if f, err := strconv.ParseFloat(val, 32); err == nil {
-			return float32(f)
-		} else {
-			return float32(0)
-		}
-	case dpb.FieldDescriptorProto_TYPE_DOUBLE:
-		if f, err := strconv.ParseFloat(val, 64); err == nil {
-			return f
-		} else {
-			return float64(0)
-		}
-	case dpb.FieldDescriptorProto_TYPE_INT32,
-		dpb.FieldDescriptorProto_TYPE_SINT32,
-		dpb.FieldDescriptorProto_TYPE_SFIXED32:
-		if i, err := strconv.ParseInt(val, 10, 32); err == nil {
-			return int32(i)
-		} else {
-			return int32(0)
-		}
-	case dpb.FieldDescriptorProto_TYPE_UINT32,
-		dpb.FieldDescriptorProto_TYPE_FIXED32:
-		if i, err := strconv.ParseUint(val, 10, 32); err == nil {
-			return uint32(i)
-		} else {
-			return uint32(0)
-		}
-	case dpb.FieldDescriptorProto_TYPE_INT64,
-		dpb.FieldDescriptorProto_TYPE_SINT64,
-		dpb.FieldDescriptorProto_TYPE_SFIXED64:
-		if i, err := strconv.ParseInt(val, 10, 64); err == nil {
-			return i
-		} else {
-			return int64(0)
-		}
-	case dpb.FieldDescriptorProto_TYPE_UINT64,
-		dpb.FieldDescriptorProto_TYPE_FIXED64:
-		if i, err := strconv.ParseUint(val, 10, 64); err == nil {
-			return i
-		} else {
-			return uint64(0)
-		}
-	default:
-		return nil
-	}
-}
-
-func unescape(s string) string {
-	// protoc encodes default values for 'bytes' fields using C escaping,
-	// so this function reverses that escaping
-	out := make([]byte, 0, len(s))
-	var buf [4]byte
-	for len(s) > 0 {
-		if s[0] != '\\' || len(s) < 2 {
-			// not escape sequence, or too short to be well-formed escape
-			out = append(out, s[0])
-			s = s[1:]
-		} else if s[1] == 'x' || s[1] == 'X' {
-			n := matchPrefix(s[2:], 2, isHex)
-			if n == 0 {
-				// bad escape
-				out = append(out, s[:2]...)
-				s = s[2:]
-			} else {
-				c, err := strconv.ParseUint(s[2:2+n], 16, 8)
-				if err != nil {
-					// shouldn't really happen...
-					out = append(out, s[:2+n]...)
-				} else {
-					out = append(out, byte(c))
-				}
-				s = s[2+n:]
-			}
-		} else if s[1] >= '0' && s[1] <= '7' {
-			n := 1 + matchPrefix(s[2:], 2, isOctal)
-			c, err := strconv.ParseUint(s[1:1+n], 8, 8)
-			if err != nil || c > 0xff {
-				out = append(out, s[:1+n]...)
-			} else {
-				out = append(out, byte(c))
-			}
-			s = s[1+n:]
-		} else if s[1] == 'u' {
-			if len(s) < 6 {
-				// bad escape
-				out = append(out, s...)
-				s = s[len(s):]
-			} else {
-				c, err := strconv.ParseUint(s[2:6], 16, 16)
-				if err != nil {
-					// bad escape
-					out = append(out, s[:6]...)
-				} else {
-					w := utf8.EncodeRune(buf[:], rune(c))
-					out = append(out, buf[:w]...)
-				}
-				s = s[6:]
-			}
-		} else if s[1] == 'U' {
-			if len(s) < 10 {
-				// bad escape
-				out = append(out, s...)
-				s = s[len(s):]
-			} else {
-				c, err := strconv.ParseUint(s[2:10], 16, 32)
-				if err != nil || c > 0x10ffff {
-					// bad escape
-					out = append(out, s[:10]...)
-				} else {
-					w := utf8.EncodeRune(buf[:], rune(c))
-					out = append(out, buf[:w]...)
-				}
-				s = s[10:]
-			}
-		} else {
-			switch s[1] {
-			case 'a':
-				out = append(out, '\a')
-			case 'b':
-				out = append(out, '\b')
-			case 'f':
-				out = append(out, '\f')
-			case 'n':
-				out = append(out, '\n')
-			case 'r':
-				out = append(out, '\r')
-			case 't':
-				out = append(out, '\t')
-			case 'v':
-				out = append(out, '\v')
-			case '\\':
-				out = append(out, '\\')
-			case '\'':
-				out = append(out, '\'')
-			case '"':
-				out = append(out, '"')
-			case '?':
-				out = append(out, '?')
-			default:
-				// invalid escape, just copy it as-is
-				out = append(out, s[:2]...)
-			}
-			s = s[2:]
-		}
-	}
-	return string(out)
-}
-
-func isOctal(b byte) bool { return b >= '0' && b <= '7' }
-func isHex(b byte) bool {
-	return (b >= '0' && b <= '9') || (b >= 'a' && b <= 'f') || (b >= 'A' && b <= 'F')
-}
-func matchPrefix(s string, limit int, fn func(byte) bool) int {
-	l := len(s)
-	if l > limit {
-		l = limit
-	}
-	i := 0
-	for ; i < l; i++ {
-		if !fn(s[i]) {
-			return i
-		}
-	}
-	return i
-}
-
-// GetName returns the name of the field.
-func (fd *FieldDescriptor) GetName() string {
-	return fd.proto.GetName()
-}
-
-// GetNumber returns the tag number of this field.
-func (fd *FieldDescriptor) GetNumber() int32 {
-	return fd.proto.GetNumber()
-}
-
-// GetFullyQualifiedName returns the fully qualified name of the field. Unlike
-// GetName, this includes fully qualified name of the enclosing message for
-// regular fields.
-//
-// For extension fields, this includes the package (if there is one) as well as
-// any enclosing messages. The package and/or enclosing messages are for where
-// the extension is defined, not the message it extends.
-//
-// If this field is part of a one-of, the fully qualified name does *not*
-// include the name of the one-of, only of the enclosing message.
-func (fd *FieldDescriptor) GetFullyQualifiedName() string {
-	return fd.fqn
-}
-
-// GetParent returns the fields's enclosing descriptor. For normal
-// (non-extension) fields, this is the enclosing message. For extensions, this
-// is the descriptor in which the extension is defined, not the message that is
-// extended. The parent for an extension may be a file descriptor or a message,
-// depending on where the extension is defined.
-func (fd *FieldDescriptor) GetParent() Descriptor {
-	return fd.parent
-}
-
-// GetFile returns the descriptor for the file in which this field is defined.
-func (fd *FieldDescriptor) GetFile() *FileDescriptor {
-	return fd.file
-}
-
-// GetOptions returns the field's options. Most usages will be more interested
-// in GetFieldOptions, which has a concrete return type. This generic version
-// is present to satisfy the Descriptor interface.
-func (fd *FieldDescriptor) GetOptions() proto.Message {
-	return fd.proto.GetOptions()
-}
-
-// GetFieldOptions returns the field's options.
-func (fd *FieldDescriptor) GetFieldOptions() *dpb.FieldOptions {
-	return fd.proto.GetOptions()
-}
-
-// GetSourceInfo returns source info for the field, if present in the
-// descriptor. Not all descriptors will contain source info. If non-nil, the
-// returned info contains information about the location in the file where the
-// field was defined and also contains comments associated with the field
-// definition.
-func (fd *FieldDescriptor) GetSourceInfo() *dpb.SourceCodeInfo_Location {
-	return fd.file.sourceInfo.Get(fd.sourceInfoPath)
-}
-
-// AsProto returns the underlying descriptor proto. Most usages will be more
-// interested in AsFieldDescriptorProto, which has a concrete return type. This
-// generic version is present to satisfy the Descriptor interface.
-func (fd *FieldDescriptor) AsProto() proto.Message {
-	return fd.proto
-}
-
-// AsFieldDescriptorProto returns the underlying descriptor proto.
-func (fd *FieldDescriptor) AsFieldDescriptorProto() *dpb.FieldDescriptorProto {
-	return fd.proto
-}
-
-// String returns the underlying descriptor proto, in compact text format.
-func (fd *FieldDescriptor) String() string {
-	return fd.proto.String()
-}
-
-// GetJSONName returns the name of the field as referenced in the message's JSON
-// format.
-func (fd *FieldDescriptor) GetJSONName() string {
-	if jsonName := fd.proto.GetJsonName(); jsonName != "" {
-		return jsonName
-	}
-	return fd.proto.GetName()
-}
-
-// GetFullyQualifiedJSONName returns the JSON format name (same as GetJSONName),
-// but includes the fully qualified name of the enclosing message.
-//
-// If the field is an extension, it will return the package name (if there is
-// one) as well as the names of any enclosing messages. The package and/or
-// enclosing messages are for where the extension is defined, not the message it
-// extends.
-func (fd *FieldDescriptor) GetFullyQualifiedJSONName() string {
-	parent := fd.GetParent()
-	switch parent := parent.(type) {
-	case *FileDescriptor:
-		pkg := parent.GetPackage()
-		if pkg == "" {
-			return fd.GetJSONName()
-		}
-		return fmt.Sprintf("%s.%s", pkg, fd.GetJSONName())
-	default:
-		return fmt.Sprintf("%s.%s", parent.GetFullyQualifiedName(), fd.GetJSONName())
-	}
-}
-
-// GetOwner returns the message type that this field belongs to. If this is a normal
-// field then this is the same as GetParent. But for extensions, this will be the
-// extendee message whereas GetParent refers to where the extension was declared.
-func (fd *FieldDescriptor) GetOwner() *MessageDescriptor {
-	return fd.owner
-}
-
-// IsExtension returns true if this is an extension field.
-func (fd *FieldDescriptor) IsExtension() bool {
-	return fd.proto.GetExtendee() != ""
-}
-
-// GetOneOf returns the one-of field set to which this field belongs. If this field
-// is not part of a one-of then this method returns nil.
-func (fd *FieldDescriptor) GetOneOf() *OneOfDescriptor {
-	return fd.oneOf
-}
-
-// GetType returns the type of this field. If the type indicates an enum, the
-// enum type can be queried via GetEnumType. If the type indicates a message, the
-// message type can be queried via GetMessageType.
-func (fd *FieldDescriptor) GetType() dpb.FieldDescriptorProto_Type {
-	return fd.proto.GetType()
-}
-
-// GetLabel returns the label for this field. The label can be required (proto2-only),
-// optional (default for proto3), or required.
-func (fd *FieldDescriptor) GetLabel() dpb.FieldDescriptorProto_Label {
-	return fd.proto.GetLabel()
-}
-
-// IsRequired returns true if this field has the "required" label.
-func (fd *FieldDescriptor) IsRequired() bool {
-	return fd.proto.GetLabel() == dpb.FieldDescriptorProto_LABEL_REQUIRED
-}
-
-// IsRepeated returns true if this field has the "repeated" label.
-func (fd *FieldDescriptor) IsRepeated() bool {
-	return fd.proto.GetLabel() == dpb.FieldDescriptorProto_LABEL_REPEATED
-}
-
-// IsMap returns true if this is a map field. If so, it will have the "repeated"
-// label its type will be a message that represents a map entry. The map entry
-// message will have exactly two fields: tag #1 is the key and tag #2 is the value.
-func (fd *FieldDescriptor) IsMap() bool {
-	return fd.isMap
-}
-
-// GetMapKeyType returns the type of the key field if this is a map field. If it is
-// not a map field, nil is returned.
-func (fd *FieldDescriptor) GetMapKeyType() *FieldDescriptor {
-	if fd.isMap {
-		return fd.msgType.FindFieldByNumber(int32(1))
-	}
-	return nil
-}
-
-// GetMapValueType returns the type of the value field if this is a map field. If it
-// is not a map field, nil is returned.
-func (fd *FieldDescriptor) GetMapValueType() *FieldDescriptor {
-	if fd.isMap {
-		return fd.msgType.FindFieldByNumber(int32(2))
-	}
-	return nil
-}
-
-// GetMessageType returns the type of this field if it is a message type. If
-// this field is not a message type, it returns nil.
-func (fd *FieldDescriptor) GetMessageType() *MessageDescriptor {
-	return fd.msgType
-}
-
-// GetEnumType returns the type of this field if it is an enum type. If this
-// field is not an enum type, it returns nil.
-func (fd *FieldDescriptor) GetEnumType() *EnumDescriptor {
-	return fd.enumType
-}
-
-// GetDefaultValue returns the default value for this field.
-//
-// If this field represents a message type, this method always returns nil (even though
-// for proto2 files, the default value should be a default instance of the message type).
-// If the field represents an enum type, this method returns an int32 corresponding to the
-// enum value. If this field is a map, it returns a nil map[interface{}]interface{}. If
-// this field is repeated (and not a map), it returns a nil []interface{}.
-//
-// Otherwise, it returns the declared default value for the field or a zero value, if no
-// default is declared or if the file is proto3. The type of said return value corresponds
-// to the type of the field:
-//  +-------------------------+-----------+
-//  |       Declared Type     |  Go Type  |
-//  +-------------------------+-----------+
-//  | int32, sint32, sfixed32 | int32     |
-//  | int64, sint64, sfixed64 | int64     |
-//  | uint32, fixed32         | uint32    |
-//  | uint64, fixed64         | uint64    |
-//  | float                   | float32   |
-//  | double                  | double32  |
-//  | bool                    | bool      |
-//  | string                  | string    |
-//  | bytes                   | []byte    |
-//  +-------------------------+-----------+
-func (fd *FieldDescriptor) GetDefaultValue() interface{} {
-	return fd.getDefaultValue()
-}
-
-// EnumDescriptor describes an enum declared in a proto file.
-type EnumDescriptor struct {
-	proto          *dpb.EnumDescriptorProto
-	parent         Descriptor
-	file           *FileDescriptor
-	values         []*EnumValueDescriptor
-	valuesByNum    sortedValues
-	fqn            string
-	sourceInfoPath []int32
-}
-
-func createEnumDescriptor(fd *FileDescriptor, parent Descriptor, enclosing string, ed *dpb.EnumDescriptorProto, symbols map[string]Descriptor) (*EnumDescriptor, string) {
-	enumName := merge(enclosing, ed.GetName())
-	ret := &EnumDescriptor{proto: ed, parent: parent, file: fd, fqn: enumName}
-	for _, ev := range ed.GetValue() {
-		evd, n := createEnumValueDescriptor(fd, ret, enumName, ev)
-		symbols[n] = evd
-		ret.values = append(ret.values, evd)
-	}
-	if len(ret.values) > 0 {
-		ret.valuesByNum = make(sortedValues, len(ret.values))
-		copy(ret.valuesByNum, ret.values)
-		sort.Stable(ret.valuesByNum)
-	}
-	return ret, enumName
-}
-
-type sortedValues []*EnumValueDescriptor
-
-func (sv sortedValues) Len() int {
-	return len(sv)
-}
-
-func (sv sortedValues) Less(i, j int) bool {
-	return sv[i].GetNumber() < sv[j].GetNumber()
-}
-
-func (sv sortedValues) Swap(i, j int) {
-	sv[i], sv[j] = sv[j], sv[i]
-}
-
-func (ed *EnumDescriptor) resolve(path []int32) {
-	ed.sourceInfoPath = append([]int32(nil), path...) // defensive copy
-	path = append(path, internal.Enum_valuesTag)
-	for i, evd := range ed.values {
-		evd.resolve(append(path, int32(i)))
-	}
-}
-
-// GetName returns the simple (unqualified) name of the enum type.
-func (ed *EnumDescriptor) GetName() string {
-	return ed.proto.GetName()
-}
-
-// GetFullyQualifiedName returns the fully qualified name of the enum type.
-// This includes the package name (if there is one) as well as the names of any
-// enclosing messages.
-func (ed *EnumDescriptor) GetFullyQualifiedName() string {
-	return ed.fqn
-}
-
-// GetParent returns the enum type's enclosing descriptor. For top-level enums,
-// this will be a file descriptor. Otherwise it will be the descriptor for the
-// enclosing message.
-func (ed *EnumDescriptor) GetParent() Descriptor {
-	return ed.parent
-}
-
-// GetFile returns the descriptor for the file in which this enum is defined.
-func (ed *EnumDescriptor) GetFile() *FileDescriptor {
-	return ed.file
-}
-
-// GetOptions returns the enum type's options. Most usages will be more
-// interested in GetEnumOptions, which has a concrete return type. This generic
-// version is present to satisfy the Descriptor interface.
-func (ed *EnumDescriptor) GetOptions() proto.Message {
-	return ed.proto.GetOptions()
-}
-
-// GetEnumOptions returns the enum type's options.
-func (ed *EnumDescriptor) GetEnumOptions() *dpb.EnumOptions {
-	return ed.proto.GetOptions()
-}
-
-// GetSourceInfo returns source info for the enum type, if present in the
-// descriptor. Not all descriptors will contain source info. If non-nil, the
-// returned info contains information about the location in the file where the
-// enum type was defined and also contains comments associated with the enum
-// definition.
-func (ed *EnumDescriptor) GetSourceInfo() *dpb.SourceCodeInfo_Location {
-	return ed.file.sourceInfo.Get(ed.sourceInfoPath)
-}
-
-// AsProto returns the underlying descriptor proto. Most usages will be more
-// interested in AsEnumDescriptorProto, which has a concrete return type. This
-// generic version is present to satisfy the Descriptor interface.
-func (ed *EnumDescriptor) AsProto() proto.Message {
-	return ed.proto
-}
-
-// AsEnumDescriptorProto returns the underlying descriptor proto.
-func (ed *EnumDescriptor) AsEnumDescriptorProto() *dpb.EnumDescriptorProto {
-	return ed.proto
-}
-
-// String returns the underlying descriptor proto, in compact text format.
-func (ed *EnumDescriptor) String() string {
-	return ed.proto.String()
-}
-
-// GetValues returns all of the allowed values defined for this enum.
-func (ed *EnumDescriptor) GetValues() []*EnumValueDescriptor {
-	return ed.values
-}
-
-// FindValueByName finds the enum value with the given name. If no such value exists
-// then nil is returned.
-func (ed *EnumDescriptor) FindValueByName(name string) *EnumValueDescriptor {
-	fqn := fmt.Sprintf("%s.%s", ed.fqn, name)
-	if vd, ok := ed.file.symbols[fqn].(*EnumValueDescriptor); ok {
-		return vd
-	} else {
-		return nil
-	}
-}
-
-// FindValueByNumber finds the value with the given numeric value. If no such value
-// exists then nil is returned. If aliases are allowed and multiple values have the
-// given number, the first declared value is returned.
-func (ed *EnumDescriptor) FindValueByNumber(num int32) *EnumValueDescriptor {
-	index := sort.Search(len(ed.valuesByNum), func(i int) bool { return ed.valuesByNum[i].GetNumber() >= num })
-	if index < len(ed.valuesByNum) {
-		vd := ed.valuesByNum[index]
-		if vd.GetNumber() == num {
-			return vd
-		}
-	}
-	return nil
-}
-
-// EnumValueDescriptor describes an allowed value of an enum declared in a proto file.
-type EnumValueDescriptor struct {
-	proto          *dpb.EnumValueDescriptorProto
-	parent         *EnumDescriptor
-	file           *FileDescriptor
-	fqn            string
-	sourceInfoPath []int32
-}
-
-func createEnumValueDescriptor(fd *FileDescriptor, parent *EnumDescriptor, enclosing string, evd *dpb.EnumValueDescriptorProto) (*EnumValueDescriptor, string) {
-	valName := merge(enclosing, evd.GetName())
-	return &EnumValueDescriptor{proto: evd, parent: parent, file: fd, fqn: valName}, valName
-}
-
-func (vd *EnumValueDescriptor) resolve(path []int32) {
-	vd.sourceInfoPath = append([]int32(nil), path...) // defensive copy
-}
-
-// GetName returns the name of the enum value.
-func (vd *EnumValueDescriptor) GetName() string {
-	return vd.proto.GetName()
-}
-
-// GetNumber returns the numeric value associated with this enum value.
-func (vd *EnumValueDescriptor) GetNumber() int32 {
-	return vd.proto.GetNumber()
-}
-
-// GetFullyQualifiedName returns the fully qualified name of the enum value.
-// Unlike GetName, this includes fully qualified name of the enclosing enum.
-func (vd *EnumValueDescriptor) GetFullyQualifiedName() string {
-	return vd.fqn
-}
-
-// GetParent returns the descriptor for the enum in which this enum value is
-// defined. Most usages will prefer to use GetEnum, which has a concrete return
-// type. This more generic method is present to satisfy the Descriptor interface.
-func (vd *EnumValueDescriptor) GetParent() Descriptor {
-	return vd.parent
-}
-
-// GetEnum returns the enum in which this enum value is defined.
-func (vd *EnumValueDescriptor) GetEnum() *EnumDescriptor {
-	return vd.parent
-}
-
-// GetFile returns the descriptor for the file in which this enum value is
-// defined.
-func (vd *EnumValueDescriptor) GetFile() *FileDescriptor {
-	return vd.file
-}
-
-// GetOptions returns the enum value's options. Most usages will be more
-// interested in GetEnumValueOptions, which has a concrete return type. This
-// generic version is present to satisfy the Descriptor interface.
-func (vd *EnumValueDescriptor) GetOptions() proto.Message {
-	return vd.proto.GetOptions()
-}
-
-// GetEnumValueOptions returns the enum value's options.
-func (vd *EnumValueDescriptor) GetEnumValueOptions() *dpb.EnumValueOptions {
-	return vd.proto.GetOptions()
-}
-
-// GetSourceInfo returns source info for the enum value, if present in the
-// descriptor. Not all descriptors will contain source info. If non-nil, the
-// returned info contains information about the location in the file where the
-// enum value was defined and also contains comments associated with the enum
-// value definition.
-func (vd *EnumValueDescriptor) GetSourceInfo() *dpb.SourceCodeInfo_Location {
-	return vd.file.sourceInfo.Get(vd.sourceInfoPath)
-}
-
-// AsProto returns the underlying descriptor proto. Most usages will be more
-// interested in AsEnumValueDescriptorProto, which has a concrete return type.
-// This generic version is present to satisfy the Descriptor interface.
-func (vd *EnumValueDescriptor) AsProto() proto.Message {
-	return vd.proto
-}
-
-// AsEnumValueDescriptorProto returns the underlying descriptor proto.
-func (vd *EnumValueDescriptor) AsEnumValueDescriptorProto() *dpb.EnumValueDescriptorProto {
-	return vd.proto
-}
-
-// String returns the underlying descriptor proto, in compact text format.
-func (vd *EnumValueDescriptor) String() string {
-	return vd.proto.String()
-}
-
-// ServiceDescriptor describes an RPC service declared in a proto file.
-type ServiceDescriptor struct {
-	proto          *dpb.ServiceDescriptorProto
-	file           *FileDescriptor
-	methods        []*MethodDescriptor
-	fqn            string
-	sourceInfoPath []int32
-}
-
-func createServiceDescriptor(fd *FileDescriptor, enclosing string, sd *dpb.ServiceDescriptorProto, symbols map[string]Descriptor) (*ServiceDescriptor, string) {
-	serviceName := merge(enclosing, sd.GetName())
-	ret := &ServiceDescriptor{proto: sd, file: fd, fqn: serviceName}
-	for _, m := range sd.GetMethod() {
-		md, n := createMethodDescriptor(fd, ret, serviceName, m)
-		symbols[n] = md
-		ret.methods = append(ret.methods, md)
-	}
-	return ret, serviceName
-}
-
-func (sd *ServiceDescriptor) resolve(path []int32, scopes []scope) error {
-	sd.sourceInfoPath = append([]int32(nil), path...) // defensive copy
-	path = append(path, internal.Service_methodsTag)
-	for i, md := range sd.methods {
-		if err := md.resolve(append(path, int32(i)), scopes); err != nil {
-			return err
-		}
-	}
-	return nil
-}
-
-// GetName returns the simple (unqualified) name of the service.
-func (sd *ServiceDescriptor) GetName() string {
-	return sd.proto.GetName()
-}
-
-// GetFullyQualifiedName returns the fully qualified name of the service. This
-// includes the package name (if there is one).
-func (sd *ServiceDescriptor) GetFullyQualifiedName() string {
-	return sd.fqn
-}
-
-// GetParent returns the descriptor for the file in which this service is
-// defined. Most usages will prefer to use GetFile, which has a concrete return
-// type. This more generic method is present to satisfy the Descriptor interface.
-func (sd *ServiceDescriptor) GetParent() Descriptor {
-	return sd.file
-}
-
-// GetFile returns the descriptor for the file in which this service is defined.
-func (sd *ServiceDescriptor) GetFile() *FileDescriptor {
-	return sd.file
-}
-
-// GetOptions returns the service's options. Most usages will be more interested
-// in GetServiceOptions, which has a concrete return type. This generic version
-// is present to satisfy the Descriptor interface.
-func (sd *ServiceDescriptor) GetOptions() proto.Message {
-	return sd.proto.GetOptions()
-}
-
-// GetServiceOptions returns the service's options.
-func (sd *ServiceDescriptor) GetServiceOptions() *dpb.ServiceOptions {
-	return sd.proto.GetOptions()
-}
-
-// GetSourceInfo returns source info for the service, if present in the
-// descriptor. Not all descriptors will contain source info. If non-nil, the
-// returned info contains information about the location in the file where the
-// service was defined and also contains comments associated with the service
-// definition.
-func (sd *ServiceDescriptor) GetSourceInfo() *dpb.SourceCodeInfo_Location {
-	return sd.file.sourceInfo.Get(sd.sourceInfoPath)
-}
-
-// AsProto returns the underlying descriptor proto. Most usages will be more
-// interested in AsServiceDescriptorProto, which has a concrete return type.
-// This generic version is present to satisfy the Descriptor interface.
-func (sd *ServiceDescriptor) AsProto() proto.Message {
-	return sd.proto
-}
-
-// AsServiceDescriptorProto returns the underlying descriptor proto.
-func (sd *ServiceDescriptor) AsServiceDescriptorProto() *dpb.ServiceDescriptorProto {
-	return sd.proto
-}
-
-// String returns the underlying descriptor proto, in compact text format.
-func (sd *ServiceDescriptor) String() string {
-	return sd.proto.String()
-}
-
-// GetMethods returns all of the RPC methods for this service.
-func (sd *ServiceDescriptor) GetMethods() []*MethodDescriptor {
-	return sd.methods
-}
-
-// FindMethodByName finds the method with the given name. If no such method exists
-// then nil is returned.
-func (sd *ServiceDescriptor) FindMethodByName(name string) *MethodDescriptor {
-	fqn := fmt.Sprintf("%s.%s", sd.fqn, name)
-	if md, ok := sd.file.symbols[fqn].(*MethodDescriptor); ok {
-		return md
-	} else {
-		return nil
-	}
-}
-
-// MethodDescriptor describes an RPC method declared in a proto file.
-type MethodDescriptor struct {
-	proto          *dpb.MethodDescriptorProto
-	parent         *ServiceDescriptor
-	file           *FileDescriptor
-	inType         *MessageDescriptor
-	outType        *MessageDescriptor
-	fqn            string
-	sourceInfoPath []int32
-}
-
-func createMethodDescriptor(fd *FileDescriptor, parent *ServiceDescriptor, enclosing string, md *dpb.MethodDescriptorProto) (*MethodDescriptor, string) {
-	// request and response types get resolved later
-	methodName := merge(enclosing, md.GetName())
-	return &MethodDescriptor{proto: md, parent: parent, file: fd, fqn: methodName}, methodName
-}
-
-func (md *MethodDescriptor) resolve(path []int32, scopes []scope) error {
-	md.sourceInfoPath = append([]int32(nil), path...) // defensive copy
-	if desc, err := resolve(md.file, md.proto.GetInputType(), scopes); err != nil {
-		return err
-	} else {
-		md.inType = desc.(*MessageDescriptor)
-	}
-	if desc, err := resolve(md.file, md.proto.GetOutputType(), scopes); err != nil {
-		return err
-	} else {
-		md.outType = desc.(*MessageDescriptor)
-	}
-	return nil
-}
-
-// GetName returns the name of the method.
-func (md *MethodDescriptor) GetName() string {
-	return md.proto.GetName()
-}
-
-// GetFullyQualifiedName returns the fully qualified name of the method. Unlike
-// GetName, this includes fully qualified name of the enclosing service.
-func (md *MethodDescriptor) GetFullyQualifiedName() string {
-	return md.fqn
-}
-
-// GetParent returns the descriptor for the service in which this method is
-// defined. Most usages will prefer to use GetService, which has a concrete
-// return type. This more generic method is present to satisfy the Descriptor
-// interface.
-func (md *MethodDescriptor) GetParent() Descriptor {
-	return md.parent
-}
-
-// GetService returns the RPC service in which this method is declared.
-func (md *MethodDescriptor) GetService() *ServiceDescriptor {
-	return md.parent
-}
-
-// GetFile returns the descriptor for the file in which this method is defined.
-func (md *MethodDescriptor) GetFile() *FileDescriptor {
-	return md.file
-}
-
-// GetOptions returns the method's options. Most usages will be more interested
-// in GetMethodOptions, which has a concrete return type. This generic version
-// is present to satisfy the Descriptor interface.
-func (md *MethodDescriptor) GetOptions() proto.Message {
-	return md.proto.GetOptions()
-}
-
-// GetMethodOptions returns the method's options.
-func (md *MethodDescriptor) GetMethodOptions() *dpb.MethodOptions {
-	return md.proto.GetOptions()
-}
-
-// GetSourceInfo returns source info for the method, if present in the
-// descriptor. Not all descriptors will contain source info. If non-nil, the
-// returned info contains information about the location in the file where the
-// method was defined and also contains comments associated with the method
-// definition.
-func (md *MethodDescriptor) GetSourceInfo() *dpb.SourceCodeInfo_Location {
-	return md.file.sourceInfo.Get(md.sourceInfoPath)
-}
-
-// AsProto returns the underlying descriptor proto. Most usages will be more
-// interested in AsMethodDescriptorProto, which has a concrete return type. This
-// generic version is present to satisfy the Descriptor interface.
-func (md *MethodDescriptor) AsProto() proto.Message {
-	return md.proto
-}
-
-// AsMethodDescriptorProto returns the underlying descriptor proto.
-func (md *MethodDescriptor) AsMethodDescriptorProto() *dpb.MethodDescriptorProto {
-	return md.proto
-}
-
-// String returns the underlying descriptor proto, in compact text format.
-func (md *MethodDescriptor) String() string {
-	return md.proto.String()
-}
-
-// IsServerStreaming returns true if this is a server-streaming method.
-func (md *MethodDescriptor) IsServerStreaming() bool {
-	return md.proto.GetServerStreaming()
-}
-
-// IsClientStreaming returns true if this is a client-streaming method.
-func (md *MethodDescriptor) IsClientStreaming() bool {
-	return md.proto.GetClientStreaming()
-}
-
-// GetInputType returns the input type, or request type, of the RPC method.
-func (md *MethodDescriptor) GetInputType() *MessageDescriptor {
-	return md.inType
-}
-
-// GetOutputType returns the output type, or response type, of the RPC method.
-func (md *MethodDescriptor) GetOutputType() *MessageDescriptor {
-	return md.outType
-}
-
-// OneOfDescriptor describes a one-of field set declared in a protocol buffer message.
-type OneOfDescriptor struct {
-	proto          *dpb.OneofDescriptorProto
-	parent         *MessageDescriptor
-	file           *FileDescriptor
-	choices        []*FieldDescriptor
-	fqn            string
-	sourceInfoPath []int32
-}
-
-func createOneOfDescriptor(fd *FileDescriptor, parent *MessageDescriptor, index int, enclosing string, od *dpb.OneofDescriptorProto) (*OneOfDescriptor, string) {
-	oneOfName := merge(enclosing, od.GetName())
-	ret := &OneOfDescriptor{proto: od, parent: parent, file: fd, fqn: oneOfName}
-	for _, f := range parent.fields {
-		oi := f.proto.OneofIndex
-		if oi != nil && *oi == int32(index) {
-			f.oneOf = ret
-			ret.choices = append(ret.choices, f)
-		}
-	}
-	return ret, oneOfName
-}
-
-func (od *OneOfDescriptor) resolve(path []int32) {
-	od.sourceInfoPath = append([]int32(nil), path...) // defensive copy
-}
-
-// GetName returns the name of the one-of.
-func (od *OneOfDescriptor) GetName() string {
-	return od.proto.GetName()
-}
-
-// GetFullyQualifiedName returns the fully qualified name of the one-of. Unlike
-// GetName, this includes fully qualified name of the enclosing message.
-func (od *OneOfDescriptor) GetFullyQualifiedName() string {
-	return od.fqn
-}
-
-// GetParent returns the descriptor for the message in which this one-of is
-// defined. Most usages will prefer to use GetOwner, which has a concrete
-// return type. This more generic method is present to satisfy the Descriptor
-// interface.
-func (od *OneOfDescriptor) GetParent() Descriptor {
-	return od.parent
-}
-
-// GetOwner returns the message to which this one-of field set belongs.
-func (od *OneOfDescriptor) GetOwner() *MessageDescriptor {
-	return od.parent
-}
-
-// GetFile returns the descriptor for the file in which this one-fof is defined.
-func (od *OneOfDescriptor) GetFile() *FileDescriptor {
-	return od.file
-}
-
-// GetOptions returns the one-of's options. Most usages will be more interested
-// in GetOneOfOptions, which has a concrete return type. This generic version
-// is present to satisfy the Descriptor interface.
-func (od *OneOfDescriptor) GetOptions() proto.Message {
-	return od.proto.GetOptions()
-}
-
-// GetOneOfOptions returns the one-of's options.
-func (od *OneOfDescriptor) GetOneOfOptions() *dpb.OneofOptions {
-	return od.proto.GetOptions()
-}
-
-// GetSourceInfo returns source info for the one-of, if present in the
-// descriptor. Not all descriptors will contain source info. If non-nil, the
-// returned info contains information about the location in the file where the
-// one-of was defined and also contains comments associated with the one-of
-// definition.
-func (od *OneOfDescriptor) GetSourceInfo() *dpb.SourceCodeInfo_Location {
-	return od.file.sourceInfo.Get(od.sourceInfoPath)
-}
-
-// AsProto returns the underlying descriptor proto. Most usages will be more
-// interested in AsOneofDescriptorProto, which has a concrete return type. This
-// generic version is present to satisfy the Descriptor interface.
-func (od *OneOfDescriptor) AsProto() proto.Message {
-	return od.proto
-}
-
-// AsOneofDescriptorProto returns the underlying descriptor proto.
-func (od *OneOfDescriptor) AsOneofDescriptorProto() *dpb.OneofDescriptorProto {
-	return od.proto
-}
-
-// String returns the underlying descriptor proto, in compact text format.
-func (od *OneOfDescriptor) String() string {
-	return od.proto.String()
-}
-
-// GetChoices returns the fields that are part of the one-of field set. At most one of
-// these fields may be set for a given message.
-func (od *OneOfDescriptor) GetChoices() []*FieldDescriptor {
-	return od.choices
-}
-
-// scope represents a lexical scope in a proto file in which messages and enums
-// can be declared.
-type scope func(string) Descriptor
-
-func fileScope(fd *FileDescriptor) scope {
-	// we search symbols in this file, but also symbols in other files that have
-	// the same package as this file or a "parent" package (in protobuf,
-	// packages are a hierarchy like C++ namespaces)
-	prefixes := internal.CreatePrefixList(fd.proto.GetPackage())
-	return func(name string) Descriptor {
-		for _, prefix := range prefixes {
-			n := merge(prefix, name)
-			d := findSymbol(fd, n, false)
-			if d != nil {
-				return d
-			}
-		}
-		return nil
-	}
-}
-
-func messageScope(md *MessageDescriptor) scope {
-	return func(name string) Descriptor {
-		n := merge(md.fqn, name)
-		if d, ok := md.file.symbols[n]; ok {
-			return d
-		}
-		return nil
-	}
-}
-
-func resolve(fd *FileDescriptor, name string, scopes []scope) (Descriptor, error) {
-	if strings.HasPrefix(name, ".") {
-		// already fully-qualified
-		d := findSymbol(fd, name[1:], false)
-		if d != nil {
-			return d, nil
-		}
-	} else {
-		// unqualified, so we look in the enclosing (last) scope first and move
-		// towards outermost (first) scope, trying to resolve the symbol
-		for i := len(scopes) - 1; i >= 0; i-- {
-			d := scopes[i](name)
-			if d != nil {
-				return d, nil
-			}
-		}
-	}
-	return nil, fmt.Errorf("file %q included an unresolvable reference to %q", fd.proto.GetName(), name)
-}
-
-func findSymbol(fd *FileDescriptor, name string, public bool) Descriptor {
-	d := fd.symbols[name]
-	if d != nil {
-		return d
-	}
-
-	// When public = false, we are searching only directly imported symbols. But we
-	// also need to search transitive public imports due to semantics of public imports.
-	var deps []*FileDescriptor
-	if public {
-		deps = fd.publicDeps
-	} else {
-		deps = fd.deps
-	}
-	for _, dep := range deps {
-		d = findSymbol(dep, name, true)
-		if d != nil {
-			return d
-		}
-	}
-
-	return nil
-}
-
-func merge(a, b string) string {
-	if a == "" {
-		return b
-	} else {
-		return a + "." + b
-	}
-}
diff --git a/vendor/github.com/jhump/protoreflect/desc/descriptor_no_unsafe.go b/vendor/github.com/jhump/protoreflect/desc/descriptor_no_unsafe.go
deleted file mode 100644
index cd7348e..0000000
--- a/vendor/github.com/jhump/protoreflect/desc/descriptor_no_unsafe.go
+++ /dev/null
@@ -1,31 +0,0 @@
-//+build appengine gopherjs purego
-// NB: other environments where unsafe is unappropriate should use "purego" build tag
-// https://github.com/golang/go/issues/23172
-
-package desc
-
-type jsonNameMap struct{}
-type memoizedDefault struct{}
-
-// FindFieldByJSONName finds the field with the given JSON field name. If no such
-// field exists then nil is returned. Only regular fields are returned, not
-// extensions.
-func (md *MessageDescriptor) FindFieldByJSONName(jsonName string) *FieldDescriptor {
-	// NB: With allowed use of unsafe, we use it to atomically define an index
-	// via atomic.LoadPointer/atomic.StorePointer. Without it, we skip the index
-	// and do an linear scan of fields each time.
-	for _, f := range md.fields {
-		jn := f.proto.GetJsonName()
-		if jn == "" {
-			jn = f.proto.GetName()
-		}
-		if jn == jsonName {
-			return f
-		}
-	}
-	return nil
-}
-
-func (fd *FieldDescriptor) getDefaultValue() interface{} {
-	return fd.determineDefault()
-}
diff --git a/vendor/github.com/jhump/protoreflect/desc/descriptor_unsafe.go b/vendor/github.com/jhump/protoreflect/desc/descriptor_unsafe.go
deleted file mode 100644
index 19b808d..0000000
--- a/vendor/github.com/jhump/protoreflect/desc/descriptor_unsafe.go
+++ /dev/null
@@ -1,60 +0,0 @@
-//+build !appengine,!gopherjs,!purego
-// NB: other environments where unsafe is unappropriate should use "purego" build tag
-// https://github.com/golang/go/issues/23172
-
-package desc
-
-import (
-	"sync/atomic"
-	"unsafe"
-)
-
-type jsonNameMap map[string]*FieldDescriptor // loaded/stored atomically via atomic+unsafe
-type memoizedDefault *interface{}            // loaded/stored atomically via atomic+unsafe
-
-// FindFieldByJSONName finds the field with the given JSON field name. If no such
-// field exists then nil is returned. Only regular fields are returned, not
-// extensions.
-func (md *MessageDescriptor) FindFieldByJSONName(jsonName string) *FieldDescriptor {
-	// NB: We don't want to eagerly index JSON names because many programs won't use it.
-	// So we want to do it lazily, but also make sure the result is thread-safe. So we
-	// atomically load/store the map as if it were a normal pointer. We don't use other
-	// mechanisms -- like sync.Mutex, sync.RWMutex, sync.Once, or atomic.Value -- to
-	// do this lazily because those types cannot be copied, and we'd rather not induce
-	// 'go vet' errors in programs that use descriptors and try to copy them.
-	// If multiple goroutines try to access the index at the same time, before it is
-	// built, they will all end up computing the index redundantly. Future reads of
-	// the index will use whatever was the "last one stored" by those racing goroutines.
-	// Since building the index is deterministic, this is fine: all indices computed
-	// will be the same.
-	addrOfJsonNames := (*unsafe.Pointer)(unsafe.Pointer(&md.jsonNames))
-	jsonNames := atomic.LoadPointer(addrOfJsonNames)
-	var index map[string]*FieldDescriptor
-	if jsonNames == nil {
-		// slow path: compute the index
-		index = map[string]*FieldDescriptor{}
-		for _, f := range md.fields {
-			jn := f.proto.GetJsonName()
-			if jn == "" {
-				jn = f.proto.GetName()
-			}
-			index[jn] = f
-		}
-		atomic.StorePointer(addrOfJsonNames, *(*unsafe.Pointer)(unsafe.Pointer(&index)))
-	} else {
-		*(*unsafe.Pointer)(unsafe.Pointer(&index)) = jsonNames
-	}
-	return index[jsonName]
-}
-
-func (fd *FieldDescriptor) getDefaultValue() interface{} {
-	addrOfDef := (*unsafe.Pointer)(unsafe.Pointer(&fd.def))
-	def := atomic.LoadPointer(addrOfDef)
-	if def != nil {
-		return *(*interface{})(def)
-	}
-	// slow path: compute the default, potentially involves decoding value
-	d := fd.determineDefault()
-	atomic.StorePointer(addrOfDef, (unsafe.Pointer(&d)))
-	return d
-}
diff --git a/vendor/github.com/jhump/protoreflect/desc/doc.go b/vendor/github.com/jhump/protoreflect/desc/doc.go
deleted file mode 100644
index 1740dce..0000000
--- a/vendor/github.com/jhump/protoreflect/desc/doc.go
+++ /dev/null
@@ -1,41 +0,0 @@
-// Package desc contains "rich descriptors" for protocol buffers. The built-in
-// descriptor types are simple protobuf messages, each one representing a
-// different kind of element in the AST of a .proto source file.
-//
-// Because of this inherent "tree" quality, these build-in descriptors cannot
-// refer to their enclosing file descriptor. Nor can a field descriptor refer to
-// a message or enum descriptor that represents the field's type (for enum and
-// nested message fields). All such links must instead be stringly typed. This
-// limitation makes them much harder to use for doing interesting things with
-// reflection.
-//
-// Without this package, resolving references to types is particularly complex.
-// For example, resolving a field's type, the message type an extension extends,
-// or the request and response types of an RPC method all require searching
-// through symbols defined not only in the file in which these elements are
-// declared but also in its transitive closure of dependencies.
-//
-// "Rich descriptors" avoid the need to deal with the complexities described
-// above. A rich descriptor has all type references resolved and provides
-// methods to access other rich descriptors for all referenced elements. Each
-// rich descriptor has a usefully broad API, but does not try to mimic the full
-// interface of the underlying descriptor proto. Instead, every rich descriptor
-// provides access to that underlying proto, for extracting descriptor
-// properties that are not immediately accessible through rich descriptor's
-// methods.
-//
-// Rich descriptors can be accessed in similar ways as their "poor" cousins
-// (descriptor protos). Instead of using proto.FileDescriptor, use
-// desc.LoadFileDescriptor. Message descriptors and extension field descriptors
-// can also be easily accessed using desc.LoadMessageDescriptor and
-// desc.LoadFieldDescriptorForExtension, respectively.
-//
-// It is also possible create rich descriptors for proto messages that a given
-// Go program doesn't even know about. For example, they could be loaded from a
-// FileDescriptorSet file (which can be generated by protoc) or loaded from a
-// server. This enables interesting things like dynamic clients: where a Go
-// program can be an RPC client of a service it wasn't compiled to know about.
-//
-// Also see the grpcreflect, dynamic, and grpcdynamic packages in this same
-// repo to see just how useful rich descriptors really are.
-package desc
diff --git a/vendor/github.com/jhump/protoreflect/desc/imports.go b/vendor/github.com/jhump/protoreflect/desc/imports.go
deleted file mode 100644
index ab93032..0000000
--- a/vendor/github.com/jhump/protoreflect/desc/imports.go
+++ /dev/null
@@ -1,313 +0,0 @@
-package desc
-
-import (
-	"fmt"
-	"path/filepath"
-	"reflect"
-	"strings"
-	"sync"
-
-	"github.com/golang/protobuf/proto"
-	dpb "github.com/golang/protobuf/protoc-gen-go/descriptor"
-)
-
-var (
-	globalImportPathConf map[string]string
-	globalImportPathMu   sync.RWMutex
-)
-
-// RegisterImportPath registers an alternate import path for a given registered
-// proto file path. For more details on why alternate import paths may need to
-// be configured, see ImportResolver.
-//
-// This method panics if provided invalid input. An empty importPath is invalid.
-// An un-registered registerPath is also invalid. For example, if an attempt is
-// made to register the import path "foo/bar.proto" as "bar.proto", but there is
-// no "bar.proto" registered in the Go protobuf runtime, this method will panic.
-// This method also panics if an attempt is made to register the same import
-// path more than once.
-//
-// This function works globally, applying to all descriptors loaded by this
-// package. If you instead want more granular support for handling alternate
-// import paths -- such as for a single invocation of a function in this
-// package or when the alternate path is only used from one file (so you don't
-// want the alternate path used when loading every other file), use an
-// ImportResolver instead.
-func RegisterImportPath(registerPath, importPath string) {
-	if len(importPath) == 0 {
-		panic("import path cannot be empty")
-	}
-	desc := proto.FileDescriptor(registerPath)
-	if len(desc) == 0 {
-		panic(fmt.Sprintf("path %q is not a registered proto file", registerPath))
-	}
-	globalImportPathMu.Lock()
-	defer globalImportPathMu.Unlock()
-	if reg := globalImportPathConf[importPath]; reg != "" {
-		panic(fmt.Sprintf("import path %q already registered for %s", importPath, reg))
-	}
-	if globalImportPathConf == nil {
-		globalImportPathConf = map[string]string{}
-	}
-	globalImportPathConf[importPath] = registerPath
-}
-
-// ResolveImport resolves the given import path. If it has been registered as an
-// alternate via RegisterImportPath, the registered path is returned. Otherwise,
-// the given import path is returned unchanged.
-func ResolveImport(importPath string) string {
-	importPath = clean(importPath)
-	globalImportPathMu.RLock()
-	defer globalImportPathMu.RUnlock()
-	reg := globalImportPathConf[importPath]
-	if reg == "" {
-		return importPath
-	}
-	return reg
-}
-
-// ImportResolver lets you work-around linking issues that are caused by
-// mismatches between how a particular proto source file is registered in the Go
-// protobuf runtime and how that same file is imported by other files. The file
-// is registered using the same relative path given to protoc when the file is
-// compiled (i.e. when Go code is generated). So if any file tries to import
-// that source file, but using a different relative path, then a link error will
-// occur when this package tries to load a descriptor for the importing file.
-//
-// For example, let's say we have two proto source files: "foo/bar.proto" and
-// "fubar/baz.proto". The latter imports the former using a line like so:
-//    import "foo/bar.proto";
-// However, when protoc is invoked, the command-line args looks like so:
-//    protoc -Ifoo/ --go_out=foo/ bar.proto
-//    protoc -I./ -Ifubar/ --go_out=fubar/ baz.proto
-// Because the path given to protoc is just "bar.proto" and "baz.proto", this is
-// how they are registered in the Go protobuf runtime. So, when loading the
-// descriptor for "fubar/baz.proto", we'll see an import path of "foo/bar.proto"
-// but will find no file registered with that path:
-//    fd, err := desc.LoadFileDescriptor("baz.proto")
-//    // err will be non-nil, complaining that there is no such file
-//    // found named "foo/bar.proto"
-//
-// This can be remedied by registering alternate import paths using an
-// ImportResolver. Continuing with the example above, the code below would fix
-// any link issue:
-//    var r desc.ImportResolver
-//    r.RegisterImportPath("bar.proto", "foo/bar.proto")
-//    fd, err := r.LoadFileDescriptor("baz.proto")
-//    // err will be nil; descriptor successfully loaded!
-//
-// If there are files that are *always* imported using a different relative
-// path then how they are registered, consider using the global
-// RegisterImportPath function, so you don't have to use an ImportResolver for
-// every file that imports it.
-type ImportResolver struct {
-	children    map[string]*ImportResolver
-	importPaths map[string]string
-
-	// By default, an ImportResolver will fallback to consulting any paths
-	// registered via the top-level RegisterImportPath function. Setting this
-	// field to true will cause the ImportResolver to skip that fallback and
-	// only examine its own locally registered paths.
-	SkipFallbackRules bool
-}
-
-// ResolveImport resolves the given import path in the context of the given
-// source file. If a matching alternate has been registered with this resolver
-// via a call to RegisterImportPath or RegisterImportPathFrom, then the
-// registered path is returned. Otherwise, the given import path is returned
-// unchanged.
-func (r *ImportResolver) ResolveImport(source, importPath string) string {
-	if r != nil {
-		res := r.resolveImport(clean(source), clean(importPath))
-		if res != "" {
-			return res
-		}
-		if r.SkipFallbackRules {
-			return importPath
-		}
-	}
-	return ResolveImport(importPath)
-}
-
-func (r *ImportResolver) resolveImport(source, importPath string) string {
-	if source == "" {
-		return r.importPaths[importPath]
-	}
-	var car, cdr string
-	idx := strings.IndexRune(source, filepath.Separator)
-	if idx < 0 {
-		car, cdr = source, ""
-	} else {
-		car, cdr = source[:idx], source[idx+1:]
-	}
-	ch := r.children[car]
-	if ch != nil {
-		if reg := ch.resolveImport(cdr, importPath); reg != "" {
-			return reg
-		}
-	}
-	return r.importPaths[importPath]
-}
-
-// RegisterImportPath registers an alternate import path for a given registered
-// proto file path with this resolver. Any appearance of the given import path
-// when linking files will instead try to link the given registered path. If the
-// registered path cannot be located, then linking will fallback to the actual
-// imported path.
-//
-// This method will panic if given an empty path or if the same import path is
-// registered more than once.
-//
-// To constrain the contexts where the given import path is to be re-written,
-// use RegisterImportPathFrom instead.
-func (r *ImportResolver) RegisterImportPath(registerPath, importPath string) {
-	r.RegisterImportPathFrom(registerPath, importPath, "")
-}
-
-// RegisterImportPathFrom registers an alternate import path for a given
-// registered proto file path with this resolver, but only for imports in the
-// specified source context.
-//
-// The source context can be the name of a folder or a proto source file. Any
-// appearance of the given import path in that context will instead try to link
-// the given registered path. To be in context, the file that is being linked
-// (i.e. the one whose import statement is being resolved) must be the same
-// relative path of the source context or be a sub-path (i.e. a descendant of
-// the source folder).
-//
-// If the registered path cannot be located, then linking will fallback to the
-// actual imported path.
-//
-// This method will panic if given an empty path. The source context, on the
-// other hand, is allowed to be blank. A blank source matches all files. This
-// method also panics if the same import path is registered in the same source
-// context more than once.
-func (r *ImportResolver) RegisterImportPathFrom(registerPath, importPath, source string) {
-	importPath = clean(importPath)
-	if len(importPath) == 0 {
-		panic("import path cannot be empty")
-	}
-	registerPath = clean(registerPath)
-	if len(registerPath) == 0 {
-		panic("registered path cannot be empty")
-	}
-	r.registerImportPathFrom(registerPath, importPath, clean(source))
-}
-
-func (r *ImportResolver) registerImportPathFrom(registerPath, importPath, source string) {
-	if source == "" {
-		if r.importPaths == nil {
-			r.importPaths = map[string]string{}
-		} else if reg := r.importPaths[importPath]; reg != "" {
-			panic(fmt.Sprintf("already registered import path %q as %q", importPath, registerPath))
-		}
-		r.importPaths[importPath] = registerPath
-		return
-	}
-	var car, cdr string
-	idx := strings.IndexRune(source, filepath.Separator)
-	if idx < 0 {
-		car, cdr = source, ""
-	} else {
-		car, cdr = source[:idx], source[idx+1:]
-	}
-	ch := r.children[car]
-	if ch == nil {
-		if r.children == nil {
-			r.children = map[string]*ImportResolver{}
-		}
-		ch = &ImportResolver{}
-		r.children[car] = ch
-	}
-	ch.registerImportPathFrom(registerPath, importPath, cdr)
-}
-
-// LoadFileDescriptor is the same as the package function of the same name, but
-// any alternate paths configured in this resolver are used when linking the
-// given descriptor proto.
-func (r *ImportResolver) LoadFileDescriptor(filePath string) (*FileDescriptor, error) {
-	return loadFileDescriptor(filePath, r)
-}
-
-// LoadMessageDescriptor is the same as the package function of the same name,
-// but any alternate paths configured in this resolver are used when linking
-// files for the returned descriptor.
-func (r *ImportResolver) LoadMessageDescriptor(msgName string) (*MessageDescriptor, error) {
-	return loadMessageDescriptor(msgName, r)
-}
-
-// LoadMessageDescriptorForMessage is the same as the package function of the
-// same name, but any alternate paths configured in this resolver are used when
-// linking files for the returned descriptor.
-func (r *ImportResolver) LoadMessageDescriptorForMessage(msg proto.Message) (*MessageDescriptor, error) {
-	return loadMessageDescriptorForMessage(msg, r)
-}
-
-// LoadMessageDescriptorForType is the same as the package function of the same
-// name, but any alternate paths configured in this resolver are used when
-// linking files for the returned descriptor.
-func (r *ImportResolver) LoadMessageDescriptorForType(msgType reflect.Type) (*MessageDescriptor, error) {
-	return loadMessageDescriptorForType(msgType, r)
-}
-
-// LoadEnumDescriptorForEnum is the same as the package function of the same
-// name, but any alternate paths configured in this resolver are used when
-// linking files for the returned descriptor.
-func (r *ImportResolver) LoadEnumDescriptorForEnum(enum protoEnum) (*EnumDescriptor, error) {
-	return loadEnumDescriptorForEnum(enum, r)
-}
-
-// LoadEnumDescriptorForType is the same as the package function of the same
-// name, but any alternate paths configured in this resolver are used when
-// linking files for the returned descriptor.
-func (r *ImportResolver) LoadEnumDescriptorForType(enumType reflect.Type) (*EnumDescriptor, error) {
-	return loadEnumDescriptorForType(enumType, r)
-}
-
-// LoadFieldDescriptorForExtension is the same as the package function of the
-// same name, but any alternate paths configured in this resolver are used when
-// linking files for the returned descriptor.
-func (r *ImportResolver) LoadFieldDescriptorForExtension(ext *proto.ExtensionDesc) (*FieldDescriptor, error) {
-	return loadFieldDescriptorForExtension(ext, r)
-}
-
-// CreateFileDescriptor is the same as the package function of the same name,
-// but any alternate paths configured in this resolver are used when linking the
-// given descriptor proto.
-func (r *ImportResolver) CreateFileDescriptor(fdp *dpb.FileDescriptorProto, deps ...*FileDescriptor) (*FileDescriptor, error) {
-	return createFileDescriptor(fdp, deps, r)
-}
-
-// CreateFileDescriptors is the same as the package function of the same name,
-// but any alternate paths configured in this resolver are used when linking the
-// given descriptor protos.
-func (r *ImportResolver) CreateFileDescriptors(fds []*dpb.FileDescriptorProto) (map[string]*FileDescriptor, error) {
-	return createFileDescriptors(fds, r)
-}
-
-// CreateFileDescriptorFromSet is the same as the package function of the same
-// name, but any alternate paths configured in this resolver are used when
-// linking the descriptor protos in the given set.
-func (r *ImportResolver) CreateFileDescriptorFromSet(fds *dpb.FileDescriptorSet) (*FileDescriptor, error) {
-	return createFileDescriptorFromSet(fds, r)
-}
-
-// CreateFileDescriptorsFromSet is the same as the package function of the same
-// name, but any alternate paths configured in this resolver are used when
-// linking the descriptor protos in the given set.
-func (r *ImportResolver) CreateFileDescriptorsFromSet(fds *dpb.FileDescriptorSet) (map[string]*FileDescriptor, error) {
-	return createFileDescriptorsFromSet(fds, r)
-}
-
-const dotPrefix = "." + string(filepath.Separator)
-
-func clean(path string) string {
-	if path == "" {
-		return ""
-	}
-	path = filepath.Clean(path)
-	if path == "." {
-		return ""
-	}
-	return strings.TrimPrefix(path, dotPrefix)
-}
diff --git a/vendor/github.com/jhump/protoreflect/desc/internal/source_info.go b/vendor/github.com/jhump/protoreflect/desc/internal/source_info.go
deleted file mode 100644
index b4150b8..0000000
--- a/vendor/github.com/jhump/protoreflect/desc/internal/source_info.go
+++ /dev/null
@@ -1,107 +0,0 @@
-package internal
-
-import (
-	dpb "github.com/golang/protobuf/protoc-gen-go/descriptor"
-)
-
-// SourceInfoMap is a map of paths in a descriptor to the corresponding source
-// code info.
-type SourceInfoMap map[string][]*dpb.SourceCodeInfo_Location
-
-// Get returns the source code info for the given path. If there are
-// multiple locations for the same path, the first one is returned.
-func (m SourceInfoMap) Get(path []int32) *dpb.SourceCodeInfo_Location {
-	v := m[asMapKey(path)]
-	if len(v) > 0 {
-		return v[0]
-	}
-	return nil
-}
-
-// GetAll returns all source code info for the given path.
-func (m SourceInfoMap) GetAll(path []int32) []*dpb.SourceCodeInfo_Location {
-	return m[asMapKey(path)]
-}
-
-// Add stores the given source code info for the given path.
-func (m SourceInfoMap) Add(path []int32, loc *dpb.SourceCodeInfo_Location) {
-	m[asMapKey(path)] = append(m[asMapKey(path)], loc)
-}
-
-// PutIfAbsent stores the given source code info for the given path only if the
-// given path does not exist in the map. This method returns true when the value
-// is stored, false if the path already exists.
-func (m SourceInfoMap) PutIfAbsent(path []int32, loc *dpb.SourceCodeInfo_Location) bool {
-	k := asMapKey(path)
-	if _, ok := m[k]; ok {
-		return false
-	}
-	m[k] = []*dpb.SourceCodeInfo_Location{loc}
-	return true
-}
-
-func asMapKey(slice []int32) string {
-	// NB: arrays should be usable as map keys, but this does not
-	// work due to a bug: https://github.com/golang/go/issues/22605
-	//rv := reflect.ValueOf(slice)
-	//arrayType := reflect.ArrayOf(rv.Len(), rv.Type().Elem())
-	//array := reflect.New(arrayType).Elem()
-	//reflect.Copy(array, rv)
-	//return array.Interface()
-
-	b := make([]byte, len(slice)*4)
-	j := 0
-	for _, s := range slice {
-		b[j] = byte(s)
-		b[j+1] = byte(s >> 8)
-		b[j+2] = byte(s >> 16)
-		b[j+3] = byte(s >> 24)
-		j += 4
-	}
-	return string(b)
-}
-
-// CreateSourceInfoMap constructs a new SourceInfoMap and populates it with the
-// source code info in the given file descriptor proto.
-func CreateSourceInfoMap(fd *dpb.FileDescriptorProto) SourceInfoMap {
-	res := SourceInfoMap{}
-	PopulateSourceInfoMap(fd, res)
-	return res
-}
-
-// PopulateSourceInfoMap populates the given SourceInfoMap with information from
-// the given file descriptor.
-func PopulateSourceInfoMap(fd *dpb.FileDescriptorProto, m SourceInfoMap) {
-	for _, l := range fd.GetSourceCodeInfo().GetLocation() {
-		m.Add(l.Path, l)
-	}
-}
-
-// NB: This wonkiness allows desc.Descriptor impl to implement an interface that
-// is only usable from this package, by embedding a SourceInfoComputeFunc that
-// implements the actual logic (which must live in desc package to avoid a
-// dependency cycle).
-
-// SourceInfoComputer is a single method which will be invoked to recompute
-// source info. This is needed for the protoparse package, which needs to link
-// descriptors without source info in order to interpret options, but then needs
-// to re-compute source info after that interpretation so that final linked
-// descriptors expose the right info.
-type SourceInfoComputer interface {
-	recomputeSourceInfo()
-}
-
-// SourceInfoComputeFunc is the type that a desc.Descriptor will embed. It will
-// be aliased in the desc package to an unexported name so it is not marked as
-// an exported field in reflection and not present in Go docs.
-type SourceInfoComputeFunc func()
-
-func (f SourceInfoComputeFunc) recomputeSourceInfo() {
-	f()
-}
-
-// RecomputeSourceInfo is used to initiate recomputation of source info. This is
-// is used by the protoparse package, after it interprets options.
-func RecomputeSourceInfo(c SourceInfoComputer) {
-	c.recomputeSourceInfo()
-}
diff --git a/vendor/github.com/jhump/protoreflect/desc/internal/util.go b/vendor/github.com/jhump/protoreflect/desc/internal/util.go
deleted file mode 100644
index 139c9cd..0000000
--- a/vendor/github.com/jhump/protoreflect/desc/internal/util.go
+++ /dev/null
@@ -1,270 +0,0 @@
-package internal
-
-import (
-	"unicode"
-	"unicode/utf8"
-)
-
-const (
-	// MaxTag is the maximum allowed tag number for a field.
-	MaxTag = 536870911 // 2^29 - 1
-
-	// SpecialReservedStart is the first tag in a range that is reserved and not
-	// allowed for use in message definitions.
-	SpecialReservedStart = 19000
-	// SpecialReservedEnd is the last tag in a range that is reserved and not
-	// allowed for use in message definitions.
-	SpecialReservedEnd = 19999
-
-	// NB: It would be nice to use constants from generated code instead of
-	// hard-coding these here. But code-gen does not emit these as constants
-	// anywhere. The only places they appear in generated code are struct tags
-	// on fields of the generated descriptor protos.
-
-	// File_packageTag is the tag number of the package element in a file
-	// descriptor proto.
-	File_packageTag = 2
-	// File_dependencyTag is the tag number of the dependencies element in a
-	// file descriptor proto.
-	File_dependencyTag = 3
-	// File_messagesTag is the tag number of the messages element in a file
-	// descriptor proto.
-	File_messagesTag = 4
-	// File_enumsTag is the tag number of the enums element in a file descriptor
-	// proto.
-	File_enumsTag = 5
-	// File_servicesTag is the tag number of the services element in a file
-	// descriptor proto.
-	File_servicesTag = 6
-	// File_extensionsTag is the tag number of the extensions element in a file
-	// descriptor proto.
-	File_extensionsTag = 7
-	// File_optionsTag is the tag number of the options element in a file
-	// descriptor proto.
-	File_optionsTag = 8
-	// File_syntaxTag is the tag number of the syntax element in a file
-	// descriptor proto.
-	File_syntaxTag = 12
-	// Message_nameTag is the tag number of the name element in a message
-	// descriptor proto.
-	Message_nameTag = 1
-	// Message_fieldsTag is the tag number of the fields element in a message
-	// descriptor proto.
-	Message_fieldsTag = 2
-	// Message_nestedMessagesTag is the tag number of the nested messages
-	// element in a message descriptor proto.
-	Message_nestedMessagesTag = 3
-	// Message_enumsTag is the tag number of the enums element in a message
-	// descriptor proto.
-	Message_enumsTag = 4
-	// Message_extensionRangeTag is the tag number of the extension ranges
-	// element in a message descriptor proto.
-	Message_extensionRangeTag = 5
-	// Message_extensionsTag is the tag number of the extensions element in a
-	// message descriptor proto.
-	Message_extensionsTag = 6
-	// Message_optionsTag is the tag number of the options element in a message
-	// descriptor proto.
-	Message_optionsTag = 7
-	// Message_oneOfsTag is the tag number of the one-ofs element in a message
-	// descriptor proto.
-	Message_oneOfsTag = 8
-	// Message_reservedRangeTag is the tag number of the reserved ranges element
-	// in a message descriptor proto.
-	Message_reservedRangeTag = 9
-	// Message_reservedNameTag is the tag number of the reserved names element
-	// in a message descriptor proto.
-	Message_reservedNameTag = 10
-	// ExtensionRange_startTag is the tag number of the start index in an
-	// extension range proto.
-	ExtensionRange_startTag = 1
-	// ExtensionRange_endTag is the tag number of the end index in an
-	// extension range proto.
-	ExtensionRange_endTag = 2
-	// ExtensionRange_optionsTag is the tag number of the options element in an
-	// extension range proto.
-	ExtensionRange_optionsTag = 3
-	// ReservedRange_startTag is the tag number of the start index in a reserved
-	// range proto.
-	ReservedRange_startTag = 1
-	// ReservedRange_endTag is the tag number of the end index in a reserved
-	// range proto.
-	ReservedRange_endTag = 2
-	// Field_nameTag is the tag number of the name element in a field descriptor
-	// proto.
-	Field_nameTag = 1
-	// Field_extendeeTag is the tag number of the extendee element in a field
-	// descriptor proto.
-	Field_extendeeTag = 2
-	// Field_numberTag is the tag number of the number element in a field
-	// descriptor proto.
-	Field_numberTag = 3
-	// Field_labelTag is the tag number of the label element in a field
-	// descriptor proto.
-	Field_labelTag = 4
-	// Field_typeTag is the tag number of the type element in a field descriptor
-	// proto.
-	Field_typeTag = 5
-	// Field_typeNameTag is the tag number of the type name element in a field
-	// descriptor proto.
-	Field_typeNameTag = 6
-	// Field_defaultTag is the tag number of the default value element in a
-	// field descriptor proto.
-	Field_defaultTag = 7
-	// Field_optionsTag is the tag number of the options element in a field
-	// descriptor proto.
-	Field_optionsTag = 8
-	// Field_jsonNameTag is the tag number of the JSON name element in a field
-	// descriptor proto.
-	Field_jsonNameTag = 10
-	// OneOf_nameTag is the tag number of the name element in a one-of
-	// descriptor proto.
-	OneOf_nameTag = 1
-	// OneOf_optionsTag is the tag number of the options element in a one-of
-	// descriptor proto.
-	OneOf_optionsTag = 2
-	// Enum_nameTag is the tag number of the name element in an enum descriptor
-	// proto.
-	Enum_nameTag = 1
-	// Enum_valuesTag is the tag number of the values element in an enum
-	// descriptor proto.
-	Enum_valuesTag = 2
-	// Enum_optionsTag is the tag number of the options element in an enum
-	// descriptor proto.
-	Enum_optionsTag = 3
-	// Enum_reservedRangeTag is the tag number of the reserved ranges element in
-	// an enum descriptor proto.
-	Enum_reservedRangeTag = 4
-	// Enum_reservedNameTag is the tag number of the reserved names element in
-	// an enum descriptor proto.
-	Enum_reservedNameTag = 5
-	// EnumVal_nameTag is the tag number of the name element in an enum value
-	// descriptor proto.
-	EnumVal_nameTag = 1
-	// EnumVal_numberTag is the tag number of the number element in an enum
-	// value descriptor proto.
-	EnumVal_numberTag = 2
-	// EnumVal_optionsTag is the tag number of the options element in an enum
-	// value descriptor proto.
-	EnumVal_optionsTag = 3
-	// Service_nameTag is the tag number of the name element in a service
-	// descriptor proto.
-	Service_nameTag = 1
-	// Service_methodsTag is the tag number of the methods element in a service
-	// descriptor proto.
-	Service_methodsTag = 2
-	// Service_optionsTag is the tag number of the options element in a service
-	// descriptor proto.
-	Service_optionsTag = 3
-	// Method_nameTag is the tag number of the name element in a method
-	// descriptor proto.
-	Method_nameTag = 1
-	// Method_inputTag is the tag number of the input type element in a method
-	// descriptor proto.
-	Method_inputTag = 2
-	// Method_outputTag is the tag number of the output type element in a method
-	// descriptor proto.
-	Method_outputTag = 3
-	// Method_optionsTag is the tag number of the options element in a method
-	// descriptor proto.
-	Method_optionsTag = 4
-	// Method_inputStreamTag is the tag number of the input stream flag in a
-	// method descriptor proto.
-	Method_inputStreamTag = 5
-	// Method_outputStreamTag is the tag number of the output stream flag in a
-	// method descriptor proto.
-	Method_outputStreamTag = 6
-
-	// UninterpretedOptionsTag is the tag number of the uninterpreted options
-	// element. All *Options messages use the same tag for the field that stores
-	// uninterpreted options.
-	UninterpretedOptionsTag = 999
-
-	// Uninterpreted_nameTag is the tag number of the name element in an
-	// uninterpreted options proto.
-	Uninterpreted_nameTag = 2
-	// Uninterpreted_identTag is the tag number of the identifier value in an
-	// uninterpreted options proto.
-	Uninterpreted_identTag = 3
-	// Uninterpreted_posIntTag is the tag number of the positive int value in an
-	// uninterpreted options proto.
-	Uninterpreted_posIntTag = 4
-	// Uninterpreted_negIntTag is the tag number of the negative int value in an
-	// uninterpreted options proto.
-	Uninterpreted_negIntTag = 5
-	// Uninterpreted_doubleTag is the tag number of the double value in an
-	// uninterpreted options proto.
-	Uninterpreted_doubleTag = 6
-	// Uninterpreted_stringTag is the tag number of the string value in an
-	// uninterpreted options proto.
-	Uninterpreted_stringTag = 7
-	// Uninterpreted_aggregateTag is the tag number of the aggregate value in an
-	// uninterpreted options proto.
-	Uninterpreted_aggregateTag = 8
-	// UninterpretedName_nameTag is the tag number of the name element in an
-	// uninterpreted option name proto.
-	UninterpretedName_nameTag = 1
-)
-
-// JsonName returns the default JSON name for a field with the given name.
-func JsonName(name string) string {
-	var js []rune
-	nextUpper := false
-	for i, r := range name {
-		if r == '_' {
-			nextUpper = true
-			continue
-		}
-		if i == 0 {
-			js = append(js, r)
-		} else if nextUpper {
-			nextUpper = false
-			js = append(js, unicode.ToUpper(r))
-		} else {
-			js = append(js, r)
-		}
-	}
-	return string(js)
-}
-
-// InitCap returns the given field name, but with the first letter capitalized.
-func InitCap(name string) string {
-	r, sz := utf8.DecodeRuneInString(name)
-	return string(unicode.ToUpper(r)) + name[sz:]
-}
-
-// CreatePrefixList returns a list of package prefixes to search when resolving
-// a symbol name. If the given package is blank, it returns only the empty
-// string. If the given package contains only one token, e.g. "foo", it returns
-// that token and the empty string, e.g. ["foo", ""]. Otherwise, it returns
-// successively shorter prefixes of the package and then the empty string. For
-// example, for a package named "foo.bar.baz" it will return the following list:
-//   ["foo.bar.baz", "foo.bar", "foo", ""]
-func CreatePrefixList(pkg string) []string {
-	if pkg == "" {
-		return []string{""}
-	}
-
-	numDots := 0
-	// one pass to pre-allocate the returned slice
-	for i := 0; i < len(pkg); i++ {
-		if pkg[i] == '.' {
-			numDots++
-		}
-	}
-	if numDots == 0 {
-		return []string{pkg, ""}
-	}
-
-	prefixes := make([]string, numDots+2)
-	// second pass to fill in returned slice
-	for i := 0; i < len(pkg); i++ {
-		if pkg[i] == '.' {
-			prefixes[numDots] = pkg[:i]
-			numDots--
-		}
-	}
-	prefixes[0] = pkg
-
-	return prefixes
-}
diff --git a/vendor/github.com/jhump/protoreflect/desc/load.go b/vendor/github.com/jhump/protoreflect/desc/load.go
deleted file mode 100644
index 4a05830..0000000
--- a/vendor/github.com/jhump/protoreflect/desc/load.go
+++ /dev/null
@@ -1,341 +0,0 @@
-package desc
-
-import (
-	"fmt"
-	"reflect"
-	"sync"
-
-	"github.com/golang/protobuf/proto"
-	dpb "github.com/golang/protobuf/protoc-gen-go/descriptor"
-
-	"github.com/jhump/protoreflect/internal"
-)
-
-var (
-	cacheMu       sync.RWMutex
-	filesCache    = map[string]*FileDescriptor{}
-	messagesCache = map[string]*MessageDescriptor{}
-	enumCache     = map[reflect.Type]*EnumDescriptor{}
-)
-
-// LoadFileDescriptor creates a file descriptor using the bytes returned by
-// proto.FileDescriptor. Descriptors are cached so that they do not need to be
-// re-processed if the same file is fetched again later.
-func LoadFileDescriptor(file string) (*FileDescriptor, error) {
-	return loadFileDescriptor(file, nil)
-}
-
-func loadFileDescriptor(file string, r *ImportResolver) (*FileDescriptor, error) {
-	f := getFileFromCache(file)
-	if f != nil {
-		return f, nil
-	}
-	cacheMu.Lock()
-	defer cacheMu.Unlock()
-	return loadFileDescriptorLocked(file, r)
-}
-
-func loadFileDescriptorLocked(file string, r *ImportResolver) (*FileDescriptor, error) {
-	f := filesCache[file]
-	if f != nil {
-		return f, nil
-	}
-	fd, err := internal.LoadFileDescriptor(file)
-	if err != nil {
-		return nil, err
-	}
-
-	f, err = toFileDescriptorLocked(fd, r)
-	if err != nil {
-		return nil, err
-	}
-	putCacheLocked(file, f)
-	return f, nil
-}
-
-func toFileDescriptorLocked(fd *dpb.FileDescriptorProto, r *ImportResolver) (*FileDescriptor, error) {
-	deps := make([]*FileDescriptor, len(fd.GetDependency()))
-	for i, dep := range fd.GetDependency() {
-		resolvedDep := r.ResolveImport(fd.GetName(), dep)
-		var err error
-		deps[i], err = loadFileDescriptorLocked(resolvedDep, r)
-		if _, ok := err.(internal.ErrNoSuchFile); ok && resolvedDep != dep {
-			// try original path
-			deps[i], err = loadFileDescriptorLocked(dep, r)
-		}
-		if err != nil {
-			return nil, err
-		}
-	}
-	return CreateFileDescriptor(fd, deps...)
-}
-
-func getFileFromCache(file string) *FileDescriptor {
-	cacheMu.RLock()
-	defer cacheMu.RUnlock()
-	return filesCache[file]
-}
-
-func putCacheLocked(filename string, fd *FileDescriptor) {
-	filesCache[filename] = fd
-	putMessageCacheLocked(fd.messages)
-}
-
-func putMessageCacheLocked(mds []*MessageDescriptor) {
-	for _, md := range mds {
-		messagesCache[md.fqn] = md
-		putMessageCacheLocked(md.nested)
-	}
-}
-
-// interface implemented by generated messages, which all have a Descriptor() method in
-// addition to the methods of proto.Message
-type protoMessage interface {
-	proto.Message
-	Descriptor() ([]byte, []int)
-}
-
-// LoadMessageDescriptor loads descriptor using the encoded descriptor proto returned by
-// Message.Descriptor() for the given message type. If the given type is not recognized,
-// then a nil descriptor is returned.
-func LoadMessageDescriptor(message string) (*MessageDescriptor, error) {
-	return loadMessageDescriptor(message, nil)
-}
-
-func loadMessageDescriptor(message string, r *ImportResolver) (*MessageDescriptor, error) {
-	m := getMessageFromCache(message)
-	if m != nil {
-		return m, nil
-	}
-
-	pt := proto.MessageType(message)
-	if pt == nil {
-		return nil, nil
-	}
-	msg, err := messageFromType(pt)
-	if err != nil {
-		return nil, err
-	}
-
-	cacheMu.Lock()
-	defer cacheMu.Unlock()
-	return loadMessageDescriptorForTypeLocked(message, msg, r)
-}
-
-// LoadMessageDescriptorForType loads descriptor using the encoded descriptor proto returned
-// by message.Descriptor() for the given message type. If the given type is not recognized,
-// then a nil descriptor is returned.
-func LoadMessageDescriptorForType(messageType reflect.Type) (*MessageDescriptor, error) {
-	return loadMessageDescriptorForType(messageType, nil)
-}
-
-func loadMessageDescriptorForType(messageType reflect.Type, r *ImportResolver) (*MessageDescriptor, error) {
-	m, err := messageFromType(messageType)
-	if err != nil {
-		return nil, err
-	}
-	return loadMessageDescriptorForMessage(m, r)
-}
-
-// LoadMessageDescriptorForMessage loads descriptor using the encoded descriptor proto
-// returned by message.Descriptor(). If the given type is not recognized, then a nil
-// descriptor is returned.
-func LoadMessageDescriptorForMessage(message proto.Message) (*MessageDescriptor, error) {
-	return loadMessageDescriptorForMessage(message, nil)
-}
-
-func loadMessageDescriptorForMessage(message proto.Message, r *ImportResolver) (*MessageDescriptor, error) {
-	// efficiently handle dynamic messages
-	type descriptorable interface {
-		GetMessageDescriptor() *MessageDescriptor
-	}
-	if d, ok := message.(descriptorable); ok {
-		return d.GetMessageDescriptor(), nil
-	}
-
-	name := proto.MessageName(message)
-	if name == "" {
-		return nil, nil
-	}
-	m := getMessageFromCache(name)
-	if m != nil {
-		return m, nil
-	}
-
-	cacheMu.Lock()
-	defer cacheMu.Unlock()
-	return loadMessageDescriptorForTypeLocked(name, message.(protoMessage), nil)
-}
-
-func messageFromType(mt reflect.Type) (protoMessage, error) {
-	if mt.Kind() != reflect.Ptr {
-		mt = reflect.PtrTo(mt)
-	}
-	m, ok := reflect.Zero(mt).Interface().(protoMessage)
-	if !ok {
-		return nil, fmt.Errorf("failed to create message from type: %v", mt)
-	}
-	return m, nil
-}
-
-func loadMessageDescriptorForTypeLocked(name string, message protoMessage, r *ImportResolver) (*MessageDescriptor, error) {
-	m := messagesCache[name]
-	if m != nil {
-		return m, nil
-	}
-
-	fdb, _ := message.Descriptor()
-	fd, err := internal.DecodeFileDescriptor(name, fdb)
-	if err != nil {
-		return nil, err
-	}
-
-	f, err := toFileDescriptorLocked(fd, r)
-	if err != nil {
-		return nil, err
-	}
-	putCacheLocked(fd.GetName(), f)
-	return f.FindSymbol(name).(*MessageDescriptor), nil
-}
-
-func getMessageFromCache(message string) *MessageDescriptor {
-	cacheMu.RLock()
-	defer cacheMu.RUnlock()
-	return messagesCache[message]
-}
-
-// interface implemented by all generated enums
-type protoEnum interface {
-	EnumDescriptor() ([]byte, []int)
-}
-
-// NB: There is no LoadEnumDescriptor that takes a fully-qualified enum name because
-// it is not useful since protoc-gen-go does not expose the name anywhere in generated
-// code or register it in a way that is it accessible for reflection code. This also
-// means we have to cache enum descriptors differently -- we can only cache them as
-// they are requested, as opposed to caching all enum types whenever a file descriptor
-// is cached. This is because we need to know the generated type of the enums, and we
-// don't know that at the time of caching file descriptors.
-
-// LoadEnumDescriptorForType loads descriptor using the encoded descriptor proto returned
-// by enum.EnumDescriptor() for the given enum type.
-func LoadEnumDescriptorForType(enumType reflect.Type) (*EnumDescriptor, error) {
-	return loadEnumDescriptorForType(enumType, nil)
-}
-
-func loadEnumDescriptorForType(enumType reflect.Type, r *ImportResolver) (*EnumDescriptor, error) {
-	// we cache descriptors using non-pointer type
-	if enumType.Kind() == reflect.Ptr {
-		enumType = enumType.Elem()
-	}
-	e := getEnumFromCache(enumType)
-	if e != nil {
-		return e, nil
-	}
-	enum, err := enumFromType(enumType)
-	if err != nil {
-		return nil, err
-	}
-
-	cacheMu.Lock()
-	defer cacheMu.Unlock()
-	return loadEnumDescriptorForTypeLocked(enumType, enum, r)
-}
-
-// LoadEnumDescriptorForEnum loads descriptor using the encoded descriptor proto
-// returned by enum.EnumDescriptor().
-func LoadEnumDescriptorForEnum(enum protoEnum) (*EnumDescriptor, error) {
-	return loadEnumDescriptorForEnum(enum, nil)
-}
-
-func loadEnumDescriptorForEnum(enum protoEnum, r *ImportResolver) (*EnumDescriptor, error) {
-	et := reflect.TypeOf(enum)
-	// we cache descriptors using non-pointer type
-	if et.Kind() == reflect.Ptr {
-		et = et.Elem()
-		enum = reflect.Zero(et).Interface().(protoEnum)
-	}
-	e := getEnumFromCache(et)
-	if e != nil {
-		return e, nil
-	}
-
-	cacheMu.Lock()
-	defer cacheMu.Unlock()
-	return loadEnumDescriptorForTypeLocked(et, enum, r)
-}
-
-func enumFromType(et reflect.Type) (protoEnum, error) {
-	if et.Kind() != reflect.Int32 {
-		et = reflect.PtrTo(et)
-	}
-	e, ok := reflect.Zero(et).Interface().(protoEnum)
-	if !ok {
-		return nil, fmt.Errorf("failed to create enum from type: %v", et)
-	}
-	return e, nil
-}
-
-func loadEnumDescriptorForTypeLocked(et reflect.Type, enum protoEnum, r *ImportResolver) (*EnumDescriptor, error) {
-	e := enumCache[et]
-	if e != nil {
-		return e, nil
-	}
-
-	fdb, path := enum.EnumDescriptor()
-	name := fmt.Sprintf("%v", et)
-	fd, err := internal.DecodeFileDescriptor(name, fdb)
-	if err != nil {
-		return nil, err
-	}
-	// see if we already have cached "rich" descriptor
-	f, ok := filesCache[fd.GetName()]
-	if !ok {
-		f, err = toFileDescriptorLocked(fd, r)
-		if err != nil {
-			return nil, err
-		}
-		putCacheLocked(fd.GetName(), f)
-	}
-
-	ed := findEnum(f, path)
-	enumCache[et] = ed
-	return ed, nil
-}
-
-func getEnumFromCache(et reflect.Type) *EnumDescriptor {
-	cacheMu.RLock()
-	defer cacheMu.RUnlock()
-	return enumCache[et]
-}
-
-func findEnum(fd *FileDescriptor, path []int) *EnumDescriptor {
-	if len(path) == 1 {
-		return fd.GetEnumTypes()[path[0]]
-	}
-	md := fd.GetMessageTypes()[path[0]]
-	for _, i := range path[1 : len(path)-1] {
-		md = md.GetNestedMessageTypes()[i]
-	}
-	return md.GetNestedEnumTypes()[path[len(path)-1]]
-}
-
-// LoadFieldDescriptorForExtension loads the field descriptor that corresponds to the given
-// extension description.
-func LoadFieldDescriptorForExtension(ext *proto.ExtensionDesc) (*FieldDescriptor, error) {
-	return loadFieldDescriptorForExtension(ext, nil)
-}
-
-func loadFieldDescriptorForExtension(ext *proto.ExtensionDesc, r *ImportResolver) (*FieldDescriptor, error) {
-	file, err := loadFileDescriptor(ext.Filename, r)
-	if err != nil {
-		return nil, err
-	}
-	field, ok := file.FindSymbol(ext.Name).(*FieldDescriptor)
-	// make sure descriptor agrees with attributes of the ExtensionDesc
-	if !ok || !field.IsExtension() || field.GetOwner().GetFullyQualifiedName() != proto.MessageName(ext.ExtendedType) ||
-		field.GetNumber() != ext.Field {
-		return nil, fmt.Errorf("file descriptor contained unexpected object with name %s", ext.Name)
-	}
-	return field, nil
-}
diff --git a/vendor/github.com/jhump/protoreflect/dynamic/binary.go b/vendor/github.com/jhump/protoreflect/dynamic/binary.go
deleted file mode 100644
index 91fd672..0000000
--- a/vendor/github.com/jhump/protoreflect/dynamic/binary.go
+++ /dev/null
@@ -1,185 +0,0 @@
-package dynamic
-
-// Binary serialization and de-serialization for dynamic messages
-
-import (
-	"fmt"
-	"github.com/golang/protobuf/proto"
-	"github.com/jhump/protoreflect/codec"
-	"io"
-)
-
-// defaultDeterminism, if true, will mean that calls to Marshal will produce
-// deterministic output. This is used to make the output of proto.Marshal(...)
-// deterministic (since there is no way to have that convey determinism intent).
-// **This is only used from tests.**
-var defaultDeterminism = false
-
-// Marshal serializes this message to bytes, returning an error if the operation
-// fails. The resulting bytes are in the standard protocol buffer binary format.
-func (m *Message) Marshal() ([]byte, error) {
-	var b codec.Buffer
-	b.SetDeterministic(defaultDeterminism)
-	if err := m.marshal(&b); err != nil {
-		return nil, err
-	}
-	return b.Bytes(), nil
-}
-
-// MarshalAppend behaves exactly the same as Marshal, except instead of allocating a
-// new byte slice to marshal into, it uses the provided byte slice. The backing array
-// for the returned byte slice *may* be the same as the one that was passed in, but
-// it's not guaranteed as a new backing array will automatically be allocated if
-// more bytes need to be written than the provided buffer has capacity for.
-func (m *Message) MarshalAppend(b []byte) ([]byte, error) {
-	codedBuf := codec.NewBuffer(b)
-	codedBuf.SetDeterministic(defaultDeterminism)
-	if err := m.marshal(codedBuf); err != nil {
-		return nil, err
-	}
-	return codedBuf.Bytes(), nil
-}
-
-// MarshalDeterministic serializes this message to bytes in a deterministic way,
-// returning an error if the operation fails. This differs from Marshal in that
-// map keys will be sorted before serializing to bytes. The protobuf spec does
-// not define ordering for map entries, so Marshal will use standard Go map
-// iteration order (which will be random). But for cases where determinism is
-// more important than performance, use this method instead.
-func (m *Message) MarshalDeterministic() ([]byte, error) {
-	var b codec.Buffer
-	b.SetDeterministic(true)
-	if err := m.marshal(&b); err != nil {
-		return nil, err
-	}
-	return b.Bytes(), nil
-}
-
-// MarshalAppendDeterministic behaves exactly the same as MarshalDeterministic,
-// except instead of allocating a new byte slice to marshal into, it uses the
-// provided byte slice. The backing array for the returned byte slice *may* be
-// the same as the one that was passed in, but it's not guaranteed as a new
-// backing array will automatically be allocated if more bytes need to be written
-// than the provided buffer has capacity for.
-func (m *Message) MarshalAppendDeterministic(b []byte) ([]byte, error) {
-	codedBuf := codec.NewBuffer(b)
-	codedBuf.SetDeterministic(true)
-	if err := m.marshal(codedBuf); err != nil {
-		return nil, err
-	}
-	return codedBuf.Bytes(), nil
-}
-
-func (m *Message) marshal(b *codec.Buffer) error {
-	if err := m.marshalKnownFields(b); err != nil {
-		return err
-	}
-	return m.marshalUnknownFields(b)
-}
-
-func (m *Message) marshalKnownFields(b *codec.Buffer) error {
-	for _, tag := range m.knownFieldTags() {
-		itag := int32(tag)
-		val := m.values[itag]
-		fd := m.FindFieldDescriptor(itag)
-		if fd == nil {
-			panic(fmt.Sprintf("Couldn't find field for tag %d", itag))
-		}
-		if err := b.EncodeFieldValue(fd, val); err != nil {
-			return err
-		}
-	}
-	return nil
-}
-
-func (m *Message) marshalUnknownFields(b *codec.Buffer) error {
-	for _, tag := range m.unknownFieldTags() {
-		itag := int32(tag)
-		sl := m.unknownFields[itag]
-		for _, u := range sl {
-			if err := b.EncodeTagAndWireType(itag, u.Encoding); err != nil {
-				return err
-			}
-			switch u.Encoding {
-			case proto.WireBytes:
-				if err := b.EncodeRawBytes(u.Contents); err != nil {
-					return err
-				}
-			case proto.WireStartGroup:
-				_, _ = b.Write(u.Contents)
-				if err := b.EncodeTagAndWireType(itag, proto.WireEndGroup); err != nil {
-					return err
-				}
-			case proto.WireFixed32:
-				if err := b.EncodeFixed32(u.Value); err != nil {
-					return err
-				}
-			case proto.WireFixed64:
-				if err := b.EncodeFixed64(u.Value); err != nil {
-					return err
-				}
-			case proto.WireVarint:
-				if err := b.EncodeVarint(u.Value); err != nil {
-					return err
-				}
-			default:
-				return codec.ErrBadWireType
-			}
-		}
-	}
-	return nil
-}
-
-// Unmarshal de-serializes the message that is present in the given bytes into
-// this message. It first resets the current message. It returns an error if the
-// given bytes do not contain a valid encoding of this message type.
-func (m *Message) Unmarshal(b []byte) error {
-	m.Reset()
-	if err := m.UnmarshalMerge(b); err != nil {
-		return err
-	}
-	return m.Validate()
-}
-
-// UnmarshalMerge de-serializes the message that is present in the given bytes
-// into this message. Unlike Unmarshal, it does not first reset the message,
-// instead merging the data in the given bytes into the existing data in this
-// message.
-func (m *Message) UnmarshalMerge(b []byte) error {
-	return m.unmarshal(codec.NewBuffer(b), false)
-}
-
-func (m *Message) unmarshal(buf *codec.Buffer, isGroup bool) error {
-	for !buf.EOF() {
-		fd, val, err := buf.DecodeFieldValue(m.FindFieldDescriptor, m.mf)
-		if err != nil {
-			if err == codec.ErrWireTypeEndGroup {
-				if isGroup {
-					// finished parsing group
-					return nil
-				}
-				return codec.ErrBadWireType
-			}
-			return err
-		}
-
-		if fd == nil {
-			if m.unknownFields == nil {
-				m.unknownFields = map[int32][]UnknownField{}
-			}
-			uv := val.(codec.UnknownField)
-			u := UnknownField{
-				Encoding: uv.Encoding,
-				Value:    uv.Value,
-				Contents: uv.Contents,
-			}
-			m.unknownFields[uv.Tag] = append(m.unknownFields[uv.Tag], u)
-		} else if err := mergeField(m, fd, val); err != nil {
-			return err
-		}
-	}
-	if isGroup {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
diff --git a/vendor/github.com/jhump/protoreflect/dynamic/doc.go b/vendor/github.com/jhump/protoreflect/dynamic/doc.go
deleted file mode 100644
index c329fcd..0000000
--- a/vendor/github.com/jhump/protoreflect/dynamic/doc.go
+++ /dev/null
@@ -1,163 +0,0 @@
-// Package dynamic provides an implementation for a dynamic protobuf message.
-//
-// The dynamic message is essentially a message descriptor along with a map of
-// tag numbers to values. It has a broad API for interacting with the message,
-// including inspection and modification. Generally, most operations have two
-// forms: a regular method that panics on bad input or error and a "Try" form
-// of the method that will instead return an error.
-//
-// A dynamic message can optionally be constructed with a MessageFactory. The
-// MessageFactory has various registries that may be used by the dynamic message,
-// such as during de-serialization. The message factory is "inherited" by any
-// other dynamic messages created, such as nested messages that are created
-// during de-serialization. Similarly, any dynamic message created using
-// MessageFactory.NewMessage will be associated with that factory, which in turn
-// will be used to create other messages or parse extension fields during
-// de-serialization.
-//
-//
-// Field Types
-//
-// The types of values expected by setters and returned by getters are the
-// same as protoc generates for scalar fields. For repeated fields, there are
-// methods for getting and setting values at a particular index or for adding
-// an element. Similarly, for map fields, there are methods for getting and
-// setting values for a particular key.
-//
-// If you use GetField for a repeated field, it will return a copy of all
-// elements as a slice []interface{}. Similarly, using GetField for a map field
-// will return a copy of all mappings as a map[interface{}]interface{}. You can
-// also use SetField to supply an entire slice or map for repeated or map fields.
-// The slice need not be []interface{} but can actually be typed according to
-// the field's expected type. For example, a repeated uint64 field can be set
-// using a slice of type []uint64.
-//
-// Descriptors for map fields describe them as repeated fields with a nested
-// message type. The nested message type is a special generated type that
-// represents a single mapping: key and value pair. The dynamic message has some
-// special affordances for this representation. For example, you can use
-// SetField to set a map field using a slice of these entry messages. Internally,
-// the slice of entries will be converted to an actual map. Similarly, you can
-// use AddRepeatedField with an entry message to add (or overwrite) a mapping.
-// However, you cannot use GetRepeatedField or SetRepeatedField to modify maps,
-// since those take numeric index arguments which are not relevant to maps
-// (since maps in Go have no defined ordering).
-//
-// When setting field values in dynamic messages, the type-checking is lenient
-// in that it accepts any named type with the right kind. So a string field can
-// be assigned to any type that is defined as a string. Enum fields require
-// int32 values (or any type that is defined as an int32).
-//
-// Unlike normal use of numeric values in Go, values will be automatically
-// widened when assigned. So, for example, an int64 field can be set using an
-// int32 value since it can be safely widened without truncation or loss of
-// precision. Similar goes for uint32 values being converted to uint64 and
-// float32 being converted to float64. Narrowing conversions are not done,
-// however. Also, unsigned values will never be automatically converted to
-// signed (and vice versa), and floating point values will never be
-// automatically converted to integral values (and vice versa). Since the bit
-// width of int and uint fields is allowed to be platform dependent, but will
-// always be less than or equal to 64, they can only be used as values for
-// int64 and uint64 fields, respectively. They cannot be used to set int32 or
-// uint32 fields, which includes enums fields.
-//
-// Fields whose type is a nested message can have values set to either other
-// dynamic messages or generated messages (e.g. pointers to structs generated by
-// protoc). Getting a value for such a field will return the actual type it is
-// set to (e.g. either a dynamic message or a generated message). If the value
-// is not set and the message uses proto2 syntax, the default message returned
-// will be whatever is returned by the dynamic message's MessageFactory (if the
-// dynamic message was not created with a factory, it will use the logic of the
-// zero value factory). In most typical cases, it will return a dynamic message,
-// but if the factory is configured with a KnownTypeRegistry, or if the field's
-// type is a well-known type, it will return a zero value generated message.
-//
-//
-// Unrecognized Fields
-//
-// Unrecognized fields are preserved by the dynamic message when unmarshaling
-// from the standard binary format. If the message's MessageFactory was
-// configured with an ExtensionRegistry, it will be used to identify and parse
-// extension fields for the message.
-//
-// Unrecognized fields can dynamically become recognized fields if the
-// application attempts to retrieve an unrecognized field's value using a
-// FieldDescriptor. In this case, the given FieldDescriptor is used to parse the
-// unknown field and move the parsed value into the message's set of known
-// fields. This behavior is most suited to the use of extensions, where an
-// ExtensionRegistry is not setup with all known extensions ahead of time. But
-// it can even happen for non-extension fields! Here's an example scenario where
-// a non-extension field can initially be unknown and become known:
-//
-//   1. A dynamic message is created with a descriptor, A, and then
-//      de-serialized from a stream of bytes. The stream includes an
-//      unrecognized tag T. The message will include tag T in its unrecognized
-//      field set.
-//   2. Another call site retrieves a newer descriptor, A', which includes a
-//      newly added field with tag T.
-//   3. That other call site then uses a FieldDescriptor to access the value of
-//      the new field. This will cause the dynamic message to parse the bytes
-//      for the unknown tag T and store them as a known field.
-//   4. Subsequent operations for tag T, including setting the field using only
-//      tag number or de-serializing a stream that includes tag T, will operate
-//      as if that tag were part of the original descriptor, A.
-//
-//
-// Compatibility
-//
-// In addition to implementing the proto.Message interface, the included
-// Message type also provides an XXX_MessageName() method, so it can work with
-// proto.MessageName. And it provides a Descriptor() method that behaves just
-// like the method of the same signature in messages generated by protoc.
-// Because of this, it is actually compatible with proto.Message in many (though
-// not all) contexts. In particular, it is compatible with proto.Marshal and
-// proto.Unmarshal for serializing and de-serializing messages.
-//
-// The dynamic message supports binary and text marshaling, using protobuf's
-// well-defined binary format and the same text format that protoc-generated
-// types use. It also supports JSON serialization/de-serialization by
-// implementing the json.Marshaler and json.Unmarshaler interfaces. And dynamic
-// messages can safely be used with the jsonpb package for JSON serialization
-// and de-serialization.
-//
-// In addition to implementing the proto.Message interface and numerous related
-// methods, it also provides inter-op with generated messages via conversion.
-// The ConvertTo, ConvertFrom, MergeInto, and MergeFrom methods copy message
-// contents from a dynamic message to a generated message and vice versa.
-//
-// When copying from a generated message into a dynamic message, if the
-// generated message contains fields unknown to the dynamic message (e.g. not
-// present in the descriptor used to create the dynamic message), these fields
-// become known to the dynamic message (as per behavior described above in
-// "Unrecognized Fields"). If the generated message has unrecognized fields of
-// its own, including unrecognized extensions, they are preserved in the dynamic
-// message. It is possible that the dynamic message knows about fields that the
-// generated message did not, like if it has a different version of the
-// descriptor or its MessageFactory has an ExtensionRegistry that knows about
-// different extensions than were linked into the program. In this case, these
-// unrecognized fields in the generated message will be known fields in the
-// dynamic message.
-//
-// Similarly, when copying from a dynamic message into a generated message, if
-// the dynamic message has unrecognized fields they can be preserved in the
-// generated message (currently only for syntax proto2 since proto3 generated
-// messages do not preserve unrecognized fields). If the generated message knows
-// about fields that the dynamic message does not, these unrecognized fields may
-// become known fields in the generated message.
-//
-//
-// Registries
-//
-// This package also contains a couple of registries, for managing known types
-// and descriptors.
-//
-// The KnownTypeRegistry allows de-serialization of a dynamic message to use
-// generated message types, instead of dynamic messages, for some kinds of
-// nested message fields. This is particularly useful for working with proto
-// messages that have special encodings as JSON (e.g. the well-known types),
-// since the dynamic message does not try to handle these special cases in its
-// JSON marshaling facilities.
-//
-// The ExtensionRegistry allows for recognizing and parsing extensions fields
-// (for proto2 messages).
-package dynamic
diff --git a/vendor/github.com/jhump/protoreflect/dynamic/dynamic_message.go b/vendor/github.com/jhump/protoreflect/dynamic/dynamic_message.go
deleted file mode 100644
index 3f19d6b..0000000
--- a/vendor/github.com/jhump/protoreflect/dynamic/dynamic_message.go
+++ /dev/null
@@ -1,2688 +0,0 @@
-package dynamic
-
-import (
-	"bytes"
-	"compress/gzip"
-	"errors"
-	"fmt"
-	"reflect"
-	"sort"
-	"strings"
-
-	"github.com/golang/protobuf/proto"
-	"github.com/golang/protobuf/protoc-gen-go/descriptor"
-
-	"github.com/jhump/protoreflect/codec"
-	"github.com/jhump/protoreflect/desc"
-)
-
-// ErrUnknownTagNumber is an error that is returned when an operation refers
-// to an unknown tag number.
-var ErrUnknownTagNumber = errors.New("unknown tag number")
-
-// UnknownTagNumberError is the same as ErrUnknownTagNumber.
-// Deprecated: use ErrUnknownTagNumber
-var UnknownTagNumberError = ErrUnknownTagNumber
-
-// ErrUnknownFieldName is an error that is returned when an operation refers
-// to an unknown field name.
-var ErrUnknownFieldName = errors.New("unknown field name")
-
-// UnknownFieldNameError is the same as ErrUnknownFieldName.
-// Deprecated: use ErrUnknownFieldName
-var UnknownFieldNameError = ErrUnknownFieldName
-
-// ErrFieldIsNotMap is an error that is returned when map-related operations
-// are attempted with fields that are not maps.
-var ErrFieldIsNotMap = errors.New("field is not a map type")
-
-// FieldIsNotMapError is the same as ErrFieldIsNotMap.
-// Deprecated: use ErrFieldIsNotMap
-var FieldIsNotMapError = ErrFieldIsNotMap
-
-// ErrFieldIsNotRepeated is an error that is returned when repeated field
-// operations are attempted with fields that are not repeated.
-var ErrFieldIsNotRepeated = errors.New("field is not repeated")
-
-// FieldIsNotRepeatedError is the same as ErrFieldIsNotRepeated.
-// Deprecated: use ErrFieldIsNotRepeated
-var FieldIsNotRepeatedError = ErrFieldIsNotRepeated
-
-// ErrIndexOutOfRange is an error that is returned when an invalid index is
-// provided when access a single element of a repeated field.
-var ErrIndexOutOfRange = errors.New("index is out of range")
-
-// IndexOutOfRangeError is the same as ErrIndexOutOfRange.
-// Deprecated: use ErrIndexOutOfRange
-var IndexOutOfRangeError = ErrIndexOutOfRange
-
-// ErrNumericOverflow is an error returned by operations that encounter a
-// numeric value that is too large, for example de-serializing a value into an
-// int32 field when the value is larger that can fit into a 32-bit value.
-var ErrNumericOverflow = errors.New("numeric value is out of range")
-
-// NumericOverflowError is the same as ErrNumericOverflow.
-// Deprecated: use ErrNumericOverflow
-var NumericOverflowError = ErrNumericOverflow
-
-var typeOfProtoMessage = reflect.TypeOf((*proto.Message)(nil)).Elem()
-var typeOfDynamicMessage = reflect.TypeOf((*Message)(nil))
-var typeOfBytes = reflect.TypeOf(([]byte)(nil))
-
-// Message is a dynamic protobuf message. Instead of a generated struct,
-// like most protobuf messages, this is a map of field number to values and
-// a message descriptor, which is used to validate the field values and
-// also to de-serialize messages (from the standard binary format, as well
-// as from the text format and from JSON).
-type Message struct {
-	md            *desc.MessageDescriptor
-	er            *ExtensionRegistry
-	mf            *MessageFactory
-	extraFields   map[int32]*desc.FieldDescriptor
-	values        map[int32]interface{}
-	unknownFields map[int32][]UnknownField
-}
-
-// UnknownField represents a field that was parsed from the binary wire
-// format for a message, but was not a recognized field number. Enough
-// information is preserved so that re-serializing the message won't lose
-// any of the unrecognized data.
-type UnknownField struct {
-	// Encoding indicates how the unknown field was encoded on the wire. If it
-	// is proto.WireBytes or proto.WireGroupStart then Contents will be set to
-	// the raw bytes. If it is proto.WireTypeFixed32 then the data is in the least
-	// significant 32 bits of Value. Otherwise, the data is in all 64 bits of
-	// Value.
-	Encoding int8
-	Contents []byte
-	Value    uint64
-}
-
-// NewMessage creates a new dynamic message for the type represented by the given
-// message descriptor. During de-serialization, a default MessageFactory is used to
-// instantiate any nested message fields and no extension fields will be parsed. To
-// use a custom MessageFactory or ExtensionRegistry, use MessageFactory.NewMessage.
-func NewMessage(md *desc.MessageDescriptor) *Message {
-	return NewMessageWithMessageFactory(md, nil)
-}
-
-// NewMessageWithExtensionRegistry creates a new dynamic message for the type
-// represented by the given message descriptor. During de-serialization, the given
-// ExtensionRegistry is used to parse extension fields and nested messages will be
-// instantiated using dynamic.NewMessageFactoryWithExtensionRegistry(er).
-func NewMessageWithExtensionRegistry(md *desc.MessageDescriptor, er *ExtensionRegistry) *Message {
-	mf := NewMessageFactoryWithExtensionRegistry(er)
-	return NewMessageWithMessageFactory(md, mf)
-}
-
-// NewMessageWithMessageFactory creates a new dynamic message for the type
-// represented by the given message descriptor. During de-serialization, the given
-// MessageFactory is used to instantiate nested messages.
-func NewMessageWithMessageFactory(md *desc.MessageDescriptor, mf *MessageFactory) *Message {
-	var er *ExtensionRegistry
-	if mf != nil {
-		er = mf.er
-	}
-	return &Message{
-		md: md,
-		mf: mf,
-		er: er,
-	}
-}
-
-// AsDynamicMessage converts the given message to a dynamic message. If the
-// given message is dynamic, it is returned. Otherwise, a dynamic message is
-// created using NewMessage.
-func AsDynamicMessage(msg proto.Message) (*Message, error) {
-	return AsDynamicMessageWithMessageFactory(msg, nil)
-}
-
-// AsDynamicMessageWithExtensionRegistry converts the given message to a dynamic
-// message. If the given message is dynamic, it is returned. Otherwise, a
-// dynamic message is created using NewMessageWithExtensionRegistry.
-func AsDynamicMessageWithExtensionRegistry(msg proto.Message, er *ExtensionRegistry) (*Message, error) {
-	mf := NewMessageFactoryWithExtensionRegistry(er)
-	return AsDynamicMessageWithMessageFactory(msg, mf)
-}
-
-// AsDynamicMessageWithMessageFactory converts the given message to a dynamic
-// message. If the given message is dynamic, it is returned. Otherwise, a
-// dynamic message is created using NewMessageWithMessageFactory.
-func AsDynamicMessageWithMessageFactory(msg proto.Message, mf *MessageFactory) (*Message, error) {
-	if dm, ok := msg.(*Message); ok {
-		return dm, nil
-	}
-	md, err := desc.LoadMessageDescriptorForMessage(msg)
-	if err != nil {
-		return nil, err
-	}
-	dm := NewMessageWithMessageFactory(md, mf)
-	err = dm.mergeFrom(msg)
-	if err != nil {
-		return nil, err
-	}
-	return dm, nil
-}
-
-// GetMessageDescriptor returns a descriptor for this message's type.
-func (m *Message) GetMessageDescriptor() *desc.MessageDescriptor {
-	return m.md
-}
-
-// GetKnownFields returns a slice of descriptors for all known fields. The
-// fields will not be in any defined order.
-func (m *Message) GetKnownFields() []*desc.FieldDescriptor {
-	if len(m.extraFields) == 0 {
-		return m.md.GetFields()
-	}
-	flds := make([]*desc.FieldDescriptor, len(m.md.GetFields()), len(m.md.GetFields())+len(m.extraFields))
-	copy(flds, m.md.GetFields())
-	for _, fld := range m.extraFields {
-		if !fld.IsExtension() {
-			flds = append(flds, fld)
-		}
-	}
-	return flds
-}
-
-// GetKnownExtensions returns a slice of descriptors for all extensions known by
-// the message's extension registry. The fields will not be in any defined order.
-func (m *Message) GetKnownExtensions() []*desc.FieldDescriptor {
-	if !m.md.IsExtendable() {
-		return nil
-	}
-	exts := m.er.AllExtensionsForType(m.md.GetFullyQualifiedName())
-	for _, fld := range m.extraFields {
-		if fld.IsExtension() {
-			exts = append(exts, fld)
-		}
-	}
-	return exts
-}
-
-// GetUnknownFields returns a slice of tag numbers for all unknown fields that
-// this message contains. The tags will not be in any defined order.
-func (m *Message) GetUnknownFields() []int32 {
-	flds := make([]int32, 0, len(m.unknownFields))
-	for tag := range m.unknownFields {
-		flds = append(flds, tag)
-	}
-	return flds
-}
-
-// Descriptor returns the serialized form of the file descriptor in which the
-// message was defined and a path to the message type therein. This mimics the
-// method of the same name on message types generated by protoc.
-func (m *Message) Descriptor() ([]byte, []int) {
-	// get encoded file descriptor
-	b, err := proto.Marshal(m.md.GetFile().AsProto())
-	if err != nil {
-		panic(fmt.Sprintf("failed to get encoded descriptor for %s: %v", m.md.GetFile().GetName(), err))
-	}
-	var zippedBytes bytes.Buffer
-	w := gzip.NewWriter(&zippedBytes)
-	if _, err := w.Write(b); err != nil {
-		panic(fmt.Sprintf("failed to get encoded descriptor for %s: %v", m.md.GetFile().GetName(), err))
-	}
-	if err := w.Close(); err != nil {
-		panic(fmt.Sprintf("failed to get an encoded descriptor for %s: %v", m.md.GetFile().GetName(), err))
-	}
-
-	// and path to message
-	path := []int{}
-	var d desc.Descriptor
-	name := m.md.GetFullyQualifiedName()
-	for d = m.md.GetParent(); d != nil; name, d = d.GetFullyQualifiedName(), d.GetParent() {
-		found := false
-		switch d := d.(type) {
-		case (*desc.FileDescriptor):
-			for i, md := range d.GetMessageTypes() {
-				if md.GetFullyQualifiedName() == name {
-					found = true
-					path = append(path, i)
-				}
-			}
-		case (*desc.MessageDescriptor):
-			for i, md := range d.GetNestedMessageTypes() {
-				if md.GetFullyQualifiedName() == name {
-					found = true
-					path = append(path, i)
-				}
-			}
-		}
-		if !found {
-			panic(fmt.Sprintf("failed to compute descriptor path for %s", m.md.GetFullyQualifiedName()))
-		}
-	}
-	// reverse the path
-	i := 0
-	j := len(path) - 1
-	for i < j {
-		path[i], path[j] = path[j], path[i]
-		i++
-		j--
-	}
-
-	return zippedBytes.Bytes(), path
-}
-
-// XXX_MessageName returns the fully qualified name of this message's type. This
-// allows dynamic messages to be used with proto.MessageName.
-func (m *Message) XXX_MessageName() string {
-	return m.md.GetFullyQualifiedName()
-}
-
-// FindFieldDescriptor returns a field descriptor for the given tag number. This
-// searches known fields in the descriptor, known fields discovered during calls
-// to GetField or SetField, and extension fields known by the message's extension
-// registry. It returns nil if the tag is unknown.
-func (m *Message) FindFieldDescriptor(tagNumber int32) *desc.FieldDescriptor {
-	fd := m.md.FindFieldByNumber(tagNumber)
-	if fd != nil {
-		return fd
-	}
-	fd = m.er.FindExtension(m.md.GetFullyQualifiedName(), tagNumber)
-	if fd != nil {
-		return fd
-	}
-	return m.extraFields[tagNumber]
-}
-
-// FindFieldDescriptorByName returns a field descriptor for the given field
-// name. This searches known fields in the descriptor, known fields discovered
-// during calls to GetField or SetField, and extension fields known by the
-// message's extension registry. It returns nil if the name is unknown. If the
-// given name refers to an extension, it should be fully qualified and may be
-// optionally enclosed in parentheses or brackets.
-func (m *Message) FindFieldDescriptorByName(name string) *desc.FieldDescriptor {
-	if name == "" {
-		return nil
-	}
-	fd := m.md.FindFieldByName(name)
-	if fd != nil {
-		return fd
-	}
-	mustBeExt := false
-	if name[0] == '(' {
-		if name[len(name)-1] != ')' {
-			// malformed name
-			return nil
-		}
-		mustBeExt = true
-		name = name[1 : len(name)-1]
-	} else if name[0] == '[' {
-		if name[len(name)-1] != ']' {
-			// malformed name
-			return nil
-		}
-		mustBeExt = true
-		name = name[1 : len(name)-1]
-	}
-	fd = m.er.FindExtensionByName(m.md.GetFullyQualifiedName(), name)
-	if fd != nil {
-		return fd
-	}
-	for _, fd := range m.extraFields {
-		if fd.IsExtension() && name == fd.GetFullyQualifiedName() {
-			return fd
-		} else if !mustBeExt && !fd.IsExtension() && name == fd.GetName() {
-			return fd
-		}
-	}
-
-	return nil
-}
-
-// FindFieldDescriptorByJSONName returns a field descriptor for the given JSON
-// name. This searches known fields in the descriptor, known fields discovered
-// during calls to GetField or SetField, and extension fields known by the
-// message's extension registry. If no field matches the given JSON name, it
-// will fall back to searching field names (e.g. FindFieldDescriptorByName). If
-// this also yields no match, nil is returned.
-func (m *Message) FindFieldDescriptorByJSONName(name string) *desc.FieldDescriptor {
-	if name == "" {
-		return nil
-	}
-	fd := m.md.FindFieldByJSONName(name)
-	if fd != nil {
-		return fd
-	}
-	mustBeExt := false
-	if name[0] == '(' {
-		if name[len(name)-1] != ')' {
-			// malformed name
-			return nil
-		}
-		mustBeExt = true
-		name = name[1 : len(name)-1]
-	} else if name[0] == '[' {
-		if name[len(name)-1] != ']' {
-			// malformed name
-			return nil
-		}
-		mustBeExt = true
-		name = name[1 : len(name)-1]
-	}
-	fd = m.er.FindExtensionByJSONName(m.md.GetFullyQualifiedName(), name)
-	if fd != nil {
-		return fd
-	}
-	for _, fd := range m.extraFields {
-		if fd.IsExtension() && name == fd.GetFullyQualifiedJSONName() {
-			return fd
-		} else if !mustBeExt && !fd.IsExtension() && name == fd.GetJSONName() {
-			return fd
-		}
-	}
-
-	// try non-JSON names
-	return m.FindFieldDescriptorByName(name)
-}
-
-func (m *Message) checkField(fd *desc.FieldDescriptor) error {
-	return checkField(fd, m.md)
-}
-
-func checkField(fd *desc.FieldDescriptor, md *desc.MessageDescriptor) error {
-	if fd.GetOwner().GetFullyQualifiedName() != md.GetFullyQualifiedName() {
-		return fmt.Errorf("given field, %s, is for wrong message type: %s; expecting %s", fd.GetName(), fd.GetOwner().GetFullyQualifiedName(), md.GetFullyQualifiedName())
-	}
-	if fd.IsExtension() && !md.IsExtension(fd.GetNumber()) {
-		return fmt.Errorf("given field, %s, is an extension but is not in message extension range: %v", fd.GetFullyQualifiedName(), md.GetExtensionRanges())
-	}
-	return nil
-}
-
-// GetField returns the value for the given field descriptor. It panics if an
-// error is encountered. See TryGetField.
-func (m *Message) GetField(fd *desc.FieldDescriptor) interface{} {
-	if v, err := m.TryGetField(fd); err != nil {
-		panic(err.Error())
-	} else {
-		return v
-	}
-}
-
-// TryGetField returns the value for the given field descriptor. An error is
-// returned if the given field descriptor does not belong to the right message
-// type.
-//
-// The Go type of the returned value, for scalar fields, is the same as protoc
-// would generate for the field (in a non-dynamic message). The table below
-// lists the scalar types and the corresponding Go types.
-//  +-------------------------+-----------+
-//  |       Declared Type     |  Go Type  |
-//  +-------------------------+-----------+
-//  | int32, sint32, sfixed32 | int32     |
-//  | int64, sint64, sfixed64 | int64     |
-//  | uint32, fixed32         | uint32    |
-//  | uint64, fixed64         | uint64    |
-//  | float                   | float32   |
-//  | double                  | double32  |
-//  | bool                    | bool      |
-//  | string                  | string    |
-//  | bytes                   | []byte    |
-//  +-------------------------+-----------+
-//
-// Values for enum fields will always be int32 values. You can use the enum
-// descriptor associated with the field to lookup value names with those values.
-// Values for message type fields may be an instance of the generated type *or*
-// may be another *dynamic.Message that represents the type.
-//
-// If the given field is a map field, the returned type will be
-// map[interface{}]interface{}. The actual concrete types of keys and values is
-// as described above. If the given field is a (non-map) repeated field, the
-// returned type is always []interface{}; the type of the actual elements is as
-// described above.
-//
-// If this message has no value for the given field, its default value is
-// returned. If the message is defined in a file with "proto3" syntax, the
-// default is always the zero value for the field. The default value for map and
-// repeated fields is a nil map or slice (respectively). For field's whose types
-// is a message, the default value is an empty message for "proto2" syntax or a
-// nil message for "proto3" syntax. Note that the in the latter case, a non-nil
-// interface with a nil pointer is returned, not a nil interface. Also note that
-// whether the returned value is an empty message or nil depends on if *this*
-// message was defined as "proto3" syntax, not the message type referred to by
-// the field's type.
-//
-// If the given field descriptor is not known (e.g. not present in the message
-// descriptor) but corresponds to an unknown field, the unknown value will be
-// parsed and become known. The parsed value will be returned, or an error will
-// be returned if the unknown value cannot be parsed according to the field
-// descriptor's type information.
-func (m *Message) TryGetField(fd *desc.FieldDescriptor) (interface{}, error) {
-	if err := m.checkField(fd); err != nil {
-		return nil, err
-	}
-	return m.getField(fd)
-}
-
-// GetFieldByName returns the value for the field with the given name. It panics
-// if an error is encountered. See TryGetFieldByName.
-func (m *Message) GetFieldByName(name string) interface{} {
-	if v, err := m.TryGetFieldByName(name); err != nil {
-		panic(err.Error())
-	} else {
-		return v
-	}
-}
-
-// TryGetFieldByName returns the value for the field with the given name. An
-// error is returned if the given name is unknown. If the given name refers to
-// an extension field, it should be fully qualified and optionally enclosed in
-// parenthesis or brackets.
-//
-// If this message has no value for the given field, its default value is
-// returned. (See TryGetField for more info on types and default field values.)
-func (m *Message) TryGetFieldByName(name string) (interface{}, error) {
-	fd := m.FindFieldDescriptorByName(name)
-	if fd == nil {
-		return nil, UnknownFieldNameError
-	}
-	return m.getField(fd)
-}
-
-// GetFieldByNumber returns the value for the field with the given tag number.
-// It panics if an error is encountered. See TryGetFieldByNumber.
-func (m *Message) GetFieldByNumber(tagNumber int) interface{} {
-	if v, err := m.TryGetFieldByNumber(tagNumber); err != nil {
-		panic(err.Error())
-	} else {
-		return v
-	}
-}
-
-// TryGetFieldByNumber returns the value for the field with the given tag
-// number. An error is returned if the given tag is unknown.
-//
-// If this message has no value for the given field, its default value is
-// returned. (See TryGetField for more info on types and default field values.)
-func (m *Message) TryGetFieldByNumber(tagNumber int) (interface{}, error) {
-	fd := m.FindFieldDescriptor(int32(tagNumber))
-	if fd == nil {
-		return nil, UnknownTagNumberError
-	}
-	return m.getField(fd)
-}
-
-func (m *Message) getField(fd *desc.FieldDescriptor) (interface{}, error) {
-	return m.doGetField(fd, false)
-}
-
-func (m *Message) doGetField(fd *desc.FieldDescriptor, nilIfAbsent bool) (interface{}, error) {
-	res := m.values[fd.GetNumber()]
-	if res == nil {
-		var err error
-		if res, err = m.parseUnknownField(fd); err != nil {
-			return nil, err
-		}
-		if res == nil {
-			if nilIfAbsent {
-				return nil, nil
-			} else {
-				def := fd.GetDefaultValue()
-				if def != nil {
-					return def, nil
-				}
-				// GetDefaultValue only returns nil for message types
-				md := fd.GetMessageType()
-				if md.IsProto3() {
-					// try to return a proper nil pointer
-					msgType := proto.MessageType(md.GetFullyQualifiedName())
-					if msgType != nil && msgType.Implements(typeOfProtoMessage) {
-						return reflect.Zero(msgType).Interface().(proto.Message), nil
-					}
-					// fallback to nil dynamic message pointer
-					return (*Message)(nil), nil
-				} else {
-					// for proto2, return default instance of message
-					return m.mf.NewMessage(md), nil
-				}
-			}
-		}
-	}
-	rt := reflect.TypeOf(res)
-	if rt.Kind() == reflect.Map {
-		// make defensive copies to prevent caller from storing illegal keys and values
-		m := res.(map[interface{}]interface{})
-		res := map[interface{}]interface{}{}
-		for k, v := range m {
-			res[k] = v
-		}
-		return res, nil
-	} else if rt.Kind() == reflect.Slice && rt != typeOfBytes {
-		// make defensive copies to prevent caller from storing illegal elements
-		sl := res.([]interface{})
-		res := make([]interface{}, len(sl))
-		copy(res, sl)
-		return res, nil
-	}
-	return res, nil
-}
-
-// HasField returns true if this message has a value for the given field. If the
-// given field is not valid (e.g. belongs to a different message type), false is
-// returned. If this message is defined in a file with "proto3" syntax, this
-// will return false even if a field was explicitly assigned its zero value (the
-// zero values for a field are intentionally indistinguishable from absent).
-func (m *Message) HasField(fd *desc.FieldDescriptor) bool {
-	if err := m.checkField(fd); err != nil {
-		return false
-	}
-	return m.HasFieldNumber(int(fd.GetNumber()))
-}
-
-// HasFieldName returns true if this message has a value for a field with the
-// given name. If the given name is unknown, this returns false.
-func (m *Message) HasFieldName(name string) bool {
-	fd := m.FindFieldDescriptorByName(name)
-	if fd == nil {
-		return false
-	}
-	return m.HasFieldNumber(int(fd.GetNumber()))
-}
-
-// HasFieldNumber returns true if this message has a value for a field with the
-// given tag number. If the given tag is unknown, this returns false.
-func (m *Message) HasFieldNumber(tagNumber int) bool {
-	if _, ok := m.values[int32(tagNumber)]; ok {
-		return true
-	}
-	_, ok := m.unknownFields[int32(tagNumber)]
-	return ok
-}
-
-// SetField sets the value for the given field descriptor to the given value. It
-// panics if an error is encountered. See TrySetField.
-func (m *Message) SetField(fd *desc.FieldDescriptor, val interface{}) {
-	if err := m.TrySetField(fd, val); err != nil {
-		panic(err.Error())
-	}
-}
-
-// TrySetField sets the value for the given field descriptor to the given value.
-// An error is returned if the given field descriptor does not belong to the
-// right message type or if the given value is not a correct/compatible type for
-// the given field.
-//
-// The Go type expected for a field  is the same as TryGetField would return for
-// the field. So message values can be supplied as either the correct generated
-// message type or as a *dynamic.Message.
-//
-// Since it is cumbersome to work with dynamic messages, some concessions are
-// made to simplify usage regarding types:
-//
-//  1. If a numeric type is provided that can be converted *without loss or
-//     overflow*, it is accepted. This allows for setting int64 fields using int
-//     or int32 values. Similarly for uint64 with uint and uint32 values and for
-//     float64 fields with float32 values.
-//  2. The value can be a named type, as long as its underlying type is correct.
-//  3. Map and repeated fields can be set using any kind of concrete map or
-//     slice type, as long as the values within are all of the correct type. So
-//     a field defined as a 'map<string, int32>` can be set using a
-//     map[string]int32, a map[string]interface{}, or even a
-//     map[interface{}]interface{}.
-//  4. Finally, dynamic code that chooses to not treat maps as a special-case
-//     find that they can set map fields using a slice where each element is a
-//     message that matches the implicit map-entry field message type.
-//
-// If the given field descriptor is not known (e.g. not present in the message
-// descriptor) it will become known. Subsequent operations using tag numbers or
-// names will be able to resolve the newly-known type. If the message has a
-// value for the unknown value, it is cleared, replaced by the given known
-// value.
-func (m *Message) TrySetField(fd *desc.FieldDescriptor, val interface{}) error {
-	if err := m.checkField(fd); err != nil {
-		return err
-	}
-	return m.setField(fd, val)
-}
-
-// SetFieldByName sets the value for the field with the given name to the given
-// value. It panics if an error is encountered. See TrySetFieldByName.
-func (m *Message) SetFieldByName(name string, val interface{}) {
-	if err := m.TrySetFieldByName(name, val); err != nil {
-		panic(err.Error())
-	}
-}
-
-// TrySetFieldByName sets the value for the field with the given name to the
-// given value. An error is returned if the given name is unknown or if the
-// given value has an incorrect type. If the given name refers to an extension
-// field, it should be fully qualified and optionally enclosed in parenthesis or
-// brackets.
-//
-// (See TrySetField for more info on types.)
-func (m *Message) TrySetFieldByName(name string, val interface{}) error {
-	fd := m.FindFieldDescriptorByName(name)
-	if fd == nil {
-		return UnknownFieldNameError
-	}
-	return m.setField(fd, val)
-}
-
-// SetFieldByNumber sets the value for the field with the given tag number to
-// the given value. It panics if an error is encountered. See
-// TrySetFieldByNumber.
-func (m *Message) SetFieldByNumber(tagNumber int, val interface{}) {
-	if err := m.TrySetFieldByNumber(tagNumber, val); err != nil {
-		panic(err.Error())
-	}
-}
-
-// TrySetFieldByNumber sets the value for the field with the given tag number to
-// the given value. An error is returned if the given tag is unknown or if the
-// given value has an incorrect type.
-//
-// (See TrySetField for more info on types.)
-func (m *Message) TrySetFieldByNumber(tagNumber int, val interface{}) error {
-	fd := m.FindFieldDescriptor(int32(tagNumber))
-	if fd == nil {
-		return UnknownTagNumberError
-	}
-	return m.setField(fd, val)
-}
-
-func (m *Message) setField(fd *desc.FieldDescriptor, val interface{}) error {
-	var err error
-	if val, err = validFieldValue(fd, val); err != nil {
-		return err
-	}
-	m.internalSetField(fd, val)
-	return nil
-}
-
-func (m *Message) internalSetField(fd *desc.FieldDescriptor, val interface{}) {
-	if fd.IsRepeated() {
-		// Unset fields and zero-length fields are indistinguishable, in both
-		// proto2 and proto3 syntax
-		if reflect.ValueOf(val).Len() == 0 {
-			if m.values != nil {
-				delete(m.values, fd.GetNumber())
-			}
-			return
-		}
-	} else if m.md.IsProto3() && fd.GetOneOf() == nil {
-		// proto3 considers fields that are set to their zero value as unset
-		// (we already handled repeated fields above)
-		var equal bool
-		if b, ok := val.([]byte); ok {
-			// can't compare slices, so we have to special-case []byte values
-			equal = ok && bytes.Equal(b, fd.GetDefaultValue().([]byte))
-		} else {
-			defVal := fd.GetDefaultValue()
-			equal = defVal == val
-			if !equal && defVal == nil {
-				// above just checks if value is the nil interface,
-				// but we should also test if the given value is a
-				// nil pointer
-				rv := reflect.ValueOf(val)
-				if rv.Kind() == reflect.Ptr && rv.IsNil() {
-					equal = true
-				}
-			}
-		}
-		if equal {
-			if m.values != nil {
-				delete(m.values, fd.GetNumber())
-			}
-			return
-		}
-	}
-	if m.values == nil {
-		m.values = map[int32]interface{}{}
-	}
-	m.values[fd.GetNumber()] = val
-	// if this field is part of a one-of, make sure all other one-of choices are cleared
-	od := fd.GetOneOf()
-	if od != nil {
-		for _, other := range od.GetChoices() {
-			if other.GetNumber() != fd.GetNumber() {
-				delete(m.values, other.GetNumber())
-			}
-		}
-	}
-	// also clear any unknown fields
-	if m.unknownFields != nil {
-		delete(m.unknownFields, fd.GetNumber())
-	}
-	// and add this field if it was previously unknown
-	if existing := m.FindFieldDescriptor(fd.GetNumber()); existing == nil {
-		m.addField(fd)
-	}
-}
-
-func (m *Message) addField(fd *desc.FieldDescriptor) {
-	if m.extraFields == nil {
-		m.extraFields = map[int32]*desc.FieldDescriptor{}
-	}
-	m.extraFields[fd.GetNumber()] = fd
-}
-
-// ClearField removes any value for the given field. It panics if an error is
-// encountered. See TryClearField.
-func (m *Message) ClearField(fd *desc.FieldDescriptor) {
-	if err := m.TryClearField(fd); err != nil {
-		panic(err.Error())
-	}
-}
-
-// TryClearField removes any value for the given field. An error is returned if
-// the given field descriptor does not belong to the right message type.
-func (m *Message) TryClearField(fd *desc.FieldDescriptor) error {
-	if err := m.checkField(fd); err != nil {
-		return err
-	}
-	m.clearField(fd)
-	return nil
-}
-
-// ClearFieldByName removes any value for the field with the given name. It
-// panics if an error is encountered. See TryClearFieldByName.
-func (m *Message) ClearFieldByName(name string) {
-	if err := m.TryClearFieldByName(name); err != nil {
-		panic(err.Error())
-	}
-}
-
-// TryClearFieldByName removes any value for the field with the given name. An
-// error is returned if the given name is unknown. If the given name refers to
-// an extension field, it should be fully qualified and optionally enclosed in
-// parenthesis or brackets.
-func (m *Message) TryClearFieldByName(name string) error {
-	fd := m.FindFieldDescriptorByName(name)
-	if fd == nil {
-		return UnknownFieldNameError
-	}
-	m.clearField(fd)
-	return nil
-}
-
-// ClearFieldByNumber removes any value for the field with the given tag number.
-// It panics if an error is encountered. See TryClearFieldByNumber.
-func (m *Message) ClearFieldByNumber(tagNumber int) {
-	if err := m.TryClearFieldByNumber(tagNumber); err != nil {
-		panic(err.Error())
-	}
-}
-
-// TryClearFieldByNumber removes any value for the field with the given tag
-// number. An error is returned if the given tag is unknown.
-func (m *Message) TryClearFieldByNumber(tagNumber int) error {
-	fd := m.FindFieldDescriptor(int32(tagNumber))
-	if fd == nil {
-		return UnknownTagNumberError
-	}
-	m.clearField(fd)
-	return nil
-}
-
-func (m *Message) clearField(fd *desc.FieldDescriptor) {
-	// clear value
-	if m.values != nil {
-		delete(m.values, fd.GetNumber())
-	}
-	// also clear any unknown fields
-	if m.unknownFields != nil {
-		delete(m.unknownFields, fd.GetNumber())
-	}
-	// and add this field if it was previously unknown
-	if existing := m.FindFieldDescriptor(fd.GetNumber()); existing == nil {
-		m.addField(fd)
-	}
-}
-
-// GetOneOfField returns which of the given one-of's fields is set and the
-// corresponding value. It panics if an error is encountered. See
-// TryGetOneOfField.
-func (m *Message) GetOneOfField(od *desc.OneOfDescriptor) (*desc.FieldDescriptor, interface{}) {
-	if fd, val, err := m.TryGetOneOfField(od); err != nil {
-		panic(err.Error())
-	} else {
-		return fd, val
-	}
-}
-
-// TryGetOneOfField returns which of the given one-of's fields is set and the
-// corresponding value. An error is returned if the given one-of belongs to the
-// wrong message type. If the given one-of has no field set, this method will
-// return nil, nil.
-//
-// The type of the value, if one is set, is the same as would be returned by
-// TryGetField using the returned field descriptor.
-//
-// Like with TryGetField, if the given one-of contains any fields that are not
-// known (e.g. not present in this message's descriptor), they will become known
-// and any unknown value will be parsed (and become a known value on success).
-func (m *Message) TryGetOneOfField(od *desc.OneOfDescriptor) (*desc.FieldDescriptor, interface{}, error) {
-	if od.GetOwner().GetFullyQualifiedName() != m.md.GetFullyQualifiedName() {
-		return nil, nil, fmt.Errorf("given one-of, %s, is for wrong message type: %s; expecting %s", od.GetName(), od.GetOwner().GetFullyQualifiedName(), m.md.GetFullyQualifiedName())
-	}
-	for _, fd := range od.GetChoices() {
-		val, err := m.doGetField(fd, true)
-		if err != nil {
-			return nil, nil, err
-		}
-		if val != nil {
-			return fd, val, nil
-		}
-	}
-	return nil, nil, nil
-}
-
-// ClearOneOfField removes any value for any of the given one-of's fields. It
-// panics if an error is encountered. See TryClearOneOfField.
-func (m *Message) ClearOneOfField(od *desc.OneOfDescriptor) {
-	if err := m.TryClearOneOfField(od); err != nil {
-		panic(err.Error())
-	}
-}
-
-// TryClearOneOfField removes any value for any of the given one-of's fields. An
-// error is returned if the given one-of descriptor does not belong to the right
-// message type.
-func (m *Message) TryClearOneOfField(od *desc.OneOfDescriptor) error {
-	if od.GetOwner().GetFullyQualifiedName() != m.md.GetFullyQualifiedName() {
-		return fmt.Errorf("given one-of, %s, is for wrong message type: %s; expecting %s", od.GetName(), od.GetOwner().GetFullyQualifiedName(), m.md.GetFullyQualifiedName())
-	}
-	for _, fd := range od.GetChoices() {
-		m.clearField(fd)
-	}
-	return nil
-}
-
-// GetMapField returns the value for the given map field descriptor and given
-// key. It panics if an error is encountered. See TryGetMapField.
-func (m *Message) GetMapField(fd *desc.FieldDescriptor, key interface{}) interface{} {
-	if v, err := m.TryGetMapField(fd, key); err != nil {
-		panic(err.Error())
-	} else {
-		return v
-	}
-}
-
-// TryGetMapField returns the value for the given map field descriptor and given
-// key. An error is returned if the given field descriptor does not belong to
-// the right message type or if it is not a map field.
-//
-// If the map field does not contain the requested key, this method returns
-// nil, nil. The Go type of the value returned mirrors the type that protoc
-// would generate for the field. (See TryGetField for more details on types).
-//
-// If the given field descriptor is not known (e.g. not present in the message
-// descriptor) but corresponds to an unknown field, the unknown value will be
-// parsed and become known. The parsed value will be searched for the requested
-// key and any value returned. An error will be returned if the unknown value
-// cannot be parsed according to the field descriptor's type information.
-func (m *Message) TryGetMapField(fd *desc.FieldDescriptor, key interface{}) (interface{}, error) {
-	if err := m.checkField(fd); err != nil {
-		return nil, err
-	}
-	return m.getMapField(fd, key)
-}
-
-// GetMapFieldByName returns the value for the map field with the given name and
-// given key. It panics if an error is encountered. See TryGetMapFieldByName.
-func (m *Message) GetMapFieldByName(name string, key interface{}) interface{} {
-	if v, err := m.TryGetMapFieldByName(name, key); err != nil {
-		panic(err.Error())
-	} else {
-		return v
-	}
-}
-
-// TryGetMapFieldByName returns the value for the map field with the given name
-// and given key. An error is returned if the given name is unknown or if it
-// names a field that is not a map field.
-//
-// If this message has no value for the given field or the value has no value
-// for the requested key, then this method returns nil, nil.
-//
-// (See TryGetField for more info on types.)
-func (m *Message) TryGetMapFieldByName(name string, key interface{}) (interface{}, error) {
-	fd := m.FindFieldDescriptorByName(name)
-	if fd == nil {
-		return nil, UnknownFieldNameError
-	}
-	return m.getMapField(fd, key)
-}
-
-// GetMapFieldByNumber returns the value for the map field with the given tag
-// number and given key. It panics if an error is encountered. See
-// TryGetMapFieldByNumber.
-func (m *Message) GetMapFieldByNumber(tagNumber int, key interface{}) interface{} {
-	if v, err := m.TryGetMapFieldByNumber(tagNumber, key); err != nil {
-		panic(err.Error())
-	} else {
-		return v
-	}
-}
-
-// TryGetMapFieldByNumber returns the value for the map field with the given tag
-// number and given key. An error is returned if the given tag is unknown or if
-// it indicates a field that is not a map field.
-//
-// If this message has no value for the given field or the value has no value
-// for the requested key, then this method returns nil, nil.
-//
-// (See TryGetField for more info on types.)
-func (m *Message) TryGetMapFieldByNumber(tagNumber int, key interface{}) (interface{}, error) {
-	fd := m.FindFieldDescriptor(int32(tagNumber))
-	if fd == nil {
-		return nil, UnknownTagNumberError
-	}
-	return m.getMapField(fd, key)
-}
-
-func (m *Message) getMapField(fd *desc.FieldDescriptor, key interface{}) (interface{}, error) {
-	if !fd.IsMap() {
-		return nil, FieldIsNotMapError
-	}
-	kfd := fd.GetMessageType().GetFields()[0]
-	ki, err := validElementFieldValue(kfd, key)
-	if err != nil {
-		return nil, err
-	}
-	mp := m.values[fd.GetNumber()]
-	if mp == nil {
-		if mp, err = m.parseUnknownField(fd); err != nil {
-			return nil, err
-		} else if mp == nil {
-			return nil, nil
-		}
-	}
-	return mp.(map[interface{}]interface{})[ki], nil
-}
-
-// ForEachMapFieldEntry executes the given function for each entry in the map
-// value for the given field descriptor. It stops iteration if the function
-// returns false. It panics if an error is encountered. See
-// TryForEachMapFieldEntry.
-func (m *Message) ForEachMapFieldEntry(fd *desc.FieldDescriptor, fn func(key, val interface{}) bool) {
-	if err := m.TryForEachMapFieldEntry(fd, fn); err != nil {
-		panic(err.Error())
-	}
-}
-
-// TryForEachMapFieldEntry executes the given function for each entry in the map
-// value for the given field descriptor. An error is returned if the given field
-// descriptor does not belong to the right message type or if it is not a  map
-// field.
-//
-// Iteration ends either when all entries have been examined or when the given
-// function returns false. So the function is expected to return true for normal
-// iteration and false to break out. If this message has no value for the given
-// field, it returns without invoking the given function.
-//
-// The Go type of the key and value supplied to the function mirrors the type
-// that protoc would generate for the field. (See TryGetField for more details
-// on types).
-//
-// If the given field descriptor is not known (e.g. not present in the message
-// descriptor) but corresponds to an unknown field, the unknown value will be
-// parsed and become known. The parsed value will be searched for the requested
-// key and any value returned. An error will be returned if the unknown value
-// cannot be parsed according to the field descriptor's type information.
-func (m *Message) TryForEachMapFieldEntry(fd *desc.FieldDescriptor, fn func(key, val interface{}) bool) error {
-	if err := m.checkField(fd); err != nil {
-		return err
-	}
-	return m.forEachMapFieldEntry(fd, fn)
-}
-
-// ForEachMapFieldEntryByName executes the given function for each entry in the
-// map value for the field with the given name. It stops iteration if the
-// function returns false. It panics if an error is encountered. See
-// TryForEachMapFieldEntryByName.
-func (m *Message) ForEachMapFieldEntryByName(name string, fn func(key, val interface{}) bool) {
-	if err := m.TryForEachMapFieldEntryByName(name, fn); err != nil {
-		panic(err.Error())
-	}
-}
-
-// TryForEachMapFieldEntryByName executes the given function for each entry in
-// the map value for the field with the given name. It stops iteration if the
-// function returns false. An error is returned if the given name is unknown or
-// if it names a field that is not a map field.
-//
-// If this message has no value for the given field, it returns without ever
-// invoking the given function.
-//
-// (See TryGetField for more info on types supplied to the function.)
-func (m *Message) TryForEachMapFieldEntryByName(name string, fn func(key, val interface{}) bool) error {
-	fd := m.FindFieldDescriptorByName(name)
-	if fd == nil {
-		return UnknownFieldNameError
-	}
-	return m.forEachMapFieldEntry(fd, fn)
-}
-
-// ForEachMapFieldEntryByNumber executes the given function for each entry in
-// the map value for the field with the given tag number. It stops iteration if
-// the function returns false. It panics if an error is encountered. See
-// TryForEachMapFieldEntryByNumber.
-func (m *Message) ForEachMapFieldEntryByNumber(tagNumber int, fn func(key, val interface{}) bool) {
-	if err := m.TryForEachMapFieldEntryByNumber(tagNumber, fn); err != nil {
-		panic(err.Error())
-	}
-}
-
-// TryForEachMapFieldEntryByNumber executes the given function for each entry in
-// the map value for the field with the given tag number. It stops iteration if
-// the function returns false. An error is returned if the given tag is unknown
-// or if it indicates a field that is not a map field.
-//
-// If this message has no value for the given field, it returns without ever
-// invoking the given function.
-//
-// (See TryGetField for more info on types supplied to the function.)
-func (m *Message) TryForEachMapFieldEntryByNumber(tagNumber int, fn func(key, val interface{}) bool) error {
-	fd := m.FindFieldDescriptor(int32(tagNumber))
-	if fd == nil {
-		return UnknownTagNumberError
-	}
-	return m.forEachMapFieldEntry(fd, fn)
-}
-
-func (m *Message) forEachMapFieldEntry(fd *desc.FieldDescriptor, fn func(key, val interface{}) bool) error {
-	if !fd.IsMap() {
-		return FieldIsNotMapError
-	}
-	mp := m.values[fd.GetNumber()]
-	if mp == nil {
-		if mp, err := m.parseUnknownField(fd); err != nil {
-			return err
-		} else if mp == nil {
-			return nil
-		}
-	}
-	for k, v := range mp.(map[interface{}]interface{}) {
-		if !fn(k, v) {
-			break
-		}
-	}
-	return nil
-}
-
-// PutMapField sets the value for the given map field descriptor and given key
-// to the given value. It panics if an error is encountered. See TryPutMapField.
-func (m *Message) PutMapField(fd *desc.FieldDescriptor, key interface{}, val interface{}) {
-	if err := m.TryPutMapField(fd, key, val); err != nil {
-		panic(err.Error())
-	}
-}
-
-// TryPutMapField sets the value for the given map field descriptor and given
-// key to the given value. An error is returned if the given field descriptor
-// does not belong to the right message type, if the given field is not a map
-// field, or if the given value is not a correct/compatible type for the given
-// field.
-//
-// The Go type expected for a field  is the same as required by TrySetField for
-// a field with the same type as the map's value type.
-//
-// If the given field descriptor is not known (e.g. not present in the message
-// descriptor) it will become known. Subsequent operations using tag numbers or
-// names will be able to resolve the newly-known type. If the message has a
-// value for the unknown value, it is cleared, replaced by the given known
-// value.
-func (m *Message) TryPutMapField(fd *desc.FieldDescriptor, key interface{}, val interface{}) error {
-	if err := m.checkField(fd); err != nil {
-		return err
-	}
-	return m.putMapField(fd, key, val)
-}
-
-// PutMapFieldByName sets the value for the map field with the given name and
-// given key to the given value. It panics if an error is encountered. See
-// TryPutMapFieldByName.
-func (m *Message) PutMapFieldByName(name string, key interface{}, val interface{}) {
-	if err := m.TryPutMapFieldByName(name, key, val); err != nil {
-		panic(err.Error())
-	}
-}
-
-// TryPutMapFieldByName sets the value for the map field with the given name and
-// the given key to the given value. An error is returned if the given name is
-// unknown, if it names a field that is not a map, or if the given value has an
-// incorrect type.
-//
-// (See TrySetField for more info on types.)
-func (m *Message) TryPutMapFieldByName(name string, key interface{}, val interface{}) error {
-	fd := m.FindFieldDescriptorByName(name)
-	if fd == nil {
-		return UnknownFieldNameError
-	}
-	return m.putMapField(fd, key, val)
-}
-
-// PutMapFieldByNumber sets the value for the map field with the given tag
-// number and given key to the given value. It panics if an error is
-// encountered. See TryPutMapFieldByNumber.
-func (m *Message) PutMapFieldByNumber(tagNumber int, key interface{}, val interface{}) {
-	if err := m.TryPutMapFieldByNumber(tagNumber, key, val); err != nil {
-		panic(err.Error())
-	}
-}
-
-// TryPutMapFieldByNumber sets the value for the map field with the given tag
-// number and the given key to the given value. An error is returned if the
-// given tag is unknown, if it indicates a field that is not a map, or if the
-// given value has an incorrect type.
-//
-// (See TrySetField for more info on types.)
-func (m *Message) TryPutMapFieldByNumber(tagNumber int, key interface{}, val interface{}) error {
-	fd := m.FindFieldDescriptor(int32(tagNumber))
-	if fd == nil {
-		return UnknownTagNumberError
-	}
-	return m.putMapField(fd, key, val)
-}
-
-func (m *Message) putMapField(fd *desc.FieldDescriptor, key interface{}, val interface{}) error {
-	if !fd.IsMap() {
-		return FieldIsNotMapError
-	}
-	kfd := fd.GetMessageType().GetFields()[0]
-	ki, err := validElementFieldValue(kfd, key)
-	if err != nil {
-		return err
-	}
-	vfd := fd.GetMessageType().GetFields()[1]
-	vi, err := validElementFieldValue(vfd, val)
-	if err != nil {
-		return err
-	}
-	mp := m.values[fd.GetNumber()]
-	if mp == nil {
-		if mp, err = m.parseUnknownField(fd); err != nil {
-			return err
-		} else if mp == nil {
-			m.internalSetField(fd, map[interface{}]interface{}{ki: vi})
-			return nil
-		}
-	}
-	mp.(map[interface{}]interface{})[ki] = vi
-	return nil
-}
-
-// RemoveMapField changes the value for the given field descriptor by removing
-// any value associated with the given key. It panics if an error is
-// encountered. See TryRemoveMapField.
-func (m *Message) RemoveMapField(fd *desc.FieldDescriptor, key interface{}) {
-	if err := m.TryRemoveMapField(fd, key); err != nil {
-		panic(err.Error())
-	}
-}
-
-// TryRemoveMapField changes the value for the given field descriptor by
-// removing any value associated with the given key. An error is returned if the
-// given field descriptor does not belong to the right message type or if the
-// given field is not a map field.
-//
-// If the given field descriptor is not known (e.g. not present in the message
-// descriptor) it will become known. Subsequent operations using tag numbers or
-// names will be able to resolve the newly-known type. If the message has a
-// value for the unknown value, it is parsed and any value for the given key
-// removed.
-func (m *Message) TryRemoveMapField(fd *desc.FieldDescriptor, key interface{}) error {
-	if err := m.checkField(fd); err != nil {
-		return err
-	}
-	return m.removeMapField(fd, key)
-}
-
-// RemoveMapFieldByName changes the value for the field with the given name by
-// removing any value associated with the given key. It panics if an error is
-// encountered. See TryRemoveMapFieldByName.
-func (m *Message) RemoveMapFieldByName(name string, key interface{}) {
-	if err := m.TryRemoveMapFieldByName(name, key); err != nil {
-		panic(err.Error())
-	}
-}
-
-// TryRemoveMapFieldByName changes the value for the field with the given name
-// by removing any value associated with the given key. An error is returned if
-// the given name is unknown or if it names a field that is not a map.
-func (m *Message) TryRemoveMapFieldByName(name string, key interface{}) error {
-	fd := m.FindFieldDescriptorByName(name)
-	if fd == nil {
-		return UnknownFieldNameError
-	}
-	return m.removeMapField(fd, key)
-}
-
-// RemoveMapFieldByNumber changes the value for the field with the given tag
-// number by removing any value associated with the given key. It panics if an
-// error is encountered. See TryRemoveMapFieldByNumber.
-func (m *Message) RemoveMapFieldByNumber(tagNumber int, key interface{}) {
-	if err := m.TryRemoveMapFieldByNumber(tagNumber, key); err != nil {
-		panic(err.Error())
-	}
-}
-
-// TryRemoveMapFieldByNumber changes the value for the field with the given tag
-// number by removing any value associated with the given key. An error is
-// returned if the given tag is unknown or if it indicates a field that is not
-// a map.
-func (m *Message) TryRemoveMapFieldByNumber(tagNumber int, key interface{}) error {
-	fd := m.FindFieldDescriptor(int32(tagNumber))
-	if fd == nil {
-		return UnknownTagNumberError
-	}
-	return m.removeMapField(fd, key)
-}
-
-func (m *Message) removeMapField(fd *desc.FieldDescriptor, key interface{}) error {
-	if !fd.IsMap() {
-		return FieldIsNotMapError
-	}
-	kfd := fd.GetMessageType().GetFields()[0]
-	ki, err := validElementFieldValue(kfd, key)
-	if err != nil {
-		return err
-	}
-	mp := m.values[fd.GetNumber()]
-	if mp == nil {
-		if mp, err = m.parseUnknownField(fd); err != nil {
-			return err
-		} else if mp == nil {
-			return nil
-		}
-	}
-	res := mp.(map[interface{}]interface{})
-	delete(res, ki)
-	if len(res) == 0 {
-		delete(m.values, fd.GetNumber())
-	}
-	return nil
-}
-
-// FieldLength returns the number of elements in this message for the given
-// field descriptor. It panics if an error is encountered. See TryFieldLength.
-func (m *Message) FieldLength(fd *desc.FieldDescriptor) int {
-	l, err := m.TryFieldLength(fd)
-	if err != nil {
-		panic(err.Error())
-	}
-	return l
-}
-
-// TryFieldLength returns the number of elements in this message for the given
-// field descriptor. An error is returned if the given field descriptor does not
-// belong to the right message type or if it is neither a map field nor a
-// repeated field.
-func (m *Message) TryFieldLength(fd *desc.FieldDescriptor) (int, error) {
-	if err := m.checkField(fd); err != nil {
-		return 0, err
-	}
-	return m.fieldLength(fd)
-}
-
-// FieldLengthByName returns the number of elements in this message for the
-// field with the given name. It panics if an error is encountered. See
-// TryFieldLengthByName.
-func (m *Message) FieldLengthByName(name string) int {
-	l, err := m.TryFieldLengthByName(name)
-	if err != nil {
-		panic(err.Error())
-	}
-	return l
-}
-
-// TryFieldLengthByName returns the number of elements in this message for the
-// field with the given name. An error is returned if the given name is unknown
-// or if the named field is neither a map field nor a repeated field.
-func (m *Message) TryFieldLengthByName(name string) (int, error) {
-	fd := m.FindFieldDescriptorByName(name)
-	if fd == nil {
-		return 0, UnknownFieldNameError
-	}
-	return m.fieldLength(fd)
-}
-
-// FieldLengthByNumber returns the number of elements in this message for the
-// field with the given tag number. It panics if an error is encountered. See
-// TryFieldLengthByNumber.
-func (m *Message) FieldLengthByNumber(tagNumber int32) int {
-	l, err := m.TryFieldLengthByNumber(tagNumber)
-	if err != nil {
-		panic(err.Error())
-	}
-	return l
-}
-
-// TryFieldLengthByNumber returns the number of elements in this message for the
-// field with the given tag number. An error is returned if the given tag is
-// unknown or if the named field is neither a map field nor a repeated field.
-func (m *Message) TryFieldLengthByNumber(tagNumber int32) (int, error) {
-	fd := m.FindFieldDescriptor(int32(tagNumber))
-	if fd == nil {
-		return 0, UnknownTagNumberError
-	}
-	return m.fieldLength(fd)
-}
-
-func (m *Message) fieldLength(fd *desc.FieldDescriptor) (int, error) {
-	if !fd.IsRepeated() {
-		return 0, FieldIsNotRepeatedError
-	}
-	val := m.values[fd.GetNumber()]
-	if val == nil {
-		var err error
-		if val, err = m.parseUnknownField(fd); err != nil {
-			return 0, err
-		} else if val == nil {
-			return 0, nil
-		}
-	}
-	if sl, ok := val.([]interface{}); ok {
-		return len(sl), nil
-	} else if mp, ok := val.(map[interface{}]interface{}); ok {
-		return len(mp), nil
-	}
-	return 0, nil
-}
-
-// GetRepeatedField returns the value for the given repeated field descriptor at
-// the given index. It panics if an error is encountered. See
-// TryGetRepeatedField.
-func (m *Message) GetRepeatedField(fd *desc.FieldDescriptor, index int) interface{} {
-	if v, err := m.TryGetRepeatedField(fd, index); err != nil {
-		panic(err.Error())
-	} else {
-		return v
-	}
-}
-
-// TryGetRepeatedField returns the value for the given repeated field descriptor
-// at the given index. An error is returned if the given field descriptor does
-// not belong to the right message type, if it is not a repeated field, or if
-// the given index is out of range (less than zero or greater than or equal to
-// the length of the repeated field). Also, even though map fields technically
-// are repeated fields, if the given field is a map field an error will result:
-// map representation does not lend itself to random access by index.
-//
-// The Go type of the value returned mirrors the type that protoc would generate
-// for the field's element type. (See TryGetField for more details on types).
-//
-// If the given field descriptor is not known (e.g. not present in the message
-// descriptor) but corresponds to an unknown field, the unknown value will be
-// parsed and become known. The value at the given index in the parsed value
-// will be returned. An error will be returned if the unknown value cannot be
-// parsed according to the field descriptor's type information.
-func (m *Message) TryGetRepeatedField(fd *desc.FieldDescriptor, index int) (interface{}, error) {
-	if index < 0 {
-		return nil, IndexOutOfRangeError
-	}
-	if err := m.checkField(fd); err != nil {
-		return nil, err
-	}
-	return m.getRepeatedField(fd, index)
-}
-
-// GetRepeatedFieldByName returns the value for the repeated field with the
-// given name at the given index. It panics if an error is encountered. See
-// TryGetRepeatedFieldByName.
-func (m *Message) GetRepeatedFieldByName(name string, index int) interface{} {
-	if v, err := m.TryGetRepeatedFieldByName(name, index); err != nil {
-		panic(err.Error())
-	} else {
-		return v
-	}
-}
-
-// TryGetRepeatedFieldByName returns the value for the repeated field with the
-// given name at the given index. An error is returned if the given name is
-// unknown, if it names a field that is not a repeated field (or is a map
-// field), or if the given index is out of range (less than zero or greater
-// than or equal to the length of the repeated field).
-//
-// (See TryGetField for more info on types.)
-func (m *Message) TryGetRepeatedFieldByName(name string, index int) (interface{}, error) {
-	if index < 0 {
-		return nil, IndexOutOfRangeError
-	}
-	fd := m.FindFieldDescriptorByName(name)
-	if fd == nil {
-		return nil, UnknownFieldNameError
-	}
-	return m.getRepeatedField(fd, index)
-}
-
-// GetRepeatedFieldByNumber returns the value for the repeated field with the
-// given tag number at the given index. It panics if an error is encountered.
-// See TryGetRepeatedFieldByNumber.
-func (m *Message) GetRepeatedFieldByNumber(tagNumber int, index int) interface{} {
-	if v, err := m.TryGetRepeatedFieldByNumber(tagNumber, index); err != nil {
-		panic(err.Error())
-	} else {
-		return v
-	}
-}
-
-// TryGetRepeatedFieldByNumber returns the value for the repeated field with the
-// given tag number at the given index. An error is returned if the given tag is
-// unknown, if it indicates a field that is not a repeated field (or is a map
-// field), or if the given index is out of range (less than zero or greater than
-// or equal to the length of the repeated field).
-//
-// (See TryGetField for more info on types.)
-func (m *Message) TryGetRepeatedFieldByNumber(tagNumber int, index int) (interface{}, error) {
-	if index < 0 {
-		return nil, IndexOutOfRangeError
-	}
-	fd := m.FindFieldDescriptor(int32(tagNumber))
-	if fd == nil {
-		return nil, UnknownTagNumberError
-	}
-	return m.getRepeatedField(fd, index)
-}
-
-func (m *Message) getRepeatedField(fd *desc.FieldDescriptor, index int) (interface{}, error) {
-	if fd.IsMap() || !fd.IsRepeated() {
-		return nil, FieldIsNotRepeatedError
-	}
-	sl := m.values[fd.GetNumber()]
-	if sl == nil {
-		var err error
-		if sl, err = m.parseUnknownField(fd); err != nil {
-			return nil, err
-		} else if sl == nil {
-			return nil, IndexOutOfRangeError
-		}
-	}
-	res := sl.([]interface{})
-	if index >= len(res) {
-		return nil, IndexOutOfRangeError
-	}
-	return res[index], nil
-}
-
-// AddRepeatedField appends the given value to the given repeated field. It
-// panics if an error is encountered. See TryAddRepeatedField.
-func (m *Message) AddRepeatedField(fd *desc.FieldDescriptor, val interface{}) {
-	if err := m.TryAddRepeatedField(fd, val); err != nil {
-		panic(err.Error())
-	}
-}
-
-// TryAddRepeatedField appends the given value to the given repeated field. An
-// error is returned if the given field descriptor does not belong to the right
-// message type, if the given field is not repeated, or if the given value is
-// not a correct/compatible type for the given field. If the given field is a
-// map field, the call will succeed if the given value is an instance of the
-// map's entry message type.
-//
-// The Go type expected for a field  is the same as required by TrySetField for
-// a non-repeated field of the same type.
-//
-// If the given field descriptor is not known (e.g. not present in the message
-// descriptor) it will become known. Subsequent operations using tag numbers or
-// names will be able to resolve the newly-known type. If the message has a
-// value for the unknown value, it is parsed and the given value is appended to
-// it.
-func (m *Message) TryAddRepeatedField(fd *desc.FieldDescriptor, val interface{}) error {
-	if err := m.checkField(fd); err != nil {
-		return err
-	}
-	return m.addRepeatedField(fd, val)
-}
-
-// AddRepeatedFieldByName appends the given value to the repeated field with the
-// given name. It panics if an error is encountered. See
-// TryAddRepeatedFieldByName.
-func (m *Message) AddRepeatedFieldByName(name string, val interface{}) {
-	if err := m.TryAddRepeatedFieldByName(name, val); err != nil {
-		panic(err.Error())
-	}
-}
-
-// TryAddRepeatedFieldByName appends the given value to the repeated field with
-// the given name. An error is returned if the given name is unknown, if it
-// names a field that is not repeated, or if the given value has an incorrect
-// type.
-//
-// (See TrySetField for more info on types.)
-func (m *Message) TryAddRepeatedFieldByName(name string, val interface{}) error {
-	fd := m.FindFieldDescriptorByName(name)
-	if fd == nil {
-		return UnknownFieldNameError
-	}
-	return m.addRepeatedField(fd, val)
-}
-
-// AddRepeatedFieldByNumber appends the given value to the repeated field with
-// the given tag number. It panics if an error is encountered. See
-// TryAddRepeatedFieldByNumber.
-func (m *Message) AddRepeatedFieldByNumber(tagNumber int, val interface{}) {
-	if err := m.TryAddRepeatedFieldByNumber(tagNumber, val); err != nil {
-		panic(err.Error())
-	}
-}
-
-// TryAddRepeatedFieldByNumber appends the given value to the repeated field
-// with the given tag number. An error is returned if the given tag is unknown,
-// if it indicates a field that is not repeated, or if the given value has an
-// incorrect type.
-//
-// (See TrySetField for more info on types.)
-func (m *Message) TryAddRepeatedFieldByNumber(tagNumber int, val interface{}) error {
-	fd := m.FindFieldDescriptor(int32(tagNumber))
-	if fd == nil {
-		return UnknownTagNumberError
-	}
-	return m.addRepeatedField(fd, val)
-}
-
-func (m *Message) addRepeatedField(fd *desc.FieldDescriptor, val interface{}) error {
-	if !fd.IsRepeated() {
-		return FieldIsNotRepeatedError
-	}
-	val, err := validElementFieldValue(fd, val)
-	if err != nil {
-		return err
-	}
-
-	if fd.IsMap() {
-		// We're lenient. Just as we allow setting a map field to a slice of entry messages, we also allow
-		// adding entries one at a time (as if the field were a normal repeated field).
-		msg := val.(proto.Message)
-		dm, err := asDynamicMessage(msg, fd.GetMessageType(), m.mf)
-		if err != nil {
-			return err
-		}
-		k, err := dm.TryGetFieldByNumber(1)
-		if err != nil {
-			return err
-		}
-		v, err := dm.TryGetFieldByNumber(2)
-		if err != nil {
-			return err
-		}
-		return m.putMapField(fd, k, v)
-	}
-
-	sl := m.values[fd.GetNumber()]
-	if sl == nil {
-		if sl, err = m.parseUnknownField(fd); err != nil {
-			return err
-		} else if sl == nil {
-			sl = []interface{}{}
-		}
-	}
-	res := sl.([]interface{})
-	res = append(res, val)
-	m.internalSetField(fd, res)
-	return nil
-}
-
-// SetRepeatedField sets the value for the given repeated field descriptor and
-// given index to the given value. It panics if an error is encountered. See
-// SetRepeatedField.
-func (m *Message) SetRepeatedField(fd *desc.FieldDescriptor, index int, val interface{}) {
-	if err := m.TrySetRepeatedField(fd, index, val); err != nil {
-		panic(err.Error())
-	}
-}
-
-// TrySetRepeatedField sets the value for the given repeated field descriptor
-// and given index to the given value. An error is returned if the given field
-// descriptor does not belong to the right message type, if the given field is
-// not repeated, or if the given value is not a correct/compatible type for the
-// given field. Also, even though map fields technically are repeated fields, if
-// the given field is a map field an error will result: map representation does
-// not lend itself to random access by index.
-//
-// The Go type expected for a field  is the same as required by TrySetField for
-// a non-repeated field of the same type.
-//
-// If the given field descriptor is not known (e.g. not present in the message
-// descriptor) it will become known. Subsequent operations using tag numbers or
-// names will be able to resolve the newly-known type. If the message has a
-// value for the unknown value, it is parsed and the element at the given index
-// is replaced with the given value.
-func (m *Message) TrySetRepeatedField(fd *desc.FieldDescriptor, index int, val interface{}) error {
-	if index < 0 {
-		return IndexOutOfRangeError
-	}
-	if err := m.checkField(fd); err != nil {
-		return err
-	}
-	return m.setRepeatedField(fd, index, val)
-}
-
-// SetRepeatedFieldByName sets the value for the repeated field with the given
-// name and given index to the given value. It panics if an error is
-// encountered. See TrySetRepeatedFieldByName.
-func (m *Message) SetRepeatedFieldByName(name string, index int, val interface{}) {
-	if err := m.TrySetRepeatedFieldByName(name, index, val); err != nil {
-		panic(err.Error())
-	}
-}
-
-// TrySetRepeatedFieldByName sets the value for the repeated field with the
-// given name and the given index to the given value. An error is returned if
-// the given name is unknown, if it names a field that is not repeated (or is a
-// map field), or if the given value has an incorrect type.
-//
-// (See TrySetField for more info on types.)
-func (m *Message) TrySetRepeatedFieldByName(name string, index int, val interface{}) error {
-	if index < 0 {
-		return IndexOutOfRangeError
-	}
-	fd := m.FindFieldDescriptorByName(name)
-	if fd == nil {
-		return UnknownFieldNameError
-	}
-	return m.setRepeatedField(fd, index, val)
-}
-
-// SetRepeatedFieldByNumber sets the value for the repeated field with the given
-// tag number and given index to the given value. It panics if an error is
-// encountered. See TrySetRepeatedFieldByNumber.
-func (m *Message) SetRepeatedFieldByNumber(tagNumber int, index int, val interface{}) {
-	if err := m.TrySetRepeatedFieldByNumber(tagNumber, index, val); err != nil {
-		panic(err.Error())
-	}
-}
-
-// TrySetRepeatedFieldByNumber sets the value for the repeated field with the
-// given tag number and the given index to the given value. An error is returned
-// if the given tag is unknown, if it indicates a field that is not repeated (or
-// is a map field), or if the given value has an incorrect type.
-//
-// (See TrySetField for more info on types.)
-func (m *Message) TrySetRepeatedFieldByNumber(tagNumber int, index int, val interface{}) error {
-	if index < 0 {
-		return IndexOutOfRangeError
-	}
-	fd := m.FindFieldDescriptor(int32(tagNumber))
-	if fd == nil {
-		return UnknownTagNumberError
-	}
-	return m.setRepeatedField(fd, index, val)
-}
-
-func (m *Message) setRepeatedField(fd *desc.FieldDescriptor, index int, val interface{}) error {
-	if fd.IsMap() || !fd.IsRepeated() {
-		return FieldIsNotRepeatedError
-	}
-	val, err := validElementFieldValue(fd, val)
-	if err != nil {
-		return err
-	}
-	sl := m.values[fd.GetNumber()]
-	if sl == nil {
-		if sl, err = m.parseUnknownField(fd); err != nil {
-			return err
-		} else if sl == nil {
-			return IndexOutOfRangeError
-		}
-	}
-	res := sl.([]interface{})
-	if index >= len(res) {
-		return IndexOutOfRangeError
-	}
-	res[index] = val
-	return nil
-}
-
-// GetUnknownField gets the value(s) for the given unknown tag number. If this
-// message has no unknown fields with the given tag, nil is returned.
-func (m *Message) GetUnknownField(tagNumber int32) []UnknownField {
-	if u, ok := m.unknownFields[tagNumber]; ok {
-		return u
-	} else {
-		return nil
-	}
-}
-
-func (m *Message) parseUnknownField(fd *desc.FieldDescriptor) (interface{}, error) {
-	unks, ok := m.unknownFields[fd.GetNumber()]
-	if !ok {
-		return nil, nil
-	}
-	var v interface{}
-	var sl []interface{}
-	var mp map[interface{}]interface{}
-	if fd.IsMap() {
-		mp = map[interface{}]interface{}{}
-	}
-	var err error
-	for _, unk := range unks {
-		var val interface{}
-		if unk.Encoding == proto.WireBytes || unk.Encoding == proto.WireStartGroup {
-			val, err = codec.DecodeLengthDelimitedField(fd, unk.Contents, m.mf)
-		} else {
-			val, err = codec.DecodeScalarField(fd, unk.Value)
-		}
-		if err != nil {
-			return nil, err
-		}
-		if fd.IsMap() {
-			newEntry := val.(*Message)
-			kk, err := newEntry.TryGetFieldByNumber(1)
-			if err != nil {
-				return nil, err
-			}
-			vv, err := newEntry.TryGetFieldByNumber(2)
-			if err != nil {
-				return nil, err
-			}
-			mp[kk] = vv
-			v = mp
-		} else if fd.IsRepeated() {
-			t := reflect.TypeOf(val)
-			if t.Kind() == reflect.Slice && t != typeOfBytes {
-				// append slices if we unmarshalled a packed repeated field
-				newVals := val.([]interface{})
-				sl = append(sl, newVals...)
-			} else {
-				sl = append(sl, val)
-			}
-			v = sl
-		} else {
-			v = val
-		}
-	}
-	m.internalSetField(fd, v)
-	return v, nil
-}
-
-func validFieldValue(fd *desc.FieldDescriptor, val interface{}) (interface{}, error) {
-	return validFieldValueForRv(fd, reflect.ValueOf(val))
-}
-
-func validFieldValueForRv(fd *desc.FieldDescriptor, val reflect.Value) (interface{}, error) {
-	if fd.IsMap() && val.Kind() == reflect.Map {
-		return validFieldValueForMapField(fd, val)
-	}
-
-	if fd.IsRepeated() { // this will also catch map fields where given value was not a map
-		if val.Kind() != reflect.Array && val.Kind() != reflect.Slice {
-			if fd.IsMap() {
-				return nil, fmt.Errorf("value for map field must be a map; instead was %v", val.Type())
-			} else {
-				return nil, fmt.Errorf("value for repeated field must be a slice; instead was %v", val.Type())
-			}
-		}
-
-		if fd.IsMap() {
-			// value should be a slice of entry messages that we need convert into a map[interface{}]interface{}
-			m := map[interface{}]interface{}{}
-			for i := 0; i < val.Len(); i++ {
-				e, err := validElementFieldValue(fd, val.Index(i).Interface())
-				if err != nil {
-					return nil, err
-				}
-				msg := e.(proto.Message)
-				dm, err := asDynamicMessage(msg, fd.GetMessageType(), nil)
-				if err != nil {
-					return nil, err
-				}
-				k, err := dm.TryGetFieldByNumber(1)
-				if err != nil {
-					return nil, err
-				}
-				v, err := dm.TryGetFieldByNumber(2)
-				if err != nil {
-					return nil, err
-				}
-				m[k] = v
-			}
-			return m, nil
-		}
-
-		// make a defensive copy while checking contents (also converts to []interface{})
-		s := make([]interface{}, val.Len())
-		for i := 0; i < val.Len(); i++ {
-			ev := val.Index(i)
-			if ev.Kind() == reflect.Interface {
-				// unwrap it
-				ev = reflect.ValueOf(ev.Interface())
-			}
-			e, err := validElementFieldValueForRv(fd, ev)
-			if err != nil {
-				return nil, err
-			}
-			s[i] = e
-		}
-
-		return s, nil
-	}
-
-	return validElementFieldValueForRv(fd, val)
-}
-
-func asDynamicMessage(m proto.Message, md *desc.MessageDescriptor, mf *MessageFactory) (*Message, error) {
-	if dm, ok := m.(*Message); ok {
-		return dm, nil
-	}
-	dm := NewMessageWithMessageFactory(md, mf)
-	if err := dm.mergeFrom(m); err != nil {
-		return nil, err
-	}
-	return dm, nil
-}
-
-func validElementFieldValue(fd *desc.FieldDescriptor, val interface{}) (interface{}, error) {
-	return validElementFieldValueForRv(fd, reflect.ValueOf(val))
-}
-
-func validElementFieldValueForRv(fd *desc.FieldDescriptor, val reflect.Value) (interface{}, error) {
-	t := fd.GetType()
-	if !val.IsValid() {
-		return nil, typeError(fd, nil)
-	}
-
-	switch t {
-	case descriptor.FieldDescriptorProto_TYPE_SFIXED32,
-		descriptor.FieldDescriptorProto_TYPE_INT32,
-		descriptor.FieldDescriptorProto_TYPE_SINT32,
-		descriptor.FieldDescriptorProto_TYPE_ENUM:
-		return toInt32(reflect.Indirect(val), fd)
-
-	case descriptor.FieldDescriptorProto_TYPE_SFIXED64,
-		descriptor.FieldDescriptorProto_TYPE_INT64,
-		descriptor.FieldDescriptorProto_TYPE_SINT64:
-		return toInt64(reflect.Indirect(val), fd)
-
-	case descriptor.FieldDescriptorProto_TYPE_FIXED32,
-		descriptor.FieldDescriptorProto_TYPE_UINT32:
-		return toUint32(reflect.Indirect(val), fd)
-
-	case descriptor.FieldDescriptorProto_TYPE_FIXED64,
-		descriptor.FieldDescriptorProto_TYPE_UINT64:
-		return toUint64(reflect.Indirect(val), fd)
-
-	case descriptor.FieldDescriptorProto_TYPE_FLOAT:
-		return toFloat32(reflect.Indirect(val), fd)
-
-	case descriptor.FieldDescriptorProto_TYPE_DOUBLE:
-		return toFloat64(reflect.Indirect(val), fd)
-
-	case descriptor.FieldDescriptorProto_TYPE_BOOL:
-		return toBool(reflect.Indirect(val), fd)
-
-	case descriptor.FieldDescriptorProto_TYPE_BYTES:
-		return toBytes(reflect.Indirect(val), fd)
-
-	case descriptor.FieldDescriptorProto_TYPE_STRING:
-		return toString(reflect.Indirect(val), fd)
-
-	case descriptor.FieldDescriptorProto_TYPE_MESSAGE,
-		descriptor.FieldDescriptorProto_TYPE_GROUP:
-		m, err := asMessage(val, fd.GetFullyQualifiedName())
-		// check that message is correct type
-		if err != nil {
-			return nil, err
-		}
-		var msgType string
-		if dm, ok := m.(*Message); ok {
-			msgType = dm.GetMessageDescriptor().GetFullyQualifiedName()
-		} else {
-			msgType = proto.MessageName(m)
-		}
-		if msgType != fd.GetMessageType().GetFullyQualifiedName() {
-			return nil, fmt.Errorf("message field %s requires value of type %s; received %s", fd.GetFullyQualifiedName(), fd.GetMessageType().GetFullyQualifiedName(), msgType)
-		}
-		return m, nil
-
-	default:
-		return nil, fmt.Errorf("unable to handle unrecognized field type: %v", fd.GetType())
-	}
-}
-
-func toInt32(v reflect.Value, fd *desc.FieldDescriptor) (int32, error) {
-	if v.Kind() == reflect.Int32 {
-		return int32(v.Int()), nil
-	}
-	return 0, typeError(fd, v.Type())
-}
-
-func toUint32(v reflect.Value, fd *desc.FieldDescriptor) (uint32, error) {
-	if v.Kind() == reflect.Uint32 {
-		return uint32(v.Uint()), nil
-	}
-	return 0, typeError(fd, v.Type())
-}
-
-func toFloat32(v reflect.Value, fd *desc.FieldDescriptor) (float32, error) {
-	if v.Kind() == reflect.Float32 {
-		return float32(v.Float()), nil
-	}
-	return 0, typeError(fd, v.Type())
-}
-
-func toInt64(v reflect.Value, fd *desc.FieldDescriptor) (int64, error) {
-	if v.Kind() == reflect.Int64 || v.Kind() == reflect.Int || v.Kind() == reflect.Int32 {
-		return v.Int(), nil
-	}
-	return 0, typeError(fd, v.Type())
-}
-
-func toUint64(v reflect.Value, fd *desc.FieldDescriptor) (uint64, error) {
-	if v.Kind() == reflect.Uint64 || v.Kind() == reflect.Uint || v.Kind() == reflect.Uint32 {
-		return v.Uint(), nil
-	}
-	return 0, typeError(fd, v.Type())
-}
-
-func toFloat64(v reflect.Value, fd *desc.FieldDescriptor) (float64, error) {
-	if v.Kind() == reflect.Float64 || v.Kind() == reflect.Float32 {
-		return v.Float(), nil
-	}
-	return 0, typeError(fd, v.Type())
-}
-
-func toBool(v reflect.Value, fd *desc.FieldDescriptor) (bool, error) {
-	if v.Kind() == reflect.Bool {
-		return v.Bool(), nil
-	}
-	return false, typeError(fd, v.Type())
-}
-
-func toBytes(v reflect.Value, fd *desc.FieldDescriptor) ([]byte, error) {
-	if v.Kind() == reflect.Slice && v.Type().Elem().Kind() == reflect.Uint8 {
-		return v.Bytes(), nil
-	}
-	return nil, typeError(fd, v.Type())
-}
-
-func toString(v reflect.Value, fd *desc.FieldDescriptor) (string, error) {
-	if v.Kind() == reflect.String {
-		return v.String(), nil
-	}
-	return "", typeError(fd, v.Type())
-}
-
-func typeError(fd *desc.FieldDescriptor, t reflect.Type) error {
-	return fmt.Errorf(
-		"%s field %s is not compatible with value of type %v",
-		getTypeString(fd), fd.GetFullyQualifiedName(), t)
-}
-
-func getTypeString(fd *desc.FieldDescriptor) string {
-	return strings.ToLower(fd.GetType().String())
-}
-
-func asMessage(v reflect.Value, fieldName string) (proto.Message, error) {
-	t := v.Type()
-	// we need a pointer to a struct that implements proto.Message
-	if t.Kind() != reflect.Ptr || t.Elem().Kind() != reflect.Struct || !t.Implements(typeOfProtoMessage) {
-		return nil, fmt.Errorf("message field %s requires is not compatible with value of type %v", fieldName, v.Type())
-	}
-	return v.Interface().(proto.Message), nil
-}
-
-// Reset resets this message to an empty message. It removes all values set in
-// the message.
-func (m *Message) Reset() {
-	for k := range m.values {
-		delete(m.values, k)
-	}
-	for k := range m.unknownFields {
-		delete(m.unknownFields, k)
-	}
-}
-
-// String returns this message rendered in compact text format.
-func (m *Message) String() string {
-	b, err := m.MarshalText()
-	if err != nil {
-		panic(fmt.Sprintf("Failed to create string representation of message: %s", err.Error()))
-	}
-	return string(b)
-}
-
-// ProtoMessage is present to satisfy the proto.Message interface.
-func (m *Message) ProtoMessage() {
-}
-
-// ConvertTo converts this dynamic message into the given message. This is
-// shorthand for resetting then merging:
-//   target.Reset()
-//   m.MergeInto(target)
-func (m *Message) ConvertTo(target proto.Message) error {
-	if err := m.checkType(target); err != nil {
-		return err
-	}
-
-	target.Reset()
-	return m.mergeInto(target)
-}
-
-// ConvertFrom converts the given message into this dynamic message. This is
-// shorthand for resetting then merging:
-//   m.Reset()
-//   m.MergeFrom(target)
-func (m *Message) ConvertFrom(target proto.Message) error {
-	if err := m.checkType(target); err != nil {
-		return err
-	}
-
-	m.Reset()
-	return m.mergeFrom(target)
-}
-
-// MergeInto merges this dynamic message into the given message. All field
-// values in this message will be set on the given message. For map fields,
-// entries are added to the given message (if the given message has existing
-// values for like keys, they are overwritten). For slice fields, elements are
-// added.
-//
-// If the given message has a different set of known fields, it is possible for
-// some known fields in this message to be represented as unknown fields in the
-// given message after merging, and vice versa.
-func (m *Message) MergeInto(target proto.Message) error {
-	if err := m.checkType(target); err != nil {
-		return err
-	}
-	return m.mergeInto(target)
-}
-
-// MergeFrom merges the given message into this dynamic message. All field
-// values in the given message will be set on this message. For map fields,
-// entries are added to this message (if this message has existing values for
-// like keys, they are overwritten). For slice fields, elements are added.
-//
-// If the given message has a different set of known fields, it is possible for
-// some known fields in that message to be represented as unknown fields in this
-// message after merging, and vice versa.
-func (m *Message) MergeFrom(source proto.Message) error {
-	if err := m.checkType(source); err != nil {
-		return err
-	}
-	return m.mergeFrom(source)
-}
-
-// Merge implements the proto.Merger interface so that dynamic messages are
-// compatible with the proto.Merge function. It delegates to MergeFrom but will
-// panic on error as the proto.Merger interface doesn't allow for returning an
-// error.
-//
-// Unlike nearly all other methods, this method can work if this message's type
-// is not defined (such as instantiating the message without using NewMessage).
-// This is strictly so that dynamic message's are compatible with the
-// proto.Clone function, which instantiates a new message via reflection (thus
-// its message descriptor will not be set) and than calls Merge.
-func (m *Message) Merge(source proto.Message) {
-	if m.md == nil {
-		// To support proto.Clone, initialize the descriptor from the source.
-		if dm, ok := source.(*Message); ok {
-			m.md = dm.md
-			// also make sure the clone uses the same message factory and
-			// extensions and also knows about the same extra fields (if any)
-			m.mf = dm.mf
-			m.er = dm.er
-			m.extraFields = dm.extraFields
-		} else if md, err := desc.LoadMessageDescriptorForMessage(source); err != nil {
-			panic(err.Error())
-		} else {
-			m.md = md
-		}
-	}
-
-	if err := m.MergeFrom(source); err != nil {
-		panic(err.Error())
-	}
-}
-
-func (m *Message) checkType(target proto.Message) error {
-	if dm, ok := target.(*Message); ok {
-		if dm.md.GetFullyQualifiedName() != m.md.GetFullyQualifiedName() {
-			return fmt.Errorf("given message has wrong type: %q; expecting %q", dm.md.GetFullyQualifiedName(), m.md.GetFullyQualifiedName())
-		}
-		return nil
-	}
-
-	msgName := proto.MessageName(target)
-	if msgName != m.md.GetFullyQualifiedName() {
-		return fmt.Errorf("given message has wrong type: %q; expecting %q", msgName, m.md.GetFullyQualifiedName())
-	}
-	return nil
-}
-
-func (m *Message) mergeInto(pm proto.Message) error {
-	if dm, ok := pm.(*Message); ok {
-		return dm.mergeFrom(m)
-	}
-
-	target := reflect.ValueOf(pm)
-	if target.Kind() == reflect.Ptr {
-		target = target.Elem()
-	}
-
-	// track tags for which the dynamic message has data but the given
-	// message doesn't know about it
-	u := target.FieldByName("XXX_unrecognized")
-	var unknownTags map[int32]struct{}
-	if u.IsValid() && u.Type() == typeOfBytes {
-		unknownTags = map[int32]struct{}{}
-		for tag := range m.values {
-			unknownTags[tag] = struct{}{}
-		}
-	}
-
-	// check that we can successfully do the merge
-	structProps := proto.GetProperties(reflect.TypeOf(pm).Elem())
-	for _, prop := range structProps.Prop {
-		if prop.Tag == 0 {
-			continue // one-of or special field (such as XXX_unrecognized, etc.)
-		}
-		tag := int32(prop.Tag)
-		v, ok := m.values[tag]
-		if !ok {
-			continue
-		}
-		if unknownTags != nil {
-			delete(unknownTags, tag)
-		}
-		f := target.FieldByName(prop.Name)
-		ft := f.Type()
-		val := reflect.ValueOf(v)
-		if !canConvert(val, ft) {
-			return fmt.Errorf("cannot convert %v to %v", val.Type(), ft)
-		}
-	}
-	// check one-of fields
-	for _, oop := range structProps.OneofTypes {
-		prop := oop.Prop
-		tag := int32(prop.Tag)
-		v, ok := m.values[tag]
-		if !ok {
-			continue
-		}
-		if unknownTags != nil {
-			delete(unknownTags, tag)
-		}
-		stf, ok := oop.Type.Elem().FieldByName(prop.Name)
-		if !ok {
-			return fmt.Errorf("one-of field indicates struct field name %s, but type %v has no such field", prop.Name, oop.Type.Elem())
-		}
-		ft := stf.Type
-		val := reflect.ValueOf(v)
-		if !canConvert(val, ft) {
-			return fmt.Errorf("cannot convert %v to %v", val.Type(), ft)
-		}
-	}
-	// and check extensions, too
-	for tag, ext := range proto.RegisteredExtensions(pm) {
-		v, ok := m.values[tag]
-		if !ok {
-			continue
-		}
-		if unknownTags != nil {
-			delete(unknownTags, tag)
-		}
-		ft := reflect.TypeOf(ext.ExtensionType)
-		val := reflect.ValueOf(v)
-		if !canConvert(val, ft) {
-			return fmt.Errorf("cannot convert %v to %v", val.Type(), ft)
-		}
-	}
-
-	// now actually perform the merge
-	for _, prop := range structProps.Prop {
-		v, ok := m.values[int32(prop.Tag)]
-		if !ok {
-			continue
-		}
-		f := target.FieldByName(prop.Name)
-		if err := mergeVal(reflect.ValueOf(v), f); err != nil {
-			return err
-		}
-	}
-	// merge one-ofs
-	for _, oop := range structProps.OneofTypes {
-		prop := oop.Prop
-		tag := int32(prop.Tag)
-		v, ok := m.values[tag]
-		if !ok {
-			continue
-		}
-		oov := reflect.New(oop.Type.Elem())
-		f := oov.Elem().FieldByName(prop.Name)
-		if err := mergeVal(reflect.ValueOf(v), f); err != nil {
-			return err
-		}
-		target.Field(oop.Field).Set(oov)
-	}
-	// merge extensions, too
-	for tag, ext := range proto.RegisteredExtensions(pm) {
-		v, ok := m.values[tag]
-		if !ok {
-			continue
-		}
-		e := reflect.New(reflect.TypeOf(ext.ExtensionType)).Elem()
-		if err := mergeVal(reflect.ValueOf(v), e); err != nil {
-			return err
-		}
-		if err := proto.SetExtension(pm, ext, e.Interface()); err != nil {
-			// shouldn't happen since we already checked that the extension type was compatible above
-			return err
-		}
-	}
-
-	// if we have fields that the given message doesn't know about, add to its unknown fields
-	if len(unknownTags) > 0 {
-		ub := u.Interface().([]byte)
-		var b codec.Buffer
-		b.SetDeterministic(defaultDeterminism)
-		for tag := range unknownTags {
-			fd := m.FindFieldDescriptor(tag)
-			if err := b.EncodeFieldValue(fd, m.values[tag]); err != nil {
-				return err
-			}
-		}
-		ub = append(ub, b.Bytes()...)
-		u.Set(reflect.ValueOf(ub))
-	}
-
-	// finally, convey unknown fields into the given message by letting it unmarshal them
-	// (this will append to its unknown fields if not known; if somehow the given message recognizes
-	// a field even though the dynamic message did not, it will get correctly unmarshalled)
-	if unknownTags != nil && len(m.unknownFields) > 0 {
-		var b codec.Buffer
-		_ = m.marshalUnknownFields(&b)
-		_ = proto.UnmarshalMerge(b.Bytes(), pm)
-	}
-
-	return nil
-}
-
-func canConvert(src reflect.Value, target reflect.Type) bool {
-	if src.Kind() == reflect.Interface {
-		src = reflect.ValueOf(src.Interface())
-	}
-	srcType := src.Type()
-	// we allow convertible types instead of requiring exact types so that calling
-	// code can, for example, assign an enum constant to an enum field. In that case,
-	// one type is the enum type (a sub-type of int32) and the other may be the int32
-	// type. So we automatically do the conversion in that case.
-	if srcType.ConvertibleTo(target) {
-		return true
-	} else if target.Kind() == reflect.Ptr && srcType.ConvertibleTo(target.Elem()) {
-		return true
-	} else if target.Kind() == reflect.Slice {
-		if srcType.Kind() != reflect.Slice {
-			return false
-		}
-		et := target.Elem()
-		for i := 0; i < src.Len(); i++ {
-			if !canConvert(src.Index(i), et) {
-				return false
-			}
-		}
-		return true
-	} else if target.Kind() == reflect.Map {
-		if srcType.Kind() != reflect.Map {
-			return false
-		}
-		return canConvertMap(src, target)
-	} else if srcType == typeOfDynamicMessage && target.Implements(typeOfProtoMessage) {
-		z := reflect.Zero(target).Interface()
-		msgType := proto.MessageName(z.(proto.Message))
-		return msgType == src.Interface().(*Message).GetMessageDescriptor().GetFullyQualifiedName()
-	} else {
-		return false
-	}
-}
-
-func mergeVal(src, target reflect.Value) error {
-	if src.Kind() == reflect.Interface && !src.IsNil() {
-		src = src.Elem()
-	}
-	srcType := src.Type()
-	targetType := target.Type()
-	if srcType.ConvertibleTo(targetType) {
-		if targetType.Implements(typeOfProtoMessage) && !target.IsNil() {
-			Merge(target.Interface().(proto.Message), src.Convert(targetType).Interface().(proto.Message))
-		} else {
-			target.Set(src.Convert(targetType))
-		}
-	} else if targetType.Kind() == reflect.Ptr && srcType.ConvertibleTo(targetType.Elem()) {
-		if !src.CanAddr() {
-			target.Set(reflect.New(targetType.Elem()))
-			target.Elem().Set(src.Convert(targetType.Elem()))
-		} else {
-			target.Set(src.Addr().Convert(targetType))
-		}
-	} else if targetType.Kind() == reflect.Slice {
-		l := target.Len()
-		newL := l + src.Len()
-		if target.Cap() < newL {
-			// expand capacity of the slice and copy
-			newSl := reflect.MakeSlice(targetType, newL, newL)
-			for i := 0; i < target.Len(); i++ {
-				newSl.Index(i).Set(target.Index(i))
-			}
-			target.Set(newSl)
-		} else {
-			target.SetLen(newL)
-		}
-		for i := 0; i < src.Len(); i++ {
-			dest := target.Index(l + i)
-			if dest.Kind() == reflect.Ptr {
-				dest.Set(reflect.New(dest.Type().Elem()))
-			}
-			if err := mergeVal(src.Index(i), dest); err != nil {
-				return err
-			}
-		}
-	} else if targetType.Kind() == reflect.Map {
-		return mergeMapVal(src, target, targetType)
-	} else if srcType == typeOfDynamicMessage && targetType.Implements(typeOfProtoMessage) {
-		dm := src.Interface().(*Message)
-		if target.IsNil() {
-			target.Set(reflect.New(targetType.Elem()))
-		}
-		m := target.Interface().(proto.Message)
-		if err := dm.mergeInto(m); err != nil {
-			return err
-		}
-	} else {
-		return fmt.Errorf("cannot convert %v to %v", srcType, targetType)
-	}
-	return nil
-}
-
-func (m *Message) mergeFrom(pm proto.Message) error {
-	if dm, ok := pm.(*Message); ok {
-		// if given message is also a dynamic message, we merge differently
-		for tag, v := range dm.values {
-			fd := m.FindFieldDescriptor(tag)
-			if fd == nil {
-				fd = dm.FindFieldDescriptor(tag)
-			}
-			if err := mergeField(m, fd, v); err != nil {
-				return err
-			}
-		}
-		return nil
-	}
-
-	pmrv := reflect.ValueOf(pm)
-	if pmrv.IsNil() {
-		// nil is an empty message, so nothing to do
-		return nil
-	}
-
-	// check that we can successfully do the merge
-	src := pmrv.Elem()
-	values := map[*desc.FieldDescriptor]interface{}{}
-	props := proto.GetProperties(reflect.TypeOf(pm).Elem())
-	if props == nil {
-		return fmt.Errorf("could not determine message properties to merge for %v", reflect.TypeOf(pm).Elem())
-	}
-
-	// regular fields
-	for _, prop := range props.Prop {
-		if prop.Tag == 0 {
-			continue // one-of or special field (such as XXX_unrecognized, etc.)
-		}
-		fd := m.FindFieldDescriptor(int32(prop.Tag))
-		if fd == nil {
-			// Our descriptor has different fields than this message object. So
-			// try to reflect on the message object's fields.
-			md, err := desc.LoadMessageDescriptorForMessage(pm)
-			if err != nil {
-				return err
-			}
-			fd = md.FindFieldByNumber(int32(prop.Tag))
-			if fd == nil {
-				return fmt.Errorf("message descriptor %q did not contain field for tag %d (%q)", md.GetFullyQualifiedName(), prop.Tag, prop.Name)
-			}
-		}
-		rv := src.FieldByName(prop.Name)
-		if (rv.Kind() == reflect.Ptr || rv.Kind() == reflect.Slice) && rv.IsNil() {
-			continue
-		}
-		if v, err := validFieldValueForRv(fd, rv); err != nil {
-			return err
-		} else {
-			values[fd] = v
-		}
-	}
-
-	// one-of fields
-	for _, oop := range props.OneofTypes {
-		oov := src.Field(oop.Field).Elem()
-		if !oov.IsValid() || oov.Type() != oop.Type {
-			// this field is unset (in other words, one-of message field is not currently set to this option)
-			continue
-		}
-		prop := oop.Prop
-		rv := oov.Elem().FieldByName(prop.Name)
-		fd := m.FindFieldDescriptor(int32(prop.Tag))
-		if fd == nil {
-			// Our descriptor has different fields than this message object. So
-			// try to reflect on the message object's fields.
-			md, err := desc.LoadMessageDescriptorForMessage(pm)
-			if err != nil {
-				return err
-			}
-			fd = md.FindFieldByNumber(int32(prop.Tag))
-			if fd == nil {
-				return fmt.Errorf("message descriptor %q did not contain field for tag %d (%q in one-of %q)", md.GetFullyQualifiedName(), prop.Tag, prop.Name, src.Type().Field(oop.Field).Name)
-			}
-		}
-		if v, err := validFieldValueForRv(fd, rv); err != nil {
-			return err
-		} else {
-			values[fd] = v
-		}
-	}
-
-	// extension fields
-	rexts, _ := proto.ExtensionDescs(pm)
-	var unknownExtensions []byte
-	for _, ed := range rexts {
-		v, _ := proto.GetExtension(pm, ed)
-		if v == nil {
-			continue
-		}
-		if ed.ExtensionType == nil {
-			extBytes, _ := v.([]byte)
-			if len(extBytes) > 0 {
-				unknownExtensions = append(unknownExtensions, extBytes...)
-			}
-			continue
-		}
-		fd := m.er.FindExtension(m.md.GetFullyQualifiedName(), ed.Field)
-		if fd == nil {
-			var err error
-			if fd, err = desc.LoadFieldDescriptorForExtension(ed); err != nil {
-				return err
-			}
-		}
-		if v, err := validFieldValue(fd, v); err != nil {
-			return err
-		} else {
-			values[fd] = v
-		}
-	}
-
-	// now actually perform the merge
-	for fd, v := range values {
-		mergeField(m, fd, v)
-	}
-
-	u := src.FieldByName("XXX_unrecognized")
-	if u.IsValid() && u.Type() == typeOfBytes {
-		// ignore any error returned: pulling in unknown fields is best-effort
-		_ = m.UnmarshalMerge(u.Interface().([]byte))
-	}
-
-	// lastly, also extract any unknown extensions the message may have (unknown extensions
-	// are stored with other extensions, not in the XXX_unrecognized field, so we have to do
-	// more than just the step above...)
-	if len(unknownExtensions) > 0 {
-		// pulling in unknown fields is best-effort, so we just ignore errors
-		_ = m.UnmarshalMerge(unknownExtensions)
-	}
-	return nil
-}
-
-// Validate checks that all required fields are present. It returns an error if any are absent.
-func (m *Message) Validate() error {
-	missingFields := m.findMissingFields()
-	if len(missingFields) == 0 {
-		return nil
-	}
-	return fmt.Errorf("some required fields missing: %v", strings.Join(missingFields, ", "))
-}
-
-func (m *Message) findMissingFields() []string {
-	if m.md.IsProto3() {
-		// proto3 does not allow required fields
-		return nil
-	}
-	var missingFields []string
-	for _, fd := range m.md.GetFields() {
-		if fd.IsRequired() {
-			if _, ok := m.values[fd.GetNumber()]; !ok {
-				missingFields = append(missingFields, fd.GetName())
-			}
-		}
-	}
-	return missingFields
-}
-
-// ValidateRecursive checks that all required fields are present and also
-// recursively validates all fields who are also messages. It returns an error
-// if any required fields, in this message or nested within, are absent.
-func (m *Message) ValidateRecursive() error {
-	return m.validateRecursive("")
-}
-
-func (m *Message) validateRecursive(prefix string) error {
-	if missingFields := m.findMissingFields(); len(missingFields) > 0 {
-		for i := range missingFields {
-			missingFields[i] = fmt.Sprintf("%s%s", prefix, missingFields[i])
-		}
-		return fmt.Errorf("some required fields missing: %v", strings.Join(missingFields, ", "))
-	}
-
-	for tag, fld := range m.values {
-		fd := m.FindFieldDescriptor(tag)
-		var chprefix string
-		var md *desc.MessageDescriptor
-		checkMsg := func(pm proto.Message) error {
-			var dm *Message
-			if d, ok := pm.(*Message); ok {
-				dm = d
-			} else {
-				dm = m.mf.NewDynamicMessage(md)
-				if err := dm.ConvertFrom(pm); err != nil {
-					return nil
-				}
-			}
-			if err := dm.validateRecursive(chprefix); err != nil {
-				return err
-			}
-			return nil
-		}
-		isMap := fd.IsMap()
-		if isMap && fd.GetMapValueType().GetMessageType() != nil {
-			md = fd.GetMapValueType().GetMessageType()
-			mp := fld.(map[interface{}]interface{})
-			for k, v := range mp {
-				chprefix = fmt.Sprintf("%s%s[%v].", prefix, getName(fd), k)
-				if err := checkMsg(v.(proto.Message)); err != nil {
-					return err
-				}
-			}
-		} else if !isMap && fd.GetMessageType() != nil {
-			md = fd.GetMessageType()
-			if fd.IsRepeated() {
-				sl := fld.([]interface{})
-				for i, v := range sl {
-					chprefix = fmt.Sprintf("%s%s[%d].", prefix, getName(fd), i)
-					if err := checkMsg(v.(proto.Message)); err != nil {
-						return err
-					}
-				}
-			} else {
-				chprefix = fmt.Sprintf("%s%s.", prefix, getName(fd))
-				if err := checkMsg(fld.(proto.Message)); err != nil {
-					return err
-				}
-			}
-		}
-	}
-
-	return nil
-}
-
-func getName(fd *desc.FieldDescriptor) string {
-	if fd.IsExtension() {
-		return fmt.Sprintf("(%s)", fd.GetFullyQualifiedName())
-	} else {
-		return fd.GetName()
-	}
-}
-
-// knownFieldTags return tags of present and recognized fields, in sorted order.
-func (m *Message) knownFieldTags() []int {
-	if len(m.values) == 0 {
-		return []int(nil)
-	}
-
-	keys := make([]int, len(m.values))
-	i := 0
-	for k := range m.values {
-		keys[i] = int(k)
-		i++
-	}
-
-	sort.Ints(keys)
-	return keys
-}
-
-// allKnownFieldTags return tags of present and recognized fields, including
-// those that are unset, in sorted order. This only includes extensions that are
-// present. Known but not-present extensions are not included in the returned
-// set of tags.
-func (m *Message) allKnownFieldTags() []int {
-	fds := m.md.GetFields()
-	keys := make([]int, 0, len(fds)+len(m.extraFields))
-
-	for k := range m.values {
-		keys = append(keys, int(k))
-	}
-
-	// also include known fields that are not present
-	for _, fd := range fds {
-		if _, ok := m.values[fd.GetNumber()]; !ok {
-			keys = append(keys, int(fd.GetNumber()))
-		}
-	}
-	for _, fd := range m.extraFields {
-		if !fd.IsExtension() { // skip extensions that are not present
-			if _, ok := m.values[fd.GetNumber()]; !ok {
-				keys = append(keys, int(fd.GetNumber()))
-			}
-		}
-	}
-
-	sort.Ints(keys)
-	return keys
-}
-
-// unknownFieldTags return tags of present but unrecognized fields, in sorted order.
-func (m *Message) unknownFieldTags() []int {
-	if len(m.unknownFields) == 0 {
-		return []int(nil)
-	}
-	keys := make([]int, len(m.unknownFields))
-	i := 0
-	for k := range m.unknownFields {
-		keys[i] = int(k)
-		i++
-	}
-	sort.Ints(keys)
-	return keys
-}
diff --git a/vendor/github.com/jhump/protoreflect/dynamic/equal.go b/vendor/github.com/jhump/protoreflect/dynamic/equal.go
deleted file mode 100644
index 5fbcc24..0000000
--- a/vendor/github.com/jhump/protoreflect/dynamic/equal.go
+++ /dev/null
@@ -1,152 +0,0 @@
-package dynamic
-
-import (
-	"bytes"
-	"reflect"
-
-	"github.com/golang/protobuf/proto"
-
-	"github.com/jhump/protoreflect/desc"
-)
-
-// Equal returns true if the given two dynamic messages are equal. Two messages are equal when they
-// have the same message type and same fields set to equal values. For proto3 messages, fields set
-// to their zero value are considered unset.
-func Equal(a, b *Message) bool {
-	if a.md.GetFullyQualifiedName() != b.md.GetFullyQualifiedName() {
-		return false
-	}
-	if len(a.values) != len(b.values) {
-		return false
-	}
-	if len(a.unknownFields) != len(b.unknownFields) {
-		return false
-	}
-	for tag, aval := range a.values {
-		bval, ok := b.values[tag]
-		if !ok {
-			return false
-		}
-		if !fieldsEqual(aval, bval) {
-			return false
-		}
-	}
-	for tag, au := range a.unknownFields {
-		bu, ok := b.unknownFields[tag]
-		if !ok {
-			return false
-		}
-		if len(au) != len(bu) {
-			return false
-		}
-		for i, aval := range au {
-			bval := bu[i]
-			if aval.Encoding != bval.Encoding {
-				return false
-			}
-			if aval.Encoding == proto.WireBytes || aval.Encoding == proto.WireStartGroup {
-				if !bytes.Equal(aval.Contents, bval.Contents) {
-					return false
-				}
-			} else if aval.Value != bval.Value {
-				return false
-			}
-		}
-	}
-	// all checks pass!
-	return true
-}
-
-func fieldsEqual(aval, bval interface{}) bool {
-	arv := reflect.ValueOf(aval)
-	brv := reflect.ValueOf(bval)
-	if arv.Type() != brv.Type() {
-		// it is possible that one is a dynamic message and one is not
-		apm, ok := aval.(proto.Message)
-		if !ok {
-			return false
-		}
-		bpm, ok := bval.(proto.Message)
-		if !ok {
-			return false
-		}
-		return MessagesEqual(apm, bpm)
-
-	} else {
-		switch arv.Kind() {
-		case reflect.Ptr:
-			apm, ok := aval.(proto.Message)
-			if !ok {
-				// Don't know how to compare pointer values that aren't messages!
-				// Maybe this should panic?
-				return false
-			}
-			bpm := bval.(proto.Message) // we know it will succeed because we know a and b have same type
-			return MessagesEqual(apm, bpm)
-
-		case reflect.Map:
-			return mapsEqual(arv, brv)
-
-		case reflect.Slice:
-			if arv.Type() == typeOfBytes {
-				return bytes.Equal(aval.([]byte), bval.([]byte))
-			} else {
-				return slicesEqual(arv, brv)
-			}
-
-		default:
-			return aval == bval
-		}
-	}
-}
-
-func slicesEqual(a, b reflect.Value) bool {
-	if a.Len() != b.Len() {
-		return false
-	}
-	for i := 0; i < a.Len(); i++ {
-		ai := a.Index(i)
-		bi := b.Index(i)
-		if !fieldsEqual(ai.Interface(), bi.Interface()) {
-			return false
-		}
-	}
-	return true
-}
-
-// MessagesEqual returns true if the given two messages are equal. Use this instead of proto.Equal
-// when one or both of the messages might be a dynamic message.
-func MessagesEqual(a, b proto.Message) bool {
-	da, aok := a.(*Message)
-	db, bok := b.(*Message)
-	// Both dynamic messages
-	if aok && bok {
-		return Equal(da, db)
-	}
-	// Neither dynamic messages
-	if !aok && !bok {
-		return proto.Equal(a, b)
-	}
-	// Mixed
-	if aok {
-		md, err := desc.LoadMessageDescriptorForMessage(b)
-		if err != nil {
-			return false
-		}
-		db = NewMessageWithMessageFactory(md, da.mf)
-		if db.ConvertFrom(b) != nil {
-			return false
-		}
-		return Equal(da, db)
-	} else {
-		md, err := desc.LoadMessageDescriptorForMessage(a)
-		if err != nil {
-			return false
-		}
-		da = NewMessageWithMessageFactory(md, db.mf)
-		if da.ConvertFrom(a) != nil {
-			return false
-		}
-		return Equal(da, db)
-	}
-}
diff --git a/vendor/github.com/jhump/protoreflect/dynamic/extension.go b/vendor/github.com/jhump/protoreflect/dynamic/extension.go
deleted file mode 100644
index 1d38161..0000000
--- a/vendor/github.com/jhump/protoreflect/dynamic/extension.go
+++ /dev/null
@@ -1,46 +0,0 @@
-package dynamic
-
-import (
-	"fmt"
-
-	"github.com/golang/protobuf/proto"
-
-	"github.com/jhump/protoreflect/codec"
-	"github.com/jhump/protoreflect/desc"
-)
-
-// SetExtension sets the given extension value. If the given message is not a
-// dynamic message, the given extension may not be recognized (or may differ
-// from the compiled and linked in version of the extension. So in that case,
-// this function will serialize the given value to bytes and then use
-// proto.SetRawExtension to set the value.
-func SetExtension(msg proto.Message, extd *desc.FieldDescriptor, val interface{}) error {
-	if !extd.IsExtension() {
-		return fmt.Errorf("given field %s is not an extension", extd.GetFullyQualifiedName())
-	}
-
-	if dm, ok := msg.(*Message); ok {
-		return dm.TrySetField(extd, val)
-	}
-
-	md, err := desc.LoadMessageDescriptorForMessage(msg)
-	if err != nil {
-		return err
-	}
-	if err := checkField(extd, md); err != nil {
-		return err
-	}
-
-	val, err = validFieldValue(extd, val)
-	if err != nil {
-		return err
-	}
-
-	var b codec.Buffer
-	b.SetDeterministic(defaultDeterminism)
-	if err := b.EncodeFieldValue(extd, val); err != nil {
-		return err
-	}
-	proto.SetRawExtension(msg, extd.GetNumber(), b.Bytes())
-	return nil
-}
diff --git a/vendor/github.com/jhump/protoreflect/dynamic/extension_registry.go b/vendor/github.com/jhump/protoreflect/dynamic/extension_registry.go
deleted file mode 100644
index 6876827..0000000
--- a/vendor/github.com/jhump/protoreflect/dynamic/extension_registry.go
+++ /dev/null
@@ -1,241 +0,0 @@
-package dynamic
-
-import (
-	"fmt"
-	"reflect"
-	"sync"
-
-	"github.com/golang/protobuf/proto"
-
-	"github.com/jhump/protoreflect/desc"
-)
-
-// ExtensionRegistry is a registry of known extension fields. This is used to parse
-// extension fields encountered when de-serializing a dynamic message.
-type ExtensionRegistry struct {
-	includeDefault bool
-	mu             sync.RWMutex
-	exts           map[string]map[int32]*desc.FieldDescriptor
-}
-
-// NewExtensionRegistryWithDefaults is a registry that includes all "default" extensions,
-// which are those that are statically linked into the current program (e.g. registered by
-// protoc-generated code via proto.RegisterExtension). Extensions explicitly added to the
-// registry will override any default extensions that are for the same extendee and have the
-// same tag number and/or name.
-func NewExtensionRegistryWithDefaults() *ExtensionRegistry {
-	return &ExtensionRegistry{includeDefault: true}
-}
-
-// AddExtensionDesc adds the given extensions to the registry.
-func (r *ExtensionRegistry) AddExtensionDesc(exts ...*proto.ExtensionDesc) error {
-	flds := make([]*desc.FieldDescriptor, len(exts))
-	for i, ext := range exts {
-		fd, err := desc.LoadFieldDescriptorForExtension(ext)
-		if err != nil {
-			return err
-		}
-		flds[i] = fd
-	}
-	r.mu.Lock()
-	defer r.mu.Unlock()
-	if r.exts == nil {
-		r.exts = map[string]map[int32]*desc.FieldDescriptor{}
-	}
-	for _, fd := range flds {
-		r.putExtensionLocked(fd)
-	}
-	return nil
-}
-
-// AddExtension adds the given extensions to the registry. The given extensions
-// will overwrite any previously added extensions that are for the same extendee
-// message and same extension tag number.
-func (r *ExtensionRegistry) AddExtension(exts ...*desc.FieldDescriptor) error {
-	for _, ext := range exts {
-		if !ext.IsExtension() {
-			return fmt.Errorf("given field is not an extension: %s", ext.GetFullyQualifiedName())
-		}
-	}
-	r.mu.Lock()
-	defer r.mu.Unlock()
-	if r.exts == nil {
-		r.exts = map[string]map[int32]*desc.FieldDescriptor{}
-	}
-	for _, ext := range exts {
-		r.putExtensionLocked(ext)
-	}
-	return nil
-}
-
-// AddExtensionsFromFile adds to the registry all extension fields defined in the given file descriptor.
-func (r *ExtensionRegistry) AddExtensionsFromFile(fd *desc.FileDescriptor) {
-	r.mu.Lock()
-	defer r.mu.Unlock()
-	r.addExtensionsFromFileLocked(fd, false, nil)
-}
-
-// AddExtensionsFromFileRecursively adds to the registry all extension fields defined in the give file
-// descriptor and also recursively adds all extensions defined in that file's dependencies. This adds
-// extensions from the entire transitive closure for the given file.
-func (r *ExtensionRegistry) AddExtensionsFromFileRecursively(fd *desc.FileDescriptor) {
-	r.mu.Lock()
-	defer r.mu.Unlock()
-	already := map[*desc.FileDescriptor]struct{}{}
-	r.addExtensionsFromFileLocked(fd, true, already)
-}
-
-func (r *ExtensionRegistry) addExtensionsFromFileLocked(fd *desc.FileDescriptor, recursive bool, alreadySeen map[*desc.FileDescriptor]struct{}) {
-	if _, ok := alreadySeen[fd]; ok {
-		return
-	}
-
-	if r.exts == nil {
-		r.exts = map[string]map[int32]*desc.FieldDescriptor{}
-	}
-	for _, ext := range fd.GetExtensions() {
-		r.putExtensionLocked(ext)
-	}
-	for _, msg := range fd.GetMessageTypes() {
-		r.addExtensionsFromMessageLocked(msg)
-	}
-
-	if recursive {
-		alreadySeen[fd] = struct{}{}
-		for _, dep := range fd.GetDependencies() {
-			r.addExtensionsFromFileLocked(dep, recursive, alreadySeen)
-		}
-	}
-}
-
-func (r *ExtensionRegistry) addExtensionsFromMessageLocked(md *desc.MessageDescriptor) {
-	for _, ext := range md.GetNestedExtensions() {
-		r.putExtensionLocked(ext)
-	}
-	for _, msg := range md.GetNestedMessageTypes() {
-		r.addExtensionsFromMessageLocked(msg)
-	}
-}
-
-func (r *ExtensionRegistry) putExtensionLocked(fd *desc.FieldDescriptor) {
-	msgName := fd.GetOwner().GetFullyQualifiedName()
-	m := r.exts[msgName]
-	if m == nil {
-		m = map[int32]*desc.FieldDescriptor{}
-		r.exts[msgName] = m
-	}
-	m[fd.GetNumber()] = fd
-}
-
-// FindExtension queries for the extension field with the given extendee name (must be a fully-qualified
-// message name) and tag number. If no extension is known, nil is returned.
-func (r *ExtensionRegistry) FindExtension(messageName string, tagNumber int32) *desc.FieldDescriptor {
-	if r == nil {
-		return nil
-	}
-	r.mu.RLock()
-	defer r.mu.RUnlock()
-	fd := r.exts[messageName][tagNumber]
-	if fd == nil && r.includeDefault {
-		ext := getDefaultExtensions(messageName)[tagNumber]
-		if ext != nil {
-			fd, _ = desc.LoadFieldDescriptorForExtension(ext)
-		}
-	}
-	return fd
-}
-
-// FindExtensionByName queries for the extension field with the given extendee name (must be a fully-qualified
-// message name) and field name (must also be a fully-qualified extension name). If no extension is known, nil
-// is returned.
-func (r *ExtensionRegistry) FindExtensionByName(messageName string, fieldName string) *desc.FieldDescriptor {
-	if r == nil {
-		return nil
-	}
-	r.mu.RLock()
-	defer r.mu.RUnlock()
-	for _, fd := range r.exts[messageName] {
-		if fd.GetFullyQualifiedName() == fieldName {
-			return fd
-		}
-	}
-	if r.includeDefault {
-		for _, ext := range getDefaultExtensions(messageName) {
-			fd, _ := desc.LoadFieldDescriptorForExtension(ext)
-			if fd.GetFullyQualifiedName() == fieldName {
-				return fd
-			}
-		}
-	}
-	return nil
-}
-
-// FindExtensionByJSONName queries for the extension field with the given extendee name (must be a fully-qualified
-// message name) and JSON field name (must also be a fully-qualified name). If no extension is known, nil is returned.
-// The fully-qualified JSON name is the same as the extension's normal fully-qualified name except that the last
-// component uses the field's JSON name (if present).
-func (r *ExtensionRegistry) FindExtensionByJSONName(messageName string, fieldName string) *desc.FieldDescriptor {
-	if r == nil {
-		return nil
-	}
-	r.mu.RLock()
-	defer r.mu.RUnlock()
-	for _, fd := range r.exts[messageName] {
-		if fd.GetFullyQualifiedJSONName() == fieldName {
-			return fd
-		}
-	}
-	if r.includeDefault {
-		for _, ext := range getDefaultExtensions(messageName) {
-			fd, _ := desc.LoadFieldDescriptorForExtension(ext)
-			if fd.GetFullyQualifiedJSONName() == fieldName {
-				return fd
-			}
-		}
-	}
-	return nil
-}
-
-func getDefaultExtensions(messageName string) map[int32]*proto.ExtensionDesc {
-	t := proto.MessageType(messageName)
-	if t != nil {
-		msg := reflect.Zero(t).Interface().(proto.Message)
-		return proto.RegisteredExtensions(msg)
-	}
-	return nil
-}
-
-// AllExtensionsForType returns all known extension fields for the given extendee name (must be a
-// fully-qualified message name).
-func (r *ExtensionRegistry) AllExtensionsForType(messageName string) []*desc.FieldDescriptor {
-	if r == nil {
-		return []*desc.FieldDescriptor(nil)
-	}
-	r.mu.RLock()
-	defer r.mu.RUnlock()
-	flds := r.exts[messageName]
-	var ret []*desc.FieldDescriptor
-	if r.includeDefault {
-		exts := getDefaultExtensions(messageName)
-		if len(exts) > 0 || len(flds) > 0 {
-			ret = make([]*desc.FieldDescriptor, 0, len(exts)+len(flds))
-		}
-		for tag, ext := range exts {
-			if _, ok := flds[tag]; ok {
-				// skip default extension and use the one explicitly registered instead
-				continue
-			}
-			fd, _ := desc.LoadFieldDescriptorForExtension(ext)
-			if fd != nil {
-				ret = append(ret, fd)
-			}
-		}
-	} else if len(flds) > 0 {
-		ret = make([]*desc.FieldDescriptor, 0, len(flds))
-	}
-
-	for _, ext := range flds {
-		ret = append(ret, ext)
-	}
-	return ret
-}
diff --git a/vendor/github.com/jhump/protoreflect/dynamic/indent.go b/vendor/github.com/jhump/protoreflect/dynamic/indent.go
deleted file mode 100644
index bd7fcaa..0000000
--- a/vendor/github.com/jhump/protoreflect/dynamic/indent.go
+++ /dev/null
@@ -1,76 +0,0 @@
-package dynamic
-
-import "bytes"
-
-type indentBuffer struct {
-	bytes.Buffer
-	indent      string
-	indentCount int
-	comma       bool
-}
-
-func (b *indentBuffer) start() error {
-	if b.indentCount >= 0 {
-		b.indentCount++
-		return b.newLine(false)
-	}
-	return nil
-}
-
-func (b *indentBuffer) sep() error {
-	if b.indentCount >= 0 {
-		_, err := b.WriteString(": ")
-		return err
-	} else {
-		return b.WriteByte(':')
-	}
-}
-
-func (b *indentBuffer) end() error {
-	if b.indentCount >= 0 {
-		b.indentCount--
-		return b.newLine(false)
-	}
-	return nil
-}
-
-func (b *indentBuffer) maybeNext(first *bool) error {
-	if *first {
-		*first = false
-		return nil
-	} else {
-		return b.next()
-	}
-}
-
-func (b *indentBuffer) next() error {
-	if b.indentCount >= 0 {
-		return b.newLine(b.comma)
-	} else if b.comma {
-		return b.WriteByte(',')
-	} else {
-		return b.WriteByte(' ')
-	}
-}
-
-func (b *indentBuffer) newLine(comma bool) error {
-	if comma {
-		err := b.WriteByte(',')
-		if err != nil {
-			return err
-		}
-	}
-
-	err := b.WriteByte('\n')
-	if err != nil {
-		return err
-	}
-
-	for i := 0; i < b.indentCount; i++ {
-		_, err := b.WriteString(b.indent)
-		if err != nil {
-			return err
-		}
-	}
-	return nil
-}
diff --git a/vendor/github.com/jhump/protoreflect/dynamic/json.go b/vendor/github.com/jhump/protoreflect/dynamic/json.go
deleted file mode 100644
index 7dfae09..0000000
--- a/vendor/github.com/jhump/protoreflect/dynamic/json.go
+++ /dev/null
@@ -1,1238 +0,0 @@
-package dynamic
-
-// JSON marshalling and unmarshalling for dynamic messages
-
-import (
-	"bytes"
-	"encoding/base64"
-	"encoding/json"
-	"fmt"
-	"io"
-	"io/ioutil"
-	"math"
-	"reflect"
-	"sort"
-	"strconv"
-	"strings"
-
-	"github.com/golang/protobuf/jsonpb"
-	"github.com/golang/protobuf/proto"
-	"github.com/golang/protobuf/protoc-gen-go/descriptor"
-	// link in the well-known-types that have a special JSON format
-	_ "github.com/golang/protobuf/ptypes/any"
-	_ "github.com/golang/protobuf/ptypes/duration"
-	_ "github.com/golang/protobuf/ptypes/empty"
-	_ "github.com/golang/protobuf/ptypes/struct"
-	_ "github.com/golang/protobuf/ptypes/timestamp"
-	_ "github.com/golang/protobuf/ptypes/wrappers"
-
-	"github.com/jhump/protoreflect/desc"
-)
-
-var wellKnownTypeNames = map[string]struct{}{
-	"google.protobuf.Any":       {},
-	"google.protobuf.Empty":     {},
-	"google.protobuf.Duration":  {},
-	"google.protobuf.Timestamp": {},
-	// struct.proto
-	"google.protobuf.Struct":    {},
-	"google.protobuf.Value":     {},
-	"google.protobuf.ListValue": {},
-	// wrappers.proto
-	"google.protobuf.DoubleValue": {},
-	"google.protobuf.FloatValue":  {},
-	"google.protobuf.Int64Value":  {},
-	"google.protobuf.UInt64Value": {},
-	"google.protobuf.Int32Value":  {},
-	"google.protobuf.UInt32Value": {},
-	"google.protobuf.BoolValue":   {},
-	"google.protobuf.StringValue": {},
-	"google.protobuf.BytesValue":  {},
-}
-
-// MarshalJSON serializes this message to bytes in JSON format, returning an
-// error if the operation fails. The resulting bytes will be a valid UTF8
-// string.
-//
-// This method uses a compact form: no newlines, and spaces between fields and
-// between field identifiers and values are elided.
-//
-// This method is convenient shorthand for invoking MarshalJSONPB with a default
-// (zero value) marshaler:
-//
-//    m.MarshalJSONPB(&jsonpb.Marshaler{})
-//
-// So enums are serialized using enum value name strings, and values that are
-// not present (including those with default/zero value for messages defined in
-// "proto3" syntax) are omitted.
-func (m *Message) MarshalJSON() ([]byte, error) {
-	return m.MarshalJSONPB(&jsonpb.Marshaler{})
-}
-
-// MarshalJSONIndent serializes this message to bytes in JSON format, returning
-// an error if the operation fails. The resulting bytes will be a valid UTF8
-// string.
-//
-// This method uses a "pretty-printed" form, with each field on its own line and
-// spaces between field identifiers and values. Indentation of two spaces is
-// used.
-//
-// This method is convenient shorthand for invoking MarshalJSONPB with a default
-// (zero value) marshaler:
-//
-//    m.MarshalJSONPB(&jsonpb.Marshaler{Indent: "  "})
-//
-// So enums are serialized using enum value name strings, and values that are
-// not present (including those with default/zero value for messages defined in
-// "proto3" syntax) are omitted.
-func (m *Message) MarshalJSONIndent() ([]byte, error) {
-	return m.MarshalJSONPB(&jsonpb.Marshaler{Indent: "  "})
-}
-
-// MarshalJSONPB serializes this message to bytes in JSON format, returning an
-// error if the operation fails. The resulting bytes will be a valid UTF8
-// string. The given marshaler is used to convey options used during marshaling.
-//
-// If this message contains nested messages that are generated message types (as
-// opposed to dynamic messages), the given marshaler is used to marshal it.
-//
-// When marshaling any nested messages, any jsonpb.AnyResolver configured in the
-// given marshaler is augmented with knowledge of message types known to this
-// message's descriptor (and its enclosing file and set of transitive
-// dependencies).
-func (m *Message) MarshalJSONPB(opts *jsonpb.Marshaler) ([]byte, error) {
-	var b indentBuffer
-	b.indent = opts.Indent
-	if len(opts.Indent) == 0 {
-		b.indentCount = -1
-	}
-	b.comma = true
-	if err := m.marshalJSON(&b, opts); err != nil {
-		return nil, err
-	}
-	return b.Bytes(), nil
-}
-
-func (m *Message) marshalJSON(b *indentBuffer, opts *jsonpb.Marshaler) error {
-	if r, changed := wrapResolver(opts.AnyResolver, m.mf, m.md.GetFile()); changed {
-		newOpts := *opts
-		newOpts.AnyResolver = r
-		opts = &newOpts
-	}
-
-	if ok, err := marshalWellKnownType(m, b, opts); ok {
-		return err
-	}
-
-	err := b.WriteByte('{')
-	if err != nil {
-		return err
-	}
-	err = b.start()
-	if err != nil {
-		return err
-	}
-
-	var tags []int
-	if opts.EmitDefaults {
-		tags = m.allKnownFieldTags()
-	} else {
-		tags = m.knownFieldTags()
-	}
-
-	first := true
-
-	for _, tag := range tags {
-		itag := int32(tag)
-		fd := m.FindFieldDescriptor(itag)
-
-		v, ok := m.values[itag]
-		if !ok {
-			if fd.GetOneOf() != nil {
-				// don't print defaults for fields in a oneof
-				continue
-			}
-			v = fd.GetDefaultValue()
-		}
-
-		err := b.maybeNext(&first)
-		if err != nil {
-			return err
-		}
-		err = marshalKnownFieldJSON(b, fd, v, opts)
-		if err != nil {
-			return err
-		}
-	}
-
-	err = b.end()
-	if err != nil {
-		return err
-	}
-	err = b.WriteByte('}')
-	if err != nil {
-		return err
-	}
-
-	return nil
-}
-
-func marshalWellKnownType(m *Message, b *indentBuffer, opts *jsonpb.Marshaler) (bool, error) {
-	fqn := m.md.GetFullyQualifiedName()
-	if _, ok := wellKnownTypeNames[fqn]; !ok {
-		return false, nil
-	}
-
-	msgType := proto.MessageType(fqn)
-	if msgType == nil {
-		// wtf?
-		panic(fmt.Sprintf("could not find registered message type for %q", fqn))
-	}
-
-	// convert dynamic message to well-known type and let jsonpb marshal it
-	msg := reflect.New(msgType.Elem()).Interface().(proto.Message)
-	if err := m.MergeInto(msg); err != nil {
-		return true, err
-	}
-	return true, opts.Marshal(b, msg)
-}
-
-func marshalKnownFieldJSON(b *indentBuffer, fd *desc.FieldDescriptor, v interface{}, opts *jsonpb.Marshaler) error {
-	var jsonName string
-	if opts.OrigName {
-		jsonName = fd.GetName()
-	} else {
-		jsonName = fd.AsFieldDescriptorProto().GetJsonName()
-		if jsonName == "" {
-			jsonName = fd.GetName()
-		}
-	}
-	if fd.IsExtension() {
-		var scope string
-		switch parent := fd.GetParent().(type) {
-		case *desc.FileDescriptor:
-			scope = parent.GetPackage()
-		default:
-			scope = parent.GetFullyQualifiedName()
-		}
-		if scope == "" {
-			jsonName = fmt.Sprintf("[%s]", jsonName)
-		} else {
-			jsonName = fmt.Sprintf("[%s.%s]", scope, jsonName)
-		}
-	}
-	err := writeJsonString(b, jsonName)
-	if err != nil {
-		return err
-	}
-	err = b.sep()
-	if err != nil {
-		return err
-	}
-
-	if isNil(v) {
-		_, err := b.WriteString("null")
-		return err
-	}
-
-	if fd.IsMap() {
-		err = b.WriteByte('{')
-		if err != nil {
-			return err
-		}
-		err = b.start()
-		if err != nil {
-			return err
-		}
-
-		md := fd.GetMessageType()
-		vfd := md.FindFieldByNumber(2)
-
-		mp := v.(map[interface{}]interface{})
-		keys := make([]interface{}, 0, len(mp))
-		for k := range mp {
-			keys = append(keys, k)
-		}
-		sort.Sort(sortable(keys))
-		first := true
-		for _, mk := range keys {
-			mv := mp[mk]
-			err := b.maybeNext(&first)
-			if err != nil {
-				return err
-			}
-
-			err = marshalKnownFieldMapEntryJSON(b, mk, vfd, mv, opts)
-			if err != nil {
-				return err
-			}
-		}
-
-		err = b.end()
-		if err != nil {
-			return err
-		}
-		return b.WriteByte('}')
-
-	} else if fd.IsRepeated() {
-		err = b.WriteByte('[')
-		if err != nil {
-			return err
-		}
-		err = b.start()
-		if err != nil {
-			return err
-		}
-
-		sl := v.([]interface{})
-		first := true
-		for _, slv := range sl {
-			err := b.maybeNext(&first)
-			if err != nil {
-				return err
-			}
-			err = marshalKnownFieldValueJSON(b, fd, slv, opts)
-			if err != nil {
-				return err
-			}
-		}
-
-		err = b.end()
-		if err != nil {
-			return err
-		}
-		return b.WriteByte(']')
-
-	} else {
-		return marshalKnownFieldValueJSON(b, fd, v, opts)
-	}
-}
-
-// sortable is used to sort map keys. Values will be integers (int32, int64, uint32, and uint64),
-// bools, or strings.
-type sortable []interface{}
-
-func (s sortable) Len() int {
-	return len(s)
-}
-
-func (s sortable) Less(i, j int) bool {
-	vi := s[i]
-	vj := s[j]
-	switch reflect.TypeOf(vi).Kind() {
-	case reflect.Int32:
-		return vi.(int32) < vj.(int32)
-	case reflect.Int64:
-		return vi.(int64) < vj.(int64)
-	case reflect.Uint32:
-		return vi.(uint32) < vj.(uint32)
-	case reflect.Uint64:
-		return vi.(uint64) < vj.(uint64)
-	case reflect.String:
-		return vi.(string) < vj.(string)
-	case reflect.Bool:
-		return !vi.(bool) && vj.(bool)
-	default:
-		panic(fmt.Sprintf("cannot compare keys of type %v", reflect.TypeOf(vi)))
-	}
-}
-
-func (s sortable) Swap(i, j int) {
-	s[i], s[j] = s[j], s[i]
-}
-
-func isNil(v interface{}) bool {
-	if v == nil {
-		return true
-	}
-	rv := reflect.ValueOf(v)
-	return rv.Kind() == reflect.Ptr && rv.IsNil()
-}
-
-func marshalKnownFieldMapEntryJSON(b *indentBuffer, mk interface{}, vfd *desc.FieldDescriptor, mv interface{}, opts *jsonpb.Marshaler) error {
-	rk := reflect.ValueOf(mk)
-	var strkey string
-	switch rk.Kind() {
-	case reflect.Bool:
-		strkey = strconv.FormatBool(rk.Bool())
-	case reflect.Int32, reflect.Int64:
-		strkey = strconv.FormatInt(rk.Int(), 10)
-	case reflect.Uint32, reflect.Uint64:
-		strkey = strconv.FormatUint(rk.Uint(), 10)
-	case reflect.String:
-		strkey = rk.String()
-	default:
-		return fmt.Errorf("invalid map key value: %v (%v)", mk, rk.Type())
-	}
-	err := writeString(b, strkey)
-	if err != nil {
-		return err
-	}
-	err = b.sep()
-	if err != nil {
-		return err
-	}
-	return marshalKnownFieldValueJSON(b, vfd, mv, opts)
-}
-
-func marshalKnownFieldValueJSON(b *indentBuffer, fd *desc.FieldDescriptor, v interface{}, opts *jsonpb.Marshaler) error {
-	rv := reflect.ValueOf(v)
-	switch rv.Kind() {
-	case reflect.Int64:
-		return writeJsonString(b, strconv.FormatInt(rv.Int(), 10))
-	case reflect.Int32:
-		ed := fd.GetEnumType()
-		if !opts.EnumsAsInts && ed != nil {
-			n := int32(rv.Int())
-			vd := ed.FindValueByNumber(n)
-			if vd == nil {
-				_, err := b.WriteString(strconv.FormatInt(rv.Int(), 10))
-				return err
-			} else {
-				return writeJsonString(b, vd.GetName())
-			}
-		} else {
-			_, err := b.WriteString(strconv.FormatInt(rv.Int(), 10))
-			return err
-		}
-	case reflect.Uint64:
-		return writeJsonString(b, strconv.FormatUint(rv.Uint(), 10))
-	case reflect.Uint32:
-		_, err := b.WriteString(strconv.FormatUint(rv.Uint(), 10))
-		return err
-	case reflect.Float32, reflect.Float64:
-		f := rv.Float()
-		var str string
-		if math.IsNaN(f) {
-			str = `"NaN"`
-		} else if math.IsInf(f, 1) {
-			str = `"Infinity"`
-		} else if math.IsInf(f, -1) {
-			str = `"-Infinity"`
-		} else {
-			var bits int
-			if rv.Kind() == reflect.Float32 {
-				bits = 32
-			} else {
-				bits = 64
-			}
-			str = strconv.FormatFloat(rv.Float(), 'g', -1, bits)
-		}
-		_, err := b.WriteString(str)
-		return err
-	case reflect.Bool:
-		_, err := b.WriteString(strconv.FormatBool(rv.Bool()))
-		return err
-	case reflect.Slice:
-		bstr := base64.StdEncoding.EncodeToString(rv.Bytes())
-		return writeJsonString(b, bstr)
-	case reflect.String:
-		return writeJsonString(b, rv.String())
-	default:
-		// must be a message
-		if dm, ok := v.(*Message); ok {
-			return dm.marshalJSON(b, opts)
-		} else {
-			var err error
-			if b.indentCount <= 0 || len(b.indent) == 0 {
-				err = opts.Marshal(b, v.(proto.Message))
-			} else {
-				str, err := opts.MarshalToString(v.(proto.Message))
-				if err != nil {
-					return err
-				}
-				indent := strings.Repeat(b.indent, b.indentCount)
-				pos := 0
-				// add indention prefix to each line
-				for pos < len(str) {
-					start := pos
-					nextPos := strings.Index(str[pos:], "\n")
-					if nextPos == -1 {
-						nextPos = len(str)
-					} else {
-						nextPos = pos + nextPos + 1 // include newline
-					}
-					line := str[start:nextPos]
-					if pos > 0 {
-						_, err = b.WriteString(indent)
-						if err != nil {
-							return err
-						}
-					}
-					_, err = b.WriteString(line)
-					if err != nil {
-						return err
-					}
-					pos = nextPos
-				}
-			}
-			return err
-		}
-	}
-}
-
-func writeJsonString(b *indentBuffer, s string) error {
-	if sbytes, err := json.Marshal(s); err != nil {
-		return err
-	} else {
-		_, err := b.Write(sbytes)
-		return err
-	}
-}
-
-// UnmarshalJSON de-serializes the message that is present, in JSON format, in
-// the given bytes into this message. It first resets the current message. It
-// returns an error if the given bytes do not contain a valid encoding of this
-// message type in JSON format.
-//
-// This method is shorthand for invoking UnmarshalJSONPB with a default (zero
-// value) unmarshaler:
-//
-//    m.UnmarshalMergeJSONPB(&jsonpb.Unmarshaler{}, js)
-//
-// So unknown fields will result in an error, and no provided jsonpb.AnyResolver
-// will be used when parsing google.protobuf.Any messages.
-func (m *Message) UnmarshalJSON(js []byte) error {
-	return m.UnmarshalJSONPB(&jsonpb.Unmarshaler{}, js)
-}
-
-// UnmarshalMergeJSON de-serializes the message that is present, in JSON format,
-// in the given bytes into this message. Unlike UnmarshalJSON, it does not first
-// reset the message, instead merging the data in the given bytes into the
-// existing data in this message.
-func (m *Message) UnmarshalMergeJSON(js []byte) error {
-	return m.UnmarshalMergeJSONPB(&jsonpb.Unmarshaler{}, js)
-}
-
-// UnmarshalJSONPB de-serializes the message that is present, in JSON format, in
-// the given bytes into this message. The given unmarshaler conveys options used
-// when parsing the JSON. This function first resets the current message. It
-// returns an error if the given bytes do not contain a valid encoding of this
-// message type in JSON format.
-//
-// The decoding is lenient:
-//  1. The JSON can refer to fields either by their JSON name or by their
-//     declared name.
-//  2. The JSON can use either numeric values or string names for enum values.
-//
-// When instantiating nested messages, if this message's associated factory
-// returns a generated message type (as opposed to a dynamic message), the given
-// unmarshaler is used to unmarshal it.
-//
-// When unmarshaling any nested messages, any jsonpb.AnyResolver configured in
-// the given unmarshaler is augmented with knowledge of message types known to
-// this message's descriptor (and its enclosing file and set of transitive
-// dependencies).
-func (m *Message) UnmarshalJSONPB(opts *jsonpb.Unmarshaler, js []byte) error {
-	m.Reset()
-	if err := m.UnmarshalMergeJSONPB(opts, js); err != nil {
-		return err
-	}
-	return m.Validate()
-}
-
-// UnmarshalMergeJSONPB de-serializes the message that is present, in JSON
-// format, in the given bytes into this message. The given unmarshaler conveys
-// options used when parsing the JSON. Unlike UnmarshalJSONPB, it does not first
-// reset the message, instead merging the data in the given bytes into the
-// existing data in this message.
-func (m *Message) UnmarshalMergeJSONPB(opts *jsonpb.Unmarshaler, js []byte) error {
-	r := newJsReader(js)
-	err := m.unmarshalJson(r, opts)
-	if err != nil {
-		return err
-	}
-	if t, err := r.poll(); err != io.EOF {
-		b, _ := ioutil.ReadAll(r.unread())
-		s := fmt.Sprintf("%v%s", t, string(b))
-		return fmt.Errorf("superfluous data found after JSON object: %q", s)
-	}
-	return nil
-}
-
-func unmarshalWellKnownType(m *Message, r *jsReader, opts *jsonpb.Unmarshaler) (bool, error) {
-	fqn := m.md.GetFullyQualifiedName()
-	if _, ok := wellKnownTypeNames[fqn]; !ok {
-		return false, nil
-	}
-
-	msgType := proto.MessageType(fqn)
-	if msgType == nil {
-		// wtf?
-		panic(fmt.Sprintf("could not find registered message type for %q", fqn))
-	}
-
-	// extract json value from r
-	var js json.RawMessage
-	if err := json.NewDecoder(r.unread()).Decode(&js); err != nil {
-		return true, err
-	}
-	if err := r.skip(); err != nil {
-		return true, err
-	}
-
-	// unmarshal into well-known type and then convert to dynamic message
-	msg := reflect.New(msgType.Elem()).Interface().(proto.Message)
-	if err := opts.Unmarshal(bytes.NewReader(js), msg); err != nil {
-		return true, err
-	}
-	return true, m.MergeFrom(msg)
-}
-
-func (m *Message) unmarshalJson(r *jsReader, opts *jsonpb.Unmarshaler) error {
-	if r, changed := wrapResolver(opts.AnyResolver, m.mf, m.md.GetFile()); changed {
-		newOpts := *opts
-		newOpts.AnyResolver = r
-		opts = &newOpts
-	}
-
-	if ok, err := unmarshalWellKnownType(m, r, opts); ok {
-		return err
-	}
-
-	t, err := r.peek()
-	if err != nil {
-		return err
-	}
-	if t == nil {
-		// if json is simply "null" we do nothing
-		r.poll()
-		return nil
-	}
-
-	if err := r.beginObject(); err != nil {
-		return err
-	}
-
-	for r.hasNext() {
-		f, err := r.nextObjectKey()
-		if err != nil {
-			return err
-		}
-		fd := m.FindFieldDescriptorByJSONName(f)
-		if fd == nil {
-			if opts.AllowUnknownFields {
-				r.skip()
-				continue
-			}
-			return fmt.Errorf("message type %s has no known field named %s", m.md.GetFullyQualifiedName(), f)
-		}
-		v, err := unmarshalJsField(fd, r, m.mf, opts)
-		if err != nil {
-			return err
-		}
-		if v != nil {
-			if err := mergeField(m, fd, v); err != nil {
-				return err
-			}
-		} else if fd.GetOneOf() != nil {
-			// preserve explicit null for oneof fields (this is a little odd but
-			// mimics the behavior of jsonpb with oneofs in generated message types)
-			if fd.GetMessageType() != nil {
-				typ := m.mf.GetKnownTypeRegistry().GetKnownType(fd.GetMessageType().GetFullyQualifiedName())
-				if typ != nil {
-					// typed nil
-					if typ.Kind() != reflect.Ptr {
-						typ = reflect.PtrTo(typ)
-					}
-					v = reflect.Zero(typ).Interface()
-				} else {
-					// can't use nil dynamic message, so we just use empty one instead
-					v = m.mf.NewDynamicMessage(fd.GetMessageType())
-				}
-				if err := m.setField(fd, v); err != nil {
-					return err
-				}
-			} else {
-				// not a message... explicit null makes no sense
-				return fmt.Errorf("message type %s cannot set field %s to null: it is not a message type", m.md.GetFullyQualifiedName(), f)
-			}
-		} else {
-			m.clearField(fd)
-		}
-	}
-
-	if err := r.endObject(); err != nil {
-		return err
-	}
-
-	return nil
-}
-
-func isWellKnownValue(fd *desc.FieldDescriptor) bool {
-	return !fd.IsRepeated() && fd.GetType() == descriptor.FieldDescriptorProto_TYPE_MESSAGE &&
-		fd.GetMessageType().GetFullyQualifiedName() == "google.protobuf.Value"
-}
-
-func isWellKnownListValue(fd *desc.FieldDescriptor) bool {
-	return !fd.IsRepeated() && fd.GetType() == descriptor.FieldDescriptorProto_TYPE_MESSAGE &&
-		fd.GetMessageType().GetFullyQualifiedName() == "google.protobuf.ListValue"
-}
-
-func unmarshalJsField(fd *desc.FieldDescriptor, r *jsReader, mf *MessageFactory, opts *jsonpb.Unmarshaler) (interface{}, error) {
-	t, err := r.peek()
-	if err != nil {
-		return nil, err
-	}
-	if t == nil && !isWellKnownValue(fd) {
-		// if value is null, just return nil
-		// (unless field is google.protobuf.Value, in which case
-		// we fall through to parse it as an instance where its
-		// underlying value is set to a NullValue)
-		r.poll()
-		return nil, nil
-	}
-
-	if t == json.Delim('{') && fd.IsMap() {
-		entryType := fd.GetMessageType()
-		keyType := entryType.FindFieldByNumber(1)
-		valueType := entryType.FindFieldByNumber(2)
-		mp := map[interface{}]interface{}{}
-
-		// TODO: if there are just two map keys "key" and "value" and they have the right type of values,
-		// treat this JSON object as a single map entry message. (In keeping with support of map fields as
-		// if they were normal repeated field of entry messages as well as supporting a transition from
-		// optional to repeated...)
-
-		if err := r.beginObject(); err != nil {
-			return nil, err
-		}
-		for r.hasNext() {
-			kk, err := unmarshalJsFieldElement(keyType, r, mf, opts)
-			if err != nil {
-				return nil, err
-			}
-			vv, err := unmarshalJsFieldElement(valueType, r, mf, opts)
-			if err != nil {
-				return nil, err
-			}
-			mp[kk] = vv
-		}
-		if err := r.endObject(); err != nil {
-			return nil, err
-		}
-
-		return mp, nil
-	} else if t == json.Delim('[') && !isWellKnownListValue(fd) {
-		// We support parsing an array, even if field is not repeated, to mimic support in proto
-		// binary wire format that supports changing an optional field to repeated and vice versa.
-		// If the field is not repeated, we only keep the last value in the array.
-
-		if err := r.beginArray(); err != nil {
-			return nil, err
-		}
-		var sl []interface{}
-		var v interface{}
-		for r.hasNext() {
-			var err error
-			v, err = unmarshalJsFieldElement(fd, r, mf, opts)
-			if err != nil {
-				return nil, err
-			}
-			if fd.IsRepeated() && v != nil {
-				sl = append(sl, v)
-			}
-		}
-		if err := r.endArray(); err != nil {
-			return nil, err
-		}
-		if fd.IsMap() {
-			mp := map[interface{}]interface{}{}
-			for _, m := range sl {
-				msg := m.(*Message)
-				kk, err := msg.TryGetFieldByNumber(1)
-				if err != nil {
-					return nil, err
-				}
-				vv, err := msg.TryGetFieldByNumber(2)
-				if err != nil {
-					return nil, err
-				}
-				mp[kk] = vv
-			}
-			return mp, nil
-		} else if fd.IsRepeated() {
-			return sl, nil
-		} else {
-			return v, nil
-		}
-	} else {
-		// We support parsing a singular value, even if field is repeated, to mimic support in proto
-		// binary wire format that supports changing an optional field to repeated and vice versa.
-		// If the field is repeated, we store value as singleton slice of that one value.
-
-		v, err := unmarshalJsFieldElement(fd, r, mf, opts)
-		if err != nil {
-			return nil, err
-		}
-		if v == nil {
-			return nil, nil
-		}
-		if fd.IsRepeated() {
-			return []interface{}{v}, nil
-		} else {
-			return v, nil
-		}
-	}
-}
-
-func unmarshalJsFieldElement(fd *desc.FieldDescriptor, r *jsReader, mf *MessageFactory, opts *jsonpb.Unmarshaler) (interface{}, error) {
-	t, err := r.peek()
-	if err != nil {
-		return nil, err
-	}
-
-	switch fd.GetType() {
-	case descriptor.FieldDescriptorProto_TYPE_MESSAGE,
-		descriptor.FieldDescriptorProto_TYPE_GROUP:
-		m := mf.NewMessage(fd.GetMessageType())
-		if dm, ok := m.(*Message); ok {
-			if err := dm.unmarshalJson(r, opts); err != nil {
-				return nil, err
-			}
-		} else {
-			var msg json.RawMessage
-			if err := json.NewDecoder(r.unread()).Decode(&msg); err != nil {
-				return nil, err
-			}
-			if err := r.skip(); err != nil {
-				return nil, err
-			}
-			if err := opts.Unmarshal(bytes.NewReader([]byte(msg)), m); err != nil {
-				return nil, err
-			}
-		}
-		return m, nil
-
-	case descriptor.FieldDescriptorProto_TYPE_ENUM:
-		if e, err := r.nextNumber(); err != nil {
-			return nil, err
-		} else {
-			// value could be string or number
-			if i, err := e.Int64(); err != nil {
-				// number cannot be parsed, so see if it's an enum value name
-				vd := fd.GetEnumType().FindValueByName(string(e))
-				if vd != nil {
-					return vd.GetNumber(), nil
-				} else {
-					return nil, fmt.Errorf("enum %q does not have value named %q", fd.GetEnumType().GetFullyQualifiedName(), e)
-				}
-			} else if i > math.MaxInt32 || i < math.MinInt32 {
-				return nil, NumericOverflowError
-			} else {
-				return int32(i), err
-			}
-		}
-
-	case descriptor.FieldDescriptorProto_TYPE_INT32,
-		descriptor.FieldDescriptorProto_TYPE_SINT32,
-		descriptor.FieldDescriptorProto_TYPE_SFIXED32:
-		if i, err := r.nextInt(); err != nil {
-			return nil, err
-		} else if i > math.MaxInt32 || i < math.MinInt32 {
-			return nil, NumericOverflowError
-		} else {
-			return int32(i), err
-		}
-
-	case descriptor.FieldDescriptorProto_TYPE_INT64,
-		descriptor.FieldDescriptorProto_TYPE_SINT64,
-		descriptor.FieldDescriptorProto_TYPE_SFIXED64:
-		return r.nextInt()
-
-	case descriptor.FieldDescriptorProto_TYPE_UINT32,
-		descriptor.FieldDescriptorProto_TYPE_FIXED32:
-		if i, err := r.nextUint(); err != nil {
-			return nil, err
-		} else if i > math.MaxUint32 {
-			return nil, NumericOverflowError
-		} else {
-			return uint32(i), err
-		}
-
-	case descriptor.FieldDescriptorProto_TYPE_UINT64,
-		descriptor.FieldDescriptorProto_TYPE_FIXED64:
-		return r.nextUint()
-
-	case descriptor.FieldDescriptorProto_TYPE_BOOL:
-		if str, ok := t.(string); ok {
-			if str == "true" {
-				r.poll() // consume token
-				return true, err
-			} else if str == "false" {
-				r.poll() // consume token
-				return false, err
-			}
-		}
-		return r.nextBool()
-
-	case descriptor.FieldDescriptorProto_TYPE_FLOAT:
-		if f, err := r.nextFloat(); err != nil {
-			return nil, err
-		} else {
-			return float32(f), nil
-		}
-
-	case descriptor.FieldDescriptorProto_TYPE_DOUBLE:
-		return r.nextFloat()
-
-	case descriptor.FieldDescriptorProto_TYPE_BYTES:
-		return r.nextBytes()
-
-	case descriptor.FieldDescriptorProto_TYPE_STRING:
-		return r.nextString()
-
-	default:
-		return nil, fmt.Errorf("unknown field type: %v", fd.GetType())
-	}
-}
-
-type jsReader struct {
-	reader  *bytes.Reader
-	dec     *json.Decoder
-	current json.Token
-	peeked  bool
-}
-
-func newJsReader(b []byte) *jsReader {
-	reader := bytes.NewReader(b)
-	dec := json.NewDecoder(reader)
-	dec.UseNumber()
-	return &jsReader{reader: reader, dec: dec}
-}
-
-func (r *jsReader) unread() io.Reader {
-	bufs := make([]io.Reader, 3)
-	var peeked []byte
-	if r.peeked {
-		if _, ok := r.current.(json.Delim); ok {
-			peeked = []byte(fmt.Sprintf("%v", r.current))
-		} else {
-			peeked, _ = json.Marshal(r.current)
-		}
-	}
-	readerCopy := *r.reader
-	decCopy := *r.dec
-
-	bufs[0] = bytes.NewReader(peeked)
-	bufs[1] = decCopy.Buffered()
-	bufs[2] = &readerCopy
-	return &concatReader{bufs: bufs}
-}
-
-func (r *jsReader) hasNext() bool {
-	return r.dec.More()
-}
-
-func (r *jsReader) peek() (json.Token, error) {
-	if r.peeked {
-		return r.current, nil
-	}
-	t, err := r.dec.Token()
-	if err != nil {
-		return nil, err
-	}
-	r.peeked = true
-	r.current = t
-	return t, nil
-}
-
-func (r *jsReader) poll() (json.Token, error) {
-	if r.peeked {
-		ret := r.current
-		r.current = nil
-		r.peeked = false
-		return ret, nil
-	}
-	return r.dec.Token()
-}
-
-func (r *jsReader) beginObject() error {
-	_, err := r.expect(func(t json.Token) bool { return t == json.Delim('{') }, nil, "start of JSON object: '{'")
-	return err
-}
-
-func (r *jsReader) endObject() error {
-	_, err := r.expect(func(t json.Token) bool { return t == json.Delim('}') }, nil, "end of JSON object: '}'")
-	return err
-}
-
-func (r *jsReader) beginArray() error {
-	_, err := r.expect(func(t json.Token) bool { return t == json.Delim('[') }, nil, "start of array: '['")
-	return err
-}
-
-func (r *jsReader) endArray() error {
-	_, err := r.expect(func(t json.Token) bool { return t == json.Delim(']') }, nil, "end of array: ']'")
-	return err
-}
-
-func (r *jsReader) nextObjectKey() (string, error) {
-	return r.nextString()
-}
-
-func (r *jsReader) nextString() (string, error) {
-	t, err := r.expect(func(t json.Token) bool { _, ok := t.(string); return ok }, "", "string")
-	if err != nil {
-		return "", err
-	}
-	return t.(string), nil
-}
-
-func (r *jsReader) nextBytes() ([]byte, error) {
-	str, err := r.nextString()
-	if err != nil {
-		return nil, err
-	}
-	return base64.StdEncoding.DecodeString(str)
-}
-
-func (r *jsReader) nextBool() (bool, error) {
-	t, err := r.expect(func(t json.Token) bool { _, ok := t.(bool); return ok }, false, "boolean")
-	if err != nil {
-		return false, err
-	}
-	return t.(bool), nil
-}
-
-func (r *jsReader) nextInt() (int64, error) {
-	n, err := r.nextNumber()
-	if err != nil {
-		return 0, err
-	}
-	return n.Int64()
-}
-
-func (r *jsReader) nextUint() (uint64, error) {
-	n, err := r.nextNumber()
-	if err != nil {
-		return 0, err
-	}
-	return strconv.ParseUint(string(n), 10, 64)
-}
-
-func (r *jsReader) nextFloat() (float64, error) {
-	n, err := r.nextNumber()
-	if err != nil {
-		return 0, err
-	}
-	return n.Float64()
-}
-
-func (r *jsReader) nextNumber() (json.Number, error) {
-	t, err := r.expect(func(t json.Token) bool { return reflect.TypeOf(t).Kind() == reflect.String }, "0", "number")
-	if err != nil {
-		return "", err
-	}
-	switch t := t.(type) {
-	case json.Number:
-		return t, nil
-	case string:
-		return json.Number(t), nil
-	}
-	return "", fmt.Errorf("expecting a number but got %v", t)
-}
-
-func (r *jsReader) skip() error {
-	t, err := r.poll()
-	if err != nil {
-		return err
-	}
-	if t == json.Delim('[') {
-		if err := r.skipArray(); err != nil {
-			return err
-		}
-	} else if t == json.Delim('{') {
-		if err := r.skipObject(); err != nil {
-			return err
-		}
-	}
-	return nil
-}
-
-func (r *jsReader) skipArray() error {
-	for r.hasNext() {
-		if err := r.skip(); err != nil {
-			return err
-		}
-	}
-	if err := r.endArray(); err != nil {
-		return err
-	}
-	return nil
-}
-
-func (r *jsReader) skipObject() error {
-	for r.hasNext() {
-		// skip object key
-		if err := r.skip(); err != nil {
-			return err
-		}
-		// and value
-		if err := r.skip(); err != nil {
-			return err
-		}
-	}
-	if err := r.endObject(); err != nil {
-		return err
-	}
-	return nil
-}
-
-func (r *jsReader) expect(predicate func(json.Token) bool, ifNil interface{}, expected string) (interface{}, error) {
-	t, err := r.poll()
-	if err != nil {
-		return nil, err
-	}
-	if t == nil && ifNil != nil {
-		return ifNil, nil
-	}
-	if !predicate(t) {
-		return t, fmt.Errorf("bad input: expecting %s ; instead got %v", expected, t)
-	}
-	return t, nil
-}
-
-type concatReader struct {
-	bufs []io.Reader
-	curr int
-}
-
-func (r *concatReader) Read(p []byte) (n int, err error) {
-	for {
-		if r.curr >= len(r.bufs) {
-			err = io.EOF
-			return
-		}
-		var c int
-		c, err = r.bufs[r.curr].Read(p)
-		n += c
-		if err != io.EOF {
-			return
-		}
-		r.curr++
-		p = p[c:]
-	}
-}
-
-// AnyResolver returns a jsonpb.AnyResolver that uses the given file descriptors
-// to resolve message names. It uses the given factory, which may be nil, to
-// instantiate messages. The messages that it returns when resolving a type name
-// may often be dynamic messages.
-func AnyResolver(mf *MessageFactory, files ...*desc.FileDescriptor) jsonpb.AnyResolver {
-	return &anyResolver{mf: mf, files: files}
-}
-
-type anyResolver struct {
-	mf      *MessageFactory
-	files   []*desc.FileDescriptor
-	ignored map[*desc.FileDescriptor]struct{}
-	other   jsonpb.AnyResolver
-}
-
-func wrapResolver(r jsonpb.AnyResolver, mf *MessageFactory, f *desc.FileDescriptor) (jsonpb.AnyResolver, bool) {
-	if r, ok := r.(*anyResolver); ok {
-		if _, ok := r.ignored[f]; ok {
-			// if the current resolver is ignoring this file, it's because another
-			// (upstream) resolver is already handling it, so nothing to do
-			return r, false
-		}
-		for _, file := range r.files {
-			if file == f {
-				// no need to wrap!
-				return r, false
-			}
-		}
-		// ignore files that will be checked by the resolver we're wrapping
-		// (we'll just delegate and let it search those files)
-		ignored := map[*desc.FileDescriptor]struct{}{}
-		for i := range r.ignored {
-			ignored[i] = struct{}{}
-		}
-		ignore(r.files, ignored)
-		return &anyResolver{mf: mf, files: []*desc.FileDescriptor{f}, ignored: ignored, other: r}, true
-	}
-	return &anyResolver{mf: mf, files: []*desc.FileDescriptor{f}, other: r}, true
-}
-
-func ignore(files []*desc.FileDescriptor, ignored map[*desc.FileDescriptor]struct{}) {
-	for _, f := range files {
-		if _, ok := ignored[f]; ok {
-			continue
-		}
-		ignored[f] = struct{}{}
-		ignore(f.GetDependencies(), ignored)
-	}
-}
-
-func (r *anyResolver) Resolve(typeUrl string) (proto.Message, error) {
-	mname := typeUrl
-	if slash := strings.LastIndex(mname, "/"); slash >= 0 {
-		mname = mname[slash+1:]
-	}
-
-	// see if the user-specified resolver is able to do the job
-	if r.other != nil {
-		msg, err := r.other.Resolve(typeUrl)
-		if err == nil {
-			return msg, nil
-		}
-	}
-
-	// try to find the message in our known set of files
-	checked := map[*desc.FileDescriptor]struct{}{}
-	for _, f := range r.files {
-		md := r.findMessage(f, mname, checked)
-		if md != nil {
-			return r.mf.NewMessage(md), nil
-		}
-	}
-	// failing that, see if the message factory knows about this type
-	var ktr *KnownTypeRegistry
-	if r.mf != nil {
-		ktr = r.mf.ktr
-	} else {
-		ktr = (*KnownTypeRegistry)(nil)
-	}
-	m := ktr.CreateIfKnown(mname)
-	if m != nil {
-		return m, nil
-	}
-
-	// no other resolver to fallback to? mimic default behavior
-	mt := proto.MessageType(mname)
-	if mt == nil {
-		return nil, fmt.Errorf("unknown message type %q", mname)
-	}
-	return reflect.New(mt.Elem()).Interface().(proto.Message), nil
-}
-
-func (r *anyResolver) findMessage(fd *desc.FileDescriptor, msgName string, checked map[*desc.FileDescriptor]struct{}) *desc.MessageDescriptor {
-	// if this is an ignored descriptor, skip
-	if _, ok := r.ignored[fd]; ok {
-		return nil
-	}
-
-	// bail if we've already checked this file
-	if _, ok := checked[fd]; ok {
-		return nil
-	}
-	checked[fd] = struct{}{}
-
-	// see if this file has the message
-	md := fd.FindMessage(msgName)
-	if md != nil {
-		return md
-	}
-
-	// if not, recursively search the file's imports
-	for _, dep := range fd.GetDependencies() {
-		md = r.findMessage(dep, msgName, checked)
-		if md != nil {
-			return md
-		}
-	}
-	return nil
-}
-
-var _ jsonpb.AnyResolver = (*anyResolver)(nil)
diff --git a/vendor/github.com/jhump/protoreflect/dynamic/maps_1.11.go b/vendor/github.com/jhump/protoreflect/dynamic/maps_1.11.go
deleted file mode 100644
index bb68d7b..0000000
--- a/vendor/github.com/jhump/protoreflect/dynamic/maps_1.11.go
+++ /dev/null
@@ -1,129 +0,0 @@
-//+build !go1.12
-
-package dynamic
-
-import (
-	"github.com/jhump/protoreflect/desc"
-	"reflect"
-)
-
-// Pre-Go-1.12, we must use reflect.Value.MapKeys to reflectively
-// iterate a map. (We can be more efficient in Go 1.12 and up...)
-
-func mapsEqual(a, b reflect.Value) bool {
-	if a.Len() != b.Len() {
-		return false
-	}
-	if a.Len() == 0 && b.Len() == 0 {
-		// Optimize the case where maps are frequently empty because MapKeys()
-		// function allocates heavily.
-		return true
-	}
-
-	for _, k := range a.MapKeys() {
-		av := a.MapIndex(k)
-		bv := b.MapIndex(k)
-		if !bv.IsValid() {
-			return false
-		}
-		if !fieldsEqual(av.Interface(), bv.Interface()) {
-			return false
-		}
-	}
-	return true
-}
-
-func validFieldValueForMapField(fd *desc.FieldDescriptor, val reflect.Value) (interface{}, error) {
-	// make a defensive copy while we check the contents
-	// (also converts to map[interface{}]interface{} if it's some other type)
-	keyField := fd.GetMessageType().GetFields()[0]
-	valField := fd.GetMessageType().GetFields()[1]
-	m := map[interface{}]interface{}{}
-	for _, k := range val.MapKeys() {
-		if k.Kind() == reflect.Interface {
-			// unwrap it
-			k = reflect.ValueOf(k.Interface())
-		}
-		kk, err := validFieldValueForRv(keyField, k)
-		if err != nil {
-			return nil, err
-		}
-		v := val.MapIndex(k)
-		if v.Kind() == reflect.Interface {
-			// unwrap it
-			v = reflect.ValueOf(v.Interface())
-		}
-		vv, err := validFieldValueForRv(valField, v)
-		if err != nil {
-			return nil, err
-		}
-		m[kk] = vv
-	}
-	return m, nil
-}
-
-func canConvertMap(src reflect.Value, target reflect.Type) bool {
-	kt := target.Key()
-	vt := target.Elem()
-	for _, k := range src.MapKeys() {
-		if !canConvert(k, kt) {
-			return false
-		}
-		if !canConvert(src.MapIndex(k), vt) {
-			return false
-		}
-	}
-	return true
-}
-
-func mergeMapVal(src, target reflect.Value, targetType reflect.Type) error {
-	tkt := targetType.Key()
-	tvt := targetType.Elem()
-	for _, k := range src.MapKeys() {
-		v := src.MapIndex(k)
-		skt := k.Type()
-		svt := v.Type()
-		var nk, nv reflect.Value
-		if tkt == skt {
-			nk = k
-		} else if tkt.Kind() == reflect.Ptr && tkt.Elem() == skt {
-			nk = k.Addr()
-		} else {
-			nk = reflect.New(tkt).Elem()
-			if err := mergeVal(k, nk); err != nil {
-				return err
-			}
-		}
-		if tvt == svt {
-			nv = v
-		} else if tvt.Kind() == reflect.Ptr && tvt.Elem() == svt {
-			nv = v.Addr()
-		} else {
-			nv = reflect.New(tvt).Elem()
-			if err := mergeVal(v, nv); err != nil {
-				return err
-			}
-		}
-		if target.IsNil() {
-			target.Set(reflect.MakeMap(targetType))
-		}
-		target.SetMapIndex(nk, nv)
-	}
-	return nil
-}
-
-func mergeMapField(m *Message, fd *desc.FieldDescriptor, rv reflect.Value) error {
-	for _, k := range rv.MapKeys() {
-		if k.Kind() == reflect.Interface && !k.IsNil() {
-			k = k.Elem()
-		}
-		v := rv.MapIndex(k)
-		if v.Kind() == reflect.Interface && !v.IsNil() {
-			v = v.Elem()
-		}
-		if err := m.putMapField(fd, k.Interface(), v.Interface()); err != nil {
-			return err
-		}
-	}
-	return nil
-}
diff --git a/vendor/github.com/jhump/protoreflect/dynamic/maps_1.12.go b/vendor/github.com/jhump/protoreflect/dynamic/maps_1.12.go
deleted file mode 100644
index f5ffd67..0000000
--- a/vendor/github.com/jhump/protoreflect/dynamic/maps_1.12.go
+++ /dev/null
@@ -1,137 +0,0 @@
-//+build go1.12
-
-package dynamic
-
-import (
-	"github.com/jhump/protoreflect/desc"
-	"reflect"
-)
-
-// With Go 1.12 and above, we can use reflect.Value.MapRange to iterate
-// over maps more efficiently than using reflect.Value.MapKeys.
-
-func mapsEqual(a, b reflect.Value) bool {
-	if a.Len() != b.Len() {
-		return false
-	}
-	if a.Len() == 0 && b.Len() == 0 {
-		// Optimize the case where maps are frequently empty
-		return true
-	}
-
-	iter := a.MapRange()
-	for iter.Next() {
-		k := iter.Key()
-		av := iter.Value()
-		bv := b.MapIndex(k)
-		if !bv.IsValid() {
-			return false
-		}
-		if !fieldsEqual(av.Interface(), bv.Interface()) {
-			return false
-		}
-	}
-	return true
-}
-
-func validFieldValueForMapField(fd *desc.FieldDescriptor, val reflect.Value) (interface{}, error) {
-	// make a defensive copy while we check the contents
-	// (also converts to map[interface{}]interface{} if it's some other type)
-	keyField := fd.GetMessageType().GetFields()[0]
-	valField := fd.GetMessageType().GetFields()[1]
-	m := map[interface{}]interface{}{}
-	iter := val.MapRange()
-	for iter.Next() {
-		k := iter.Key()
-		if k.Kind() == reflect.Interface {
-			// unwrap it
-			k = reflect.ValueOf(k.Interface())
-		}
-		kk, err := validFieldValueForRv(keyField, k)
-		if err != nil {
-			return nil, err
-		}
-		v := iter.Value()
-		if v.Kind() == reflect.Interface {
-			// unwrap it
-			v = reflect.ValueOf(v.Interface())
-		}
-		vv, err := validFieldValueForRv(valField, v)
-		if err != nil {
-			return nil, err
-		}
-		m[kk] = vv
-	}
-	return m, nil
-}
-
-func canConvertMap(src reflect.Value, target reflect.Type) bool {
-	kt := target.Key()
-	vt := target.Elem()
-	iter := src.MapRange()
-	for iter.Next() {
-		if !canConvert(iter.Key(), kt) {
-			return false
-		}
-		if !canConvert(iter.Value(), vt) {
-			return false
-		}
-	}
-	return true
-}
-
-func mergeMapVal(src, target reflect.Value, targetType reflect.Type) error {
-	tkt := targetType.Key()
-	tvt := targetType.Elem()
-	iter := src.MapRange()
-	for iter.Next() {
-		k := iter.Key()
-		v := iter.Value()
-		skt := k.Type()
-		svt := v.Type()
-		var nk, nv reflect.Value
-		if tkt == skt {
-			nk = k
-		} else if tkt.Kind() == reflect.Ptr && tkt.Elem() == skt {
-			nk = k.Addr()
-		} else {
-			nk = reflect.New(tkt).Elem()
-			if err := mergeVal(k, nk); err != nil {
-				return err
-			}
-		}
-		if tvt == svt {
-			nv = v
-		} else if tvt.Kind() == reflect.Ptr && tvt.Elem() == svt {
-			nv = v.Addr()
-		} else {
-			nv = reflect.New(tvt).Elem()
-			if err := mergeVal(v, nv); err != nil {
-				return err
-			}
-		}
-		if target.IsNil() {
-			target.Set(reflect.MakeMap(targetType))
-		}
-		target.SetMapIndex(nk, nv)
-	}
-	return nil
-}
-
-func mergeMapField(m *Message, fd *desc.FieldDescriptor, rv reflect.Value) error {
-	iter := rv.MapRange()
-	for iter.Next() {
-		k := iter.Key()
-		v := iter.Value()
-		if k.Kind() == reflect.Interface && !k.IsNil() {
-			k = k.Elem()
-		}
-		if v.Kind() == reflect.Interface && !v.IsNil() {
-			v = v.Elem()
-		}
-		if err := m.putMapField(fd, k.Interface(), v.Interface()); err != nil {
-			return err
-		}
-	}
-	return nil
-}
diff --git a/vendor/github.com/jhump/protoreflect/dynamic/merge.go b/vendor/github.com/jhump/protoreflect/dynamic/merge.go
deleted file mode 100644
index ce727fd..0000000
--- a/vendor/github.com/jhump/protoreflect/dynamic/merge.go
+++ /dev/null
@@ -1,100 +0,0 @@
-package dynamic
-
-import (
-	"errors"
-	"reflect"
-
-	"github.com/golang/protobuf/proto"
-
-	"github.com/jhump/protoreflect/desc"
-)
-
-// Merge merges the given source message into the given destination message. Use
-// use this instead of proto.Merge when one or both of the messages might be a
-// a dynamic message. If there is a problem merging the messages, such as the
-// two messages having different types, then this method will panic (just as
-// proto.Merges does).
-func Merge(dst, src proto.Message) {
-	if dm, ok := dst.(*Message); ok {
-		if err := dm.MergeFrom(src); err != nil {
-			panic(err.Error())
-		}
-	} else if dm, ok := src.(*Message); ok {
-		if err := dm.MergeInto(dst); err != nil {
-			panic(err.Error())
-		}
-	} else {
-		proto.Merge(dst, src)
-	}
-}
-
-// TryMerge merges the given source message into the given destination message.
-// You can use this instead of proto.Merge when one or both of the messages
-// might be a dynamic message. Unlike proto.Merge, this method will return an
-// error on failure instead of panic'ing.
-func TryMerge(dst, src proto.Message) error {
-	if dm, ok := dst.(*Message); ok {
-		if err := dm.MergeFrom(src); err != nil {
-			return err
-		}
-	} else if dm, ok := src.(*Message); ok {
-		if err := dm.MergeInto(dst); err != nil {
-			return err
-		}
-	} else {
-		// proto.Merge panics on bad input, so we first verify
-		// inputs and return error instead of panic
-		out := reflect.ValueOf(dst)
-		if out.IsNil() {
-			return errors.New("proto: nil destination")
-		}
-		in := reflect.ValueOf(src)
-		if in.Type() != out.Type() {
-			return errors.New("proto: type mismatch")
-		}
-		proto.Merge(dst, src)
-	}
-	return nil
-}
-
-func mergeField(m *Message, fd *desc.FieldDescriptor, val interface{}) error {
-	rv := reflect.ValueOf(val)
-
-	if fd.IsMap() && rv.Kind() == reflect.Map {
-		return mergeMapField(m, fd, rv)
-	}
-
-	if fd.IsRepeated() && rv.Kind() == reflect.Slice && rv.Type() != typeOfBytes {
-		for i := 0; i < rv.Len(); i++ {
-			e := rv.Index(i)
-			if e.Kind() == reflect.Interface && !e.IsNil() {
-				e = e.Elem()
-			}
-			if err := m.addRepeatedField(fd, e.Interface()); err != nil {
-				return err
-			}
-		}
-		return nil
-	}
-
-	if fd.IsRepeated() {
-		return m.addRepeatedField(fd, val)
-	} else if fd.GetMessageType() == nil {
-		return m.setField(fd, val)
-	}
-
-	// it's a message type, so we want to merge contents
-	var err error
-	if val, err = validFieldValue(fd, val); err != nil {
-		return err
-	}
-
-	existing, _ := m.doGetField(fd, true)
-	if existing != nil && !reflect.ValueOf(existing).IsNil() {
-		return TryMerge(existing.(proto.Message), val.(proto.Message))
-	}
-
-	// no existing message, so just set field
-	m.internalSetField(fd, val)
-	return nil
-}
diff --git a/vendor/github.com/jhump/protoreflect/dynamic/message_factory.go b/vendor/github.com/jhump/protoreflect/dynamic/message_factory.go
deleted file mode 100644
index 6c54de8..0000000
--- a/vendor/github.com/jhump/protoreflect/dynamic/message_factory.go
+++ /dev/null
@@ -1,189 +0,0 @@
-package dynamic
-
-import (
-	"reflect"
-	"sync"
-
-	"github.com/golang/protobuf/proto"
-
-	"github.com/jhump/protoreflect/desc"
-)
-
-// MessageFactory can be used to create new empty message objects. A default instance
-// (without extension registry or known-type registry specified) will always return
-// dynamic messages (e.g. type will be *dynamic.Message) except for "well-known" types.
-// The well-known types include primitive wrapper types and a handful of other special
-// types defined in standard protobuf definitions, like Any, Duration, and Timestamp.
-type MessageFactory struct {
-	er  *ExtensionRegistry
-	ktr *KnownTypeRegistry
-}
-
-// NewMessageFactoryWithExtensionRegistry creates a new message factory where any
-// dynamic messages produced will use the given extension registry to recognize and
-// parse extension fields.
-func NewMessageFactoryWithExtensionRegistry(er *ExtensionRegistry) *MessageFactory {
-	return NewMessageFactoryWithRegistries(er, nil)
-}
-
-// NewMessageFactoryWithKnownTypeRegistry creates a new message factory where the
-// known types, per the given registry, will be returned as normal protobuf messages
-// (e.g. generated structs, instead of dynamic messages).
-func NewMessageFactoryWithKnownTypeRegistry(ktr *KnownTypeRegistry) *MessageFactory {
-	return NewMessageFactoryWithRegistries(nil, ktr)
-}
-
-// NewMessageFactoryWithDefaults creates a new message factory where all "default" types
-// (those for which protoc-generated code is statically linked into the Go program) are
-// known types. If any dynamic messages are produced, they will recognize and parse all
-// "default" extension fields. This is the equivalent of:
-//   NewMessageFactoryWithRegistries(
-//       NewExtensionRegistryWithDefaults(),
-//       NewKnownTypeRegistryWithDefaults())
-func NewMessageFactoryWithDefaults() *MessageFactory {
-	return NewMessageFactoryWithRegistries(NewExtensionRegistryWithDefaults(), NewKnownTypeRegistryWithDefaults())
-}
-
-// NewMessageFactoryWithRegistries creates a new message factory with the given extension
-// and known type registries.
-func NewMessageFactoryWithRegistries(er *ExtensionRegistry, ktr *KnownTypeRegistry) *MessageFactory {
-	return &MessageFactory{
-		er:  er,
-		ktr: ktr,
-	}
-}
-
-// NewMessage creates a new empty message that corresponds to the given descriptor.
-// If the given descriptor describes a "known type" then that type is instantiated.
-// Otherwise, an empty dynamic message is returned.
-func (f *MessageFactory) NewMessage(md *desc.MessageDescriptor) proto.Message {
-	var ktr *KnownTypeRegistry
-	if f != nil {
-		ktr = f.ktr
-	}
-	if m := ktr.CreateIfKnown(md.GetFullyQualifiedName()); m != nil {
-		return m
-	}
-	return NewMessageWithMessageFactory(md, f)
-}
-
-// NewDynamicMessage creates a new empty dynamic message that corresponds to the given
-// descriptor. This is like f.NewMessage(md) except the known type registry is not
-// consulted so the return value is always a dynamic message.
-//
-// This is also like dynamic.NewMessage(md) except that the returned message will use
-// this factory when creating other messages, like during de-serialization of fields
-// that are themselves message types.
-func (f *MessageFactory) NewDynamicMessage(md *desc.MessageDescriptor) *Message {
-	return NewMessageWithMessageFactory(md, f)
-}
-
-// GetKnownTypeRegistry returns the known type registry that this factory uses to
-// instantiate known (e.g. generated) message types.
-func (f *MessageFactory) GetKnownTypeRegistry() *KnownTypeRegistry {
-	if f == nil {
-		return nil
-	}
-	return f.ktr
-}
-
-// GetExtensionRegistry returns the extension registry that this factory uses to
-// create dynamic messages. The registry is used by dynamic messages to recognize
-// and parse extension fields during de-serialization.
-func (f *MessageFactory) GetExtensionRegistry() *ExtensionRegistry {
-	if f == nil {
-		return nil
-	}
-	return f.er
-}
-
-type wkt interface {
-	XXX_WellKnownType() string
-}
-
-var typeOfWkt = reflect.TypeOf((*wkt)(nil)).Elem()
-
-// KnownTypeRegistry is a registry of known message types, as identified by their
-// fully-qualified name. A known message type is one for which a protoc-generated
-// struct exists, so a dynamic message is not necessary to represent it. A
-// MessageFactory uses a KnownTypeRegistry to decide whether to create a generated
-// struct or a dynamic message. The zero-value registry (including the behavior of
-// a nil pointer) only knows about the "well-known types" in protobuf. These
-// include only the wrapper types and a handful of other special types like Any,
-// Duration, and Timestamp.
-type KnownTypeRegistry struct {
-	excludeWkt     bool
-	includeDefault bool
-	mu             sync.RWMutex
-	types          map[string]reflect.Type
-}
-
-// NewKnownTypeRegistryWithDefaults creates a new registry that knows about all
-// "default" types (those for which protoc-generated code is statically linked
-// into the Go program).
-func NewKnownTypeRegistryWithDefaults() *KnownTypeRegistry {
-	return &KnownTypeRegistry{includeDefault: true}
-}
-
-// NewKnownTypeRegistryWithoutWellKnownTypes creates a new registry that does *not*
-// include the "well-known types" in protobuf. So even well-known types would be
-// represented by a dynamic message.
-func NewKnownTypeRegistryWithoutWellKnownTypes() *KnownTypeRegistry {
-	return &KnownTypeRegistry{excludeWkt: true}
-}
-
-// AddKnownType adds the types of the given messages as known types.
-func (r *KnownTypeRegistry) AddKnownType(kts ...proto.Message) {
-	r.mu.Lock()
-	defer r.mu.Unlock()
-	if r.types == nil {
-		r.types = map[string]reflect.Type{}
-	}
-	for _, kt := range kts {
-		r.types[proto.MessageName(kt)] = reflect.TypeOf(kt)
-	}
-}
-
-// CreateIfKnown will construct an instance of the given message if it is a known type.
-// If the given name is unknown, nil is returned.
-func (r *KnownTypeRegistry) CreateIfKnown(messageName string) proto.Message {
-	msgType := r.GetKnownType(messageName)
-	if msgType == nil {
-		return nil
-	}
-
-	if msgType.Kind() == reflect.Ptr {
-		return reflect.New(msgType.Elem()).Interface().(proto.Message)
-	} else {
-		return reflect.New(msgType).Elem().Interface().(proto.Message)
-	}
-}
-
-// GetKnownType will return the reflect.Type for the given message name if it is
-// known. If it is not known, nil is returned.
-func (r *KnownTypeRegistry) GetKnownType(messageName string) reflect.Type {
-	var msgType reflect.Type
-	if r == nil {
-		// a nil registry behaves the same as zero value instance: only know of well-known types
-		t := proto.MessageType(messageName)
-		if t != nil && t.Implements(typeOfWkt) {
-			msgType = t
-		}
-	} else {
-		if r.includeDefault {
-			msgType = proto.MessageType(messageName)
-		} else if !r.excludeWkt {
-			t := proto.MessageType(messageName)
-			if t != nil && t.Implements(typeOfWkt) {
-				msgType = t
-			}
-		}
-		if msgType == nil {
-			r.mu.RLock()
-			msgType = r.types[messageName]
-			r.mu.RUnlock()
-		}
-	}
-
-	return msgType
-}
diff --git a/vendor/github.com/jhump/protoreflect/dynamic/text.go b/vendor/github.com/jhump/protoreflect/dynamic/text.go
deleted file mode 100644
index 72636f2..0000000
--- a/vendor/github.com/jhump/protoreflect/dynamic/text.go
+++ /dev/null
@@ -1,1175 +0,0 @@
-package dynamic
-
-// Marshalling and unmarshalling of dynamic messages to/from proto's standard text format
-
-import (
-	"bytes"
-	"fmt"
-	"io"
-	"math"
-	"reflect"
-	"sort"
-	"strconv"
-	"strings"
-	"text/scanner"
-	"unicode"
-
-	"github.com/golang/protobuf/proto"
-	"github.com/golang/protobuf/protoc-gen-go/descriptor"
-
-	"github.com/jhump/protoreflect/codec"
-	"github.com/jhump/protoreflect/desc"
-)
-
-// MarshalText serializes this message to bytes in the standard text format,
-// returning an error if the operation fails. The resulting bytes will be a
-// valid UTF8 string.
-//
-// This method uses a compact form: no newlines, and spaces between field
-// identifiers and values are elided.
-func (m *Message) MarshalText() ([]byte, error) {
-	var b indentBuffer
-	b.indentCount = -1 // no indentation
-	if err := m.marshalText(&b); err != nil {
-		return nil, err
-	}
-	return b.Bytes(), nil
-}
-
-// MarshalTextIndent serializes this message to bytes in the standard text
-// format, returning an error if the operation fails. The resulting bytes will
-// be a valid UTF8 string.
-//
-// This method uses a "pretty-printed" form, with each field on its own line and
-// spaces between field identifiers and values.
-func (m *Message) MarshalTextIndent() ([]byte, error) {
-	var b indentBuffer
-	b.indent = "  " // TODO: option for indent?
-	if err := m.marshalText(&b); err != nil {
-		return nil, err
-	}
-	return b.Bytes(), nil
-}
-
-func (m *Message) marshalText(b *indentBuffer) error {
-	// TODO: option for emitting extended Any format?
-	first := true
-	// first the known fields
-	for _, tag := range m.knownFieldTags() {
-		itag := int32(tag)
-		v := m.values[itag]
-		fd := m.FindFieldDescriptor(itag)
-		if fd.IsMap() {
-			md := fd.GetMessageType()
-			kfd := md.FindFieldByNumber(1)
-			vfd := md.FindFieldByNumber(2)
-			mp := v.(map[interface{}]interface{})
-			keys := make([]interface{}, 0, len(mp))
-			for k := range mp {
-				keys = append(keys, k)
-			}
-			sort.Sort(sortable(keys))
-			for _, mk := range keys {
-				mv := mp[mk]
-				err := b.maybeNext(&first)
-				if err != nil {
-					return err
-				}
-				err = marshalKnownFieldMapEntryText(b, fd, kfd, mk, vfd, mv)
-				if err != nil {
-					return err
-				}
-			}
-		} else if fd.IsRepeated() {
-			sl := v.([]interface{})
-			for _, slv := range sl {
-				err := b.maybeNext(&first)
-				if err != nil {
-					return err
-				}
-				err = marshalKnownFieldText(b, fd, slv)
-				if err != nil {
-					return err
-				}
-			}
-		} else {
-			err := b.maybeNext(&first)
-			if err != nil {
-				return err
-			}
-			err = marshalKnownFieldText(b, fd, v)
-			if err != nil {
-				return err
-			}
-		}
-	}
-	// then the unknown fields
-	for _, tag := range m.unknownFieldTags() {
-		itag := int32(tag)
-		ufs := m.unknownFields[itag]
-		for _, uf := range ufs {
-			err := b.maybeNext(&first)
-			if err != nil {
-				return err
-			}
-			_, err = fmt.Fprintf(b, "%d", tag)
-			if err != nil {
-				return err
-			}
-			if uf.Encoding == proto.WireStartGroup {
-				err = b.WriteByte('{')
-				if err != nil {
-					return err
-				}
-				err = b.start()
-				if err != nil {
-					return err
-				}
-				in := codec.NewBuffer(uf.Contents)
-				err = marshalUnknownGroupText(b, in, true)
-				if err != nil {
-					return err
-				}
-				err = b.end()
-				if err != nil {
-					return err
-				}
-				err = b.WriteByte('}')
-				if err != nil {
-					return err
-				}
-			} else {
-				err = b.sep()
-				if err != nil {
-					return err
-				}
-				if uf.Encoding == proto.WireBytes {
-					err = writeString(b, string(uf.Contents))
-					if err != nil {
-						return err
-					}
-				} else {
-					_, err = b.WriteString(strconv.FormatUint(uf.Value, 10))
-					if err != nil {
-						return err
-					}
-				}
-			}
-		}
-	}
-	return nil
-}
-
-func marshalKnownFieldMapEntryText(b *indentBuffer, fd *desc.FieldDescriptor, kfd *desc.FieldDescriptor, mk interface{}, vfd *desc.FieldDescriptor, mv interface{}) error {
-	var name string
-	if fd.IsExtension() {
-		name = fmt.Sprintf("[%s]", fd.GetFullyQualifiedName())
-	} else {
-		name = fd.GetName()
-	}
-	_, err := b.WriteString(name)
-	if err != nil {
-		return err
-	}
-	err = b.sep()
-	if err != nil {
-		return err
-	}
-
-	err = b.WriteByte('<')
-	if err != nil {
-		return err
-	}
-	err = b.start()
-	if err != nil {
-		return err
-	}
-
-	err = marshalKnownFieldText(b, kfd, mk)
-	if err != nil {
-		return err
-	}
-	err = b.next()
-	if err != nil {
-		return err
-	}
-	err = marshalKnownFieldText(b, vfd, mv)
-	if err != nil {
-		return err
-	}
-
-	err = b.end()
-	if err != nil {
-		return err
-	}
-	return b.WriteByte('>')
-}
-
-func marshalKnownFieldText(b *indentBuffer, fd *desc.FieldDescriptor, v interface{}) error {
-	group := fd.GetType() == descriptor.FieldDescriptorProto_TYPE_GROUP
-	if group {
-		var name string
-		if fd.IsExtension() {
-			name = fmt.Sprintf("[%s]", fd.GetMessageType().GetFullyQualifiedName())
-		} else {
-			name = fd.GetMessageType().GetName()
-		}
-		_, err := b.WriteString(name)
-		if err != nil {
-			return err
-		}
-	} else {
-		var name string
-		if fd.IsExtension() {
-			name = fmt.Sprintf("[%s]", fd.GetFullyQualifiedName())
-		} else {
-			name = fd.GetName()
-		}
-		_, err := b.WriteString(name)
-		if err != nil {
-			return err
-		}
-		err = b.sep()
-		if err != nil {
-			return err
-		}
-	}
-	rv := reflect.ValueOf(v)
-	switch rv.Kind() {
-	case reflect.Int32, reflect.Int64:
-		ed := fd.GetEnumType()
-		if ed != nil {
-			n := int32(rv.Int())
-			vd := ed.FindValueByNumber(n)
-			if vd == nil {
-				_, err := b.WriteString(strconv.FormatInt(rv.Int(), 10))
-				return err
-			} else {
-				_, err := b.WriteString(vd.GetName())
-				return err
-			}
-		} else {
-			_, err := b.WriteString(strconv.FormatInt(rv.Int(), 10))
-			return err
-		}
-	case reflect.Uint32, reflect.Uint64:
-		_, err := b.WriteString(strconv.FormatUint(rv.Uint(), 10))
-		return err
-	case reflect.Float32, reflect.Float64:
-		f := rv.Float()
-		var str string
-		if math.IsNaN(f) {
-			str = "nan"
-		} else if math.IsInf(f, 1) {
-			str = "inf"
-		} else if math.IsInf(f, -1) {
-			str = "-inf"
-		} else {
-			var bits int
-			if rv.Kind() == reflect.Float32 {
-				bits = 32
-			} else {
-				bits = 64
-			}
-			str = strconv.FormatFloat(rv.Float(), 'g', -1, bits)
-		}
-		_, err := b.WriteString(str)
-		return err
-	case reflect.Bool:
-		_, err := b.WriteString(strconv.FormatBool(rv.Bool()))
-		return err
-	case reflect.Slice:
-		return writeString(b, string(rv.Bytes()))
-	case reflect.String:
-		return writeString(b, rv.String())
-	default:
-		var err error
-		if group {
-			err = b.WriteByte('{')
-		} else {
-			err = b.WriteByte('<')
-		}
-		if err != nil {
-			return err
-		}
-		err = b.start()
-		if err != nil {
-			return err
-		}
-		// must be a message
-		if dm, ok := v.(*Message); ok {
-			err = dm.marshalText(b)
-			if err != nil {
-				return err
-			}
-		} else {
-			err = proto.CompactText(b, v.(proto.Message))
-			if err != nil {
-				return err
-			}
-		}
-		err = b.end()
-		if err != nil {
-			return err
-		}
-		if group {
-			return b.WriteByte('}')
-		} else {
-			return b.WriteByte('>')
-		}
-	}
-}
-
-// writeString writes a string in the protocol buffer text format.
-// It is similar to strconv.Quote except we don't use Go escape sequences,
-// we treat the string as a byte sequence, and we use octal escapes.
-// These differences are to maintain interoperability with the other
-// languages' implementations of the text format.
-func writeString(b *indentBuffer, s string) error {
-	// use WriteByte here to get any needed indent
-	if err := b.WriteByte('"'); err != nil {
-		return err
-	}
-	// Loop over the bytes, not the runes.
-	for i := 0; i < len(s); i++ {
-		var err error
-		// Divergence from C++: we don't escape apostrophes.
-		// There's no need to escape them, and the C++ parser
-		// copes with a naked apostrophe.
-		switch c := s[i]; c {
-		case '\n':
-			_, err = b.WriteString("\\n")
-		case '\r':
-			_, err = b.WriteString("\\r")
-		case '\t':
-			_, err = b.WriteString("\\t")
-		case '"':
-			_, err = b.WriteString("\\")
-		case '\\':
-			_, err = b.WriteString("\\\\")
-		default:
-			if c >= 0x20 && c < 0x7f {
-				err = b.WriteByte(c)
-			} else {
-				_, err = fmt.Fprintf(b, "\\%03o", c)
-			}
-		}
-		if err != nil {
-			return err
-		}
-	}
-	return b.WriteByte('"')
-}
-
-func marshalUnknownGroupText(b *indentBuffer, in *codec.Buffer, topLevel bool) error {
-	first := true
-	for {
-		if in.EOF() {
-			if topLevel {
-				return nil
-			}
-			// this is a nested message: we are expecting an end-group tag, not EOF!
-			return io.ErrUnexpectedEOF
-		}
-		tag, wireType, err := in.DecodeTagAndWireType()
-		if err != nil {
-			return err
-		}
-		if wireType == proto.WireEndGroup {
-			return nil
-		}
-		err = b.maybeNext(&first)
-		if err != nil {
-			return err
-		}
-		_, err = fmt.Fprintf(b, "%d", tag)
-		if err != nil {
-			return err
-		}
-		if wireType == proto.WireStartGroup {
-			err = b.WriteByte('{')
-			if err != nil {
-				return err
-			}
-			err = b.start()
-			if err != nil {
-				return err
-			}
-			err = marshalUnknownGroupText(b, in, false)
-			if err != nil {
-				return err
-			}
-			err = b.end()
-			if err != nil {
-				return err
-			}
-			err = b.WriteByte('}')
-			if err != nil {
-				return err
-			}
-			continue
-		} else {
-			err = b.sep()
-			if err != nil {
-				return err
-			}
-			if wireType == proto.WireBytes {
-				contents, err := in.DecodeRawBytes(false)
-				if err != nil {
-					return err
-				}
-				err = writeString(b, string(contents))
-				if err != nil {
-					return err
-				}
-			} else {
-				var v uint64
-				switch wireType {
-				case proto.WireVarint:
-					v, err = in.DecodeVarint()
-				case proto.WireFixed32:
-					v, err = in.DecodeFixed32()
-				case proto.WireFixed64:
-					v, err = in.DecodeFixed64()
-				default:
-					return proto.ErrInternalBadWireType
-				}
-				if err != nil {
-					return err
-				}
-				_, err = b.WriteString(strconv.FormatUint(v, 10))
-				if err != nil {
-					return err
-				}
-			}
-		}
-	}
-}
-
-// UnmarshalText de-serializes the message that is present, in text format, in
-// the given bytes into this message. It first resets the current message. It
-// returns an error if the given bytes do not contain a valid encoding of this
-// message type in the standard text format
-func (m *Message) UnmarshalText(text []byte) error {
-	m.Reset()
-	if err := m.UnmarshalMergeText(text); err != nil {
-		return err
-	}
-	return m.Validate()
-}
-
-// UnmarshalMergeText de-serializes the message that is present, in text format,
-// in the given bytes into this message. Unlike UnmarshalText, it does not first
-// reset the message, instead merging the data in the given bytes into the
-// existing data in this message.
-func (m *Message) UnmarshalMergeText(text []byte) error {
-	return m.unmarshalText(newReader(text), tokenEOF)
-}
-
-func (m *Message) unmarshalText(tr *txtReader, end tokenType) error {
-	for {
-		tok := tr.next()
-		if tok.tokTyp == end {
-			return nil
-		}
-		if tok.tokTyp == tokenEOF {
-			return io.ErrUnexpectedEOF
-		}
-		var fd *desc.FieldDescriptor
-		var extendedAnyType *desc.MessageDescriptor
-		if tok.tokTyp == tokenInt {
-			// tag number (indicates unknown field)
-			tag, err := strconv.ParseInt(tok.val.(string), 10, 32)
-			if err != nil {
-				return err
-			}
-			itag := int32(tag)
-			fd = m.FindFieldDescriptor(itag)
-			if fd == nil {
-				// can't parse the value w/out field descriptor, so skip it
-				tok = tr.next()
-				if tok.tokTyp == tokenEOF {
-					return io.ErrUnexpectedEOF
-				} else if tok.tokTyp == tokenOpenBrace {
-					if err := skipMessageText(tr, true); err != nil {
-						return err
-					}
-				} else if tok.tokTyp == tokenColon {
-					if err := skipFieldValueText(tr); err != nil {
-						return err
-					}
-				} else {
-					return textError(tok, "Expecting a colon ':' or brace '{'; instead got %q", tok.txt)
-				}
-				tok = tr.peek()
-				if tok.tokTyp.IsSep() {
-					tr.next() // consume separator
-				}
-				continue
-			}
-		} else {
-			fieldName, err := unmarshalFieldNameText(tr, tok)
-			if err != nil {
-				return err
-			}
-			fd = m.FindFieldDescriptorByName(fieldName)
-			if fd == nil {
-				// See if it's a group name
-				for _, field := range m.md.GetFields() {
-					if field.GetType() == descriptor.FieldDescriptorProto_TYPE_GROUP && field.GetMessageType().GetName() == fieldName {
-						fd = field
-						break
-					}
-				}
-				if fd == nil {
-					// maybe this is an extended Any
-					if m.md.GetFullyQualifiedName() == "google.protobuf.Any" && fieldName[0] == '[' && strings.Contains(fieldName, "/") {
-						// strip surrounding "[" and "]" and extract type name from URL
-						typeUrl := fieldName[1 : len(fieldName)-1]
-						mname := typeUrl
-						if slash := strings.LastIndex(mname, "/"); slash >= 0 {
-							mname = mname[slash+1:]
-						}
-						// TODO: add a way to weave an AnyResolver to this point
-						extendedAnyType = findMessageDescriptor(mname, m.md.GetFile())
-						if extendedAnyType == nil {
-							return textError(tok, "could not parse Any with unknown type URL %q", fieldName)
-						}
-						// field 1 is "type_url"
-						typeUrlField := m.md.FindFieldByNumber(1)
-						if err := m.TrySetField(typeUrlField, typeUrl); err != nil {
-							return err
-						}
-					} else {
-						// TODO: add a flag to just ignore unrecognized field names
-						return textError(tok, "%q is not a recognized field name of %q", fieldName, m.md.GetFullyQualifiedName())
-					}
-				}
-			}
-		}
-		tok = tr.next()
-		if tok.tokTyp == tokenEOF {
-			return io.ErrUnexpectedEOF
-		}
-		if extendedAnyType != nil {
-			// consume optional colon; make sure this is a "start message" token
-			if tok.tokTyp == tokenColon {
-				tok = tr.next()
-				if tok.tokTyp == tokenEOF {
-					return io.ErrUnexpectedEOF
-				}
-			}
-			if tok.tokTyp.EndToken() == tokenError {
-				return textError(tok, "Expecting a '<' or '{'; instead got %q", tok.txt)
-			}
-
-			// TODO: use mf.NewMessage and, if not a dynamic message, use proto.UnmarshalText to unmarshal it
-			g := m.mf.NewDynamicMessage(extendedAnyType)
-			if err := g.unmarshalText(tr, tok.tokTyp.EndToken()); err != nil {
-				return err
-			}
-			// now we marshal the message to bytes and store in the Any
-			b, err := g.Marshal()
-			if err != nil {
-				return err
-			}
-			// field 2 is "value"
-			anyValueField := m.md.FindFieldByNumber(2)
-			if err := m.TrySetField(anyValueField, b); err != nil {
-				return err
-			}
-
-		} else if (fd.GetType() == descriptor.FieldDescriptorProto_TYPE_GROUP ||
-			fd.GetType() == descriptor.FieldDescriptorProto_TYPE_MESSAGE) &&
-			tok.tokTyp.EndToken() != tokenError {
-
-			// TODO: use mf.NewMessage and, if not a dynamic message, use proto.UnmarshalText to unmarshal it
-			g := m.mf.NewDynamicMessage(fd.GetMessageType())
-			if err := g.unmarshalText(tr, tok.tokTyp.EndToken()); err != nil {
-				return err
-			}
-			if fd.IsRepeated() {
-				if err := m.TryAddRepeatedField(fd, g); err != nil {
-					return err
-				}
-			} else {
-				if err := m.TrySetField(fd, g); err != nil {
-					return err
-				}
-			}
-		} else {
-			if tok.tokTyp != tokenColon {
-				return textError(tok, "Expecting a colon ':'; instead got %q", tok.txt)
-			}
-			if err := m.unmarshalFieldValueText(fd, tr); err != nil {
-				return err
-			}
-		}
-		tok = tr.peek()
-		if tok.tokTyp.IsSep() {
-			tr.next() // consume separator
-		}
-	}
-}
-func findMessageDescriptor(name string, fd *desc.FileDescriptor) *desc.MessageDescriptor {
-	md := findMessageInTransitiveDeps(name, fd, map[*desc.FileDescriptor]struct{}{})
-	if md == nil {
-		// couldn't find it; see if we have this message linked in
-		md, _ = desc.LoadMessageDescriptor(name)
-	}
-	return md
-}
-
-func findMessageInTransitiveDeps(name string, fd *desc.FileDescriptor, seen map[*desc.FileDescriptor]struct{}) *desc.MessageDescriptor {
-	if _, ok := seen[fd]; ok {
-		// already checked this file
-		return nil
-	}
-	seen[fd] = struct{}{}
-	md := fd.FindMessage(name)
-	if md != nil {
-		return md
-	}
-	// not in this file so recursively search its deps
-	for _, dep := range fd.GetDependencies() {
-		md = findMessageInTransitiveDeps(name, dep, seen)
-		if md != nil {
-			return md
-		}
-	}
-	// couldn't find it
-	return nil
-}
-
-func textError(tok *token, format string, args ...interface{}) error {
-	var msg string
-	if tok.tokTyp == tokenError {
-		msg = tok.val.(error).Error()
-	} else {
-		msg = fmt.Sprintf(format, args...)
-	}
-	return fmt.Errorf("line %d, col %d: %s", tok.pos.Line, tok.pos.Column, msg)
-}
-
-type setFunction func(*Message, *desc.FieldDescriptor, interface{}) error
-
-func (m *Message) unmarshalFieldValueText(fd *desc.FieldDescriptor, tr *txtReader) error {
-	var set setFunction
-	if fd.IsRepeated() {
-		set = (*Message).addRepeatedField
-	} else {
-		set = mergeField
-	}
-	tok := tr.peek()
-	if tok.tokTyp == tokenOpenBracket {
-		tr.next() // consume tok
-		for {
-			if err := m.unmarshalFieldElementText(fd, tr, set); err != nil {
-				return err
-			}
-			tok = tr.peek()
-			if tok.tokTyp == tokenCloseBracket {
-				tr.next() // consume tok
-				return nil
-			} else if tok.tokTyp.IsSep() {
-				tr.next() // consume separator
-			}
-		}
-	}
-	return m.unmarshalFieldElementText(fd, tr, set)
-}
-
-func (m *Message) unmarshalFieldElementText(fd *desc.FieldDescriptor, tr *txtReader, set setFunction) error {
-	tok := tr.next()
-	if tok.tokTyp == tokenEOF {
-		return io.ErrUnexpectedEOF
-	}
-
-	var expected string
-	switch fd.GetType() {
-	case descriptor.FieldDescriptorProto_TYPE_BOOL:
-		if tok.tokTyp == tokenIdent {
-			if tok.val.(string) == "true" {
-				return set(m, fd, true)
-			} else if tok.val.(string) == "false" {
-				return set(m, fd, false)
-			}
-		}
-		expected = "boolean value"
-	case descriptor.FieldDescriptorProto_TYPE_BYTES:
-		if tok.tokTyp == tokenString {
-			return set(m, fd, []byte(tok.val.(string)))
-		}
-		expected = "bytes string value"
-	case descriptor.FieldDescriptorProto_TYPE_STRING:
-		if tok.tokTyp == tokenString {
-			return set(m, fd, tok.val)
-		}
-		expected = "string value"
-	case descriptor.FieldDescriptorProto_TYPE_FLOAT:
-		switch tok.tokTyp {
-		case tokenFloat:
-			return set(m, fd, float32(tok.val.(float64)))
-		case tokenInt:
-			if f, err := strconv.ParseFloat(tok.val.(string), 32); err != nil {
-				return err
-			} else {
-				return set(m, fd, float32(f))
-			}
-		case tokenIdent:
-			ident := strings.ToLower(tok.val.(string))
-			if ident == "inf" {
-				return set(m, fd, float32(math.Inf(1)))
-			} else if ident == "nan" {
-				return set(m, fd, float32(math.NaN()))
-			}
-		case tokenMinus:
-			peeked := tr.peek()
-			if peeked.tokTyp == tokenIdent {
-				ident := strings.ToLower(peeked.val.(string))
-				if ident == "inf" {
-					tr.next() // consume peeked token
-					return set(m, fd, float32(math.Inf(-1)))
-				}
-			}
-		}
-		expected = "float value"
-	case descriptor.FieldDescriptorProto_TYPE_DOUBLE:
-		switch tok.tokTyp {
-		case tokenFloat:
-			return set(m, fd, tok.val)
-		case tokenInt:
-			if f, err := strconv.ParseFloat(tok.val.(string), 64); err != nil {
-				return err
-			} else {
-				return set(m, fd, f)
-			}
-		case tokenIdent:
-			ident := strings.ToLower(tok.val.(string))
-			if ident == "inf" {
-				return set(m, fd, math.Inf(1))
-			} else if ident == "nan" {
-				return set(m, fd, math.NaN())
-			}
-		case tokenMinus:
-			peeked := tr.peek()
-			if peeked.tokTyp == tokenIdent {
-				ident := strings.ToLower(peeked.val.(string))
-				if ident == "inf" {
-					tr.next() // consume peeked token
-					return set(m, fd, math.Inf(-1))
-				}
-			}
-		}
-		expected = "float value"
-	case descriptor.FieldDescriptorProto_TYPE_INT32,
-		descriptor.FieldDescriptorProto_TYPE_SINT32,
-		descriptor.FieldDescriptorProto_TYPE_SFIXED32:
-		if tok.tokTyp == tokenInt {
-			if i, err := strconv.ParseInt(tok.val.(string), 10, 32); err != nil {
-				return err
-			} else {
-				return set(m, fd, int32(i))
-			}
-		}
-		expected = "int value"
-	case descriptor.FieldDescriptorProto_TYPE_INT64,
-		descriptor.FieldDescriptorProto_TYPE_SINT64,
-		descriptor.FieldDescriptorProto_TYPE_SFIXED64:
-		if tok.tokTyp == tokenInt {
-			if i, err := strconv.ParseInt(tok.val.(string), 10, 64); err != nil {
-				return err
-			} else {
-				return set(m, fd, i)
-			}
-		}
-		expected = "int value"
-	case descriptor.FieldDescriptorProto_TYPE_UINT32,
-		descriptor.FieldDescriptorProto_TYPE_FIXED32:
-		if tok.tokTyp == tokenInt {
-			if i, err := strconv.ParseUint(tok.val.(string), 10, 32); err != nil {
-				return err
-			} else {
-				return set(m, fd, uint32(i))
-			}
-		}
-		expected = "unsigned int value"
-	case descriptor.FieldDescriptorProto_TYPE_UINT64,
-		descriptor.FieldDescriptorProto_TYPE_FIXED64:
-		if tok.tokTyp == tokenInt {
-			if i, err := strconv.ParseUint(tok.val.(string), 10, 64); err != nil {
-				return err
-			} else {
-				return set(m, fd, i)
-			}
-		}
-		expected = "unsigned int value"
-	case descriptor.FieldDescriptorProto_TYPE_ENUM:
-		if tok.tokTyp == tokenIdent {
-			// TODO: add a flag to just ignore unrecognized enum value names?
-			vd := fd.GetEnumType().FindValueByName(tok.val.(string))
-			if vd != nil {
-				return set(m, fd, vd.GetNumber())
-			}
-		} else if tok.tokTyp == tokenInt {
-			if i, err := strconv.ParseInt(tok.val.(string), 10, 32); err != nil {
-				return err
-			} else {
-				return set(m, fd, int32(i))
-			}
-		}
-		expected = fmt.Sprintf("enum %s value", fd.GetEnumType().GetFullyQualifiedName())
-	case descriptor.FieldDescriptorProto_TYPE_MESSAGE,
-		descriptor.FieldDescriptorProto_TYPE_GROUP:
-
-		endTok := tok.tokTyp.EndToken()
-		if endTok != tokenError {
-			dm := m.mf.NewDynamicMessage(fd.GetMessageType())
-			if err := dm.unmarshalText(tr, endTok); err != nil {
-				return err
-			}
-			// TODO: ideally we would use mf.NewMessage and, if not a dynamic message, use
-			// proto package to unmarshal it. But the text parser isn't particularly amenable
-			// to that, so we instead convert a dynamic message to a generated one if the
-			// known-type registry knows about the generated type...
-			var ktr *KnownTypeRegistry
-			if m.mf != nil {
-				ktr = m.mf.ktr
-			}
-			pm := ktr.CreateIfKnown(fd.GetMessageType().GetFullyQualifiedName())
-			if pm != nil {
-				if err := dm.ConvertTo(pm); err != nil {
-					return set(m, fd, pm)
-				}
-			}
-			return set(m, fd, dm)
-		}
-		expected = fmt.Sprintf("message %s value", fd.GetMessageType().GetFullyQualifiedName())
-	default:
-		return fmt.Errorf("field %q of message %q has unrecognized type: %v", fd.GetFullyQualifiedName(), m.md.GetFullyQualifiedName(), fd.GetType())
-	}
-
-	// if we get here, token was wrong type; create error message
-	var article string
-	if strings.Contains("aieou", expected[0:1]) {
-		article = "an"
-	} else {
-		article = "a"
-	}
-	return textError(tok, "Expecting %s %s; got %q", article, expected, tok.txt)
-}
-
-func unmarshalFieldNameText(tr *txtReader, tok *token) (string, error) {
-	if tok.tokTyp == tokenOpenBracket || tok.tokTyp == tokenOpenParen {
-		// extension name
-		var closeType tokenType
-		var closeChar string
-		if tok.tokTyp == tokenOpenBracket {
-			closeType = tokenCloseBracket
-			closeChar = "close bracket ']'"
-		} else {
-			closeType = tokenCloseParen
-			closeChar = "close paren ')'"
-		}
-		// must be followed by an identifier
-		idents := make([]string, 0, 1)
-		for {
-			tok = tr.next()
-			if tok.tokTyp == tokenEOF {
-				return "", io.ErrUnexpectedEOF
-			} else if tok.tokTyp != tokenIdent {
-				return "", textError(tok, "Expecting an identifier; instead got %q", tok.txt)
-			}
-			idents = append(idents, tok.val.(string))
-			// and then close bracket/paren, or "/" to keep adding URL elements to name
-			tok = tr.next()
-			if tok.tokTyp == tokenEOF {
-				return "", io.ErrUnexpectedEOF
-			} else if tok.tokTyp == closeType {
-				break
-			} else if tok.tokTyp != tokenSlash {
-				return "", textError(tok, "Expecting a %s; instead got %q", closeChar, tok.txt)
-			}
-		}
-		return "[" + strings.Join(idents, "/") + "]", nil
-	} else if tok.tokTyp == tokenIdent {
-		// normal field name
-		return tok.val.(string), nil
-	} else {
-		return "", textError(tok, "Expecting an identifier or tag number; instead got %q", tok.txt)
-	}
-}
-
-func skipFieldNameText(tr *txtReader) error {
-	tok := tr.next()
-	if tok.tokTyp == tokenEOF {
-		return io.ErrUnexpectedEOF
-	} else if tok.tokTyp == tokenInt || tok.tokTyp == tokenIdent {
-		return nil
-	} else {
-		_, err := unmarshalFieldNameText(tr, tok)
-		return err
-	}
-}
-
-func skipFieldValueText(tr *txtReader) error {
-	tok := tr.peek()
-	if tok.tokTyp == tokenOpenBracket {
-		tr.next() // consume tok
-		for {
-			if err := skipFieldElementText(tr); err != nil {
-				return err
-			}
-			tok = tr.peek()
-			if tok.tokTyp == tokenCloseBracket {
-				tr.next() // consume tok
-				return nil
-			} else if tok.tokTyp.IsSep() {
-				tr.next() // consume separator
-			}
-
-		}
-	}
-	return skipFieldElementText(tr)
-}
-
-func skipFieldElementText(tr *txtReader) error {
-	tok := tr.next()
-	switch tok.tokTyp {
-	case tokenEOF:
-		return io.ErrUnexpectedEOF
-	case tokenInt, tokenFloat, tokenString, tokenIdent:
-		return nil
-	case tokenOpenAngle:
-		return skipMessageText(tr, false)
-	default:
-		return textError(tok, "Expecting an angle bracket '<' or a value; instead got %q", tok.txt)
-	}
-}
-
-func skipMessageText(tr *txtReader, isGroup bool) error {
-	for {
-		tok := tr.peek()
-		if tok.tokTyp == tokenEOF {
-			return io.ErrUnexpectedEOF
-		} else if isGroup && tok.tokTyp == tokenCloseBrace {
-			return nil
-		} else if !isGroup && tok.tokTyp == tokenCloseAngle {
-			return nil
-		}
-
-		// field name or tag
-		if err := skipFieldNameText(tr); err != nil {
-			return err
-		}
-
-		// field value
-		tok = tr.next()
-		if tok.tokTyp == tokenEOF {
-			return io.ErrUnexpectedEOF
-		} else if tok.tokTyp == tokenOpenBrace {
-			if err := skipMessageText(tr, true); err != nil {
-				return err
-			}
-		} else if tok.tokTyp == tokenColon {
-			if err := skipFieldValueText(tr); err != nil {
-				return err
-			}
-		} else {
-			return textError(tok, "Expecting a colon ':' or brace '{'; instead got %q", tok.txt)
-		}
-
-		tok = tr.peek()
-		if tok.tokTyp.IsSep() {
-			tr.next() // consume separator
-		}
-	}
-}
-
-type tokenType int
-
-const (
-	tokenError tokenType = iota
-	tokenEOF
-	tokenIdent
-	tokenString
-	tokenInt
-	tokenFloat
-	tokenColon
-	tokenComma
-	tokenSemiColon
-	tokenOpenBrace
-	tokenCloseBrace
-	tokenOpenBracket
-	tokenCloseBracket
-	tokenOpenAngle
-	tokenCloseAngle
-	tokenOpenParen
-	tokenCloseParen
-	tokenSlash
-	tokenMinus
-)
-
-func (t tokenType) IsSep() bool {
-	return t == tokenComma || t == tokenSemiColon
-}
-
-func (t tokenType) EndToken() tokenType {
-	switch t {
-	case tokenOpenAngle:
-		return tokenCloseAngle
-	case tokenOpenBrace:
-		return tokenCloseBrace
-	default:
-		return tokenError
-	}
-}
-
-type token struct {
-	tokTyp tokenType
-	val    interface{}
-	txt    string
-	pos    scanner.Position
-}
-
-type txtReader struct {
-	scanner    scanner.Scanner
-	peeked     token
-	havePeeked bool
-}
-
-func newReader(text []byte) *txtReader {
-	sc := scanner.Scanner{}
-	sc.Init(bytes.NewReader(text))
-	sc.Mode = scanner.ScanIdents | scanner.ScanInts | scanner.ScanFloats | scanner.ScanChars |
-		scanner.ScanStrings | scanner.ScanComments | scanner.SkipComments
-	// identifiers are same restrictions as Go identifiers, except we also allow dots since
-	// we accept fully-qualified names
-	sc.IsIdentRune = func(ch rune, i int) bool {
-		return ch == '_' || unicode.IsLetter(ch) ||
-			(i > 0 && unicode.IsDigit(ch)) ||
-			(i > 0 && ch == '.')
-	}
-	// ignore errors; we handle them if/when we see malformed tokens
-	sc.Error = func(s *scanner.Scanner, msg string) {}
-	return &txtReader{scanner: sc}
-}
-
-func (p *txtReader) peek() *token {
-	if p.havePeeked {
-		return &p.peeked
-	}
-	t := p.scanner.Scan()
-	if t == scanner.EOF {
-		p.peeked.tokTyp = tokenEOF
-		p.peeked.val = nil
-		p.peeked.txt = ""
-		p.peeked.pos = p.scanner.Position
-	} else if err := p.processToken(t, p.scanner.TokenText(), p.scanner.Position); err != nil {
-		p.peeked.tokTyp = tokenError
-		p.peeked.val = err
-	}
-	p.havePeeked = true
-	return &p.peeked
-}
-
-func (p *txtReader) processToken(t rune, text string, pos scanner.Position) error {
-	p.peeked.pos = pos
-	p.peeked.txt = text
-	switch t {
-	case scanner.Ident:
-		p.peeked.tokTyp = tokenIdent
-		p.peeked.val = text
-	case scanner.Int:
-		p.peeked.tokTyp = tokenInt
-		p.peeked.val = text // can't parse the number because we don't know if it's signed or unsigned
-	case scanner.Float:
-		p.peeked.tokTyp = tokenFloat
-		var err error
-		if p.peeked.val, err = strconv.ParseFloat(text, 64); err != nil {
-			return err
-		}
-	case scanner.Char, scanner.String:
-		p.peeked.tokTyp = tokenString
-		var err error
-		if p.peeked.val, err = strconv.Unquote(text); err != nil {
-			return err
-		}
-	case '-': // unary minus, for negative ints and floats
-		ch := p.scanner.Peek()
-		if ch < '0' || ch > '9' {
-			p.peeked.tokTyp = tokenMinus
-			p.peeked.val = '-'
-		} else {
-			t := p.scanner.Scan()
-			if t == scanner.EOF {
-				return io.ErrUnexpectedEOF
-			} else if t == scanner.Float {
-				p.peeked.tokTyp = tokenFloat
-				text += p.scanner.TokenText()
-				p.peeked.txt = text
-				var err error
-				if p.peeked.val, err = strconv.ParseFloat(text, 64); err != nil {
-					p.peeked.pos = p.scanner.Position
-					return err
-				}
-			} else if t == scanner.Int {
-				p.peeked.tokTyp = tokenInt
-				text += p.scanner.TokenText()
-				p.peeked.txt = text
-				p.peeked.val = text // can't parse the number because we don't know if it's signed or unsigned
-			} else {
-				p.peeked.pos = p.scanner.Position
-				return fmt.Errorf("expecting an int or float but got %q", p.scanner.TokenText())
-			}
-		}
-	case ':':
-		p.peeked.tokTyp = tokenColon
-		p.peeked.val = ':'
-	case ',':
-		p.peeked.tokTyp = tokenComma
-		p.peeked.val = ','
-	case ';':
-		p.peeked.tokTyp = tokenSemiColon
-		p.peeked.val = ';'
-	case '{':
-		p.peeked.tokTyp = tokenOpenBrace
-		p.peeked.val = '{'
-	case '}':
-		p.peeked.tokTyp = tokenCloseBrace
-		p.peeked.val = '}'
-	case '<':
-		p.peeked.tokTyp = tokenOpenAngle
-		p.peeked.val = '<'
-	case '>':
-		p.peeked.tokTyp = tokenCloseAngle
-		p.peeked.val = '>'
-	case '[':
-		p.peeked.tokTyp = tokenOpenBracket
-		p.peeked.val = '['
-	case ']':
-		p.peeked.tokTyp = tokenCloseBracket
-		p.peeked.val = ']'
-	case '(':
-		p.peeked.tokTyp = tokenOpenParen
-		p.peeked.val = '('
-	case ')':
-		p.peeked.tokTyp = tokenCloseParen
-		p.peeked.val = ')'
-	case '/':
-		// only allowed to separate URL components in expanded Any format
-		p.peeked.tokTyp = tokenSlash
-		p.peeked.val = '/'
-	default:
-		return fmt.Errorf("invalid character: %c", t)
-	}
-	return nil
-}
-
-func (p *txtReader) next() *token {
-	t := p.peek()
-	if t.tokTyp != tokenEOF && t.tokTyp != tokenError {
-		p.havePeeked = false
-	}
-	return t
-}
diff --git a/vendor/github.com/jhump/protoreflect/internal/standard_files.go b/vendor/github.com/jhump/protoreflect/internal/standard_files.go
deleted file mode 100644
index 4a8b47a..0000000
--- a/vendor/github.com/jhump/protoreflect/internal/standard_files.go
+++ /dev/null
@@ -1,127 +0,0 @@
-// Package internal contains some code that should not be exported but needs to
-// be shared across more than one of the protoreflect sub-packages.
-package internal
-
-import (
-	"bytes"
-	"compress/gzip"
-	"fmt"
-	"io/ioutil"
-
-	"github.com/golang/protobuf/proto"
-	dpb "github.com/golang/protobuf/protoc-gen-go/descriptor"
-)
-
-// TODO: replace this alias configuration with desc.RegisterImportPath?
-
-// StdFileAliases are the standard protos included with protoc, but older versions of
-// their respective packages registered them using incorrect paths.
-var StdFileAliases = map[string]string{
-	// Files for the github.com/golang/protobuf/ptypes package at one point were
-	// registered using the path where the proto files are mirrored in GOPATH,
-	// inside the golang/protobuf repo.
-	// (Fixed as of https://github.com/golang/protobuf/pull/412)
-	"google/protobuf/any.proto":       "github.com/golang/protobuf/ptypes/any/any.proto",
-	"google/protobuf/duration.proto":  "github.com/golang/protobuf/ptypes/duration/duration.proto",
-	"google/protobuf/empty.proto":     "github.com/golang/protobuf/ptypes/empty/empty.proto",
-	"google/protobuf/struct.proto":    "github.com/golang/protobuf/ptypes/struct/struct.proto",
-	"google/protobuf/timestamp.proto": "github.com/golang/protobuf/ptypes/timestamp/timestamp.proto",
-	"google/protobuf/wrappers.proto":  "github.com/golang/protobuf/ptypes/wrappers/wrappers.proto",
-	// Files for the google.golang.org/genproto/protobuf package at one point
-	// were registered with an anomalous "src/" prefix.
-	// (Fixed as of https://github.com/google/go-genproto/pull/31)
-	"google/protobuf/api.proto":            "src/google/protobuf/api.proto",
-	"google/protobuf/field_mask.proto":     "src/google/protobuf/field_mask.proto",
-	"google/protobuf/source_context.proto": "src/google/protobuf/source_context.proto",
-	"google/protobuf/type.proto":           "src/google/protobuf/type.proto",
-
-	// Other standard files (descriptor.proto and compiler/plugin.proto) are
-	// registered correctly, so we don't need rules for them here.
-}
-
-func init() {
-	// We provide aliasing in both directions, to support files with the
-	// proper import path linked against older versions of the generated
-	// files AND files that used the aliased import path but linked against
-	// newer versions of the generated files (which register with the
-	// correct path).
-
-	// Get all files defined above
-	keys := make([]string, 0, len(StdFileAliases))
-	for k := range StdFileAliases {
-		keys = append(keys, k)
-	}
-	// And add inverse mappings
-	for _, k := range keys {
-		alias := StdFileAliases[k]
-		StdFileAliases[alias] = k
-	}
-}
-
-type ErrNoSuchFile string
-
-func (e ErrNoSuchFile) Error() string {
-	return fmt.Sprintf("no such file: %q", string(e))
-}
-
-// LoadFileDescriptor loads a registered descriptor and decodes it. If the given
-// name cannot be loaded but is a known standard name, an alias will be tried,
-// so the standard files can be loaded even if linked against older "known bad"
-// versions of packages.
-func LoadFileDescriptor(file string) (*dpb.FileDescriptorProto, error) {
-	fdb := proto.FileDescriptor(file)
-	aliased := false
-	if fdb == nil {
-		var ok bool
-		alias, ok := StdFileAliases[file]
-		if ok {
-			aliased = true
-			if fdb = proto.FileDescriptor(alias); fdb == nil {
-				return nil, ErrNoSuchFile(file)
-			}
-		} else {
-			return nil, ErrNoSuchFile(file)
-		}
-	}
-
-	fd, err := DecodeFileDescriptor(file, fdb)
-	if err != nil {
-		return nil, err
-	}
-
-	if aliased {
-		// the file descriptor will have the alias used to load it, but
-		// we need it to have the specified name in order to link it
-		fd.Name = proto.String(file)
-	}
-
-	return fd, nil
-}
-
-// DecodeFileDescriptor decodes the bytes of a registered file descriptor.
-// Registered file descriptors are first "proto encoded" (e.g. binary format
-// for the descriptor protos) and then gzipped. So this function gunzips and
-// then unmarshals into a descriptor proto.
-func DecodeFileDescriptor(element string, fdb []byte) (*dpb.FileDescriptorProto, error) {
-	raw, err := decompress(fdb)
-	if err != nil {
-		return nil, fmt.Errorf("failed to decompress %q descriptor: %v", element, err)
-	}
-	fd := dpb.FileDescriptorProto{}
-	if err := proto.Unmarshal(raw, &fd); err != nil {
-		return nil, fmt.Errorf("bad descriptor for %q: %v", element, err)
-	}
-	return &fd, nil
-}
-
-func decompress(b []byte) ([]byte, error) {
-	r, err := gzip.NewReader(bytes.NewReader(b))
-	if err != nil {
-		return nil, fmt.Errorf("bad gzipped descriptor: %v", err)
-	}
-	out, err := ioutil.ReadAll(r)
-	if err != nil {
-		return nil, fmt.Errorf("bad gzipped descriptor: %v", err)
-	}
-	return out, nil
-}
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 54d7b54..1697510 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -24,7 +24,6 @@
 github.com/golang/protobuf/ptypes
 github.com/golang/protobuf/ptypes/any
 github.com/golang/protobuf/ptypes/duration
-github.com/golang/protobuf/ptypes/empty
 github.com/golang/protobuf/ptypes/struct
 github.com/golang/protobuf/ptypes/timestamp
 github.com/golang/protobuf/ptypes/wrappers
@@ -56,12 +55,6 @@
 github.com/jcmturner/gofork/x/crypto/pbkdf2
 # github.com/jessevdk/go-flags v1.4.0
 github.com/jessevdk/go-flags
-# github.com/jhump/protoreflect v1.5.0
-github.com/jhump/protoreflect/codec
-github.com/jhump/protoreflect/desc
-github.com/jhump/protoreflect/desc/internal
-github.com/jhump/protoreflect/dynamic
-github.com/jhump/protoreflect/internal
 # github.com/jpillora/backoff v1.0.0
 github.com/jpillora/backoff
 # github.com/klauspost/compress v1.9.8
