[VOL-4648] Add connection to sysrepo and subscribe to NETCONF 'get' requests with dummy callback

Change-Id: I9124d9b9430ee1358885bdb5c65dedfb3c5d3978
diff --git a/.dockerignore b/.dockerignore
index 1d6b926..171d965 100644
--- a/.dockerignore
+++ b/.dockerignore
@@ -1,3 +1,4 @@
 build/*
+!build/yang-files*
 tests/*
 docs/*
\ No newline at end of file
diff --git a/Makefile b/Makefile
index e0f3c8b..41523df 100644
--- a/Makefile
+++ b/Makefile
@@ -49,13 +49,26 @@
 # tool containers
 VOLTHA_TOOLS_VERSION ?= 2.5.3
 
-GO                = docker run --rm --user $$(id -u):$$(id -g) -v ${CURDIR}:/app $(shell test -t 0 && echo "-it") -v gocache:/.cache -v gocache-${VOLTHA_TOOLS_VERSION}:/go/pkg voltha/voltha-ci-tools:${VOLTHA_TOOLS_VERSION}-golang go
-GO_JUNIT_REPORT   = docker run --rm --user $$(id -u):$$(id -g) -v ${CURDIR}:/app -i voltha/voltha-ci-tools:${VOLTHA_TOOLS_VERSION}-go-junit-report go-junit-report
-GOCOVER_COBERTURA = docker run --rm --user $$(id -u):$$(id -g) -v ${CURDIR}:/app/src/github.com/opencord/voltha-northbound-bbf-adapter -i voltha/voltha-ci-tools:${VOLTHA_TOOLS_VERSION}-gocover-cobertura gocover-cobertura
-GOLANGCI_LINT     = docker run --rm --user $$(id -u):$$(id -g) -v ${CURDIR}:/app $(shell test -t 0 && echo "-it") -v gocache:/.cache -v gocache-${VOLTHA_TOOLS_VERSION}:/go/pkg voltha/voltha-ci-tools:${VOLTHA_TOOLS_VERSION}-golangci-lint golangci-lint
-HADOLINT          = docker run --rm --user $$(id -u):$$(id -g) -v ${CURDIR}:/app $(shell test -t 0 && echo "-it") voltha/voltha-ci-tools:${VOLTHA_TOOLS_VERSION}-hadolint hadolint
+# This container is built to include the necessary sysrepo libraries
+# to succesfully build and test the code in this repository
+BUILDER_IMAGE_AND_TAG ?= voltha/bbf-adapter-builder:local 
+build-tools: build/tools/Dockerfile.builder
+	docker build \
+	  -t ${BUILDER_IMAGE_AND_TAG} \
+	  -f build/tools/Dockerfile.builder .
 
-.PHONY: docker-build local-protos local-lib-go help
+GO_LOCAL_BUILDER            = docker run --rm --user $$(id -u):$$(id -g) -v ${CURDIR}:/app $(shell test -t 0 && echo "-it") -v gocache:/.cache -v gocache-${VOLTHA_TOOLS_VERSION}:/go/pkg ${BUILDER_IMAGE_AND_TAG} go
+GO                          = docker run --rm --user $$(id -u):$$(id -g) -v ${CURDIR}:/app $(shell test -t 0 && echo "-it") -v gocache:/.cache -v gocache-${VOLTHA_TOOLS_VERSION}:/go/pkg voltha/voltha-ci-tools:${VOLTHA_TOOLS_VERSION}-golang go
+GO_JUNIT_REPORT             = docker run --rm --user $$(id -u):$$(id -g) -v ${CURDIR}:/app -i voltha/voltha-ci-tools:${VOLTHA_TOOLS_VERSION}-go-junit-report go-junit-report
+GOCOVER_COBERTURA           = docker run --rm --user $$(id -u):$$(id -g) -v ${CURDIR}:/app/src/github.com/opencord/voltha-northbound-bbf-adapter -v gocache:/.cache -v gocache-${VOLTHA_TOOLS_VERSION}:/go/pkg voltha/voltha-ci-tools:${VOLTHA_TOOLS_VERSION}-gocover-cobertura gocover-cobertura
+GOLANGCI_LINT_LOCAL_BUILDER = docker run --rm --user $$(id -u):$$(id -g) -v ${CURDIR}:/app $(shell test -t 0 && echo "-it") -v gocache:/.cache -v gocache-${VOLTHA_TOOLS_VERSION}:/go/pkg ${BUILDER_IMAGE_AND_TAG} golangci-lint
+HADOLINT                    = docker run --rm --user $$(id -u):$$(id -g) -v ${CURDIR}:/app $(shell test -t 0 && echo "-it") voltha/voltha-ci-tools:${VOLTHA_TOOLS_VERSION}-hadolint hadolint
+
+# Default user and password for the netconf user in docker-build
+NETCONF_USER ?= voltha
+NETCONF_PASSWORD ?= onf
+
+.PHONY: docker-build local-protos local-lib-go help test sca
 .DEFAULT_GOAL := help
 
 help: ## Print help for each Makefile target
@@ -87,10 +100,12 @@
 ## Docker targets
 build: docker-build ## Alias for 'docker build'
 
-docker-build: local-lib-go ## Build the BBF Adapter docker container
+docker-build: local-lib-go build-tools ## Build the BBF Adapter docker container
 	docker build \
 	  -t ${DOCKER_REGISTRY}${DOCKER_REPOSITORY}voltha-northbound-bbf-adapter:${DOCKER_TAG} \
-	  -f build/package/Dockerfile.bbf-adapter .
+	  -f build/package/Dockerfile.bbf-adapter . \
+	  --build-arg NETCONF_USER=${NETCONF_USER} \
+	  --build-arg NETCONF_PASSWORD=${NETCONF_PASSWORD}
 
 docker-push: ## Push the docker images to an external repository
 	docker push ${ADAPTER_IMAGENAME}
@@ -105,9 +120,9 @@
 	@if [ "`kind get clusters | grep voltha-$(TYPE)`" = '' ]; then echo "no voltha-$(TYPE) cluster found" && exit 1; fi
 	kind load docker-image ${ADAPTER_IMAGENAME} --name=voltha-$(TYPE) --nodes $(shell kubectl get nodes --template='{{range .items}}{{.metadata.name}},{{end}}' | sed 's/,$$//')
 
-test: ## Run unit tests
+test: build-tools ## Run unit tests
 	@mkdir -p ./tests/results
-	@${GO} test -mod=vendor -v -coverprofile ./tests/results/go-test-coverage.out -covermode count ./... 2>&1 | tee ./tests/results/go-test-results.out ;\
+	@${GO_LOCAL_BUILDER} test -mod=vendor -v -coverprofile ./tests/results/go-test-coverage.out -covermode count ./... 2>&1 | tee ./tests/results/go-test-results.out ;\
 	RETURN=$$? ;\
 	${GO_JUNIT_REPORT} < ./tests/results/go-test-results.out > ./tests/results/go-test-results.xml ;\
 	${GOCOVER_COBERTURA} < ./tests/results/go-test-coverage.out > ./tests/results/go-test-coverage.xml ;\
@@ -134,11 +149,11 @@
 	@[[ `git ls-files --exclude-standard --others go.mod go.sum vendor` == "" ]] || (echo "ERROR: Untracked files detected after running go mod tidy / go mod vendor" && git status -- go.mod go.sum vendor && git checkout -- go.mod go.sum vendor && exit 1)
 	@echo "Vendor check OK."
 
-sca: ## Runs static code analysis with the golangci-lint tool
+sca: build-tools ## Runs static code analysis with the golangci-lint tool
 	@rm -rf ./sca-report
 	@mkdir -p ./sca-report
 	@echo "Running static code analysis..."
-	@${GOLANGCI_LINT} run --deadline=6m --out-format junit-xml ./... | tee ./sca-report/sca-report.xml
+	@${GOLANGCI_LINT_LOCAL_BUILDER} run --deadline=6m --out-format junit-xml ./... | tee ./sca-report/sca-report.xml
 	@echo ""
 	@echo "Static code analysis OK"
 
diff --git a/README.md b/README.md
index 8265afa..cb0dc8c 100644
--- a/README.md
+++ b/README.md
@@ -2,6 +2,17 @@
 
 The Northbound BBF Adapter is a translation layer between the VOLTHA Northbound APIs and the BBF yang model, enabling VOLTHA to be integrated into a full fledged BBF Cloud CO deployment.
 
+## Architecture
+
+The Northbound BBF Adapter is implemented as a plugin for the [sysrepo](https://github.com/sysrepo/sysrepo) data store. Using `libsysrepo`, the adapter is able to act upon requests coming from NETCONF clients through the [netopeer2](https://github.com/CESNET/netopeer2) NETCONF server.
+A deployment of the adapter's container includes an instance of netopeer2 and the bbf-adapter process itself.
+
+![bbf-adapter-architecture](docs/images/bbf-adapter-architecture.svg)
+
+## Documentation
+
+For information on how to deploy the BBF Adapter, please refer to [the docs folder](docs/deploy.md).
+
 ## Development `make` targets
 
 The `Makefile` contains many commands that are useful in development:
diff --git a/build/package/Dockerfile.bbf-adapter b/build/package/Dockerfile.bbf-adapter
index 0566d2e..0d8fadc 100644
--- a/build/package/Dockerfile.bbf-adapter
+++ b/build/package/Dockerfile.bbf-adapter
@@ -17,10 +17,7 @@
 #-------------
 # Build stage
 
-FROM --platform=linux/amd64 golang:1.16.3-alpine3.13 AS dev
-
-# Install required packages
-RUN apk add --no-cache build-base=0.5-r2
+FROM voltha/bbf-adapter-builder:local AS dev
 
 # Use Standard go build directory structure
 WORKDIR /go/src
@@ -28,7 +25,7 @@
 
 ARG EXTRA_GO_BUILD_TAGS=""
 
-ARG CGO_PARAMETER=0
+ARG CGO_PARAMETER=1
 
 ARG org_label_schema_version=unknown
 ARG org_label_schema_vcs_url=unknown
@@ -38,7 +35,7 @@
 ARG org_opencord_vcs_dirty=unknown
 
 # Build
-SHELL ["/bin/ash", "-o", "pipefail", "-c"]
+SHELL ["/bin/bash", "-o", "pipefail", "-c"]
 RUN \
       CGO_ENABLED=$CGO_PARAMETER go build $EXTRA_GO_BUILD_TAGS -mod=vendor -o /app/bbf-adapter \
       -ldflags \
@@ -55,7 +52,41 @@
 
 # -------------
 # Image creation stage
-FROM --platform=linux/amd64 gcr.io/distroless/static:nonroot as prod
+FROM ubuntu:hirsute-20220113 AS prod
+
+SHELL ["/bin/bash", "-o", "pipefail", "-c"]
+RUN \
+      apt-get update && \
+      apt-get install -y \
+            wget=1.21-1ubuntu3 ca-certificates=20210119ubuntu0.21.04.1 \
+            libpcre2-8-0=10.36-2ubuntu5 \
+            libcrypt1=1:4.4.17-1ubuntu3 \
+            libssh-4=0.9.5-1ubuntu0.1 \
+            --no-install-recommends && \
+      rm -rf /var/lib/apt/lists/*
+
+# Download and install library packages
+RUN \
+      wget https://github.com/CESNET/libyang/releases/download/v2.0.112/libyang2_2.0.112.1-1_amd64.deb -O libyang2.deb && \
+      wget https://github.com/sysrepo/sysrepo/releases/download/v2.0.53/libsysrepo6_2.0.53.1-1_amd64.deb -O libsysrepo6.deb && \
+      wget https://github.com/sysrepo/sysrepo/releases/download/v2.0.53/sysrepo-tools_2.0.53.1-1_amd64.deb -O sysrepo-tools.deb && \
+      wget https://github.com/CESNET/libnetconf2/releases/download/v2.0.24/libnetconf2-2_2.0.24.1-1_amd64.deb -O libnetconf2-2.deb && \
+      wget https://github.com/CESNET/netopeer2/releases/download/v2.0.35/netopeer2_2.0.35.2-1_amd64.deb -O netopeer2_2.deb
+
+RUN dpkg -i libyang2.deb libsysrepo6.deb sysrepo-tools.deb libnetconf2-2.deb netopeer2_2.deb
+
+RUN rm libyang2.deb libsysrepo6.deb sysrepo-tools.deb libnetconf2-2.deb netopeer2_2.deb
+
+# Copy yang files and install them to sysrepo
+COPY ./build/yang-files /yang
+RUN sysrepoctl -a -i /yang/bbf-device-aggregation.yang -s /yang -p 664 -v3
+
+# Add user for connecting to netopeer2-server through ssh
+ARG NETCONF_USER=voltha
+ARG NETCONF_PASSWORD=onf
+
+RUN useradd -rm -g netconf -u 1001 $NETCONF_USER
+RUN echo $NETCONF_USER:$NETCONF_PASSWORD | chpasswd
 
 # Set the working directory
 WORKDIR /app
@@ -81,4 +112,5 @@
 org.opencord.vcs-commit-date=$org_opencord_vcs_commit_date \
 org.opencord.vcs-dirty=$org_opencord_vcs_dirty
 
-USER nonroot:nonroot
\ No newline at end of file
+# running netopeer2-server as a standard user is not supported right now
+# https://github.com/sysrepo/sysrepo/issues/2148#issuecomment-695950173
\ No newline at end of file
diff --git a/build/tools/Dockerfile.builder b/build/tools/Dockerfile.builder
new file mode 100644
index 0000000..7e7f710
--- /dev/null
+++ b/build/tools/Dockerfile.builder
@@ -0,0 +1,57 @@
+# Copyright 2022-present Open Networking Foundation
+#
+# 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.
+
+# Dockerfile with golang and the sysrepo dependencies for voltha-northbound-bff-adapter
+# This image is used for testing, static code analysis and building
+
+FROM --platform=linux/amd64 golang:1.16.3-buster AS dev
+
+RUN mkdir -m 777 /.cache /go/pkg
+
+#Install golangci-lint
+RUN go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.44.2
+
+RUN \
+    apt-get update && apt-get install -y libpcre2-dev=10.32-5 --no-install-recommends && \
+    rm -rf /var/lib/apt/lists/*
+
+# Download and install library packages
+RUN \
+    wget https://github.com/CESNET/libyang/releases/download/v2.0.112/libyang2_2.0.112.1-1_amd64.deb -O libyang2.deb && \
+    wget https://github.com/CESNET/libyang/releases/download/v2.0.112/libyang2-dev_2.0.112.1-1_amd64.deb -O libyang2-dev.deb && \
+    wget https://github.com/sysrepo/sysrepo/releases/download/v2.0.53/libsysrepo6_2.0.53.1-1_amd64.deb -O libsysrepo6.deb && \
+    wget https://github.com/sysrepo/sysrepo/releases/download/v2.0.53/libsysrepo-dev_2.0.53.1-1_amd64.deb -O libsysrepo-dev.deb
+
+RUN dpkg -i libyang2.deb libyang2-dev.deb libsysrepo6.deb libsysrepo-dev.deb
+
+RUN rm libyang2.deb libyang2-dev.deb libsysrepo6.deb libsysrepo-dev.deb
+
+WORKDIR /app
+
+ARG org_label_schema_version=unknown
+ARG org_label_schema_vcs_url=unknown
+ARG org_label_schema_vcs_ref=unknown
+ARG org_label_schema_build_date=unknown
+ARG org_opencord_vcs_commit_date=unknown
+ARG org_opencord_vcs_dirty=unknown
+
+LABEL \
+org.label-schema.schema-version=1.0 \
+org.label-schema.name=voltha-northbound-bbf-adapter \
+org.label-schema.version=$org_label_schema_version \
+org.label-schema.vcs-url=$org_label_schema_vcs_url \
+org.label-schema.vcs-ref=$org_label_schema_vcs_ref \
+org.label-schema.build-date=$org_label_schema_build_date \
+org.opencord.vcs-commit-date=$org_opencord_vcs_commit_date \
+org.opencord.vcs-dirty=$org_opencord_vcs_dirty
\ No newline at end of file
diff --git a/build/yang-files/bbf-device-aggregation.yang b/build/yang-files/bbf-device-aggregation.yang
new file mode 100644
index 0000000..24a5141
--- /dev/null
+++ b/build/yang-files/bbf-device-aggregation.yang
@@ -0,0 +1,154 @@
+module bbf-device-aggregation {
+  yang-version 1.1;
+  namespace "urn:bbf:yang:bbf-device-aggregation";
+  prefix bbf-dev-agg;
+
+  import bbf-yang-types {
+    prefix bbf-yang;
+  }
+  import bbf-device-types {
+    prefix bbf-dvct;
+  }
+  import ietf-yang-schema-mount {
+    prefix yangmnt;
+  }
+
+  organization
+    "Broadband Forum <https://www.broadband-forum.org>
+     Common YANG Work Area";
+  contact
+    "Comments or questions about this Broadband Forum YANG module
+     should be directed to <mailto:help@broadband-forum.org>.
+
+     Editor:      Nick Hancock, ADTRAN
+
+     Editor:      Ludwig Pauwels, Nokia
+
+     PS Leader:   Joey Boyd, ADTRAN
+
+     WA Director: Joey Boyd, ADTRAN
+
+     WA Director: Sven Ooghe, Nokia";
+  description
+    "This module contains a collection of YANG definitions for
+     supporting the Broadband Forum requirements on device
+     aggregation. As such, this module is specific to access network
+     equipment (e.g., BBF-specified Access Nodes and FTTdp DPUs).
+
+     Copyright (c) 2017-2022, Broadband Forum
+
+     Redistribution and use in source and binary forms, with or
+     without modification, are permitted provided that the following
+     conditions are met:
+
+     1. Redistributions of source code must retain the above copyright
+        notice, this list of conditions and the following disclaimer.
+
+     2. 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.
+
+     3. Neither the name of the copyright holder 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 HOLDER 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.
+
+     The above license is used as a license under copyright only.
+     Please reference the Forum IPR Policy for patent licensing terms
+     <https://www.broadband-forum.org/ipr-policy>.
+
+     Any moral rights which are necessary to exercise under the above
+     license grant are also deemed granted under this license.
+
+     This version of this YANG module is part of TR-383a5; see
+     the TR itself for full legal notices.";
+
+  revision 2022-03-01 {
+    description
+      "Amendment 5.
+       * Approval Date:    2022-03-01.
+       * Publication Date: 2022-03-01.";
+    reference
+      "TR-383a5: Common YANG Modules
+                 <https://www.broadband-forum.org/technical/download/
+                          TR-383_Amendment-5.pdf>";
+  }
+
+  container devices {
+    description
+      "Aggregation and management of multiple devices.";
+    list device {
+      key "name";
+      description
+        "An aggregated device.";
+      leaf name {
+        type bbf-yang:string-ascii64;
+        description
+          "The unique name of the device.";
+      }
+      leaf type {
+        type identityref {
+          base bbf-dvct:device-type;
+        }
+        mandatory true;
+        description
+          "The type of device.";
+      }
+      container identification {
+        presence
+          "Presence of the container indicates that data nodes that
+           identify the device exist.";
+        description
+          "Data nodes identifying the device instance.";
+        choice identification {
+          mandatory true;
+          description
+            "A choice for different methods to uniquely identify a
+             device instance.";
+          case hardware-inventory-data {
+            leaf mfg-name {
+              type string;
+              description
+                "The name of the manufacturer of the device.";
+            }
+            leaf model-name {
+              type string;
+              description
+                "The vendor-specific model name associated with the
+                 device.";
+            }
+            leaf serial-num {
+              type string;
+              description
+                "The vendor-specific serial number string for the
+                 device.";
+            }
+          }
+        }
+      }
+      container data {
+        description
+          "The data nodes of the device's schema.";
+        yangmnt:mount-point "device-yang-library" {
+          description
+            "The YANG library associated with the device.";
+        }
+      }
+    }
+  }
+}
diff --git a/build/yang-files/bbf-device-types.yang b/build/yang-files/bbf-device-types.yang
new file mode 100644
index 0000000..8448e2f
--- /dev/null
+++ b/build/yang-files/bbf-device-types.yang
@@ -0,0 +1,185 @@
+module bbf-device-types {
+  yang-version 1.1;
+  namespace "urn:bbf:yang:bbf-device-types";
+  prefix bbf-dvct;
+
+  organization
+    "Broadband Forum <https://www.broadband-forum.org>
+     Common YANG Work Area";
+  contact
+    "Comments or questions about this Broadband Forum YANG module
+     should be directed to <mailto:help@broadband-forum.org>.
+
+     Editor:      Nick Hancock, ADTRAN
+
+     Editor:      Ludwig Pauwels, Nokia
+
+     PS Leader:   Joey Boyd, ADTRAN
+
+     PS Leader:   Sowrirajan Padmanabhan, Nokia
+
+     WA Director: Joey Boyd, ADTRAN
+
+     WA Director: Sven Ooghe, Nokia";
+  description
+    "This module contains a collection of YANG definitions for
+     supporting the Broadband Forum requirements on managing physical
+     devices.
+
+     Specifically, this module defines common types associated with
+     device management.
+
+     Copyright (c) 2017-2021, Broadband Forum
+
+     Redistribution and use in source and binary forms, with or
+     without modification, are permitted provided that the following
+     conditions are met:
+
+     1. Redistributions of source code must retain the above copyright
+        notice, this list of conditions and the following disclaimer.
+
+     2. 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.
+
+     3. Neither the name of the copyright holder 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 HOLDER 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.
+
+     The above license is used as a license under copyright only.
+     Please reference the Forum IPR Policy for patent licensing terms
+     <https://www.broadband-forum.org/ipr-policy>.
+
+     Any moral rights which are necessary to exercise under the above
+     license grant are also deemed granted under this license.
+
+     This version of this YANG module is part of TR-383a4; see
+     the TR itself for full legal notices.";
+
+  revision 2021-06-02 {
+    description
+      "Amendment 4.
+       * Approval Date:    2021-06-02.
+       * Publication Date: 2021-06-02.";
+    reference
+      "TR-383a4: Common YANG Modules
+                 <https://www.broadband-forum.org/technical/download/
+                          TR-383_Amendment-4.pdf>";
+  }
+
+  // Identities
+  // Device types
+
+  identity device-type {
+    description
+      "Base identity from which specific device node types are
+       derived.";
+  }
+
+  identity access-device-type {
+    base device-type;
+    description
+      "Base identity from which specific access device node types are
+       derived.";
+  }
+
+  identity dpu {
+    base access-device-type;
+    description
+      "Distribution Point Unit (DPU).";
+  }
+
+  identity msan {
+    base access-device-type;
+    description
+      "Multiservice Access Node (MSAN).";
+  }
+
+  identity dslam {
+    base access-device-type;
+    description
+      "Digital Subscriber Line Access Multiplexer (DSLAM).";
+  }
+
+  identity olt {
+    base access-device-type;
+    description
+      "Optical Line Terminal (OLT).";
+  }
+
+  identity onu {
+    base access-device-type;
+    description
+      "Optical Network Unit (ONU).";
+  }
+
+  identity fast-cpe {
+    base access-device-type;
+    description
+      "The G.fast CPE. G.fast is a Digital Subscriber Line (DSL)
+       protocol standard.";
+  }
+
+  identity vdsl2-cpe {
+    base access-device-type;
+    description
+      "The Very High-speed Digital Subscriber Line 2 (VDSL2) CPE.";
+  }
+
+  // Device Subcategory
+
+  identity device-subcategory {
+    description
+      "Base identity from which specific subcategories of device types
+       are derived.";
+  }
+
+  identity access-device-subcategory {
+    base device-subcategory;
+    description
+      "Identity from which specific subcategories of access device
+       types are derived.";
+  }
+
+  identity multi-card {
+    base access-device-subcategory;
+    description
+      "The multi card subcategory.
+
+       An access device of this or a derived identity is a device that
+       has the capability to support multiple cards, independent of
+       the actual deployment.";
+  }
+
+  identity single-card {
+    base access-device-subcategory;
+    description
+      "The single card subcategory.
+
+       An access device of this or a derived identity is a device that
+       is a fully self-contained device that does not has the
+       capability to plug or unplug cards.";
+  }
+
+  identity pluggable-transceiver {
+    base access-device-subcategory;
+    description
+      "The pluggable transceiver subcategory.";
+  }
+}
diff --git a/build/yang-files/bbf-yang-types.yang b/build/yang-files/bbf-yang-types.yang
new file mode 100644
index 0000000..efa31d5
--- /dev/null
+++ b/build/yang-files/bbf-yang-types.yang
@@ -0,0 +1,275 @@
+module bbf-yang-types {
+  yang-version 1.1;
+  namespace "urn:bbf:yang:bbf-yang-types";
+  prefix bbf-yang;
+
+  organization
+    "Broadband Forum <https://www.broadband-forum.org>
+     Common YANG Work Area";
+  contact
+    "Comments or questions about this Broadband Forum YANG module
+     should be directed to <mailto:help@broadband-forum.org>.
+
+     Editor:      Nick Hancock, ADTRAN
+
+     Editor:      Ludwig Pauwels, Nokia
+
+     PS Leader:   Joey Boyd, ADTRAN
+
+     WA Director: Joey Boyd, ADTRAN
+
+     WA Director: Sven Ooghe, Nokia";
+  description
+    "This module contains a collection of YANG definitions for
+     supporting the Broadband Forum requirements on reusable data
+     types as applicable to access network equipment. As such, this
+     module is specific to access network equipment (e.g.,
+     BBF-specified Access Nodes and FTTdp DPUs).
+
+     Specifically, this module defines common types used throughout
+     BBF data models.
+
+     Copyright (c) 2017-2022, Broadband Forum
+
+     Redistribution and use in source and binary forms, with or
+     without modification, are permitted provided that the following
+     conditions are met:
+
+     1. Redistributions of source code must retain the above copyright
+        notice, this list of conditions and the following disclaimer.
+
+     2. 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.
+
+     3. Neither the name of the copyright holder 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 HOLDER 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.
+
+     The above license is used as a license under copyright only.
+     Please reference the Forum IPR Policy for patent licensing terms
+     <https://www.broadband-forum.org/ipr-policy>.
+
+     Any moral rights which are necessary to exercise under the above
+     license grant are also deemed granted under this license.
+
+     This version of this YANG module is part of TR-383a5; see
+     the TR itself for full legal notices.";
+
+  revision 2022-03-01 {
+    description
+      "Amendment 5.
+       * Approval Date:    2022-03-01.
+       * Publication Date: 2022-03-01.";
+    reference
+      "TR-383a5: Common YANG Modules
+                 <https://www.broadband-forum.org/technical/download/
+                          TR-383_Amendment-5.pdf>";
+  }
+  revision 2021-06-02 {
+    description
+      "Amendment 4.
+       * Approval Date:    2021-06-02.
+       * Publication Date: 2021-06-02.";
+    reference
+      "TR-383a4: Common YANG Modules
+                 <https://www.broadband-forum.org/technical/download/
+                          TR-383_Amendment-4.pdf>";
+  }
+  revision 2020-10-13 {
+    description
+      "Amendment 3.
+       * Approval Date:    2020-10-13.
+       * Publication Date: 2020-10-13.";
+    reference
+      "TR-383a3: Common YANG Modules
+                 <https://www.broadband-forum.org/technical/download/
+                          TR-383_Amendment-3.pdf>";
+  }
+  revision 2019-10-21 {
+    description
+      "Amendment 2 Corrigendum 1.
+       * Approval Date:    2019-10-21.
+       * Publication Date: 2019-10-21.";
+    reference
+      "TR-383a2c1: Common YANG Modules
+                 <https://www.broadband-forum.org/technical/download/
+                          TR-383_Amendment-2.pdf>";
+  }
+  revision 2018-07-13 {
+    description
+      "Amendment 1.
+       * Approval Date:    2018-06-04.
+       * Publication Date: see revision date above.";
+    reference
+      "TR-383: Common YANG Modules
+               <https://www.broadband-forum.org/technical/download/
+                        TR-383_Amendment-1.pdf>";
+  }
+  revision 2017-05-08 {
+    description
+      "Initial revision.
+       * Approval Date:    see revision date above.
+       * Publication Date: 2017-06-02.";
+    reference
+      "TR-383: Common YANG Modules
+               <https://www.broadband-forum.org/technical/download/
+                        TR-383.pdf>";
+  }
+  revision 2016-07-18 {
+    description
+      "Initial revision.
+       * Approval Date:    see revision date above.
+       * Publication Date: 2016-08-05.";
+    reference
+      "TR-355: YANG Modules for FTTdp Management
+               <https://www.broadband-forum.org/technical/download/
+                        TR-355.pdf>";
+  }
+
+  typedef name-string {
+    type string {
+      length "1..64";
+    }
+    description
+      "Used where a string is needed which has a maximum length of
+       64 characters and a minimum length of 1 character.";
+  }
+
+  typedef percent {
+    type uint8 {
+      range "0..100";
+    }
+    units "percentage";
+    description
+      "A percentage.";
+  }
+
+  typedef performance-counter32 {
+    type uint32;
+    description
+      "The 'performance-counter32' type represents a non-negative
+       integer that monotonically increases until it reaches a maximum
+       value of 2^32-1 (4294967295 decimal), but does not wrap around
+       once the maximum value is reached.";
+  }
+
+  typedef performance-counter32-or-inactive {
+    type union {
+      type uint32;
+      type enumeration {
+        enum inactive {
+          description
+            "Indicates that this counter is not active.";
+        }
+      }
+    }
+    description
+      "The 'performance-counter32-or-inactive' type represents a
+       non-negative integer that monotonically increases until it
+       reaches a maximum value of 2^32-1 (4294967295 decimal), but
+       does not wrap around once the maximum value is reached.
+
+       A special value (enum inactive) indicates that this counter
+       is not active.";
+  }
+
+  typedef performance-counter64 {
+    type uint64;
+    description
+      "The 'performance-counter64' type represents a non-negative
+       integer that monotonically increases until it reaches a maximum
+       value of 2^64-1 (18446744073709551615 decimal), but does not
+       wrap around once the maximum value is reached.";
+  }
+
+  typedef string-ascii63-or-empty {
+    type string {
+      length "0..63";
+      pattern '[ -~]*';
+      // allows the 95 printable ASCII characters
+    }
+    description
+      "Used where a string is needed which has a maximum length of
+       63 characters and also allows for a null string (length = 0).
+
+       The character set is limited to the 95 printable ASCII
+       characters.";
+  }
+
+  typedef string-ascii64 {
+    type string {
+      length "1..64";
+      pattern '[ -~]*';
+    }
+    description
+      "Used where a string is represented using at least 1 and no more
+       than 64 ASCII characters.
+
+       The character set is limited to the 95 printable ASCII
+       characters.";
+  }
+
+  typedef string-ascii64-or-empty {
+    type string {
+      length "0..64";
+      pattern '[ -~]*';
+    }
+    description
+      "Used where a string is needed which has a maximum length of
+       64 characters and also allows for a null string (length = 0).
+
+       The character set is limited to the 95 printable ASCII
+       characters.";
+  }
+
+  typedef undetermined {
+    type enumeration {
+      enum undetermined {
+        description
+          "Indicates the value is not determined.";
+      }
+    }
+    description
+      "A type which defines an enumeration representing when
+       the value for an object is not determined. Often, this is
+       combined with other data via a union acting as a special value
+       to indicate the undetermined state.";
+  }
+
+  typedef data-rate32 {
+    type uint32;
+    units "kbits/second";
+    description
+      "A type which represents the rate at which data is being
+       transferred.";
+  }
+
+  typedef data-rate32-or-undetermined {
+    type union {
+      type undetermined;
+      type data-rate32;
+    }
+    units "kbits/second";
+    description
+      "A type which represents the rate at which data is being
+       transferred. A special value, 'undetermined', is used to
+       indicate the data rate is undetermined.";
+  }
+}
diff --git a/cmd/bbf-adapter/main.go b/cmd/bbf-adapter/main.go
index d68287e..48ac7b8 100644
--- a/cmd/bbf-adapter/main.go
+++ b/cmd/bbf-adapter/main.go
@@ -29,19 +29,22 @@
 	"github.com/opencord/voltha-lib-go/v7/pkg/log"
 	"github.com/opencord/voltha-lib-go/v7/pkg/probe"
 	"github.com/opencord/voltha-lib-go/v7/pkg/version"
-	clients "github.com/opencord/voltha-northbound-bbf-adapter/internal/clients"
+	"github.com/opencord/voltha-northbound-bbf-adapter/internal/clients"
 	"github.com/opencord/voltha-northbound-bbf-adapter/internal/config"
+	"github.com/opencord/voltha-northbound-bbf-adapter/internal/sysrepo"
 )
 
 //String for readiness probe services
 const (
 	bbfAdapterService = "bbf-adapter-service"
+	sysrepoService    = "sysrepo"
 )
 
 type bbfAdapter struct {
 	conf            *config.BBFAdapterConfig
 	volthaNbiClient *clients.VolthaNbiClient
 	oltAppClient    *clients.OltAppClient
+	sysrepoPlugin   *sysrepo.SysrepoPlugin
 }
 
 func newBbfAdapter(conf *config.BBFAdapterConfig) *bbfAdapter {
@@ -69,6 +72,14 @@
 		probe.UpdateStatusFromContext(ctx, a.conf.OnosRestEndpoint, probe.ServiceStatusRunning)
 	}
 
+	//Load sysrepo plugin
+	a.sysrepoPlugin, err = sysrepo.StartNewPlugin(ctx)
+	if err != nil {
+		logger.Fatalw(ctx, "failed-to-start-sysrepo-plugin", log.Fields{"err": err})
+	} else {
+		probe.UpdateStatusFromContext(ctx, sysrepoService, probe.ServiceStatusRunning)
+	}
+
 	//Run the main logic of the BBF adapter
 
 	//Set the service as running, making the adapter finally ready
@@ -113,8 +124,12 @@
 }
 
 //Close all connections of the adapter
-func (a *bbfAdapter) cleanup() {
-	a.volthaNbiClient.Close()
+func (a *bbfAdapter) cleanup(ctx context.Context) {
+	a.volthaNbiClient.Close(ctx)
+	err := a.sysrepoPlugin.Stop(ctx)
+	if err != nil {
+		logger.Errorw(ctx, "failed-to-stop-sysrepo-plugin", log.Fields{"err": err})
+	}
 }
 
 func printBanner() {
@@ -217,6 +232,7 @@
 		bbfAdapterService,
 		conf.VolthaNbiEndpoint,
 		conf.OnosRestEndpoint,
+		sysrepoService,
 	)
 
 	closer, err := log.GetGlobalLFM().InitTracingAndLogCorrelation(conf.TraceEnabled, conf.TraceAgentAddress, conf.LogCorrelationEnabled)
@@ -232,7 +248,7 @@
 	wg := &sync.WaitGroup{}
 	wg.Add(1)
 	go adapter.start(probeCtx, wg)
-	defer adapter.cleanup()
+	defer adapter.cleanup(probeCtx)
 
 	//Wait a signal to stop execution
 	code := waitForExit(ctx)
diff --git a/docs/deploy.md b/docs/deploy.md
new file mode 100644
index 0000000..44f5a3a
--- /dev/null
+++ b/docs/deploy.md
@@ -0,0 +1,65 @@
+# Deployment of the BBF adapter
+
+Similarly to other components of the VOLTHA stack, the BBF adapter is deployed with a helm chart.
+
+## Prerequisites
+
+BBF adapter requires a working deployment of the voltha-infra and voltha-stack helm charts for a successful installation.
+Please refer to [docs.voltha.org](https://docs.voltha.org/master/voltha-helm-charts/README.html) to learn how to set them up.
+
+## Install the voltha-northbound-bbf-adapter helm chart
+
+The adapter's chart can be installed with the following command, assuming the voltha-infra and voltha-stack charts have been deployed with suggested names from [docs.voltha.org](https://docs.voltha.org/master/voltha-helm-charts/README.html).
+
+```
+helm upgrade --install --create-namespace -n voltha bbf \
+            onf/voltha-northbound-bbf-adapter/ --devel \
+            --set global.voltha_infra_name=voltha-infra \
+            --set global.voltha_infra_namespace=infra \
+            --set global.voltha_stack_name=voltha \
+            --set global.voltha_stack_namespace=voltha \
+            --set global.log_level=INFO \
+            --set images.voltha_northbound_bbf_adapter.tag=master
+```
+
+The SSH port on which netopeer2 is listening can be exposed on localhost by running:
+
+```
+kubectl -n voltha port-forward svc/bbf-voltha-northbound-bbf-adapter-netopeer2 50830
+```
+
+The logs of the adapter can be followed in a separate terminal:
+
+```
+kubectl -n voltha logs --follow $(kubectl -n voltha get pods -l app=bbf-adapter -o name)
+```
+
+## Make NETCONF requests
+
+After a succesful installation, a NETCONF client can be used to perform requests to the adapter's netopeer2 instance.
+For this example, we will use netopeer2-cli.
+
+```
+docker run --rm --net=host -it erap320/netopeer2-cli
+```
+
+Running the following instruction will connect to the adapter's netopeer2 instance as the default `voltha` user.
+
+```
+connect --ssh --host localhost --port 50830 --login voltha
+```
+
+When presented with the server's fingerprint, confirm by entering `yes`, and then log in with password `onf`.
+
+After a successful login, a request can be performed:
+
+```
+get-data --datastore operational --filter-xpath /bbf-device-aggregation:devices
+```
+
+The adapter doesn't perform request translations yet, but the success of the operation can be inferred by looking at the container's logs, which will show a `>>>>>>>RECEIVED REQUEST FROM SYSREPO<<<<<<<` message.
+
+## Stop the BBF adapter
+```
+helm delete -n voltha bbf
+```
\ No newline at end of file
diff --git a/docs/images/bbf-adapter-architecture.svg b/docs/images/bbf-adapter-architecture.svg
new file mode 100644
index 0000000..25754ed
--- /dev/null
+++ b/docs/images/bbf-adapter-architecture.svg
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Do not edit this file with editors other than diagrams.net -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="281px" height="475px" viewBox="-0.5 -0.5 281 475" content="&lt;mxfile host=&quot;app.diagrams.net&quot; modified=&quot;2022-03-14T15:39:08.751Z&quot; agent=&quot;5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36&quot; etag=&quot;ge9tlxE5m3qdNw-N6kSt&quot; version=&quot;17.1.2&quot; type=&quot;device&quot;&gt;&lt;diagram id=&quot;kWiRV7-ioKWRuaYgKj7s&quot; name=&quot;Page-1&quot;&gt;3Vnfc9o4EP5reKRjW2DgMaHkeje5JA2Z9voobGGrFZZHFgH615+EJduyzM8EnOkLY61Xa+nb/Va7ogPGi/VfDKbxvzREpOM54boDPnc8b+gC8SsFm1zQA14uiBgOc5FbCqb4N1JCR0mXOESZocgpJRynpjCgSYICbsggY3Rlqs0pMb+awghZgmkAiS39jkMeq215g1L+BeEo1l92/VH+ZgG1stpJFsOQrioiMOmAMaOU50+L9RgRiZ3GJZ93t+NtsTCGEn7MhGcvvJtm/3TB168xjn59g88/QbenFvcKyVLtWK2WbzQEEaPLVKkhxtG6CXg40+qOvTC32K4IE0QXiLONUFGGPND/1M8nqSBx9bJWJeTeQEVSXIHbGyhFqNwcFdZLJMSDAuMEYNzeYWAELkmIpBW3A25XMeZomsJAvl0JMghZzBdEvZ5jQsaUULadC0KIhvNAyEOYxYWNjDP6C1XU/GCIZnPxZif+VZz3uNhGvz1sNZQVbF8FpWPYTSjj8UzC2p3N5l0YwpQj1vF8IhZ1O5NPEd+iUZeIMOQQJ1K55iUBGDddYaKc0ATV/KNEkOAoEUOWg3Ir0cciNdwo+QKHofxKo+vL4HAu4j5NHp0oNXX6FnN8x3bu6GK86befUIDrmZgMhhYorteAijvyLwQLsFDJNhlDKd2TVJzDSeX8sMr9ZEOoIBt4xyHWv1gcuRYyKBQnsxrKPEEjmkAyKaU1zpU695SmCrGfiPONKjPgklMTT7TG/D85XRxI+eiHMiafP6+rg40eJGK/lUly+EPbk4Ny2nak52UcMn4jSxQhCAjMMhxo8R0mpovl3s9xsACQLlmA9iWYXE98NkL7DILmgGGIQI5fzdW9ezjYp7FxPnxIDrk9v2US+RZqCeI0RYjtK2Zawaw1jEaHz6srJJ6PkgzAkcnAbzMZuEPLZw+Tl/Hjw11DXUiwhMZyKSGig9xVu50a6Qf6m1HPKEea0kLft0Pev1TI6xa83abPrNF6g4aWb3jNRADsVvjb4/3Ll5vtfhlqK2PmQH2gjAlcC6jHh8fpR8NHm/HtwLoyXnbxb+ejJLSzfwUeE8uyTPWqdaquYE+rU8vK9NJ1qi7p360i3dEaH30KqalPFMsjomgfR2ZLDeqRkW9AzfIqN241Q71DhvIdWoa2UVbs5w2BZ1fN0fOTsOXcPP3dWOXcwxkiMtxQhn+r7O6YkagvRQLhVlF677kVabhR2X96nMX+VtsScMRtx7nUHoz8ag/6aSTKiBb5Lb/1hBgWwEm3V261rsv5HWXFGznfc2pUHZ7J+YLjRV1Tu1K6NOftnu95Mn35szi/o4e8Euft7uOtnD/zBumc26rrn+b+kczOu7p3Z7ZXY3ZR+53M7EOGLs1s+6ai6Hr/DFq/cwAoPxWXH3oKnc8zdKKLxLD8pzZXL//uBpP/AQ==&lt;/diagram&gt;&lt;/mxfile&gt;"><defs/><g><rect x="3.5" y="94" width="273" height="270" rx="40.5" ry="40.5" fill="#dae8fc" stroke="#6c8ebf" stroke-dasharray="3 3" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-end; width: 58px; height: 1px; padding-top: 154px; margin-left: 214px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: right;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; white-space: normal; overflow-wrap: normal;">voltha-northbound-bbf-adapter<br /><br />container</div></div></div></foreignObject><text x="272" y="158" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="end">voltha-nor...</text></switch></g><rect x="80" y="204" width="120" height="50" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 229px; margin-left: 81px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; white-space: normal; overflow-wrap: normal;">sysrepo</div></div></div></foreignObject><text x="140" y="233" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">sysrepo</text></switch></g><path d="M 140 271.63 L 140 260.37" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><path d="M 140 276.88 L 136.5 269.88 L 140 271.63 L 143.5 269.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><path d="M 140 255.12 L 143.5 262.12 L 140 260.37 L 136.5 262.12 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><rect x="80" y="278" width="120" height="50" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 303px; margin-left: 81px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; white-space: normal; overflow-wrap: normal;">bbf-adapter</div></div></div></foreignObject><text x="140" y="307" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">bbf-adapter</text></switch></g><rect x="80" y="132" width="120" height="50" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 157px; margin-left: 81px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; white-space: normal; overflow-wrap: normal;">netopeer2</div></div></div></foreignObject><text x="140" y="161" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">netopeer2</text></switch></g><path d="M 140.03 197.63 L 140.03 184 L 140.03 202 L 140.03 188.37" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><path d="M 140.03 202.88 L 136.53 195.88 L 140.03 197.63 L 143.53 195.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><path d="M 140.03 183.12 L 143.53 190.12 L 140.03 188.37 L 136.53 190.12 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><ellipse cx="140" cy="30" rx="78" ry="30" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 154px; height: 1px; padding-top: 30px; margin-left: 63px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; white-space: normal; overflow-wrap: normal;">NETCONF<br />client</div></div></div></foreignObject><text x="140" y="34" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">NETCONF...</text></switch></g><rect x="0" y="424" width="120" height="50" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 449px; margin-left: 1px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; white-space: normal; overflow-wrap: normal;">VOLTHA core</div></div></div></foreignObject><text x="60" y="453" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">VOLTHA core</text></switch></g><rect x="160" y="424" width="120" height="50" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 449px; margin-left: 161px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; white-space: normal; overflow-wrap: normal;">ONOS</div></div></div></foreignObject><text x="220" y="453" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">ONOS</text></switch></g><path d="M 107.06 333.65 L 62.94 418.35" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><path d="M 109.48 328.99 L 109.35 336.82 L 107.06 333.65 L 103.15 333.58 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><path d="M 60.52 423.01 L 60.65 415.18 L 62.94 418.35 L 66.85 418.42 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 376px; margin-left: 85px;"><div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; background-color: rgb(255, 255, 255); white-space: nowrap;">gRPC API</div></div></div></foreignObject><text x="85" y="380" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="11px" text-anchor="middle">gRPC API</text></switch></g><path d="M 178.19 333.48 L 217.33 418.22" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><path d="M 175.99 328.71 L 182.1 333.6 L 178.19 333.48 L 175.75 336.54 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><path d="M 219.53 422.99 L 213.42 418.1 L 217.33 418.22 L 219.77 415.16 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 376px; margin-left: 198px;"><div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; background-color: rgb(255, 255, 255); white-space: nowrap;">REST API</div></div></div></foreignObject><text x="198" y="380" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="11px" text-anchor="middle">REST API</text></switch></g><path d="M 140 125.63 L 140 66.37" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><path d="M 140 130.88 L 136.5 123.88 L 140 125.63 L 143.5 123.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><path d="M 140 61.12 L 143.5 68.12 L 140 66.37 L 136.5 68.12 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 81px; margin-left: 140px;"><div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; background-color: rgb(255, 255, 255); white-space: nowrap;">NETCONF</div></div></div></foreignObject><text x="140" y="85" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="11px" text-anchor="middle">NETCONF</text></switch></g></g><switch><g requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"/><a transform="translate(0,-5)" xlink:href="https://www.diagrams.net/doc/faq/svg-export-text-problems" target="_blank"><text text-anchor="middle" font-size="10px" x="50%" y="100%">Text is not SVG - cannot display</text></a></switch></svg>
\ No newline at end of file
diff --git a/go.sum b/go.sum
index 1230bfd..b910087 100644
--- a/go.sum
+++ b/go.sum
@@ -55,6 +55,7 @@
 github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
 github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
 github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
+github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
 github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
 github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
 github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
@@ -93,6 +94,7 @@
 github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4=
 github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM=
 github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
+github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw=
 github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y=
 github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
 github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
@@ -104,6 +106,7 @@
 github.com/jcmturner/goidentity/v6 v6.0.1/go.mod h1:X1YW3bgtvwAXju7V3LCIMpY0Gbxyjn/mY9zx4tFonSg=
 github.com/jcmturner/gokrb5/v8 v8.4.2/go.mod h1:sb+Xq/fTY5yktf/VxLsE3wlfPqQjp0aWNYyvBVK62bc=
 github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc=
+github.com/jhump/protoreflect v1.10.2 h1:Qc3VJs63tedVbKAI+nT56poeo81VC/Qz1erp5No5ROU=
 github.com/jhump/protoreflect v1.10.2/go.mod h1:7GcYQDdMU/O/BBrl/cX6PNHpXh6cenjd8pneu5yW7Tg=
 github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8=
 github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
@@ -151,6 +154,7 @@
 github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
 github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs=
 github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc=
+github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2 h1:JhzVVoYvbOACxoUmOs6V/G4D5nPVUW73rKvXxP4XUJc=
 github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2/go.mod h1:iIss55rKnNBTvrwdmkUpLnDpZoAHvWaiq5+iMmen4AE=
 github.com/pierrec/lz4 v2.6.0+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
 github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
diff --git a/internal/clients/nbi.go b/internal/clients/nbi.go
index 48df827..37dac96 100644
--- a/internal/clients/nbi.go
+++ b/internal/clients/nbi.go
@@ -22,6 +22,7 @@
 	"fmt"
 	"time"
 
+	vgrpc "github.com/opencord/voltha-lib-go/v7/pkg/grpc"
 	"github.com/opencord/voltha-lib-go/v7/pkg/log"
 	"github.com/opencord/voltha-protos/v5/go/voltha"
 	"google.golang.org/grpc"
@@ -31,7 +32,8 @@
 )
 
 const (
-	nbiMaxBackoffInterval = time.Second * 10
+	nbiInitialBackoffInterval = time.Second
+	nbiMaxBackoffInterval     = time.Second * 10
 )
 
 //Used to keep track of a connection to a grpc endpoint of the northbound api
@@ -81,6 +83,7 @@
 	}
 
 	//Wait for the connection to be successful, with periodic updates on its status
+	backoff := vgrpc.NewBackoff(nbiInitialBackoffInterval, nbiMaxBackoffInterval, vgrpc.DefaultBackoffMaxElapsedTime)
 	for {
 		if state := c.conn.GetState(); state == connectivity.Ready {
 			break
@@ -88,11 +91,8 @@
 			logger.Warnw(ctx, "voltha-nbi-grpc-not-ready", log.Fields{"state": state})
 		}
 
-		select {
-		case <-ctx.Done():
+		if err := backoff.Backoff(ctx); err != nil {
 			return fmt.Errorf("voltha-nbi-connection-stopped-due-to-context-done")
-		case <-time.After(nbiMaxBackoffInterval):
-			continue
 		}
 	}
 
@@ -104,7 +104,9 @@
 }
 
 // Closes the connection and cleans up
-func (c *VolthaNbiClient) Close() {
+func (c *VolthaNbiClient) Close(ctx context.Context) {
 	c.conn.Close()
 	c.Service = nil
+
+	logger.Debug(ctx, "closed-voltha-nbi-grpc-connection")
 }
diff --git a/internal/sysrepo/logger.go b/internal/sysrepo/logger.go
new file mode 100644
index 0000000..9743c0c
--- /dev/null
+++ b/internal/sysrepo/logger.go
@@ -0,0 +1,32 @@
+/*
+* Copyright 2022-present Open Networking Foundation
+
+* 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 sysrepo
+
+import (
+	"github.com/opencord/voltha-lib-go/v7/pkg/log"
+)
+
+var logger log.CLogger
+
+func init() {
+	// Setup this package so that it's log level can be modified at run time
+	var err error
+	logger, err = log.RegisterPackage(log.JSON, log.ErrorLevel, log.Fields{})
+	if err != nil {
+		panic(err)
+	}
+}
diff --git a/internal/sysrepo/plugin.c b/internal/sysrepo/plugin.c
new file mode 100644
index 0000000..edbf0e5
--- /dev/null
+++ b/internal/sysrepo/plugin.c
@@ -0,0 +1,39 @@
+/*
+* Copyright 2022-present Open Networking Foundation
+
+* 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.
+ */
+
+#include <sysrepo.h>
+#include <sysrepo/xpath.h>
+
+//Needed to handle callback functions with a working data type in CGO
+typedef void (*function)(); // https://golang.org/issue/19835
+
+//Exported by sysrepo.go
+void get_data_cb();
+
+int get_data_cb_wrapper(
+    sr_session_ctx_t *session,
+    uint32_t subscription_id,
+    const char *module_name,
+    const char *path,
+    const char *request_xpath,
+    uint32_t request_id,
+    struct lyd_node **parent,
+    void *private_data)
+{
+    get_data_cb();
+
+    return SR_ERR_OK;
+}
\ No newline at end of file
diff --git a/internal/sysrepo/sysrepo.go b/internal/sysrepo/sysrepo.go
new file mode 100644
index 0000000..b0ebc1f
--- /dev/null
+++ b/internal/sysrepo/sysrepo.go
@@ -0,0 +1,160 @@
+/*
+* Copyright 2022-present Open Networking Foundation
+
+* 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 sysrepo
+
+//#cgo CFLAGS: -I/usr/include
+//#cgo LDFLAGS: -lsysrepo -Wl,--allow-multiple-definition
+//#include "plugin.c"
+import "C"
+import (
+	"context"
+	"fmt"
+
+	"github.com/opencord/voltha-lib-go/v7/pkg/log"
+)
+
+const (
+	BASE_YANG_MODEL    = "bbf-device-aggregation"
+	DEVICES_YANG_MODEL = "/" + BASE_YANG_MODEL + ":devices"
+)
+
+type SysrepoPlugin struct {
+	connection   *C.sr_conn_ctx_t
+	session      *C.sr_session_ctx_t
+	subscription *C.sr_subscription_ctx_t
+}
+
+func errorMsg(code C.int) string {
+	return C.GoString(C.sr_strerror(code))
+}
+
+//createPluginState populates a SysrepoPlugin struct by establishing
+//a connection and a session
+func (p *SysrepoPlugin) createSession(ctx context.Context) error {
+
+	var errCode C.int
+
+	//Populates connection
+	errCode = C.sr_connect(C.SR_CONN_DEFAULT, &p.connection)
+	if errCode != C.SR_ERR_OK {
+		err := fmt.Errorf("sysrepo-connect-error")
+		logger.Errorw(ctx, err.Error(), log.Fields{"errCode": errCode, "errMsg": errorMsg(errCode)})
+		return err
+	}
+
+	//Populates session
+	errCode = C.sr_session_start(p.connection, C.SR_DS_RUNNING, &p.session)
+	if errCode != C.SR_ERR_OK {
+		err := fmt.Errorf("sysrepo-session-error")
+		logger.Errorw(ctx, err.Error(), log.Fields{"errCode": errCode, "errMsg": errorMsg(errCode)})
+
+		_ = p.Stop(ctx)
+
+		return err
+	}
+
+	return nil
+}
+
+//export get_data_cb
+func get_data_cb() {
+	//This function is a callback for the retrieval of data from sysrepo
+	//The "export" comment instructs CGO to create a C function for it
+
+	//As a placeholder, it just reports that a request to get data
+	//has been received from the netconf server
+
+	//TODO: get actual information
+	ctx := context.Background()
+	logger.Info(ctx, ">>>>>>>RECEIVED REQUEST FROM SYSREPO<<<<<<<")
+}
+
+func StartNewPlugin(ctx context.Context) (*SysrepoPlugin, error) {
+	plugin := &SysrepoPlugin{}
+
+	//Open a session to sysrepo
+	err := plugin.createSession(ctx)
+	if err != nil {
+		return nil, err
+	}
+
+	//TODO: could be useful to set it according to the adapter log level
+	C.sr_log_stderr(C.SR_LL_WRN)
+
+	//Set callbacks for events
+
+	//Subscribe with a callback to the request of data on a certain path
+	errCode := C.sr_oper_get_items_subscribe(
+		plugin.session,
+		C.CString(BASE_YANG_MODEL),
+		C.CString(DEVICES_YANG_MODEL+"/*"),
+		C.function(C.get_data_cb_wrapper),
+		C.NULL,
+		C.SR_SUBSCR_CTX_REUSE,
+		&plugin.subscription,
+	)
+	if errCode != C.SR_ERR_OK {
+		err := fmt.Errorf("sysrepo-failed-subscription-to-get-events")
+		logger.Errorw(ctx, err.Error(), log.Fields{"errCode": errCode, "errMsg": errorMsg(errCode)})
+		return nil, err
+	}
+
+	logger.Debug(ctx, "sysrepo-plugin-started")
+
+	return plugin, nil
+}
+
+func (p *SysrepoPlugin) Stop(ctx context.Context) error {
+	var errCode C.int
+
+	//Frees subscription
+	if p.subscription != nil {
+		errCode = C.sr_unsubscribe(p.subscription)
+		if errCode != C.SR_ERR_OK {
+			err := fmt.Errorf("failed-to-close-sysrepo-subscription")
+			logger.Errorw(ctx, err.Error(), log.Fields{"errCode": errCode, "errMsg": errorMsg(errCode)})
+			return err
+		}
+		p.subscription = nil
+	}
+
+	//Frees session
+	if p.session != nil {
+		errCode = C.sr_session_stop(p.session)
+		if errCode != C.SR_ERR_OK {
+			err := fmt.Errorf("failed-to-close-sysrepo-session")
+			logger.Errorw(ctx, err.Error(), log.Fields{"errCode": errCode, "errMsg": errorMsg(errCode)})
+			return err
+		}
+		p.session = nil
+	}
+
+	//Frees connection
+	if p.connection != nil {
+		errCode = C.sr_disconnect(p.connection)
+		if errCode != C.SR_ERR_OK {
+			err := fmt.Errorf("failed-to-close-sysrepo-connection")
+			logger.Errorw(ctx, err.Error(), log.Fields{"errCode": errCode, "errMsg": errorMsg(errCode)})
+			return err
+		}
+		p.connection = nil
+	}
+
+	logger.Debug(ctx, "sysrepo-plugin-stopped")
+
+	return nil
+}
diff --git a/vendor/github.com/golang/protobuf/jsonpb/decode.go b/vendor/github.com/golang/protobuf/jsonpb/decode.go
new file mode 100644
index 0000000..60e82ca
--- /dev/null
+++ b/vendor/github.com/golang/protobuf/jsonpb/decode.go
@@ -0,0 +1,524 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package jsonpb
+
+import (
+	"encoding/json"
+	"errors"
+	"fmt"
+	"io"
+	"math"
+	"reflect"
+	"strconv"
+	"strings"
+	"time"
+
+	"github.com/golang/protobuf/proto"
+	"google.golang.org/protobuf/encoding/protojson"
+	protoV2 "google.golang.org/protobuf/proto"
+	"google.golang.org/protobuf/reflect/protoreflect"
+	"google.golang.org/protobuf/reflect/protoregistry"
+)
+
+const wrapJSONUnmarshalV2 = false
+
+// UnmarshalNext unmarshals the next JSON object from d into m.
+func UnmarshalNext(d *json.Decoder, m proto.Message) error {
+	return new(Unmarshaler).UnmarshalNext(d, m)
+}
+
+// Unmarshal unmarshals a JSON object from r into m.
+func Unmarshal(r io.Reader, m proto.Message) error {
+	return new(Unmarshaler).Unmarshal(r, m)
+}
+
+// UnmarshalString unmarshals a JSON object from s into m.
+func UnmarshalString(s string, m proto.Message) error {
+	return new(Unmarshaler).Unmarshal(strings.NewReader(s), m)
+}
+
+// Unmarshaler is a configurable object for converting from a JSON
+// representation to a protocol buffer object.
+type Unmarshaler struct {
+	// AllowUnknownFields specifies whether to allow messages to contain
+	// unknown JSON fields, as opposed to failing to unmarshal.
+	AllowUnknownFields bool
+
+	// AnyResolver is used to resolve the google.protobuf.Any well-known type.
+	// If unset, the global registry is used by default.
+	AnyResolver AnyResolver
+}
+
+// JSONPBUnmarshaler is implemented by protobuf messages that customize the way
+// they are unmarshaled from JSON. Messages that implement this should also
+// implement JSONPBMarshaler so that the custom format can be produced.
+//
+// The JSON unmarshaling must follow the JSON to proto specification:
+//	https://developers.google.com/protocol-buffers/docs/proto3#json
+//
+// Deprecated: Custom types should implement protobuf reflection instead.
+type JSONPBUnmarshaler interface {
+	UnmarshalJSONPB(*Unmarshaler, []byte) error
+}
+
+// Unmarshal unmarshals a JSON object from r into m.
+func (u *Unmarshaler) Unmarshal(r io.Reader, m proto.Message) error {
+	return u.UnmarshalNext(json.NewDecoder(r), m)
+}
+
+// UnmarshalNext unmarshals the next JSON object from d into m.
+func (u *Unmarshaler) UnmarshalNext(d *json.Decoder, m proto.Message) error {
+	if m == nil {
+		return errors.New("invalid nil message")
+	}
+
+	// Parse the next JSON object from the stream.
+	raw := json.RawMessage{}
+	if err := d.Decode(&raw); err != nil {
+		return err
+	}
+
+	// Check for custom unmarshalers first since they may not properly
+	// implement protobuf reflection that the logic below relies on.
+	if jsu, ok := m.(JSONPBUnmarshaler); ok {
+		return jsu.UnmarshalJSONPB(u, raw)
+	}
+
+	mr := proto.MessageReflect(m)
+
+	// NOTE: For historical reasons, a top-level null is treated as a noop.
+	// This is incorrect, but kept for compatibility.
+	if string(raw) == "null" && mr.Descriptor().FullName() != "google.protobuf.Value" {
+		return nil
+	}
+
+	if wrapJSONUnmarshalV2 {
+		// NOTE: If input message is non-empty, we need to preserve merge semantics
+		// of the old jsonpb implementation. These semantics are not supported by
+		// the protobuf JSON specification.
+		isEmpty := true
+		mr.Range(func(protoreflect.FieldDescriptor, protoreflect.Value) bool {
+			isEmpty = false // at least one iteration implies non-empty
+			return false
+		})
+		if !isEmpty {
+			// Perform unmarshaling into a newly allocated, empty message.
+			mr = mr.New()
+
+			// Use a defer to copy all unmarshaled fields into the original message.
+			dst := proto.MessageReflect(m)
+			defer mr.Range(func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool {
+				dst.Set(fd, v)
+				return true
+			})
+		}
+
+		// Unmarshal using the v2 JSON unmarshaler.
+		opts := protojson.UnmarshalOptions{
+			DiscardUnknown: u.AllowUnknownFields,
+		}
+		if u.AnyResolver != nil {
+			opts.Resolver = anyResolver{u.AnyResolver}
+		}
+		return opts.Unmarshal(raw, mr.Interface())
+	} else {
+		if err := u.unmarshalMessage(mr, raw); err != nil {
+			return err
+		}
+		return protoV2.CheckInitialized(mr.Interface())
+	}
+}
+
+func (u *Unmarshaler) unmarshalMessage(m protoreflect.Message, in []byte) error {
+	md := m.Descriptor()
+	fds := md.Fields()
+
+	if jsu, ok := proto.MessageV1(m.Interface()).(JSONPBUnmarshaler); ok {
+		return jsu.UnmarshalJSONPB(u, in)
+	}
+
+	if string(in) == "null" && md.FullName() != "google.protobuf.Value" {
+		return nil
+	}
+
+	switch wellKnownType(md.FullName()) {
+	case "Any":
+		var jsonObject map[string]json.RawMessage
+		if err := json.Unmarshal(in, &jsonObject); err != nil {
+			return err
+		}
+
+		rawTypeURL, ok := jsonObject["@type"]
+		if !ok {
+			return errors.New("Any JSON doesn't have '@type'")
+		}
+		typeURL, err := unquoteString(string(rawTypeURL))
+		if err != nil {
+			return fmt.Errorf("can't unmarshal Any's '@type': %q", rawTypeURL)
+		}
+		m.Set(fds.ByNumber(1), protoreflect.ValueOfString(typeURL))
+
+		var m2 protoreflect.Message
+		if u.AnyResolver != nil {
+			mi, err := u.AnyResolver.Resolve(typeURL)
+			if err != nil {
+				return err
+			}
+			m2 = proto.MessageReflect(mi)
+		} else {
+			mt, err := protoregistry.GlobalTypes.FindMessageByURL(typeURL)
+			if err != nil {
+				if err == protoregistry.NotFound {
+					return fmt.Errorf("could not resolve Any message type: %v", typeURL)
+				}
+				return err
+			}
+			m2 = mt.New()
+		}
+
+		if wellKnownType(m2.Descriptor().FullName()) != "" {
+			rawValue, ok := jsonObject["value"]
+			if !ok {
+				return errors.New("Any JSON doesn't have 'value'")
+			}
+			if err := u.unmarshalMessage(m2, rawValue); err != nil {
+				return fmt.Errorf("can't unmarshal Any nested proto %v: %v", typeURL, err)
+			}
+		} else {
+			delete(jsonObject, "@type")
+			rawJSON, err := json.Marshal(jsonObject)
+			if err != nil {
+				return fmt.Errorf("can't generate JSON for Any's nested proto to be unmarshaled: %v", err)
+			}
+			if err = u.unmarshalMessage(m2, rawJSON); err != nil {
+				return fmt.Errorf("can't unmarshal Any nested proto %v: %v", typeURL, err)
+			}
+		}
+
+		rawWire, err := protoV2.Marshal(m2.Interface())
+		if err != nil {
+			return fmt.Errorf("can't marshal proto %v into Any.Value: %v", typeURL, err)
+		}
+		m.Set(fds.ByNumber(2), protoreflect.ValueOfBytes(rawWire))
+		return nil
+	case "BoolValue", "BytesValue", "StringValue",
+		"Int32Value", "UInt32Value", "FloatValue",
+		"Int64Value", "UInt64Value", "DoubleValue":
+		fd := fds.ByNumber(1)
+		v, err := u.unmarshalValue(m.NewField(fd), in, fd)
+		if err != nil {
+			return err
+		}
+		m.Set(fd, v)
+		return nil
+	case "Duration":
+		v, err := unquoteString(string(in))
+		if err != nil {
+			return err
+		}
+		d, err := time.ParseDuration(v)
+		if err != nil {
+			return fmt.Errorf("bad Duration: %v", err)
+		}
+
+		sec := d.Nanoseconds() / 1e9
+		nsec := d.Nanoseconds() % 1e9
+		m.Set(fds.ByNumber(1), protoreflect.ValueOfInt64(int64(sec)))
+		m.Set(fds.ByNumber(2), protoreflect.ValueOfInt32(int32(nsec)))
+		return nil
+	case "Timestamp":
+		v, err := unquoteString(string(in))
+		if err != nil {
+			return err
+		}
+		t, err := time.Parse(time.RFC3339Nano, v)
+		if err != nil {
+			return fmt.Errorf("bad Timestamp: %v", err)
+		}
+
+		sec := t.Unix()
+		nsec := t.Nanosecond()
+		m.Set(fds.ByNumber(1), protoreflect.ValueOfInt64(int64(sec)))
+		m.Set(fds.ByNumber(2), protoreflect.ValueOfInt32(int32(nsec)))
+		return nil
+	case "Value":
+		switch {
+		case string(in) == "null":
+			m.Set(fds.ByNumber(1), protoreflect.ValueOfEnum(0))
+		case string(in) == "true":
+			m.Set(fds.ByNumber(4), protoreflect.ValueOfBool(true))
+		case string(in) == "false":
+			m.Set(fds.ByNumber(4), protoreflect.ValueOfBool(false))
+		case hasPrefixAndSuffix('"', in, '"'):
+			s, err := unquoteString(string(in))
+			if err != nil {
+				return fmt.Errorf("unrecognized type for Value %q", in)
+			}
+			m.Set(fds.ByNumber(3), protoreflect.ValueOfString(s))
+		case hasPrefixAndSuffix('[', in, ']'):
+			v := m.Mutable(fds.ByNumber(6))
+			return u.unmarshalMessage(v.Message(), in)
+		case hasPrefixAndSuffix('{', in, '}'):
+			v := m.Mutable(fds.ByNumber(5))
+			return u.unmarshalMessage(v.Message(), in)
+		default:
+			f, err := strconv.ParseFloat(string(in), 0)
+			if err != nil {
+				return fmt.Errorf("unrecognized type for Value %q", in)
+			}
+			m.Set(fds.ByNumber(2), protoreflect.ValueOfFloat64(f))
+		}
+		return nil
+	case "ListValue":
+		var jsonArray []json.RawMessage
+		if err := json.Unmarshal(in, &jsonArray); err != nil {
+			return fmt.Errorf("bad ListValue: %v", err)
+		}
+
+		lv := m.Mutable(fds.ByNumber(1)).List()
+		for _, raw := range jsonArray {
+			ve := lv.NewElement()
+			if err := u.unmarshalMessage(ve.Message(), raw); err != nil {
+				return err
+			}
+			lv.Append(ve)
+		}
+		return nil
+	case "Struct":
+		var jsonObject map[string]json.RawMessage
+		if err := json.Unmarshal(in, &jsonObject); err != nil {
+			return fmt.Errorf("bad StructValue: %v", err)
+		}
+
+		mv := m.Mutable(fds.ByNumber(1)).Map()
+		for key, raw := range jsonObject {
+			kv := protoreflect.ValueOf(key).MapKey()
+			vv := mv.NewValue()
+			if err := u.unmarshalMessage(vv.Message(), raw); err != nil {
+				return fmt.Errorf("bad value in StructValue for key %q: %v", key, err)
+			}
+			mv.Set(kv, vv)
+		}
+		return nil
+	}
+
+	var jsonObject map[string]json.RawMessage
+	if err := json.Unmarshal(in, &jsonObject); err != nil {
+		return err
+	}
+
+	// Handle known fields.
+	for i := 0; i < fds.Len(); i++ {
+		fd := fds.Get(i)
+		if fd.IsWeak() && fd.Message().IsPlaceholder() {
+			continue //  weak reference is not linked in
+		}
+
+		// Search for any raw JSON value associated with this field.
+		var raw json.RawMessage
+		name := string(fd.Name())
+		if fd.Kind() == protoreflect.GroupKind {
+			name = string(fd.Message().Name())
+		}
+		if v, ok := jsonObject[name]; ok {
+			delete(jsonObject, name)
+			raw = v
+		}
+		name = string(fd.JSONName())
+		if v, ok := jsonObject[name]; ok {
+			delete(jsonObject, name)
+			raw = v
+		}
+
+		field := m.NewField(fd)
+		// Unmarshal the field value.
+		if raw == nil || (string(raw) == "null" && !isSingularWellKnownValue(fd) && !isSingularJSONPBUnmarshaler(field, fd)) {
+			continue
+		}
+		v, err := u.unmarshalValue(field, raw, fd)
+		if err != nil {
+			return err
+		}
+		m.Set(fd, v)
+	}
+
+	// Handle extension fields.
+	for name, raw := range jsonObject {
+		if !strings.HasPrefix(name, "[") || !strings.HasSuffix(name, "]") {
+			continue
+		}
+
+		// Resolve the extension field by name.
+		xname := protoreflect.FullName(name[len("[") : len(name)-len("]")])
+		xt, _ := protoregistry.GlobalTypes.FindExtensionByName(xname)
+		if xt == nil && isMessageSet(md) {
+			xt, _ = protoregistry.GlobalTypes.FindExtensionByName(xname.Append("message_set_extension"))
+		}
+		if xt == nil {
+			continue
+		}
+		delete(jsonObject, name)
+		fd := xt.TypeDescriptor()
+		if fd.ContainingMessage().FullName() != m.Descriptor().FullName() {
+			return fmt.Errorf("extension field %q does not extend message %q", xname, m.Descriptor().FullName())
+		}
+
+		field := m.NewField(fd)
+		// Unmarshal the field value.
+		if raw == nil || (string(raw) == "null" && !isSingularWellKnownValue(fd) && !isSingularJSONPBUnmarshaler(field, fd)) {
+			continue
+		}
+		v, err := u.unmarshalValue(field, raw, fd)
+		if err != nil {
+			return err
+		}
+		m.Set(fd, v)
+	}
+
+	if !u.AllowUnknownFields && len(jsonObject) > 0 {
+		for name := range jsonObject {
+			return fmt.Errorf("unknown field %q in %v", name, md.FullName())
+		}
+	}
+	return nil
+}
+
+func isSingularWellKnownValue(fd protoreflect.FieldDescriptor) bool {
+	if md := fd.Message(); md != nil {
+		return md.FullName() == "google.protobuf.Value" && fd.Cardinality() != protoreflect.Repeated
+	}
+	return false
+}
+
+func isSingularJSONPBUnmarshaler(v protoreflect.Value, fd protoreflect.FieldDescriptor) bool {
+	if fd.Message() != nil && fd.Cardinality() != protoreflect.Repeated {
+		_, ok := proto.MessageV1(v.Interface()).(JSONPBUnmarshaler)
+		return ok
+	}
+	return false
+}
+
+func (u *Unmarshaler) unmarshalValue(v protoreflect.Value, in []byte, fd protoreflect.FieldDescriptor) (protoreflect.Value, error) {
+	switch {
+	case fd.IsList():
+		var jsonArray []json.RawMessage
+		if err := json.Unmarshal(in, &jsonArray); err != nil {
+			return v, err
+		}
+		lv := v.List()
+		for _, raw := range jsonArray {
+			ve, err := u.unmarshalSingularValue(lv.NewElement(), raw, fd)
+			if err != nil {
+				return v, err
+			}
+			lv.Append(ve)
+		}
+		return v, nil
+	case fd.IsMap():
+		var jsonObject map[string]json.RawMessage
+		if err := json.Unmarshal(in, &jsonObject); err != nil {
+			return v, err
+		}
+		kfd := fd.MapKey()
+		vfd := fd.MapValue()
+		mv := v.Map()
+		for key, raw := range jsonObject {
+			var kv protoreflect.MapKey
+			if kfd.Kind() == protoreflect.StringKind {
+				kv = protoreflect.ValueOf(key).MapKey()
+			} else {
+				v, err := u.unmarshalSingularValue(kfd.Default(), []byte(key), kfd)
+				if err != nil {
+					return v, err
+				}
+				kv = v.MapKey()
+			}
+
+			vv, err := u.unmarshalSingularValue(mv.NewValue(), raw, vfd)
+			if err != nil {
+				return v, err
+			}
+			mv.Set(kv, vv)
+		}
+		return v, nil
+	default:
+		return u.unmarshalSingularValue(v, in, fd)
+	}
+}
+
+var nonFinite = map[string]float64{
+	`"NaN"`:       math.NaN(),
+	`"Infinity"`:  math.Inf(+1),
+	`"-Infinity"`: math.Inf(-1),
+}
+
+func (u *Unmarshaler) unmarshalSingularValue(v protoreflect.Value, in []byte, fd protoreflect.FieldDescriptor) (protoreflect.Value, error) {
+	switch fd.Kind() {
+	case protoreflect.BoolKind:
+		return unmarshalValue(in, new(bool))
+	case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind:
+		return unmarshalValue(trimQuote(in), new(int32))
+	case protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind:
+		return unmarshalValue(trimQuote(in), new(int64))
+	case protoreflect.Uint32Kind, protoreflect.Fixed32Kind:
+		return unmarshalValue(trimQuote(in), new(uint32))
+	case protoreflect.Uint64Kind, protoreflect.Fixed64Kind:
+		return unmarshalValue(trimQuote(in), new(uint64))
+	case protoreflect.FloatKind:
+		if f, ok := nonFinite[string(in)]; ok {
+			return protoreflect.ValueOfFloat32(float32(f)), nil
+		}
+		return unmarshalValue(trimQuote(in), new(float32))
+	case protoreflect.DoubleKind:
+		if f, ok := nonFinite[string(in)]; ok {
+			return protoreflect.ValueOfFloat64(float64(f)), nil
+		}
+		return unmarshalValue(trimQuote(in), new(float64))
+	case protoreflect.StringKind:
+		return unmarshalValue(in, new(string))
+	case protoreflect.BytesKind:
+		return unmarshalValue(in, new([]byte))
+	case protoreflect.EnumKind:
+		if hasPrefixAndSuffix('"', in, '"') {
+			vd := fd.Enum().Values().ByName(protoreflect.Name(trimQuote(in)))
+			if vd == nil {
+				return v, fmt.Errorf("unknown value %q for enum %s", in, fd.Enum().FullName())
+			}
+			return protoreflect.ValueOfEnum(vd.Number()), nil
+		}
+		return unmarshalValue(in, new(protoreflect.EnumNumber))
+	case protoreflect.MessageKind, protoreflect.GroupKind:
+		err := u.unmarshalMessage(v.Message(), in)
+		return v, err
+	default:
+		panic(fmt.Sprintf("invalid kind %v", fd.Kind()))
+	}
+}
+
+func unmarshalValue(in []byte, v interface{}) (protoreflect.Value, error) {
+	err := json.Unmarshal(in, v)
+	return protoreflect.ValueOf(reflect.ValueOf(v).Elem().Interface()), err
+}
+
+func unquoteString(in string) (out string, err error) {
+	err = json.Unmarshal([]byte(in), &out)
+	return out, err
+}
+
+func hasPrefixAndSuffix(prefix byte, in []byte, suffix byte) bool {
+	if len(in) >= 2 && in[0] == prefix && in[len(in)-1] == suffix {
+		return true
+	}
+	return false
+}
+
+// trimQuote is like unquoteString but simply strips surrounding quotes.
+// This is incorrect, but is behavior done by the legacy implementation.
+func trimQuote(in []byte) []byte {
+	if len(in) >= 2 && in[0] == '"' && in[len(in)-1] == '"' {
+		in = in[1 : len(in)-1]
+	}
+	return in
+}
diff --git a/vendor/github.com/golang/protobuf/jsonpb/encode.go b/vendor/github.com/golang/protobuf/jsonpb/encode.go
new file mode 100644
index 0000000..685c80a
--- /dev/null
+++ b/vendor/github.com/golang/protobuf/jsonpb/encode.go
@@ -0,0 +1,559 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package jsonpb
+
+import (
+	"encoding/json"
+	"errors"
+	"fmt"
+	"io"
+	"math"
+	"reflect"
+	"sort"
+	"strconv"
+	"strings"
+	"time"
+
+	"github.com/golang/protobuf/proto"
+	"google.golang.org/protobuf/encoding/protojson"
+	protoV2 "google.golang.org/protobuf/proto"
+	"google.golang.org/protobuf/reflect/protoreflect"
+	"google.golang.org/protobuf/reflect/protoregistry"
+)
+
+const wrapJSONMarshalV2 = false
+
+// Marshaler is a configurable object for marshaling protocol buffer messages
+// to the specified JSON representation.
+type Marshaler struct {
+	// OrigName specifies whether to use the original protobuf name for fields.
+	OrigName bool
+
+	// EnumsAsInts specifies whether to render enum values as integers,
+	// as opposed to string values.
+	EnumsAsInts bool
+
+	// EmitDefaults specifies whether to render fields with zero values.
+	EmitDefaults bool
+
+	// Indent controls whether the output is compact or not.
+	// If empty, the output is compact JSON. Otherwise, every JSON object
+	// entry and JSON array value will be on its own line.
+	// Each line will be preceded by repeated copies of Indent, where the
+	// number of copies is the current indentation depth.
+	Indent string
+
+	// AnyResolver is used to resolve the google.protobuf.Any well-known type.
+	// If unset, the global registry is used by default.
+	AnyResolver AnyResolver
+}
+
+// JSONPBMarshaler is implemented by protobuf messages that customize the
+// way they are marshaled to JSON. Messages that implement this should also
+// implement JSONPBUnmarshaler so that the custom format can be parsed.
+//
+// The JSON marshaling must follow the proto to JSON specification:
+//	https://developers.google.com/protocol-buffers/docs/proto3#json
+//
+// Deprecated: Custom types should implement protobuf reflection instead.
+type JSONPBMarshaler interface {
+	MarshalJSONPB(*Marshaler) ([]byte, error)
+}
+
+// Marshal serializes a protobuf message as JSON into w.
+func (jm *Marshaler) Marshal(w io.Writer, m proto.Message) error {
+	b, err := jm.marshal(m)
+	if len(b) > 0 {
+		if _, err := w.Write(b); err != nil {
+			return err
+		}
+	}
+	return err
+}
+
+// MarshalToString serializes a protobuf message as JSON in string form.
+func (jm *Marshaler) MarshalToString(m proto.Message) (string, error) {
+	b, err := jm.marshal(m)
+	if err != nil {
+		return "", err
+	}
+	return string(b), nil
+}
+
+func (jm *Marshaler) marshal(m proto.Message) ([]byte, error) {
+	v := reflect.ValueOf(m)
+	if m == nil || (v.Kind() == reflect.Ptr && v.IsNil()) {
+		return nil, errors.New("Marshal called with nil")
+	}
+
+	// Check for custom marshalers first since they may not properly
+	// implement protobuf reflection that the logic below relies on.
+	if jsm, ok := m.(JSONPBMarshaler); ok {
+		return jsm.MarshalJSONPB(jm)
+	}
+
+	if wrapJSONMarshalV2 {
+		opts := protojson.MarshalOptions{
+			UseProtoNames:   jm.OrigName,
+			UseEnumNumbers:  jm.EnumsAsInts,
+			EmitUnpopulated: jm.EmitDefaults,
+			Indent:          jm.Indent,
+		}
+		if jm.AnyResolver != nil {
+			opts.Resolver = anyResolver{jm.AnyResolver}
+		}
+		return opts.Marshal(proto.MessageReflect(m).Interface())
+	} else {
+		// Check for unpopulated required fields first.
+		m2 := proto.MessageReflect(m)
+		if err := protoV2.CheckInitialized(m2.Interface()); err != nil {
+			return nil, err
+		}
+
+		w := jsonWriter{Marshaler: jm}
+		err := w.marshalMessage(m2, "", "")
+		return w.buf, err
+	}
+}
+
+type jsonWriter struct {
+	*Marshaler
+	buf []byte
+}
+
+func (w *jsonWriter) write(s string) {
+	w.buf = append(w.buf, s...)
+}
+
+func (w *jsonWriter) marshalMessage(m protoreflect.Message, indent, typeURL string) error {
+	if jsm, ok := proto.MessageV1(m.Interface()).(JSONPBMarshaler); ok {
+		b, err := jsm.MarshalJSONPB(w.Marshaler)
+		if err != nil {
+			return err
+		}
+		if typeURL != "" {
+			// we are marshaling this object to an Any type
+			var js map[string]*json.RawMessage
+			if err = json.Unmarshal(b, &js); err != nil {
+				return fmt.Errorf("type %T produced invalid JSON: %v", m.Interface(), err)
+			}
+			turl, err := json.Marshal(typeURL)
+			if err != nil {
+				return fmt.Errorf("failed to marshal type URL %q to JSON: %v", typeURL, err)
+			}
+			js["@type"] = (*json.RawMessage)(&turl)
+			if b, err = json.Marshal(js); err != nil {
+				return err
+			}
+		}
+		w.write(string(b))
+		return nil
+	}
+
+	md := m.Descriptor()
+	fds := md.Fields()
+
+	// Handle well-known types.
+	const secondInNanos = int64(time.Second / time.Nanosecond)
+	switch wellKnownType(md.FullName()) {
+	case "Any":
+		return w.marshalAny(m, indent)
+	case "BoolValue", "BytesValue", "StringValue",
+		"Int32Value", "UInt32Value", "FloatValue",
+		"Int64Value", "UInt64Value", "DoubleValue":
+		fd := fds.ByNumber(1)
+		return w.marshalValue(fd, m.Get(fd), indent)
+	case "Duration":
+		const maxSecondsInDuration = 315576000000
+		// "Generated output always contains 0, 3, 6, or 9 fractional digits,
+		//  depending on required precision."
+		s := m.Get(fds.ByNumber(1)).Int()
+		ns := m.Get(fds.ByNumber(2)).Int()
+		if s < -maxSecondsInDuration || s > maxSecondsInDuration {
+			return fmt.Errorf("seconds out of range %v", s)
+		}
+		if ns <= -secondInNanos || ns >= secondInNanos {
+			return fmt.Errorf("ns out of range (%v, %v)", -secondInNanos, secondInNanos)
+		}
+		if (s > 0 && ns < 0) || (s < 0 && ns > 0) {
+			return errors.New("signs of seconds and nanos do not match")
+		}
+		var sign string
+		if s < 0 || ns < 0 {
+			sign, s, ns = "-", -1*s, -1*ns
+		}
+		x := fmt.Sprintf("%s%d.%09d", sign, s, ns)
+		x = strings.TrimSuffix(x, "000")
+		x = strings.TrimSuffix(x, "000")
+		x = strings.TrimSuffix(x, ".000")
+		w.write(fmt.Sprintf(`"%vs"`, x))
+		return nil
+	case "Timestamp":
+		// "RFC 3339, where generated output will always be Z-normalized
+		//  and uses 0, 3, 6 or 9 fractional digits."
+		s := m.Get(fds.ByNumber(1)).Int()
+		ns := m.Get(fds.ByNumber(2)).Int()
+		if ns < 0 || ns >= secondInNanos {
+			return fmt.Errorf("ns out of range [0, %v)", secondInNanos)
+		}
+		t := time.Unix(s, ns).UTC()
+		// time.RFC3339Nano isn't exactly right (we need to get 3/6/9 fractional digits).
+		x := t.Format("2006-01-02T15:04:05.000000000")
+		x = strings.TrimSuffix(x, "000")
+		x = strings.TrimSuffix(x, "000")
+		x = strings.TrimSuffix(x, ".000")
+		w.write(fmt.Sprintf(`"%vZ"`, x))
+		return nil
+	case "Value":
+		// JSON value; which is a null, number, string, bool, object, or array.
+		od := md.Oneofs().Get(0)
+		fd := m.WhichOneof(od)
+		if fd == nil {
+			return errors.New("nil Value")
+		}
+		return w.marshalValue(fd, m.Get(fd), indent)
+	case "Struct", "ListValue":
+		// JSON object or array.
+		fd := fds.ByNumber(1)
+		return w.marshalValue(fd, m.Get(fd), indent)
+	}
+
+	w.write("{")
+	if w.Indent != "" {
+		w.write("\n")
+	}
+
+	firstField := true
+	if typeURL != "" {
+		if err := w.marshalTypeURL(indent, typeURL); err != nil {
+			return err
+		}
+		firstField = false
+	}
+
+	for i := 0; i < fds.Len(); {
+		fd := fds.Get(i)
+		if od := fd.ContainingOneof(); od != nil {
+			fd = m.WhichOneof(od)
+			i += od.Fields().Len()
+			if fd == nil {
+				continue
+			}
+		} else {
+			i++
+		}
+
+		v := m.Get(fd)
+
+		if !m.Has(fd) {
+			if !w.EmitDefaults || fd.ContainingOneof() != nil {
+				continue
+			}
+			if fd.Cardinality() != protoreflect.Repeated && (fd.Message() != nil || fd.Syntax() == protoreflect.Proto2) {
+				v = protoreflect.Value{} // use "null" for singular messages or proto2 scalars
+			}
+		}
+
+		if !firstField {
+			w.writeComma()
+		}
+		if err := w.marshalField(fd, v, indent); err != nil {
+			return err
+		}
+		firstField = false
+	}
+
+	// Handle proto2 extensions.
+	if md.ExtensionRanges().Len() > 0 {
+		// Collect a sorted list of all extension descriptor and values.
+		type ext struct {
+			desc protoreflect.FieldDescriptor
+			val  protoreflect.Value
+		}
+		var exts []ext
+		m.Range(func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool {
+			if fd.IsExtension() {
+				exts = append(exts, ext{fd, v})
+			}
+			return true
+		})
+		sort.Slice(exts, func(i, j int) bool {
+			return exts[i].desc.Number() < exts[j].desc.Number()
+		})
+
+		for _, ext := range exts {
+			if !firstField {
+				w.writeComma()
+			}
+			if err := w.marshalField(ext.desc, ext.val, indent); err != nil {
+				return err
+			}
+			firstField = false
+		}
+	}
+
+	if w.Indent != "" {
+		w.write("\n")
+		w.write(indent)
+	}
+	w.write("}")
+	return nil
+}
+
+func (w *jsonWriter) writeComma() {
+	if w.Indent != "" {
+		w.write(",\n")
+	} else {
+		w.write(",")
+	}
+}
+
+func (w *jsonWriter) marshalAny(m protoreflect.Message, indent string) error {
+	// "If the Any contains a value that has a special JSON mapping,
+	//  it will be converted as follows: {"@type": xxx, "value": yyy}.
+	//  Otherwise, the value will be converted into a JSON object,
+	//  and the "@type" field will be inserted to indicate the actual data type."
+	md := m.Descriptor()
+	typeURL := m.Get(md.Fields().ByNumber(1)).String()
+	rawVal := m.Get(md.Fields().ByNumber(2)).Bytes()
+
+	var m2 protoreflect.Message
+	if w.AnyResolver != nil {
+		mi, err := w.AnyResolver.Resolve(typeURL)
+		if err != nil {
+			return err
+		}
+		m2 = proto.MessageReflect(mi)
+	} else {
+		mt, err := protoregistry.GlobalTypes.FindMessageByURL(typeURL)
+		if err != nil {
+			return err
+		}
+		m2 = mt.New()
+	}
+
+	if err := protoV2.Unmarshal(rawVal, m2.Interface()); err != nil {
+		return err
+	}
+
+	if wellKnownType(m2.Descriptor().FullName()) == "" {
+		return w.marshalMessage(m2, indent, typeURL)
+	}
+
+	w.write("{")
+	if w.Indent != "" {
+		w.write("\n")
+	}
+	if err := w.marshalTypeURL(indent, typeURL); err != nil {
+		return err
+	}
+	w.writeComma()
+	if w.Indent != "" {
+		w.write(indent)
+		w.write(w.Indent)
+		w.write(`"value": `)
+	} else {
+		w.write(`"value":`)
+	}
+	if err := w.marshalMessage(m2, indent+w.Indent, ""); err != nil {
+		return err
+	}
+	if w.Indent != "" {
+		w.write("\n")
+		w.write(indent)
+	}
+	w.write("}")
+	return nil
+}
+
+func (w *jsonWriter) marshalTypeURL(indent, typeURL string) error {
+	if w.Indent != "" {
+		w.write(indent)
+		w.write(w.Indent)
+	}
+	w.write(`"@type":`)
+	if w.Indent != "" {
+		w.write(" ")
+	}
+	b, err := json.Marshal(typeURL)
+	if err != nil {
+		return err
+	}
+	w.write(string(b))
+	return nil
+}
+
+// marshalField writes field description and value to the Writer.
+func (w *jsonWriter) marshalField(fd protoreflect.FieldDescriptor, v protoreflect.Value, indent string) error {
+	if w.Indent != "" {
+		w.write(indent)
+		w.write(w.Indent)
+	}
+	w.write(`"`)
+	switch {
+	case fd.IsExtension():
+		// For message set, use the fname of the message as the extension name.
+		name := string(fd.FullName())
+		if isMessageSet(fd.ContainingMessage()) {
+			name = strings.TrimSuffix(name, ".message_set_extension")
+		}
+
+		w.write("[" + name + "]")
+	case w.OrigName:
+		name := string(fd.Name())
+		if fd.Kind() == protoreflect.GroupKind {
+			name = string(fd.Message().Name())
+		}
+		w.write(name)
+	default:
+		w.write(string(fd.JSONName()))
+	}
+	w.write(`":`)
+	if w.Indent != "" {
+		w.write(" ")
+	}
+	return w.marshalValue(fd, v, indent)
+}
+
+func (w *jsonWriter) marshalValue(fd protoreflect.FieldDescriptor, v protoreflect.Value, indent string) error {
+	switch {
+	case fd.IsList():
+		w.write("[")
+		comma := ""
+		lv := v.List()
+		for i := 0; i < lv.Len(); i++ {
+			w.write(comma)
+			if w.Indent != "" {
+				w.write("\n")
+				w.write(indent)
+				w.write(w.Indent)
+				w.write(w.Indent)
+			}
+			if err := w.marshalSingularValue(fd, lv.Get(i), indent+w.Indent); err != nil {
+				return err
+			}
+			comma = ","
+		}
+		if w.Indent != "" {
+			w.write("\n")
+			w.write(indent)
+			w.write(w.Indent)
+		}
+		w.write("]")
+		return nil
+	case fd.IsMap():
+		kfd := fd.MapKey()
+		vfd := fd.MapValue()
+		mv := v.Map()
+
+		// Collect a sorted list of all map keys and values.
+		type entry struct{ key, val protoreflect.Value }
+		var entries []entry
+		mv.Range(func(k protoreflect.MapKey, v protoreflect.Value) bool {
+			entries = append(entries, entry{k.Value(), v})
+			return true
+		})
+		sort.Slice(entries, func(i, j int) bool {
+			switch kfd.Kind() {
+			case protoreflect.BoolKind:
+				return !entries[i].key.Bool() && entries[j].key.Bool()
+			case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind, protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind:
+				return entries[i].key.Int() < entries[j].key.Int()
+			case protoreflect.Uint32Kind, protoreflect.Fixed32Kind, protoreflect.Uint64Kind, protoreflect.Fixed64Kind:
+				return entries[i].key.Uint() < entries[j].key.Uint()
+			case protoreflect.StringKind:
+				return entries[i].key.String() < entries[j].key.String()
+			default:
+				panic("invalid kind")
+			}
+		})
+
+		w.write(`{`)
+		comma := ""
+		for _, entry := range entries {
+			w.write(comma)
+			if w.Indent != "" {
+				w.write("\n")
+				w.write(indent)
+				w.write(w.Indent)
+				w.write(w.Indent)
+			}
+
+			s := fmt.Sprint(entry.key.Interface())
+			b, err := json.Marshal(s)
+			if err != nil {
+				return err
+			}
+			w.write(string(b))
+
+			w.write(`:`)
+			if w.Indent != "" {
+				w.write(` `)
+			}
+
+			if err := w.marshalSingularValue(vfd, entry.val, indent+w.Indent); err != nil {
+				return err
+			}
+			comma = ","
+		}
+		if w.Indent != "" {
+			w.write("\n")
+			w.write(indent)
+			w.write(w.Indent)
+		}
+		w.write(`}`)
+		return nil
+	default:
+		return w.marshalSingularValue(fd, v, indent)
+	}
+}
+
+func (w *jsonWriter) marshalSingularValue(fd protoreflect.FieldDescriptor, v protoreflect.Value, indent string) error {
+	switch {
+	case !v.IsValid():
+		w.write("null")
+		return nil
+	case fd.Message() != nil:
+		return w.marshalMessage(v.Message(), indent+w.Indent, "")
+	case fd.Enum() != nil:
+		if fd.Enum().FullName() == "google.protobuf.NullValue" {
+			w.write("null")
+			return nil
+		}
+
+		vd := fd.Enum().Values().ByNumber(v.Enum())
+		if vd == nil || w.EnumsAsInts {
+			w.write(strconv.Itoa(int(v.Enum())))
+		} else {
+			w.write(`"` + string(vd.Name()) + `"`)
+		}
+		return nil
+	default:
+		switch v.Interface().(type) {
+		case float32, float64:
+			switch {
+			case math.IsInf(v.Float(), +1):
+				w.write(`"Infinity"`)
+				return nil
+			case math.IsInf(v.Float(), -1):
+				w.write(`"-Infinity"`)
+				return nil
+			case math.IsNaN(v.Float()):
+				w.write(`"NaN"`)
+				return nil
+			}
+		case int64, uint64:
+			w.write(fmt.Sprintf(`"%d"`, v.Interface()))
+			return nil
+		}
+
+		b, err := json.Marshal(v.Interface())
+		if err != nil {
+			return err
+		}
+		w.write(string(b))
+		return nil
+	}
+}
diff --git a/vendor/github.com/golang/protobuf/jsonpb/json.go b/vendor/github.com/golang/protobuf/jsonpb/json.go
new file mode 100644
index 0000000..480e244
--- /dev/null
+++ b/vendor/github.com/golang/protobuf/jsonpb/json.go
@@ -0,0 +1,69 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package jsonpb provides functionality to marshal and unmarshal between a
+// protocol buffer message and JSON. It follows the specification at
+// https://developers.google.com/protocol-buffers/docs/proto3#json.
+//
+// Do not rely on the default behavior of the standard encoding/json package
+// when called on generated message types as it does not operate correctly.
+//
+// Deprecated: Use the "google.golang.org/protobuf/encoding/protojson"
+// package instead.
+package jsonpb
+
+import (
+	"github.com/golang/protobuf/proto"
+	"google.golang.org/protobuf/reflect/protoreflect"
+	"google.golang.org/protobuf/reflect/protoregistry"
+	"google.golang.org/protobuf/runtime/protoimpl"
+)
+
+// AnyResolver takes a type URL, present in an Any message,
+// and resolves it into an instance of the associated message.
+type AnyResolver interface {
+	Resolve(typeURL string) (proto.Message, error)
+}
+
+type anyResolver struct{ AnyResolver }
+
+func (r anyResolver) FindMessageByName(message protoreflect.FullName) (protoreflect.MessageType, error) {
+	return r.FindMessageByURL(string(message))
+}
+
+func (r anyResolver) FindMessageByURL(url string) (protoreflect.MessageType, error) {
+	m, err := r.Resolve(url)
+	if err != nil {
+		return nil, err
+	}
+	return protoimpl.X.MessageTypeOf(m), nil
+}
+
+func (r anyResolver) FindExtensionByName(field protoreflect.FullName) (protoreflect.ExtensionType, error) {
+	return protoregistry.GlobalTypes.FindExtensionByName(field)
+}
+
+func (r anyResolver) FindExtensionByNumber(message protoreflect.FullName, field protoreflect.FieldNumber) (protoreflect.ExtensionType, error) {
+	return protoregistry.GlobalTypes.FindExtensionByNumber(message, field)
+}
+
+func wellKnownType(s protoreflect.FullName) string {
+	if s.Parent() == "google.protobuf" {
+		switch s.Name() {
+		case "Empty", "Any",
+			"BoolValue", "BytesValue", "StringValue",
+			"Int32Value", "UInt32Value", "FloatValue",
+			"Int64Value", "UInt64Value", "DoubleValue",
+			"Duration", "Timestamp",
+			"NullValue", "Struct", "Value", "ListValue":
+			return string(s.Name())
+		}
+	}
+	return ""
+}
+
+func isMessageSet(md protoreflect.MessageDescriptor) bool {
+	ms, ok := md.(interface{ IsMessageSet() bool })
+	return ok && ms.IsMessageSet()
+}
diff --git a/vendor/github.com/golang/protobuf/protoc-gen-go/descriptor/descriptor.pb.go b/vendor/github.com/golang/protobuf/protoc-gen-go/descriptor/descriptor.pb.go
new file mode 100644
index 0000000..63dc057
--- /dev/null
+++ b/vendor/github.com/golang/protobuf/protoc-gen-go/descriptor/descriptor.pb.go
@@ -0,0 +1,200 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// source: github.com/golang/protobuf/protoc-gen-go/descriptor/descriptor.proto
+
+package descriptor
+
+import (
+	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+	descriptorpb "google.golang.org/protobuf/types/descriptorpb"
+	reflect "reflect"
+)
+
+// Symbols defined in public import of google/protobuf/descriptor.proto.
+
+type FieldDescriptorProto_Type = descriptorpb.FieldDescriptorProto_Type
+
+const FieldDescriptorProto_TYPE_DOUBLE = descriptorpb.FieldDescriptorProto_TYPE_DOUBLE
+const FieldDescriptorProto_TYPE_FLOAT = descriptorpb.FieldDescriptorProto_TYPE_FLOAT
+const FieldDescriptorProto_TYPE_INT64 = descriptorpb.FieldDescriptorProto_TYPE_INT64
+const FieldDescriptorProto_TYPE_UINT64 = descriptorpb.FieldDescriptorProto_TYPE_UINT64
+const FieldDescriptorProto_TYPE_INT32 = descriptorpb.FieldDescriptorProto_TYPE_INT32
+const FieldDescriptorProto_TYPE_FIXED64 = descriptorpb.FieldDescriptorProto_TYPE_FIXED64
+const FieldDescriptorProto_TYPE_FIXED32 = descriptorpb.FieldDescriptorProto_TYPE_FIXED32
+const FieldDescriptorProto_TYPE_BOOL = descriptorpb.FieldDescriptorProto_TYPE_BOOL
+const FieldDescriptorProto_TYPE_STRING = descriptorpb.FieldDescriptorProto_TYPE_STRING
+const FieldDescriptorProto_TYPE_GROUP = descriptorpb.FieldDescriptorProto_TYPE_GROUP
+const FieldDescriptorProto_TYPE_MESSAGE = descriptorpb.FieldDescriptorProto_TYPE_MESSAGE
+const FieldDescriptorProto_TYPE_BYTES = descriptorpb.FieldDescriptorProto_TYPE_BYTES
+const FieldDescriptorProto_TYPE_UINT32 = descriptorpb.FieldDescriptorProto_TYPE_UINT32
+const FieldDescriptorProto_TYPE_ENUM = descriptorpb.FieldDescriptorProto_TYPE_ENUM
+const FieldDescriptorProto_TYPE_SFIXED32 = descriptorpb.FieldDescriptorProto_TYPE_SFIXED32
+const FieldDescriptorProto_TYPE_SFIXED64 = descriptorpb.FieldDescriptorProto_TYPE_SFIXED64
+const FieldDescriptorProto_TYPE_SINT32 = descriptorpb.FieldDescriptorProto_TYPE_SINT32
+const FieldDescriptorProto_TYPE_SINT64 = descriptorpb.FieldDescriptorProto_TYPE_SINT64
+
+var FieldDescriptorProto_Type_name = descriptorpb.FieldDescriptorProto_Type_name
+var FieldDescriptorProto_Type_value = descriptorpb.FieldDescriptorProto_Type_value
+
+type FieldDescriptorProto_Label = descriptorpb.FieldDescriptorProto_Label
+
+const FieldDescriptorProto_LABEL_OPTIONAL = descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL
+const FieldDescriptorProto_LABEL_REQUIRED = descriptorpb.FieldDescriptorProto_LABEL_REQUIRED
+const FieldDescriptorProto_LABEL_REPEATED = descriptorpb.FieldDescriptorProto_LABEL_REPEATED
+
+var FieldDescriptorProto_Label_name = descriptorpb.FieldDescriptorProto_Label_name
+var FieldDescriptorProto_Label_value = descriptorpb.FieldDescriptorProto_Label_value
+
+type FileOptions_OptimizeMode = descriptorpb.FileOptions_OptimizeMode
+
+const FileOptions_SPEED = descriptorpb.FileOptions_SPEED
+const FileOptions_CODE_SIZE = descriptorpb.FileOptions_CODE_SIZE
+const FileOptions_LITE_RUNTIME = descriptorpb.FileOptions_LITE_RUNTIME
+
+var FileOptions_OptimizeMode_name = descriptorpb.FileOptions_OptimizeMode_name
+var FileOptions_OptimizeMode_value = descriptorpb.FileOptions_OptimizeMode_value
+
+type FieldOptions_CType = descriptorpb.FieldOptions_CType
+
+const FieldOptions_STRING = descriptorpb.FieldOptions_STRING
+const FieldOptions_CORD = descriptorpb.FieldOptions_CORD
+const FieldOptions_STRING_PIECE = descriptorpb.FieldOptions_STRING_PIECE
+
+var FieldOptions_CType_name = descriptorpb.FieldOptions_CType_name
+var FieldOptions_CType_value = descriptorpb.FieldOptions_CType_value
+
+type FieldOptions_JSType = descriptorpb.FieldOptions_JSType
+
+const FieldOptions_JS_NORMAL = descriptorpb.FieldOptions_JS_NORMAL
+const FieldOptions_JS_STRING = descriptorpb.FieldOptions_JS_STRING
+const FieldOptions_JS_NUMBER = descriptorpb.FieldOptions_JS_NUMBER
+
+var FieldOptions_JSType_name = descriptorpb.FieldOptions_JSType_name
+var FieldOptions_JSType_value = descriptorpb.FieldOptions_JSType_value
+
+type MethodOptions_IdempotencyLevel = descriptorpb.MethodOptions_IdempotencyLevel
+
+const MethodOptions_IDEMPOTENCY_UNKNOWN = descriptorpb.MethodOptions_IDEMPOTENCY_UNKNOWN
+const MethodOptions_NO_SIDE_EFFECTS = descriptorpb.MethodOptions_NO_SIDE_EFFECTS
+const MethodOptions_IDEMPOTENT = descriptorpb.MethodOptions_IDEMPOTENT
+
+var MethodOptions_IdempotencyLevel_name = descriptorpb.MethodOptions_IdempotencyLevel_name
+var MethodOptions_IdempotencyLevel_value = descriptorpb.MethodOptions_IdempotencyLevel_value
+
+type FileDescriptorSet = descriptorpb.FileDescriptorSet
+type FileDescriptorProto = descriptorpb.FileDescriptorProto
+type DescriptorProto = descriptorpb.DescriptorProto
+type ExtensionRangeOptions = descriptorpb.ExtensionRangeOptions
+type FieldDescriptorProto = descriptorpb.FieldDescriptorProto
+type OneofDescriptorProto = descriptorpb.OneofDescriptorProto
+type EnumDescriptorProto = descriptorpb.EnumDescriptorProto
+type EnumValueDescriptorProto = descriptorpb.EnumValueDescriptorProto
+type ServiceDescriptorProto = descriptorpb.ServiceDescriptorProto
+type MethodDescriptorProto = descriptorpb.MethodDescriptorProto
+
+const Default_MethodDescriptorProto_ClientStreaming = descriptorpb.Default_MethodDescriptorProto_ClientStreaming
+const Default_MethodDescriptorProto_ServerStreaming = descriptorpb.Default_MethodDescriptorProto_ServerStreaming
+
+type FileOptions = descriptorpb.FileOptions
+
+const Default_FileOptions_JavaMultipleFiles = descriptorpb.Default_FileOptions_JavaMultipleFiles
+const Default_FileOptions_JavaStringCheckUtf8 = descriptorpb.Default_FileOptions_JavaStringCheckUtf8
+const Default_FileOptions_OptimizeFor = descriptorpb.Default_FileOptions_OptimizeFor
+const Default_FileOptions_CcGenericServices = descriptorpb.Default_FileOptions_CcGenericServices
+const Default_FileOptions_JavaGenericServices = descriptorpb.Default_FileOptions_JavaGenericServices
+const Default_FileOptions_PyGenericServices = descriptorpb.Default_FileOptions_PyGenericServices
+const Default_FileOptions_PhpGenericServices = descriptorpb.Default_FileOptions_PhpGenericServices
+const Default_FileOptions_Deprecated = descriptorpb.Default_FileOptions_Deprecated
+const Default_FileOptions_CcEnableArenas = descriptorpb.Default_FileOptions_CcEnableArenas
+
+type MessageOptions = descriptorpb.MessageOptions
+
+const Default_MessageOptions_MessageSetWireFormat = descriptorpb.Default_MessageOptions_MessageSetWireFormat
+const Default_MessageOptions_NoStandardDescriptorAccessor = descriptorpb.Default_MessageOptions_NoStandardDescriptorAccessor
+const Default_MessageOptions_Deprecated = descriptorpb.Default_MessageOptions_Deprecated
+
+type FieldOptions = descriptorpb.FieldOptions
+
+const Default_FieldOptions_Ctype = descriptorpb.Default_FieldOptions_Ctype
+const Default_FieldOptions_Jstype = descriptorpb.Default_FieldOptions_Jstype
+const Default_FieldOptions_Lazy = descriptorpb.Default_FieldOptions_Lazy
+const Default_FieldOptions_Deprecated = descriptorpb.Default_FieldOptions_Deprecated
+const Default_FieldOptions_Weak = descriptorpb.Default_FieldOptions_Weak
+
+type OneofOptions = descriptorpb.OneofOptions
+type EnumOptions = descriptorpb.EnumOptions
+
+const Default_EnumOptions_Deprecated = descriptorpb.Default_EnumOptions_Deprecated
+
+type EnumValueOptions = descriptorpb.EnumValueOptions
+
+const Default_EnumValueOptions_Deprecated = descriptorpb.Default_EnumValueOptions_Deprecated
+
+type ServiceOptions = descriptorpb.ServiceOptions
+
+const Default_ServiceOptions_Deprecated = descriptorpb.Default_ServiceOptions_Deprecated
+
+type MethodOptions = descriptorpb.MethodOptions
+
+const Default_MethodOptions_Deprecated = descriptorpb.Default_MethodOptions_Deprecated
+const Default_MethodOptions_IdempotencyLevel = descriptorpb.Default_MethodOptions_IdempotencyLevel
+
+type UninterpretedOption = descriptorpb.UninterpretedOption
+type SourceCodeInfo = descriptorpb.SourceCodeInfo
+type GeneratedCodeInfo = descriptorpb.GeneratedCodeInfo
+type DescriptorProto_ExtensionRange = descriptorpb.DescriptorProto_ExtensionRange
+type DescriptorProto_ReservedRange = descriptorpb.DescriptorProto_ReservedRange
+type EnumDescriptorProto_EnumReservedRange = descriptorpb.EnumDescriptorProto_EnumReservedRange
+type UninterpretedOption_NamePart = descriptorpb.UninterpretedOption_NamePart
+type SourceCodeInfo_Location = descriptorpb.SourceCodeInfo_Location
+type GeneratedCodeInfo_Annotation = descriptorpb.GeneratedCodeInfo_Annotation
+
+var File_github_com_golang_protobuf_protoc_gen_go_descriptor_descriptor_proto protoreflect.FileDescriptor
+
+var file_github_com_golang_protobuf_protoc_gen_go_descriptor_descriptor_proto_rawDesc = []byte{
+	0x0a, 0x44, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c,
+	0x61, 0x6e, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x72, 0x6f,
+	0x74, 0x6f, 0x63, 0x2d, 0x67, 0x65, 0x6e, 0x2d, 0x67, 0x6f, 0x2f, 0x64, 0x65, 0x73, 0x63, 0x72,
+	0x69, 0x70, 0x74, 0x6f, 0x72, 0x2f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72,
+	0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x20, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70,
+	0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74,
+	0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x42, 0x40, 0x5a, 0x3e, 0x67, 0x69, 0x74, 0x68,
+	0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2f, 0x70, 0x72,
+	0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x2d, 0x67, 0x65,
+	0x6e, 0x2d, 0x67, 0x6f, 0x2f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x3b,
+	0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x00, 0x62, 0x06, 0x70, 0x72,
+	0x6f, 0x74, 0x6f, 0x32,
+}
+
+var file_github_com_golang_protobuf_protoc_gen_go_descriptor_descriptor_proto_goTypes = []interface{}{}
+var file_github_com_golang_protobuf_protoc_gen_go_descriptor_descriptor_proto_depIdxs = []int32{
+	0, // [0:0] is the sub-list for method output_type
+	0, // [0:0] is the sub-list for method input_type
+	0, // [0:0] is the sub-list for extension type_name
+	0, // [0:0] is the sub-list for extension extendee
+	0, // [0:0] is the sub-list for field type_name
+}
+
+func init() { file_github_com_golang_protobuf_protoc_gen_go_descriptor_descriptor_proto_init() }
+func file_github_com_golang_protobuf_protoc_gen_go_descriptor_descriptor_proto_init() {
+	if File_github_com_golang_protobuf_protoc_gen_go_descriptor_descriptor_proto != nil {
+		return
+	}
+	type x struct{}
+	out := protoimpl.TypeBuilder{
+		File: protoimpl.DescBuilder{
+			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+			RawDescriptor: file_github_com_golang_protobuf_protoc_gen_go_descriptor_descriptor_proto_rawDesc,
+			NumEnums:      0,
+			NumMessages:   0,
+			NumExtensions: 0,
+			NumServices:   0,
+		},
+		GoTypes:           file_github_com_golang_protobuf_protoc_gen_go_descriptor_descriptor_proto_goTypes,
+		DependencyIndexes: file_github_com_golang_protobuf_protoc_gen_go_descriptor_descriptor_proto_depIdxs,
+	}.Build()
+	File_github_com_golang_protobuf_protoc_gen_go_descriptor_descriptor_proto = out.File
+	file_github_com_golang_protobuf_protoc_gen_go_descriptor_descriptor_proto_rawDesc = nil
+	file_github_com_golang_protobuf_protoc_gen_go_descriptor_descriptor_proto_goTypes = nil
+	file_github_com_golang_protobuf_protoc_gen_go_descriptor_descriptor_proto_depIdxs = nil
+}
diff --git a/vendor/github.com/golang/protobuf/ptypes/struct/struct.pb.go b/vendor/github.com/golang/protobuf/ptypes/struct/struct.pb.go
new file mode 100644
index 0000000..8d82abe
--- /dev/null
+++ b/vendor/github.com/golang/protobuf/ptypes/struct/struct.pb.go
@@ -0,0 +1,78 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// source: github.com/golang/protobuf/ptypes/struct/struct.proto
+
+package structpb
+
+import (
+	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+	structpb "google.golang.org/protobuf/types/known/structpb"
+	reflect "reflect"
+)
+
+// Symbols defined in public import of google/protobuf/struct.proto.
+
+type NullValue = structpb.NullValue
+
+const NullValue_NULL_VALUE = structpb.NullValue_NULL_VALUE
+
+var NullValue_name = structpb.NullValue_name
+var NullValue_value = structpb.NullValue_value
+
+type Struct = structpb.Struct
+type Value = structpb.Value
+type Value_NullValue = structpb.Value_NullValue
+type Value_NumberValue = structpb.Value_NumberValue
+type Value_StringValue = structpb.Value_StringValue
+type Value_BoolValue = structpb.Value_BoolValue
+type Value_StructValue = structpb.Value_StructValue
+type Value_ListValue = structpb.Value_ListValue
+type ListValue = structpb.ListValue
+
+var File_github_com_golang_protobuf_ptypes_struct_struct_proto protoreflect.FileDescriptor
+
+var file_github_com_golang_protobuf_ptypes_struct_struct_proto_rawDesc = []byte{
+	0x0a, 0x35, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c,
+	0x61, 0x6e, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x74, 0x79,
+	0x70, 0x65, 0x73, 0x2f, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x2f, 0x73, 0x74, 0x72, 0x75, 0x63,
+	0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f,
+	0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x2e,
+	0x70, 0x72, 0x6f, 0x74, 0x6f, 0x42, 0x33, 0x5a, 0x31, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e,
+	0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+	0x62, 0x75, 0x66, 0x2f, 0x70, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x73, 0x74, 0x72, 0x75, 0x63,
+	0x74, 0x3b, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x70, 0x62, 0x50, 0x00, 0x62, 0x06, 0x70, 0x72,
+	0x6f, 0x74, 0x6f, 0x33,
+}
+
+var file_github_com_golang_protobuf_ptypes_struct_struct_proto_goTypes = []interface{}{}
+var file_github_com_golang_protobuf_ptypes_struct_struct_proto_depIdxs = []int32{
+	0, // [0:0] is the sub-list for method output_type
+	0, // [0:0] is the sub-list for method input_type
+	0, // [0:0] is the sub-list for extension type_name
+	0, // [0:0] is the sub-list for extension extendee
+	0, // [0:0] is the sub-list for field type_name
+}
+
+func init() { file_github_com_golang_protobuf_ptypes_struct_struct_proto_init() }
+func file_github_com_golang_protobuf_ptypes_struct_struct_proto_init() {
+	if File_github_com_golang_protobuf_ptypes_struct_struct_proto != nil {
+		return
+	}
+	type x struct{}
+	out := protoimpl.TypeBuilder{
+		File: protoimpl.DescBuilder{
+			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+			RawDescriptor: file_github_com_golang_protobuf_ptypes_struct_struct_proto_rawDesc,
+			NumEnums:      0,
+			NumMessages:   0,
+			NumExtensions: 0,
+			NumServices:   0,
+		},
+		GoTypes:           file_github_com_golang_protobuf_ptypes_struct_struct_proto_goTypes,
+		DependencyIndexes: file_github_com_golang_protobuf_ptypes_struct_struct_proto_depIdxs,
+	}.Build()
+	File_github_com_golang_protobuf_ptypes_struct_struct_proto = out.File
+	file_github_com_golang_protobuf_ptypes_struct_struct_proto_rawDesc = nil
+	file_github_com_golang_protobuf_ptypes_struct_struct_proto_goTypes = nil
+	file_github_com_golang_protobuf_ptypes_struct_struct_proto_depIdxs = nil
+}
diff --git a/vendor/github.com/golang/protobuf/ptypes/wrappers/wrappers.pb.go b/vendor/github.com/golang/protobuf/ptypes/wrappers/wrappers.pb.go
new file mode 100644
index 0000000..cc40f27
--- /dev/null
+++ b/vendor/github.com/golang/protobuf/ptypes/wrappers/wrappers.pb.go
@@ -0,0 +1,71 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// source: github.com/golang/protobuf/ptypes/wrappers/wrappers.proto
+
+package wrappers
+
+import (
+	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+	wrapperspb "google.golang.org/protobuf/types/known/wrapperspb"
+	reflect "reflect"
+)
+
+// Symbols defined in public import of google/protobuf/wrappers.proto.
+
+type DoubleValue = wrapperspb.DoubleValue
+type FloatValue = wrapperspb.FloatValue
+type Int64Value = wrapperspb.Int64Value
+type UInt64Value = wrapperspb.UInt64Value
+type Int32Value = wrapperspb.Int32Value
+type UInt32Value = wrapperspb.UInt32Value
+type BoolValue = wrapperspb.BoolValue
+type StringValue = wrapperspb.StringValue
+type BytesValue = wrapperspb.BytesValue
+
+var File_github_com_golang_protobuf_ptypes_wrappers_wrappers_proto protoreflect.FileDescriptor
+
+var file_github_com_golang_protobuf_ptypes_wrappers_wrappers_proto_rawDesc = []byte{
+	0x0a, 0x39, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c,
+	0x61, 0x6e, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x74, 0x79,
+	0x70, 0x65, 0x73, 0x2f, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x73, 0x2f, 0x77, 0x72, 0x61,
+	0x70, 0x70, 0x65, 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1e, 0x67, 0x6f, 0x6f,
+	0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x77, 0x72, 0x61,
+	0x70, 0x70, 0x65, 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x42, 0x35, 0x5a, 0x33, 0x67,
+	0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67,
+	0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x74, 0x79, 0x70, 0x65, 0x73,
+	0x2f, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x73, 0x3b, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65,
+	0x72, 0x73, 0x50, 0x00, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+}
+
+var file_github_com_golang_protobuf_ptypes_wrappers_wrappers_proto_goTypes = []interface{}{}
+var file_github_com_golang_protobuf_ptypes_wrappers_wrappers_proto_depIdxs = []int32{
+	0, // [0:0] is the sub-list for method output_type
+	0, // [0:0] is the sub-list for method input_type
+	0, // [0:0] is the sub-list for extension type_name
+	0, // [0:0] is the sub-list for extension extendee
+	0, // [0:0] is the sub-list for field type_name
+}
+
+func init() { file_github_com_golang_protobuf_ptypes_wrappers_wrappers_proto_init() }
+func file_github_com_golang_protobuf_ptypes_wrappers_wrappers_proto_init() {
+	if File_github_com_golang_protobuf_ptypes_wrappers_wrappers_proto != nil {
+		return
+	}
+	type x struct{}
+	out := protoimpl.TypeBuilder{
+		File: protoimpl.DescBuilder{
+			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+			RawDescriptor: file_github_com_golang_protobuf_ptypes_wrappers_wrappers_proto_rawDesc,
+			NumEnums:      0,
+			NumMessages:   0,
+			NumExtensions: 0,
+			NumServices:   0,
+		},
+		GoTypes:           file_github_com_golang_protobuf_ptypes_wrappers_wrappers_proto_goTypes,
+		DependencyIndexes: file_github_com_golang_protobuf_ptypes_wrappers_wrappers_proto_depIdxs,
+	}.Build()
+	File_github_com_golang_protobuf_ptypes_wrappers_wrappers_proto = out.File
+	file_github_com_golang_protobuf_ptypes_wrappers_wrappers_proto_rawDesc = nil
+	file_github_com_golang_protobuf_ptypes_wrappers_wrappers_proto_goTypes = nil
+	file_github_com_golang_protobuf_ptypes_wrappers_wrappers_proto_depIdxs = nil
+}
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/.gitignore b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/.gitignore
new file mode 100644
index 0000000..826caa3
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/.gitignore
@@ -0,0 +1,204 @@
+# Created by .ignore support plugin (hsz.mobi)
+### Go template
+# Compiled Object files, Static and Dynamic libs (Shared Objects)
+*.o
+*.a
+*.so
+
+# Folders
+_obj
+_test
+
+# Architecture specific extensions/prefixes
+*.[568vq]
+[568vq].out
+
+*.cgo1.go
+*.cgo2.c
+_cgo_defun.c
+_cgo_gotypes.go
+_cgo_export.*
+
+_testmain.go
+
+*.exe
+*.test
+*.prof
+### Windows template
+# Windows image file caches
+Thumbs.db
+ehthumbs.db
+
+# Folder config file
+Desktop.ini
+
+# Recycle Bin used on file shares
+$RECYCLE.BIN/
+
+# Windows Installer files
+*.cab
+*.msi
+*.msm
+*.msp
+
+# Windows shortcuts
+*.lnk
+### Kate template
+# Swap Files #
+.*.kate-swp
+.swp.*
+### SublimeText template
+# cache files for sublime text
+*.tmlanguage.cache
+*.tmPreferences.cache
+*.stTheme.cache
+
+# workspace files are user-specific
+*.sublime-workspace
+
+# project files should be checked into the repository, unless a significant
+# proportion of contributors will probably not be using SublimeText
+# *.sublime-project
+
+# sftp configuration file
+sftp-config.json
+### Linux template
+*~
+
+# temporary files which can be created if a process still has a handle open of a deleted file
+.fuse_hidden*
+
+# KDE directory preferences
+.directory
+
+# Linux trash folder which might appear on any partition or disk
+.Trash-*
+### JetBrains template
+# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
+# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
+
+# User-specific stuff:
+.idea
+.idea/tasks.xml
+.idea/dictionaries
+.idea/vcs.xml
+.idea/jsLibraryMappings.xml
+
+# Sensitive or high-churn files:
+.idea/dataSources.ids
+.idea/dataSources.xml
+.idea/dataSources.local.xml
+.idea/sqlDataSources.xml
+.idea/dynamic.xml
+.idea/uiDesigner.xml
+
+# Gradle:
+.idea/gradle.xml
+.idea/libraries
+
+# Mongo Explorer plugin:
+.idea/mongoSettings.xml
+
+## File-based project format:
+*.iws
+
+## Plugin-specific files:
+
+# IntelliJ
+/out/
+
+# mpeltonen/sbt-idea plugin
+.idea_modules/
+
+# JIRA plugin
+atlassian-ide-plugin.xml
+
+# Crashlytics plugin (for Android Studio and IntelliJ)
+com_crashlytics_export_strings.xml
+crashlytics.properties
+crashlytics-build.properties
+fabric.properties
+### Xcode template
+# Xcode
+#
+# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
+
+## Build generated
+build/
+DerivedData/
+
+## Various settings
+*.pbxuser
+!default.pbxuser
+*.mode1v3
+!default.mode1v3
+*.mode2v3
+!default.mode2v3
+*.perspectivev3
+!default.perspectivev3
+xcuserdata/
+
+## Other
+*.moved-aside
+*.xccheckout
+*.xcscmblueprint
+### Eclipse template
+
+.metadata
+bin/
+tmp/
+*.tmp
+*.bak
+*.swp
+*~.nib
+local.properties
+.settings/
+.loadpath
+.recommenders
+
+# Eclipse Core
+.project
+
+# External tool builders
+.externalToolBuilders/
+
+# Locally stored "Eclipse launch configurations"
+*.launch
+
+# PyDev specific (Python IDE for Eclipse)
+*.pydevproject
+
+# CDT-specific (C/C++ Development Tooling)
+.cproject
+
+# JDT-specific (Eclipse Java Development Tools)
+.classpath
+
+# Java annotation processor (APT)
+.factorypath
+
+# PDT-specific (PHP Development Tools)
+.buildpath
+
+# sbteclipse plugin
+.target
+
+# Tern plugin
+.tern-project
+
+# TeXlipse plugin
+.texlipse
+
+# STS (Spring Tool Suite)
+.springBeans
+
+# Code Recommenders
+.recommenders/
+
+
+coverage.txt
+
+#vendor
+vendor/
+
+.envrc
\ No newline at end of file
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/.travis.yml b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/.travis.yml
new file mode 100644
index 0000000..fc198d8
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/.travis.yml
@@ -0,0 +1,16 @@
+sudo: false
+language: go
+go:
+  - 1.13.x
+  - 1.14.x
+  - 1.15.x
+
+env:
+  global:
+    - GO111MODULE=on
+
+script:
+ - make test
+
+after_success:
+  - bash <(curl -s https://codecov.io/bash)
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/CHANGELOG.md b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/CHANGELOG.md
new file mode 100644
index 0000000..6eeb7e2
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/CHANGELOG.md
@@ -0,0 +1,51 @@
+# Changelog
+All notable changes to this project will be documented in this file.
+
+The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
+and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
+
+Types of changes:
+- `Added` for new features.
+- `Changed` for changes in existing functionality.
+- `Deprecated` for soon-to-be removed features.
+- `Removed` for now removed features.
+- `Fixed` for any bug fixes.
+- `Security` in case of vulnerabilities.
+
+## [Unreleased]
+
+### Added
+
+- [#223](https://github.com/grpc-ecosystem/go-grpc-middleware/pull/223) Add go-kit logging middleware - [adrien-f](https://github.com/adrien-f)
+
+## [v1.1.0] - 2019-09-12
+### Added
+- [#226](https://github.com/grpc-ecosystem/go-grpc-middleware/pull/226) Support for go modules.
+- [#221](https://github.com/grpc-ecosystem/go-grpc-middleware/pull/221) logging/zap add support for gRPC LoggerV2  - [kush-patel-hs](https://github.com/kush-patel-hs)
+- [#181](https://github.com/grpc-ecosystem/go-grpc-middleware/pull/181) Rate Limit support - [ceshihao](https://github.com/ceshihao)
+- [#161](https://github.com/grpc-ecosystem/go-grpc-middleware/pull/161) Retry on server stream call - [lonnblad](https://github.com/lonnblad)
+- [#152](https://github.com/grpc-ecosystem/go-grpc-middleware/pull/152) Exponential backoff functions - [polyfloyd](https://github.com/polyfloyd)
+- [#147](https://github.com/grpc-ecosystem/go-grpc-middleware/pull/147) Jaeger support for ctxtags extraction - [vporoshok](https://github.com/vporoshok)
+- [#184](https://github.com/grpc-ecosystem/go-grpc-middleware/pull/184) ctxTags identifies if the call was sampled
+
+### Deprecated
+- [#201](https://github.com/grpc-ecosystem/go-grpc-middleware/pull/201) `golang.org/x/net/context` - [houz42](https://github.com/houz42)
+- [#183](https://github.com/grpc-ecosystem/go-grpc-middleware/pull/183) Documentation Generation in favour of <godoc.org>.
+
+### Fixed
+- [172](https://github.com/grpc-ecosystem/go-grpc-middleware/pull/172) Passing ctx into retry and recover - [johanbrandhorst](https://github.com/johanbrandhorst)
+- Numerious documentation fixes.
+
+## v1.0.0 - 2018-05-08
+### Added
+- grpc_auth 
+- grpc_ctxtags
+- grpc_zap
+- grpc_logrus
+- grpc_opentracing
+- grpc_retry
+- grpc_validator
+- grpc_recovery
+
+[Unreleased]: https://github.com/grpc-ecosystem/go-grpc-middleware/compare/v1.1.0...HEAD 
+[v1.1.0]: https://github.com/grpc-ecosystem/go-grpc-middleware/compare/v1.0.0...v1.1.0 
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/CONTRIBUTING.md b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/CONTRIBUTING.md
new file mode 100644
index 0000000..dd52ab8
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/CONTRIBUTING.md
@@ -0,0 +1,20 @@
+# Contributing
+
+We would love to have people submit pull requests and help make `grpc-ecosystem/go-grpc-middleware` even better 👍.
+
+Fork, then clone the repo:
+
+```bash
+git clone git@github.com:your-username/go-grpc-middleware.git
+```    
+
+Before checking in please run the following:
+
+```bash
+make all
+```
+
+This will `vet`, `fmt`, regenerate documentation and run all tests.
+
+
+Push to your fork and open a pull request.
\ No newline at end of file
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/LICENSE b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/LICENSE
new file mode 100644
index 0000000..b2b0650
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/LICENSE
@@ -0,0 +1,201 @@
+                 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.
\ No newline at end of file
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/README.md b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/README.md
new file mode 100644
index 0000000..814e155
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/README.md
@@ -0,0 +1,86 @@
+# Go gRPC Middleware
+
+[![Travis Build](https://travis-ci.org/grpc-ecosystem/go-grpc-middleware.svg?branch=master)](https://travis-ci.org/grpc-ecosystem/go-grpc-middleware)
+[![Go Report Card](https://goreportcard.com/badge/github.com/grpc-ecosystem/go-grpc-middleware)](https://goreportcard.com/report/github.com/grpc-ecosystem/go-grpc-middleware)
+[![GoDoc](http://img.shields.io/badge/GoDoc-Reference-blue.svg)](https://godoc.org/github.com/grpc-ecosystem/go-grpc-middleware)
+[![SourceGraph](https://sourcegraph.com/github.com/grpc-ecosystem/go-grpc-middleware/-/badge.svg)](https://sourcegraph.com/github.com/grpc-ecosystem/go-grpc-middleware/?badge)
+[![codecov](https://codecov.io/gh/grpc-ecosystem/go-grpc-middleware/branch/master/graph/badge.svg)](https://codecov.io/gh/grpc-ecosystem/go-grpc-middleware)
+[![Apache 2.0 License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](LICENSE)
+[![quality: production](https://img.shields.io/badge/quality-production-orange.svg)](#status)
+[![Slack](https://img.shields.io/badge/slack-%23grpc--middleware-brightgreen)](https://slack.com/share/IRUQCFC23/9Tm7hxRFVKKNoajQfMOcUiIk/enQtODc4ODI4NTIyMDcxLWM5NDA0ZTE4Njg5YjRjYWZkMTI5MzQwNDY3YzBjMzE1YzdjOGM5ZjI1NDNiM2JmNzI2YjM5ODE5OTRiNTEyOWE)
+
+[gRPC Go](https://github.com/grpc/grpc-go) Middleware: interceptors, helpers, utilities.
+
+## Middleware
+
+[gRPC Go](https://github.com/grpc/grpc-go) recently acquired support for
+Interceptors, i.e. [middleware](https://medium.com/@matryer/writing-middleware-in-golang-and-how-go-makes-it-so-much-fun-4375c1246e81#.gv7tdlghs) 
+that is executed either on the gRPC Server before the request is passed onto the user's application logic, or on the gRPC client around the user call. It is a perfect way to implement
+common patterns: auth, logging, message, validation, retries or monitoring.
+
+These are generic building blocks that make it easy to build multiple microservices easily.
+The purpose of this repository is to act as a go-to point for such reusable functionality. It contains
+some of them itself, but also will link to useful external repos.
+
+`grpc_middleware` itself provides support for chaining interceptors, here's an example:
+
+```go
+import "github.com/grpc-ecosystem/go-grpc-middleware"
+
+myServer := grpc.NewServer(
+    grpc.StreamInterceptor(grpc_middleware.ChainStreamServer(
+        grpc_recovery.StreamServerInterceptor(),
+        grpc_ctxtags.StreamServerInterceptor(),
+        grpc_opentracing.StreamServerInterceptor(),
+        grpc_prometheus.StreamServerInterceptor,
+        grpc_zap.StreamServerInterceptor(zapLogger),
+        grpc_auth.StreamServerInterceptor(myAuthFunction),
+    )),
+    grpc.UnaryInterceptor(grpc_middleware.ChainUnaryServer(
+        grpc_recovery.UnaryServerInterceptor(),
+        grpc_ctxtags.UnaryServerInterceptor(),
+        grpc_opentracing.UnaryServerInterceptor(),
+        grpc_prometheus.UnaryServerInterceptor,
+        grpc_zap.UnaryServerInterceptor(zapLogger),
+        grpc_auth.UnaryServerInterceptor(myAuthFunction),
+    )),
+)
+```
+
+## Interceptors
+
+*Please send a PR to add new interceptors or middleware to this list*
+
+#### Auth
+   * [`grpc_auth`](auth) - a customizable (via `AuthFunc`) piece of auth middleware 
+
+#### Logging
+   * [`grpc_ctxtags`](tags/) - a library that adds a `Tag` map to context, with data populated from request body
+   * [`grpc_zap`](logging/zap/) - integration of [zap](https://github.com/uber-go/zap) logging library into gRPC handlers.
+   * [`grpc_logrus`](logging/logrus/) - integration of [logrus](https://github.com/sirupsen/logrus) logging library into gRPC handlers.
+   * [`grpc_kit`](logging/kit/) - integration of [go-kit](https://github.com/go-kit/kit/tree/master/log) logging library into gRPC handlers.
+   * [`grpc_grpc_logsettable`](logging/settable/) - a wrapper around `grpclog.LoggerV2` that allows to replace loggers in runtime (thread-safe).
+
+#### Monitoring
+   * [`grpc_prometheus`⚡](https://github.com/grpc-ecosystem/go-grpc-prometheus) - Prometheus client-side and server-side monitoring middleware
+   * [`otgrpc`⚡](https://github.com/grpc-ecosystem/grpc-opentracing/tree/master/go/otgrpc) - [OpenTracing](http://opentracing.io/) client-side and server-side interceptors
+   * [`grpc_opentracing`](tracing/opentracing) - [OpenTracing](http://opentracing.io/) client-side and server-side interceptors with support for streaming and handler-returned tags
+
+#### Client
+   * [`grpc_retry`](retry/) - a generic gRPC response code retry mechanism, client-side middleware
+
+#### Server
+   * [`grpc_validator`](validator/) - codegen inbound message validation from `.proto` options
+   * [`grpc_recovery`](recovery/) - turn panics into gRPC errors
+   * [`ratelimit`](ratelimit/) - grpc rate limiting by your own limiter
+
+
+## Status
+
+This code has been running in *production* since May 2016 as the basis of the gRPC micro services stack at [Improbable](https://improbable.io).
+
+Additional tooling will be added, and contributions are welcome.
+
+## License
+
+`go-grpc-middleware` is released under the Apache 2.0 license. See the [LICENSE](LICENSE) file for details.
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/chain.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/chain.go
new file mode 100644
index 0000000..ea3738b
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/chain.go
@@ -0,0 +1,120 @@
+// Copyright 2016 Michal Witkowski. All Rights Reserved.
+// See LICENSE for licensing terms.
+
+// gRPC Server Interceptor chaining middleware.
+
+package grpc_middleware
+
+import (
+	"context"
+
+	"google.golang.org/grpc"
+)
+
+// ChainUnaryServer creates a single interceptor out of a chain of many interceptors.
+//
+// Execution is done in left-to-right order, including passing of context.
+// For example ChainUnaryServer(one, two, three) will execute one before two before three, and three
+// will see context changes of one and two.
+func ChainUnaryServer(interceptors ...grpc.UnaryServerInterceptor) grpc.UnaryServerInterceptor {
+	n := len(interceptors)
+
+	return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
+		chainer := func(currentInter grpc.UnaryServerInterceptor, currentHandler grpc.UnaryHandler) grpc.UnaryHandler {
+			return func(currentCtx context.Context, currentReq interface{}) (interface{}, error) {
+				return currentInter(currentCtx, currentReq, info, currentHandler)
+			}
+		}
+
+		chainedHandler := handler
+		for i := n - 1; i >= 0; i-- {
+			chainedHandler = chainer(interceptors[i], chainedHandler)
+		}
+
+		return chainedHandler(ctx, req)
+	}
+}
+
+// ChainStreamServer creates a single interceptor out of a chain of many interceptors.
+//
+// Execution is done in left-to-right order, including passing of context.
+// For example ChainUnaryServer(one, two, three) will execute one before two before three.
+// If you want to pass context between interceptors, use WrapServerStream.
+func ChainStreamServer(interceptors ...grpc.StreamServerInterceptor) grpc.StreamServerInterceptor {
+	n := len(interceptors)
+
+	return func(srv interface{}, ss grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error {
+		chainer := func(currentInter grpc.StreamServerInterceptor, currentHandler grpc.StreamHandler) grpc.StreamHandler {
+			return func(currentSrv interface{}, currentStream grpc.ServerStream) error {
+				return currentInter(currentSrv, currentStream, info, currentHandler)
+			}
+		}
+
+		chainedHandler := handler
+		for i := n - 1; i >= 0; i-- {
+			chainedHandler = chainer(interceptors[i], chainedHandler)
+		}
+
+		return chainedHandler(srv, ss)
+	}
+}
+
+// ChainUnaryClient creates a single interceptor out of a chain of many interceptors.
+//
+// Execution is done in left-to-right order, including passing of context.
+// For example ChainUnaryClient(one, two, three) will execute one before two before three.
+func ChainUnaryClient(interceptors ...grpc.UnaryClientInterceptor) grpc.UnaryClientInterceptor {
+	n := len(interceptors)
+
+	return func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {
+		chainer := func(currentInter grpc.UnaryClientInterceptor, currentInvoker grpc.UnaryInvoker) grpc.UnaryInvoker {
+			return func(currentCtx context.Context, currentMethod string, currentReq, currentRepl interface{}, currentConn *grpc.ClientConn, currentOpts ...grpc.CallOption) error {
+				return currentInter(currentCtx, currentMethod, currentReq, currentRepl, currentConn, currentInvoker, currentOpts...)
+			}
+		}
+
+		chainedInvoker := invoker
+		for i := n - 1; i >= 0; i-- {
+			chainedInvoker = chainer(interceptors[i], chainedInvoker)
+		}
+
+		return chainedInvoker(ctx, method, req, reply, cc, opts...)
+	}
+}
+
+// ChainStreamClient creates a single interceptor out of a chain of many interceptors.
+//
+// Execution is done in left-to-right order, including passing of context.
+// For example ChainStreamClient(one, two, three) will execute one before two before three.
+func ChainStreamClient(interceptors ...grpc.StreamClientInterceptor) grpc.StreamClientInterceptor {
+	n := len(interceptors)
+
+	return func(ctx context.Context, desc *grpc.StreamDesc, cc *grpc.ClientConn, method string, streamer grpc.Streamer, opts ...grpc.CallOption) (grpc.ClientStream, error) {
+		chainer := func(currentInter grpc.StreamClientInterceptor, currentStreamer grpc.Streamer) grpc.Streamer {
+			return func(currentCtx context.Context, currentDesc *grpc.StreamDesc, currentConn *grpc.ClientConn, currentMethod string, currentOpts ...grpc.CallOption) (grpc.ClientStream, error) {
+				return currentInter(currentCtx, currentDesc, currentConn, currentMethod, currentStreamer, currentOpts...)
+			}
+		}
+
+		chainedStreamer := streamer
+		for i := n - 1; i >= 0; i-- {
+			chainedStreamer = chainer(interceptors[i], chainedStreamer)
+		}
+
+		return chainedStreamer(ctx, desc, cc, method, opts...)
+	}
+}
+
+// Chain creates a single interceptor out of a chain of many interceptors.
+//
+// WithUnaryServerChain is a grpc.Server config option that accepts multiple unary interceptors.
+// Basically syntactic sugar.
+func WithUnaryServerChain(interceptors ...grpc.UnaryServerInterceptor) grpc.ServerOption {
+	return grpc.UnaryInterceptor(ChainUnaryServer(interceptors...))
+}
+
+// WithStreamServerChain is a grpc.Server config option that accepts multiple stream interceptors.
+// Basically syntactic sugar.
+func WithStreamServerChain(interceptors ...grpc.StreamServerInterceptor) grpc.ServerOption {
+	return grpc.StreamInterceptor(ChainStreamServer(interceptors...))
+}
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/doc.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/doc.go
new file mode 100644
index 0000000..718e100
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/doc.go
@@ -0,0 +1,69 @@
+// Copyright 2016 Michal Witkowski. All Rights Reserved.
+// See LICENSE for licensing terms.
+
+/*
+`grpc_middleware` is a collection of gRPC middleware packages: interceptors, helpers and tools.
+
+Middleware
+
+gRPC is a fantastic RPC middleware, which sees a lot of adoption in the Golang world. However, the
+upstream gRPC codebase is relatively bare bones.
+
+This package, and most of its child packages provides commonly needed middleware for gRPC:
+client-side interceptors for retires, server-side interceptors for input validation and auth,
+functions for chaining said interceptors, metadata convenience methods and more.
+
+Chaining
+
+By default, gRPC doesn't allow one to have more than one interceptor either on the client nor on
+the server side. `grpc_middleware` provides convenient chaining methods
+
+Simple way of turning a multiple interceptors into a single interceptor. Here's an example for
+server chaining:
+
+	myServer := grpc.NewServer(
+	    grpc.StreamInterceptor(grpc_middleware.ChainStreamServer(loggingStream, monitoringStream, authStream)),
+	    grpc.UnaryInterceptor(grpc_middleware.ChainUnaryServer(loggingUnary, monitoringUnary, authUnary)),
+	)
+
+These interceptors will be executed from left to right: logging, monitoring and auth.
+
+Here's an example for client side chaining:
+
+	clientConn, err = grpc.Dial(
+	    address,
+	        grpc.WithUnaryInterceptor(grpc_middleware.ChainUnaryClient(monitoringClientUnary, retryUnary)),
+	        grpc.WithStreamInterceptor(grpc_middleware.ChainStreamClient(monitoringClientStream, retryStream)),
+	)
+	client = pb_testproto.NewTestServiceClient(clientConn)
+	resp, err := client.PingEmpty(s.ctx, &myservice.Request{Msg: "hello"})
+
+These interceptors will be executed from left to right: monitoring and then retry logic.
+
+The retry interceptor will call every interceptor that follows it whenever when a retry happens.
+
+Writing Your Own
+
+Implementing your own interceptor is pretty trivial: there are interfaces for that. But the interesting
+bit exposing common data to handlers (and other middleware), similarly to HTTP Middleware design.
+For example, you may want to pass the identity of the caller from the auth interceptor all the way
+to the handling function.
+
+For example, a client side interceptor example for auth looks like:
+
+	func FakeAuthUnaryInterceptor(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
+	   newCtx := context.WithValue(ctx, "user_id", "john@example.com")
+	   return handler(newCtx, req)
+	}
+
+Unfortunately, it's not as easy for streaming RPCs. These have the `context.Context` embedded within
+the `grpc.ServerStream` object. To pass values through context, a wrapper (`WrappedServerStream`) is
+needed. For example:
+
+	func FakeAuthStreamingInterceptor(srv interface{}, stream grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error {
+	   newStream := grpc_middleware.WrapServerStream(stream)
+	   newStream.WrappedContext = context.WithValue(ctx, "user_id", "john@example.com")
+	   return handler(srv, newStream)
+	}
+*/
+package grpc_middleware
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/go.mod b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/go.mod
new file mode 100644
index 0000000..7dc62e5
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/go.mod
@@ -0,0 +1,22 @@
+module github.com/grpc-ecosystem/go-grpc-middleware
+
+require (
+	github.com/go-kit/kit v0.9.0
+	github.com/go-logfmt/logfmt v0.4.0 // indirect
+	github.com/go-stack/stack v1.8.0 // indirect
+	github.com/gogo/protobuf v1.3.2
+	github.com/golang/protobuf v1.3.3
+	github.com/opentracing/opentracing-go v1.1.0
+	github.com/pkg/errors v0.8.1 // indirect
+	github.com/sirupsen/logrus v1.4.2
+	github.com/stretchr/testify v1.4.0
+	go.uber.org/atomic v1.4.0 // indirect
+	go.uber.org/multierr v1.1.0 // indirect
+	go.uber.org/zap v1.10.0
+	golang.org/x/net v0.0.0-20201021035429-f5854403a974
+	golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be
+	google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215 // indirect
+	google.golang.org/grpc v1.29.1
+)
+
+go 1.14
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/go.sum b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/go.sum
new file mode 100644
index 0000000..ee522cd
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/go.sum
@@ -0,0 +1,122 @@
+cloud.google.com/go v0.26.0 h1:e0WKqKTd5BnrG8aKH3J3h+QvEIQtSUcf2n5UZ5ZgLtQ=
+cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
+github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
+github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
+github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
+github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
+github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
+github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
+github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
+github.com/go-kit/kit v0.9.0 h1:wDJmvq38kDhkVxi50ni9ykkdUr1PKgqKOoi01fa0Mdk=
+github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
+github.com/go-logfmt/logfmt v0.4.0 h1:MP4Eh7ZCb31lleYCFuwm0oe4/YGak+5l1vA2NOE80nA=
+github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
+github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
+github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
+github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
+github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
+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.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.3.3 h1:gyjaxf+svBWX08ZjK86iN9geUJF0H6gp2IRKX6Nf6/I=
+github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
+github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ=
+github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
+github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
+github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
+github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
+github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
+github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515 h1:T+h1c/A9Gawja4Y9mFVWj2vyii2bbUNDw3kt9VxK2EY=
+github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
+github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU=
+github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
+github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
+github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
+github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
+github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
+github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
+github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
+github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU=
+go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
+go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI=
+go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
+go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM=
+go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
+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/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+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=
+golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20201021035429-f5854403a974 h1:IX6qOQeG5uLjB/hjjwjedwfjND0hgjPMMyO1RoIXQNI=
+golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
+golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be h1:vEDujvNQGv4jgYKudGeI/+DAX4Jffq6hpD55MmoEvKs=
+golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
+golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f h1:+Nyd8tzPX9R7BWHguqsrbFdRx3WQ/1ib8I44HXV5yTA=
+golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
+golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
+golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
+golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
+golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
+google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508=
+google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
+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-20200423170343-7949de9c1215 h1:0Uz5jLJQioKgVozXa1gzGbzYxbb/rhQEVvSWxzw5oUs=
+google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
+google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
+google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
+google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
+google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
+google.golang.org/grpc v1.29.1 h1:EC2SB8S04d2r73uptxphDSUG+kTKVgjRPF+N3xpxRB4=
+google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
+gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/makefile b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/makefile
new file mode 100644
index 0000000..b18d2d2
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/makefile
@@ -0,0 +1,17 @@
+SHELL=/bin/bash
+
+GOFILES_NOVENDOR = $(shell go list ./... | grep -v /vendor/)
+
+all: vet fmt test
+
+fmt:
+	go fmt $(GOFILES_NOVENDOR)
+
+vet:
+	# do not check lostcancel, they are intentional.
+	go vet -lostcancel=false $(GOFILES_NOVENDOR)
+
+test: vet
+	./scripts/test_all.sh
+
+.PHONY: all test
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/slack.png b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/slack.png
new file mode 100644
index 0000000..cc8f9a6
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/slack.png
Binary files differ
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tags/context.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tags/context.go
new file mode 100644
index 0000000..0da1658
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tags/context.go
@@ -0,0 +1,78 @@
+package grpc_ctxtags
+
+import (
+	"context"
+)
+
+type ctxMarker struct{}
+
+var (
+	// ctxMarkerKey is the Context value marker used by *all* logging middleware.
+	// The logging middleware object must interf
+	ctxMarkerKey = &ctxMarker{}
+	// NoopTags is a trivial, minimum overhead implementation of Tags for which all operations are no-ops.
+	NoopTags = &noopTags{}
+)
+
+// Tags is the interface used for storing request tags between Context calls.
+// The default implementation is *not* thread safe, and should be handled only in the context of the request.
+type Tags interface {
+	// Set sets the given key in the metadata tags.
+	Set(key string, value interface{}) Tags
+	// Has checks if the given key exists.
+	Has(key string) bool
+	// Values returns a map of key to values.
+	// Do not modify the underlying map, please use Set instead.
+	Values() map[string]interface{}
+}
+
+type mapTags struct {
+	values map[string]interface{}
+}
+
+func (t *mapTags) Set(key string, value interface{}) Tags {
+	t.values[key] = value
+	return t
+}
+
+func (t *mapTags) Has(key string) bool {
+	_, ok := t.values[key]
+	return ok
+}
+
+func (t *mapTags) Values() map[string]interface{} {
+	return t.values
+}
+
+type noopTags struct{}
+
+func (t *noopTags) Set(key string, value interface{}) Tags {
+	return t
+}
+
+func (t *noopTags) Has(key string) bool {
+	return false
+}
+
+func (t *noopTags) Values() map[string]interface{} {
+	return nil
+}
+
+// Extracts returns a pre-existing Tags object in the Context.
+// If the context wasn't set in a tag interceptor, a no-op Tag storage is returned that will *not* be propagated in context.
+func Extract(ctx context.Context) Tags {
+	t, ok := ctx.Value(ctxMarkerKey).(Tags)
+	if !ok {
+		return NoopTags
+	}
+
+	return t
+}
+
+func SetInContext(ctx context.Context, tags Tags) context.Context {
+	return context.WithValue(ctx, ctxMarkerKey, tags)
+}
+
+func NewTags() Tags {
+	return &mapTags{values: make(map[string]interface{})}
+}
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tags/doc.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tags/doc.go
new file mode 100644
index 0000000..960638d
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tags/doc.go
@@ -0,0 +1,22 @@
+/*
+`grpc_ctxtags` adds a Tag object to the context that can be used by other middleware to add context about a request.
+
+Request Context Tags
+
+Tags describe information about the request, and can be set and used by other middleware, or handlers. Tags are used
+for logging and tracing of requests. Tags are populated both upwards, *and* downwards in the interceptor-handler stack.
+
+You can automatically extract tags (in `grpc.request.<field_name>`) from request payloads.
+
+For unary and server-streaming methods, pass in the `WithFieldExtractor` option. For client-streams and bidirectional-streams, you can
+use `WithFieldExtractorForInitialReq` which will extract the tags from the first message passed from client to server.
+Note the tags will not be modified for subsequent requests, so this option only makes sense when the initial message
+establishes the meta-data for the stream.
+
+If a user doesn't use the interceptors that initialize the `Tags` object, all operations following from an `Extract(ctx)`
+will be no-ops. This is to ensure that code doesn't panic if the interceptors weren't used.
+
+Tags fields are typed, and shallow and should follow the OpenTracing semantics convention:
+https://github.com/opentracing/specification/blob/master/semantic_conventions.md
+*/
+package grpc_ctxtags
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tags/fieldextractor.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tags/fieldextractor.go
new file mode 100644
index 0000000..a4073ab
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tags/fieldextractor.go
@@ -0,0 +1,85 @@
+// Copyright 2017 Michal Witkowski. All Rights Reserved.
+// See LICENSE for licensing terms.
+
+package grpc_ctxtags
+
+import (
+	"reflect"
+)
+
+// RequestFieldExtractorFunc is a user-provided function that extracts field information from a gRPC request.
+// It is called from tags middleware on arrival of unary request or a server-stream request.
+// Keys and values will be added to the context tags of the request. If there are no fields, you should return a nil.
+type RequestFieldExtractorFunc func(fullMethod string, req interface{}) map[string]interface{}
+
+type requestFieldsExtractor interface {
+	// ExtractRequestFields is a method declared on a Protobuf message that extracts fields from the interface.
+	// The values from the extracted fields should be set in the appendToMap, in order to avoid allocations.
+	ExtractRequestFields(appendToMap map[string]interface{})
+}
+
+// CodeGenRequestFieldExtractor is a function that relies on code-generated functions that export log fields from requests.
+// These are usually coming from a protoc-plugin that generates additional information based on custom field options.
+func CodeGenRequestFieldExtractor(fullMethod string, req interface{}) map[string]interface{} {
+	if ext, ok := req.(requestFieldsExtractor); ok {
+		retMap := make(map[string]interface{})
+		ext.ExtractRequestFields(retMap)
+		if len(retMap) == 0 {
+			return nil
+		}
+		return retMap
+	}
+	return nil
+}
+
+// TagBasedRequestFieldExtractor is a function that relies on Go struct tags to export log fields from requests.
+// These are usually coming from a protoc-plugin, such as Gogo protobuf.
+//
+//  message Metadata {
+//     repeated string tags = 1 [ (gogoproto.moretags) = "log_field:\"meta_tags\"" ];
+//  }
+//
+// The tagName is configurable using the tagName variable. Here it would be "log_field".
+func TagBasedRequestFieldExtractor(tagName string) RequestFieldExtractorFunc {
+	return func(fullMethod string, req interface{}) map[string]interface{} {
+		retMap := make(map[string]interface{})
+		reflectMessageTags(req, retMap, tagName)
+		if len(retMap) == 0 {
+			return nil
+		}
+		return retMap
+	}
+}
+
+func reflectMessageTags(msg interface{}, existingMap map[string]interface{}, tagName string) {
+	v := reflect.ValueOf(msg)
+	// Only deal with pointers to structs.
+	if v.Kind() != reflect.Ptr || v.Elem().Kind() != reflect.Struct {
+		return
+	}
+	// Deref the pointer get to the struct.
+	v = v.Elem()
+	t := v.Type()
+	for i := 0; i < v.NumField(); i++ {
+		field := v.Field(i)
+		kind := field.Kind()
+		// Only recurse down direct pointers, which should only be to nested structs.
+		if (kind == reflect.Ptr || kind == reflect.Interface) && field.CanInterface() {
+			reflectMessageTags(field.Interface(), existingMap, tagName)
+		}
+		// In case of arrays/slices (repeated fields) go down to the concrete type.
+		if kind == reflect.Array || kind == reflect.Slice {
+			if field.Len() == 0 {
+				continue
+			}
+			kind = field.Index(0).Kind()
+		}
+		// Only be interested in
+		if (kind >= reflect.Bool && kind <= reflect.Float64) || kind == reflect.String {
+			if tag := t.Field(i).Tag.Get(tagName); tag != "" {
+				existingMap[tag] = field.Interface()
+			}
+		}
+	}
+	return
+}
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tags/interceptors.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tags/interceptors.go
new file mode 100644
index 0000000..a7ced60
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tags/interceptors.go
@@ -0,0 +1,85 @@
+// Copyright 2017 Michal Witkowski. All Rights Reserved.
+// See LICENSE for licensing terms.
+
+package grpc_ctxtags
+
+import (
+	"context"
+
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/peer"
+
+	"github.com/grpc-ecosystem/go-grpc-middleware"
+)
+
+// UnaryServerInterceptor returns a new unary server interceptors that sets the values for request tags.
+func UnaryServerInterceptor(opts ...Option) grpc.UnaryServerInterceptor {
+	o := evaluateOptions(opts)
+	return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
+		newCtx := newTagsForCtx(ctx)
+		if o.requestFieldsFunc != nil {
+			setRequestFieldTags(newCtx, o.requestFieldsFunc, info.FullMethod, req)
+		}
+		return handler(newCtx, req)
+	}
+}
+
+// StreamServerInterceptor returns a new streaming server interceptor that sets the values for request tags.
+func StreamServerInterceptor(opts ...Option) grpc.StreamServerInterceptor {
+	o := evaluateOptions(opts)
+	return func(srv interface{}, stream grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error {
+		newCtx := newTagsForCtx(stream.Context())
+		if o.requestFieldsFunc == nil {
+			// Short-circuit, don't do the expensive bit of allocating a wrappedStream.
+			wrappedStream := grpc_middleware.WrapServerStream(stream)
+			wrappedStream.WrappedContext = newCtx
+			return handler(srv, wrappedStream)
+		}
+		wrapped := &wrappedStream{stream, info, o, newCtx, true}
+		err := handler(srv, wrapped)
+		return err
+	}
+}
+
+// wrappedStream is a thin wrapper around grpc.ServerStream that allows modifying context and extracts log fields from the initial message.
+type wrappedStream struct {
+	grpc.ServerStream
+	info *grpc.StreamServerInfo
+	opts *options
+	// WrappedContext is the wrapper's own Context. You can assign it.
+	WrappedContext context.Context
+	initial        bool
+}
+
+// Context returns the wrapper's WrappedContext, overwriting the nested grpc.ServerStream.Context()
+func (w *wrappedStream) Context() context.Context {
+	return w.WrappedContext
+}
+
+func (w *wrappedStream) RecvMsg(m interface{}) error {
+	err := w.ServerStream.RecvMsg(m)
+	// We only do log fields extraction on the single-request of a server-side stream.
+	if !w.info.IsClientStream || w.opts.requestFieldsFromInitial && w.initial {
+		w.initial = false
+
+		setRequestFieldTags(w.Context(), w.opts.requestFieldsFunc, w.info.FullMethod, m)
+	}
+	return err
+}
+
+func newTagsForCtx(ctx context.Context) context.Context {
+	t := NewTags()
+	if peer, ok := peer.FromContext(ctx); ok {
+		t.Set("peer.address", peer.Addr.String())
+	}
+	return SetInContext(ctx, t)
+}
+
+func setRequestFieldTags(ctx context.Context, f RequestFieldExtractorFunc, fullMethodName string, req interface{}) {
+	if valMap := f(fullMethodName, req); valMap != nil {
+		t := Extract(ctx)
+		for k, v := range valMap {
+			t.Set("grpc.request."+k, v)
+		}
+	}
+}
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tags/options.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tags/options.go
new file mode 100644
index 0000000..952775f
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tags/options.go
@@ -0,0 +1,44 @@
+// Copyright 2017 Michal Witkowski. All Rights Reserved.
+// See LICENSE for licensing terms.
+
+package grpc_ctxtags
+
+var (
+	defaultOptions = &options{
+		requestFieldsFunc: nil,
+	}
+)
+
+type options struct {
+	requestFieldsFunc        RequestFieldExtractorFunc
+	requestFieldsFromInitial bool
+}
+
+func evaluateOptions(opts []Option) *options {
+	optCopy := &options{}
+	*optCopy = *defaultOptions
+	for _, o := range opts {
+		o(optCopy)
+	}
+	return optCopy
+}
+
+type Option func(*options)
+
+// WithFieldExtractor customizes the function for extracting log fields from protobuf messages, for
+// unary and server-streamed methods only.
+func WithFieldExtractor(f RequestFieldExtractorFunc) Option {
+	return func(o *options) {
+		o.requestFieldsFunc = f
+	}
+}
+
+// WithFieldExtractorForInitialReq customizes the function for extracting log fields from protobuf messages,
+// for all unary and streaming methods. For client-streams and bidirectional-streams, the tags will be
+// extracted from the first message from the client.
+func WithFieldExtractorForInitialReq(f RequestFieldExtractorFunc) Option {
+	return func(o *options) {
+		o.requestFieldsFunc = f
+		o.requestFieldsFromInitial = true
+	}
+}
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing/client_interceptors.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing/client_interceptors.go
new file mode 100644
index 0000000..2e9cafd
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing/client_interceptors.go
@@ -0,0 +1,143 @@
+// Copyright 2017 Michal Witkowski. All Rights Reserved.
+// See LICENSE for licensing terms.
+
+package grpc_opentracing
+
+import (
+	"context"
+	"io"
+	"sync"
+
+	"github.com/grpc-ecosystem/go-grpc-middleware/util/metautils"
+	opentracing "github.com/opentracing/opentracing-go"
+	"github.com/opentracing/opentracing-go/ext"
+	"github.com/opentracing/opentracing-go/log"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/grpclog"
+	"google.golang.org/grpc/metadata"
+)
+
+// UnaryClientInterceptor returns a new unary client interceptor for OpenTracing.
+func UnaryClientInterceptor(opts ...Option) grpc.UnaryClientInterceptor {
+	o := evaluateOptions(opts)
+	return func(parentCtx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {
+		if o.filterOutFunc != nil && !o.filterOutFunc(parentCtx, method) {
+			return invoker(parentCtx, method, req, reply, cc, opts...)
+		}
+		newCtx, clientSpan := newClientSpanFromContext(parentCtx, o.tracer, method)
+		if o.unaryRequestHandlerFunc != nil {
+			o.unaryRequestHandlerFunc(clientSpan, req)
+		}
+		err := invoker(newCtx, method, req, reply, cc, opts...)
+		finishClientSpan(clientSpan, err)
+		return err
+	}
+}
+
+// StreamClientInterceptor returns a new streaming client interceptor for OpenTracing.
+func StreamClientInterceptor(opts ...Option) grpc.StreamClientInterceptor {
+	o := evaluateOptions(opts)
+	return func(parentCtx context.Context, desc *grpc.StreamDesc, cc *grpc.ClientConn, method string, streamer grpc.Streamer, opts ...grpc.CallOption) (grpc.ClientStream, error) {
+		if o.filterOutFunc != nil && !o.filterOutFunc(parentCtx, method) {
+			return streamer(parentCtx, desc, cc, method, opts...)
+		}
+		newCtx, clientSpan := newClientSpanFromContext(parentCtx, o.tracer, method)
+		clientStream, err := streamer(newCtx, desc, cc, method, opts...)
+		if err != nil {
+			finishClientSpan(clientSpan, err)
+			return nil, err
+		}
+		return &tracedClientStream{ClientStream: clientStream, clientSpan: clientSpan}, nil
+	}
+}
+
+// type serverStreamingRetryingStream is the implementation of grpc.ClientStream that acts as a
+// proxy to the underlying call. If any of the RecvMsg() calls fail, it will try to reestablish
+// a new ClientStream according to the retry policy.
+type tracedClientStream struct {
+	grpc.ClientStream
+	mu              sync.Mutex
+	alreadyFinished bool
+	clientSpan      opentracing.Span
+}
+
+func (s *tracedClientStream) Header() (metadata.MD, error) {
+	h, err := s.ClientStream.Header()
+	if err != nil {
+		s.finishClientSpan(err)
+	}
+	return h, err
+}
+
+func (s *tracedClientStream) SendMsg(m interface{}) error {
+	err := s.ClientStream.SendMsg(m)
+	if err != nil {
+		s.finishClientSpan(err)
+	}
+	return err
+}
+
+func (s *tracedClientStream) CloseSend() error {
+	err := s.ClientStream.CloseSend()
+	s.finishClientSpan(err)
+	return err
+}
+
+func (s *tracedClientStream) RecvMsg(m interface{}) error {
+	err := s.ClientStream.RecvMsg(m)
+	if err != nil {
+		s.finishClientSpan(err)
+	}
+	return err
+}
+
+func (s *tracedClientStream) finishClientSpan(err error) {
+	s.mu.Lock()
+	defer s.mu.Unlock()
+	if !s.alreadyFinished {
+		finishClientSpan(s.clientSpan, err)
+		s.alreadyFinished = true
+	}
+}
+
+// ClientAddContextTags returns a context with specified opentracing tags, which
+// are used by UnaryClientInterceptor/StreamClientInterceptor when creating a
+// new span.
+func ClientAddContextTags(ctx context.Context, tags opentracing.Tags) context.Context {
+	return context.WithValue(ctx, clientSpanTagKey{}, tags)
+}
+
+type clientSpanTagKey struct{}
+
+func newClientSpanFromContext(ctx context.Context, tracer opentracing.Tracer, fullMethodName string) (context.Context, opentracing.Span) {
+	var parentSpanCtx opentracing.SpanContext
+	if parent := opentracing.SpanFromContext(ctx); parent != nil {
+		parentSpanCtx = parent.Context()
+	}
+	opts := []opentracing.StartSpanOption{
+		opentracing.ChildOf(parentSpanCtx),
+		ext.SpanKindRPCClient,
+		grpcTag,
+	}
+	if tagx := ctx.Value(clientSpanTagKey{}); tagx != nil {
+		if opt, ok := tagx.(opentracing.StartSpanOption); ok {
+			opts = append(opts, opt)
+		}
+	}
+	clientSpan := tracer.StartSpan(fullMethodName, opts...)
+	// Make sure we add this to the metadata of the call, so it gets propagated:
+	md := metautils.ExtractOutgoing(ctx).Clone()
+	if err := tracer.Inject(clientSpan.Context(), opentracing.HTTPHeaders, metadataTextMap(md)); err != nil {
+		grpclog.Infof("grpc_opentracing: failed serializing trace information: %v", err)
+	}
+	ctxWithMetadata := md.ToOutgoing(ctx)
+	return opentracing.ContextWithSpan(ctxWithMetadata, clientSpan), clientSpan
+}
+
+func finishClientSpan(clientSpan opentracing.Span, err error) {
+	if err != nil && err != io.EOF {
+		ext.Error.Set(clientSpan, true)
+		clientSpan.LogFields(log.String("event", "error"), log.String("message", err.Error()))
+	}
+	clientSpan.Finish()
+}
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing/doc.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing/doc.go
new file mode 100644
index 0000000..7a58efc
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing/doc.go
@@ -0,0 +1,22 @@
+// Copyright 2017 Michal Witkowski. All Rights Reserved.
+// See LICENSE for licensing terms.
+
+/*
+`grpc_opentracing` adds OpenTracing
+
+OpenTracing Interceptors
+
+These are both client-side and server-side interceptors for OpenTracing. They are a provider-agnostic, with backends
+such as Zipkin, or Google Stackdriver Trace.
+
+For a service that sends out requests and receives requests, you *need* to use both, otherwise downstream requests will
+not have the appropriate requests propagated.
+
+All server-side spans are tagged with grpc_ctxtags information.
+
+For more information see:
+http://opentracing.io/documentation/
+https://github.com/opentracing/specification/blob/master/semantic_conventions.md
+
+*/
+package grpc_opentracing
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing/id_extract.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing/id_extract.go
new file mode 100644
index 0000000..bc7302e
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing/id_extract.go
@@ -0,0 +1,82 @@
+package grpc_opentracing
+
+import (
+	"strings"
+
+	grpc_ctxtags "github.com/grpc-ecosystem/go-grpc-middleware/tags"
+	opentracing "github.com/opentracing/opentracing-go"
+	"google.golang.org/grpc/grpclog"
+)
+
+const (
+	TagTraceId           = "trace.traceid"
+	TagSpanId            = "trace.spanid"
+	TagSampled           = "trace.sampled"
+	jaegerNotSampledFlag = "0"
+)
+
+// injectOpentracingIdsToTags writes trace data to ctxtags.
+// This is done in an incredibly hacky way, because the public-facing interface of opentracing doesn't give access to
+// the TraceId and SpanId of the SpanContext. Only the Tracer's Inject/Extract methods know what these are.
+// Most tracers have them encoded as keys with 'traceid' and 'spanid':
+// https://github.com/openzipkin/zipkin-go-opentracing/blob/594640b9ef7e5c994e8d9499359d693c032d738c/propagation_ot.go#L29
+// https://github.com/opentracing/basictracer-go/blob/1b32af207119a14b1b231d451df3ed04a72efebf/propagation_ot.go#L26
+// Jaeger from Uber use one-key schema with next format '{trace-id}:{span-id}:{parent-span-id}:{flags}'
+// https://www.jaegertracing.io/docs/client-libraries/#trace-span-identity
+// Datadog uses keys ending with 'trace-id' and 'parent-id' (for span) by default:
+// https://github.com/DataDog/dd-trace-go/blob/v1/ddtrace/tracer/textmap.go#L77
+func injectOpentracingIdsToTags(traceHeaderName string, span opentracing.Span, tags grpc_ctxtags.Tags) {
+	if err := span.Tracer().Inject(span.Context(), opentracing.HTTPHeaders,
+		&tagsCarrier{Tags: tags, traceHeaderName: traceHeaderName}); err != nil {
+		grpclog.Infof("grpc_opentracing: failed extracting trace info into ctx %v", err)
+	}
+}
+
+// tagsCarrier is a really hacky way of
+type tagsCarrier struct {
+	grpc_ctxtags.Tags
+	traceHeaderName string
+}
+
+func (t *tagsCarrier) Set(key, val string) {
+	key = strings.ToLower(key)
+
+	if key == t.traceHeaderName {
+		parts := strings.Split(val, ":")
+		if len(parts) == 4 {
+			t.Tags.Set(TagTraceId, parts[0])
+			t.Tags.Set(TagSpanId, parts[1])
+
+			if parts[3] != jaegerNotSampledFlag {
+				t.Tags.Set(TagSampled, "true")
+			} else {
+				t.Tags.Set(TagSampled, "false")
+			}
+
+			return
+		}
+	}
+
+	if strings.Contains(key, "traceid") {
+		t.Tags.Set(TagTraceId, val) // this will most likely be base-16 (hex) encoded
+	}
+
+	if strings.Contains(key, "spanid") && !strings.Contains(strings.ToLower(key), "parent") {
+		t.Tags.Set(TagSpanId, val) // this will most likely be base-16 (hex) encoded
+	}
+
+	if strings.Contains(key, "sampled") {
+		switch val {
+		case "true", "false":
+			t.Tags.Set(TagSampled, val)
+		}
+	}
+
+	if strings.HasSuffix(key, "trace-id") {
+		t.Tags.Set(TagTraceId, val)
+	}
+
+	if strings.HasSuffix(key, "parent-id") {
+		t.Tags.Set(TagSpanId, val)
+	}
+}
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing/metadata.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing/metadata.go
new file mode 100644
index 0000000..3649fb5
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing/metadata.go
@@ -0,0 +1,50 @@
+// Copyright 2017 Michal Witkowski. All Rights Reserved.
+// See LICENSE for licensing terms.
+
+package grpc_opentracing
+
+import (
+	"encoding/base64"
+	"strings"
+
+	"google.golang.org/grpc/metadata"
+)
+
+const (
+	binHdrSuffix = "-bin"
+)
+
+// metadataTextMap extends a metadata.MD to be an opentracing textmap
+type metadataTextMap metadata.MD
+
+// Set is a opentracing.TextMapReader interface that extracts values.
+func (m metadataTextMap) Set(key, val string) {
+	// gRPC allows for complex binary values to be written.
+	encodedKey, encodedVal := encodeKeyValue(key, val)
+	// The metadata object is a multimap, and previous values may exist, but for opentracing headers, we do not append
+	// we just override.
+	m[encodedKey] = []string{encodedVal}
+}
+
+// ForeachKey is a opentracing.TextMapReader interface that extracts values.
+func (m metadataTextMap) ForeachKey(callback func(key, val string) error) error {
+	for k, vv := range m {
+		for _, v := range vv {
+			if err := callback(k, v); err != nil {
+				return err
+			}
+		}
+	}
+	return nil
+}
+
+// encodeKeyValue encodes key and value qualified for transmission via gRPC.
+// note: copy pasted from private values of grpc.metadata
+func encodeKeyValue(k, v string) (string, string) {
+	k = strings.ToLower(k)
+	if strings.HasSuffix(k, binHdrSuffix) {
+		val := base64.StdEncoding.EncodeToString([]byte(v))
+		v = string(val)
+	}
+	return k, v
+}
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing/options.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing/options.go
new file mode 100644
index 0000000..430fe56
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing/options.go
@@ -0,0 +1,89 @@
+// Copyright 2017 Michal Witkowski. All Rights Reserved.
+// See LICENSE for licensing terms.
+
+package grpc_opentracing
+
+import (
+	"context"
+
+	"github.com/opentracing/opentracing-go"
+)
+
+var (
+	defaultOptions = &options{
+		filterOutFunc: nil,
+		tracer:        nil,
+	}
+)
+
+// FilterFunc allows users to provide a function that filters out certain methods from being traced.
+//
+// If it returns false, the given request will not be traced.
+type FilterFunc func(ctx context.Context, fullMethodName string) bool
+
+// UnaryRequestHandlerFunc is a custom request handler
+type UnaryRequestHandlerFunc func(span opentracing.Span, req interface{})
+
+// OpNameFunc is a func that allows custom operation names instead of the gRPC method.
+type OpNameFunc func(method string) string
+
+type options struct {
+	filterOutFunc           FilterFunc
+	tracer                  opentracing.Tracer
+	traceHeaderName         string
+	unaryRequestHandlerFunc UnaryRequestHandlerFunc
+	opNameFunc              OpNameFunc
+}
+
+func evaluateOptions(opts []Option) *options {
+	optCopy := &options{}
+	*optCopy = *defaultOptions
+	for _, o := range opts {
+		o(optCopy)
+	}
+	if optCopy.tracer == nil {
+		optCopy.tracer = opentracing.GlobalTracer()
+	}
+	if optCopy.traceHeaderName == "" {
+		optCopy.traceHeaderName = "uber-trace-id"
+	}
+	return optCopy
+}
+
+type Option func(*options)
+
+// WithFilterFunc customizes the function used for deciding whether a given call is traced or not.
+func WithFilterFunc(f FilterFunc) Option {
+	return func(o *options) {
+		o.filterOutFunc = f
+	}
+}
+
+// WithTraceHeaderName customizes the trace header name where trace metadata passed with requests.
+// Default one is `uber-trace-id`
+func WithTraceHeaderName(name string) Option {
+	return func(o *options) {
+		o.traceHeaderName = name
+	}
+}
+
+// WithTracer sets a custom tracer to be used for this middleware, otherwise the opentracing.GlobalTracer is used.
+func WithTracer(tracer opentracing.Tracer) Option {
+	return func(o *options) {
+		o.tracer = tracer
+	}
+}
+
+// WithUnaryRequestHandlerFunc sets a custom handler for the request
+func WithUnaryRequestHandlerFunc(f UnaryRequestHandlerFunc) Option {
+	return func(o *options) {
+		o.unaryRequestHandlerFunc = f
+	}
+}
+
+// WithOpName customizes the trace Operation name
+func WithOpName(f OpNameFunc) Option {
+	return func(o *options) {
+		o.opNameFunc = f
+	}
+}
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing/server_interceptors.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing/server_interceptors.go
new file mode 100644
index 0000000..186b108
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing/server_interceptors.go
@@ -0,0 +1,98 @@
+// Copyright 2017 Michal Witkowski. All Rights Reserved.
+// See LICENSE for licensing terms.
+
+package grpc_opentracing
+
+import (
+	"context"
+
+	"github.com/grpc-ecosystem/go-grpc-middleware"
+	"github.com/grpc-ecosystem/go-grpc-middleware/tags"
+	"github.com/grpc-ecosystem/go-grpc-middleware/util/metautils"
+	"github.com/opentracing/opentracing-go"
+	"github.com/opentracing/opentracing-go/ext"
+	"github.com/opentracing/opentracing-go/log"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/grpclog"
+)
+
+var (
+	grpcTag = opentracing.Tag{Key: string(ext.Component), Value: "gRPC"}
+)
+
+// UnaryServerInterceptor returns a new unary server interceptor for OpenTracing.
+func UnaryServerInterceptor(opts ...Option) grpc.UnaryServerInterceptor {
+	o := evaluateOptions(opts)
+	return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
+		if o.filterOutFunc != nil && !o.filterOutFunc(ctx, info.FullMethod) {
+			return handler(ctx, req)
+		}
+		opName := info.FullMethod
+		if o.opNameFunc != nil {
+			opName = o.opNameFunc(info.FullMethod)
+		}
+		newCtx, serverSpan := newServerSpanFromInbound(ctx, o.tracer, o.traceHeaderName, opName)
+		if o.unaryRequestHandlerFunc != nil {
+			o.unaryRequestHandlerFunc(serverSpan, req)
+		}
+		resp, err := handler(newCtx, req)
+		finishServerSpan(ctx, serverSpan, err)
+		return resp, err
+	}
+}
+
+// StreamServerInterceptor returns a new streaming server interceptor for OpenTracing.
+func StreamServerInterceptor(opts ...Option) grpc.StreamServerInterceptor {
+	o := evaluateOptions(opts)
+	return func(srv interface{}, stream grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error {
+		if o.filterOutFunc != nil && !o.filterOutFunc(stream.Context(), info.FullMethod) {
+			return handler(srv, stream)
+		}
+		opName := info.FullMethod
+		if o.opNameFunc != nil {
+			opName = o.opNameFunc(info.FullMethod)
+		}
+		newCtx, serverSpan := newServerSpanFromInbound(stream.Context(), o.tracer, o.traceHeaderName, opName)
+		wrappedStream := grpc_middleware.WrapServerStream(stream)
+		wrappedStream.WrappedContext = newCtx
+		err := handler(srv, wrappedStream)
+		finishServerSpan(newCtx, serverSpan, err)
+		return err
+	}
+}
+
+func newServerSpanFromInbound(ctx context.Context, tracer opentracing.Tracer, traceHeaderName, opName string) (context.Context, opentracing.Span) {
+	md := metautils.ExtractIncoming(ctx)
+	parentSpanContext, err := tracer.Extract(opentracing.HTTPHeaders, metadataTextMap(md))
+	if err != nil && err != opentracing.ErrSpanContextNotFound {
+		grpclog.Infof("grpc_opentracing: failed parsing trace information: %v", err)
+	}
+
+	serverSpan := tracer.StartSpan(
+		opName,
+		// this is magical, it attaches the new span to the parent parentSpanContext, and creates an unparented one if empty.
+		ext.RPCServerOption(parentSpanContext),
+		grpcTag,
+	)
+
+	injectOpentracingIdsToTags(traceHeaderName, serverSpan, grpc_ctxtags.Extract(ctx))
+	return opentracing.ContextWithSpan(ctx, serverSpan), serverSpan
+}
+
+func finishServerSpan(ctx context.Context, serverSpan opentracing.Span, err error) {
+	// Log context information
+	tags := grpc_ctxtags.Extract(ctx)
+	for k, v := range tags.Values() {
+		// Don't tag errors, log them instead.
+		if vErr, ok := v.(error); ok {
+			serverSpan.LogKV(k, vErr.Error())
+		} else {
+			serverSpan.SetTag(k, v)
+		}
+	}
+	if err != nil {
+		ext.Error.Set(serverSpan, true)
+		serverSpan.LogFields(log.String("event", "error"), log.String("message", err.Error()))
+	}
+	serverSpan.Finish()
+}
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/util/metautils/doc.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/util/metautils/doc.go
new file mode 100644
index 0000000..1ed9bb4
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/util/metautils/doc.go
@@ -0,0 +1,19 @@
+// Copyright 2016 Michal Witkowski. All Rights Reserved.
+// See LICENSE for licensing terms.
+
+/*
+Package `metautils` provides convenience functions for dealing with gRPC metadata.MD objects inside
+Context handlers.
+
+While the upstream grpc-go package contains decent functionality (see https://github.com/grpc/grpc-go/blob/master/Documentation/grpc-metadata.md)
+they are hard to use.
+
+The majority of functions center around the NiceMD, which is a convenience wrapper around metadata.MD. For example
+the following code allows you to easily extract incoming metadata (server handler) and put it into a new client context
+metadata.
+
+  nmd := metautils.ExtractIncoming(serverCtx).Clone(":authorization", ":custom")
+  clientCtx := nmd.Set("x-client-header", "2").Set("x-another", "3").ToOutgoing(ctx)
+*/
+
+package metautils
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/util/metautils/nicemd.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/util/metautils/nicemd.go
new file mode 100644
index 0000000..1c60585
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/util/metautils/nicemd.go
@@ -0,0 +1,126 @@
+// Copyright 2016 Michal Witkowski. All Rights Reserved.
+// See LICENSE for licensing terms.
+
+package metautils
+
+import (
+	"context"
+	"strings"
+
+	"google.golang.org/grpc/metadata"
+)
+
+// NiceMD is a convenience wrapper definiting extra functions on the metadata.
+type NiceMD metadata.MD
+
+// ExtractIncoming extracts an inbound metadata from the server-side context.
+//
+// This function always returns a NiceMD wrapper of the metadata.MD, in case the context doesn't have metadata it returns
+// a new empty NiceMD.
+func ExtractIncoming(ctx context.Context) NiceMD {
+	md, ok := metadata.FromIncomingContext(ctx)
+	if !ok {
+		return NiceMD(metadata.Pairs())
+	}
+	return NiceMD(md)
+}
+
+// ExtractOutgoing extracts an outbound metadata from the client-side context.
+//
+// This function always returns a NiceMD wrapper of the metadata.MD, in case the context doesn't have metadata it returns
+// a new empty NiceMD.
+func ExtractOutgoing(ctx context.Context) NiceMD {
+	md, ok := metadata.FromOutgoingContext(ctx)
+	if !ok {
+		return NiceMD(metadata.Pairs())
+	}
+	return NiceMD(md)
+}
+
+// Clone performs a *deep* copy of the metadata.MD.
+//
+// You can specify the lower-case copiedKeys to only copy certain whitelisted keys. If no keys are explicitly whitelisted
+// all keys get copied.
+func (m NiceMD) Clone(copiedKeys ...string) NiceMD {
+	newMd := NiceMD(metadata.Pairs())
+	for k, vv := range m {
+		found := false
+		if len(copiedKeys) == 0 {
+			found = true
+		} else {
+			for _, allowedKey := range copiedKeys {
+				if strings.EqualFold(allowedKey, k) {
+					found = true
+					break
+				}
+			}
+		}
+		if !found {
+			continue
+		}
+		newMd[k] = make([]string, len(vv))
+		copy(newMd[k], vv)
+	}
+	return NiceMD(newMd)
+}
+
+// ToOutgoing sets the given NiceMD as a client-side context for dispatching.
+func (m NiceMD) ToOutgoing(ctx context.Context) context.Context {
+	return metadata.NewOutgoingContext(ctx, metadata.MD(m))
+}
+
+// ToIncoming sets the given NiceMD as a server-side context for dispatching.
+//
+// This is mostly useful in ServerInterceptors..
+func (m NiceMD) ToIncoming(ctx context.Context) context.Context {
+	return metadata.NewIncomingContext(ctx, metadata.MD(m))
+}
+
+// Get retrieves a single value from the metadata.
+//
+// It works analogously to http.Header.Get, returning the first value if there are many set. If the value is not set,
+// an empty string is returned.
+//
+// The function is binary-key safe.
+func (m NiceMD) Get(key string) string {
+	k := strings.ToLower(key)
+	vv, ok := m[k]
+	if !ok {
+		return ""
+	}
+	return vv[0]
+}
+
+// Del retrieves a single value from the metadata.
+//
+// It works analogously to http.Header.Del, deleting all values if they exist.
+//
+// The function is binary-key safe.
+
+func (m NiceMD) Del(key string) NiceMD {
+	k := strings.ToLower(key)
+	delete(m, k)
+	return m
+}
+
+// Set sets the given value in a metadata.
+//
+// It works analogously to http.Header.Set, overwriting all previous metadata values.
+//
+// The function is binary-key safe.
+func (m NiceMD) Set(key string, value string) NiceMD {
+	k := strings.ToLower(key)
+	m[k] = []string{value}
+	return m
+}
+
+// Add retrieves a single value from the metadata.
+//
+// It works analogously to http.Header.Add, as it appends to any existing values associated with key.
+//
+// The function is binary-key safe.
+func (m NiceMD) Add(key string, value string) NiceMD {
+	k := strings.ToLower(key)
+	m[k] = append(m[k], value)
+	return m
+}
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/wrappers.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/wrappers.go
new file mode 100644
index 0000000..05ccfb3
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/wrappers.go
@@ -0,0 +1,30 @@
+// Copyright 2016 Michal Witkowski. All Rights Reserved.
+// See LICENSE for licensing terms.
+
+package grpc_middleware
+
+import (
+	"context"
+
+	"google.golang.org/grpc"
+)
+
+// WrappedServerStream is a thin wrapper around grpc.ServerStream that allows modifying context.
+type WrappedServerStream struct {
+	grpc.ServerStream
+	// WrappedContext is the wrapper's own Context. You can assign it.
+	WrappedContext context.Context
+}
+
+// Context returns the wrapper's WrappedContext, overwriting the nested grpc.ServerStream.Context()
+func (w *WrappedServerStream) Context() context.Context {
+	return w.WrappedContext
+}
+
+// WrapServerStream returns a ServerStream that has the ability to overwrite context.
+func WrapServerStream(stream grpc.ServerStream) *WrappedServerStream {
+	if existing, ok := stream.(*WrappedServerStream); ok {
+		return existing
+	}
+	return &WrappedServerStream{ServerStream: stream, WrappedContext: stream.Context()}
+}
diff --git a/vendor/github.com/jhump/protoreflect/LICENSE b/vendor/github.com/jhump/protoreflect/LICENSE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/vendor/github.com/jhump/protoreflect/LICENSE
@@ -0,0 +1,202 @@
+
+                                 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/codec.go b/vendor/github.com/jhump/protoreflect/codec/codec.go
new file mode 100644
index 0000000..b6f4ed0
--- /dev/null
+++ b/vendor/github.com/jhump/protoreflect/codec/codec.go
@@ -0,0 +1,217 @@
+package codec
+
+import (
+	"io"
+
+	"github.com/golang/protobuf/proto"
+	"github.com/jhump/protoreflect/internal/codec"
+)
+
+// ErrOverflow is returned when an integer is too large to be represented.
+var ErrOverflow = codec.ErrOverflow
+
+// ErrBadWireType is returned when decoding a wire-type from a buffer that
+// is not valid.
+var ErrBadWireType = codec.ErrBadWireType
+
+// NB: much of the implementation is in an internal package, to avoid an import
+// cycle between this codec package and the desc package. We export it from
+// this package, but we can't use a type alias because we also need to add
+// methods to it, to broaden the exposed API.
+
+// 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 codec.Buffer
+
+// NewBuffer creates a new buffer with the given slice of bytes as the
+// buffer's initial contents.
+func NewBuffer(buf []byte) *Buffer {
+	return (*Buffer)(codec.NewBuffer(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) {
+	(*codec.Buffer)(cb).SetDeterministic(deterministic)
+}
+
+// IsDeterministic returns whether or not this buffer is configured to encode
+// messages deterministically.
+func (cb *Buffer) IsDeterministic() bool {
+	return (*codec.Buffer)(cb).IsDeterministic()
+}
+
+// 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() {
+	(*codec.Buffer)(cb).Reset()
+}
+
+// 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 (*codec.Buffer)(cb).Bytes()
+}
+
+// String returns the remaining bytes in the buffer as a string.
+func (cb *Buffer) String() string {
+	return (*codec.Buffer)(cb).String()
+}
+
+// EOF returns true if there are no more bytes remaining to read.
+func (cb *Buffer) EOF() bool {
+	return (*codec.Buffer)(cb).EOF()
+}
+
+// Skip attempts to skip the given number of bytes in the input. If
+// the input has fewer bytes than the given count, io.ErrUnexpectedEOF
+// is returned and the buffer is unchanged. Otherwise, the given number
+// of bytes are skipped and nil is returned.
+func (cb *Buffer) Skip(count int) error {
+	return (*codec.Buffer)(cb).Skip(count)
+
+}
+
+// Len returns the remaining number of bytes in the buffer.
+func (cb *Buffer) Len() int {
+	return (*codec.Buffer)(cb).Len()
+}
+
+// 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) {
+	return (*codec.Buffer)(cb).Read(dest)
+}
+
+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) {
+	return (*codec.Buffer)(cb).Write(data)
+}
+
+var _ io.Writer = (*Buffer)(nil)
+
+// 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) {
+	return (*codec.Buffer)(cb).DecodeVarint()
+}
+
+// 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) {
+	return (*codec.Buffer)(cb).DecodeTagAndWireType()
+}
+
+// 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) {
+	return (*codec.Buffer)(cb).DecodeFixed64()
+}
+
+// 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) {
+	return (*codec.Buffer)(cb).DecodeFixed32()
+}
+
+// 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) {
+	return (*codec.Buffer)(cb).DecodeRawBytes(alloc)
+}
+
+// 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) {
+	return (*codec.Buffer)(cb).ReadGroup(alloc)
+}
+
+// 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 {
+	return (*codec.Buffer)(cb).SkipGroup()
+}
+
+// SkipField attempts to skip the value of a field with the given wire
+// type. When consuming a protobuf-encoded stream, it can be called immediately
+// after DecodeTagAndWireType to discard the subsequent data for the field.
+func (cb *Buffer) SkipField(wireType int8) error {
+	return (*codec.Buffer)(cb).SkipField(wireType)
+}
+
+// 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 {
+	return (*codec.Buffer)(cb).EncodeVarint(x)
+}
+
+// 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 {
+	return (*codec.Buffer)(cb).EncodeTagAndWireType(tag, wireType)
+}
+
+// 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 {
+	return (*codec.Buffer)(cb).EncodeFixed64(x)
+
+}
+
+// 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 {
+	return (*codec.Buffer)(cb).EncodeFixed32(x)
+}
+
+// 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 {
+	return (*codec.Buffer)(cb).EncodeRawBytes(b)
+}
+
+// EncodeMessage writes the given message to the buffer.
+func (cb *Buffer) EncodeMessage(pm proto.Message) error {
+	return (*codec.Buffer)(cb).EncodeMessage(pm)
+}
+
+// EncodeDelimitedMessage writes the given message to the buffer with a
+// varint-encoded length prefix (the delimiter).
+func (cb *Buffer) EncodeDelimitedMessage(pm proto.Message) error {
+	return (*codec.Buffer)(cb).EncodeDelimitedMessage(pm)
+}
diff --git a/vendor/github.com/jhump/protoreflect/codec/decode_fields.go b/vendor/github.com/jhump/protoreflect/codec/decode_fields.go
new file mode 100644
index 0000000..02f8a32
--- /dev/null
+++ b/vendor/github.com/jhump/protoreflect/codec/decode_fields.go
@@ -0,0 +1,318 @@
+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"
+)
+
+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
+}
+
+// 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
+}
+
+// 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))
+}
+
+// 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
new file mode 100644
index 0000000..f76499f
--- /dev/null
+++ b/vendor/github.com/jhump/protoreflect/codec/doc.go
@@ -0,0 +1,7 @@
+// 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_fields.go b/vendor/github.com/jhump/protoreflect/codec/encode_fields.go
new file mode 100644
index 0000000..499aa95
--- /dev/null
+++ b/vendor/github.com/jhump/protoreflect/codec/encode_fields.go
@@ -0,0 +1,288 @@
+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"
+)
+
+// 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)))
+}
+
+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.IsDeterministic() {
+			entryBuffer.SetDeterministic(true)
+			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
+				}
+				rv := reflect.ValueOf(v)
+				if rv.Kind() != reflect.Ptr || !rv.IsNil() {
+					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
+				}
+				rv := reflect.ValueOf(v)
+				if rv.Kind() != reflect.Ptr || !rv.IsNil() {
+					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) > 0 &&
+			(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
new file mode 100644
index 0000000..538820c
--- /dev/null
+++ b/vendor/github.com/jhump/protoreflect/desc/convert.go
@@ -0,0 +1,231 @@
+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
new file mode 100644
index 0000000..42f0f8e
--- /dev/null
+++ b/vendor/github.com/jhump/protoreflect/desc/descriptor.go
@@ -0,0 +1,1723 @@
+package desc
+
+import (
+	"bytes"
+	"fmt"
+	"sort"
+	"strconv"
+	"strings"
+	"unicode"
+	"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:]
+	}
+	if ret := fd.symbols[symbol]; ret != nil {
+		return ret
+	}
+
+	// allow accessing symbols through public imports, too
+	for _, dep := range fd.GetPublicDependencies() {
+		if ret := dep.FindSymbol(symbol); ret != nil {
+			return ret
+		}
+	}
+
+	// not found
+	return nil
+}
+
+// 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.JsonName; jsonName != nil {
+		// if json name is present, use its value
+		return *jsonName
+	}
+	// otherwise, compute the proper JSON name from the field name
+	return jsonCamelCase(fd.proto.GetName())
+}
+
+func jsonCamelCase(s string) string {
+	// This mirrors the implementation in protoc/C++ runtime and in the Java runtime:
+	//   https://github.com/protocolbuffers/protobuf/blob/a104dffcb6b1958a424f5fa6f9e6bdc0ab9b6f9e/src/google/protobuf/descriptor.cc#L276
+	//   https://github.com/protocolbuffers/protobuf/blob/a1c886834425abb64a966231dd2c9dd84fb289b3/java/core/src/main/java/com/google/protobuf/Descriptors.java#L1286
+	var buf bytes.Buffer
+	prevWasUnderscore := false
+	for _, r := range s {
+		if r == '_' {
+			prevWasUnderscore = true
+			continue
+		}
+		if prevWasUnderscore {
+			r = unicode.ToUpper(r)
+			prevWasUnderscore = false
+		}
+		buf.WriteRune(r)
+	}
+	return buf.String()
+}
+
+// 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
+}
+
+// IsProto3Optional returns true if this field has an explicit "optional" label
+// and is in a "proto3" syntax file. Such fields, if they are normal fields (not
+// extensions), will be nested in synthetic oneofs that contain only the single
+// field.
+func (fd *FieldDescriptor) IsProto3Optional() bool {
+	return internal.GetProto3Optional(fd.proto)
+}
+
+// HasPresence returns true if this field can distinguish when a value is
+// present or not. Scalar fields in "proto3" syntax files, for example, return
+// false since absent values are indistinguishable from zero values.
+func (fd *FieldDescriptor) HasPresence() bool {
+	if !fd.file.isProto3 {
+		return true
+	}
+	return fd.msgType != nil || fd.oneOf != nil
+}
+
+// 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
+}
+
+func (od *OneOfDescriptor) IsSynthetic() bool {
+	return len(od.choices) == 1 && od.choices[0].IsProto3Optional()
+}
+
+// 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
new file mode 100644
index 0000000..25d619a
--- /dev/null
+++ b/vendor/github.com/jhump/protoreflect/desc/descriptor_no_unsafe.go
@@ -0,0 +1,30 @@
+//go:build appengine || gopherjs || purego
+// +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 must do a linear scan of fields each time.
+	for _, f := range md.fields {
+		jn := f.GetJSONName()
+		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
new file mode 100644
index 0000000..691f0d8
--- /dev/null
+++ b/vendor/github.com/jhump/protoreflect/desc/descriptor_unsafe.go
@@ -0,0 +1,59 @@
+//go:build !appengine && !gopherjs && !purego
+// +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.GetJSONName()
+			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
new file mode 100644
index 0000000..1740dce
--- /dev/null
+++ b/vendor/github.com/jhump/protoreflect/desc/doc.go
@@ -0,0 +1,41 @@
+// 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
new file mode 100644
index 0000000..ab93032
--- /dev/null
+++ b/vendor/github.com/jhump/protoreflect/desc/imports.go
@@ -0,0 +1,313 @@
+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/proto3_optional.go b/vendor/github.com/jhump/protoreflect/desc/internal/proto3_optional.go
new file mode 100644
index 0000000..9aa4a3e
--- /dev/null
+++ b/vendor/github.com/jhump/protoreflect/desc/internal/proto3_optional.go
@@ -0,0 +1,120 @@
+package internal
+
+import (
+	"github.com/golang/protobuf/proto"
+	dpb "github.com/golang/protobuf/protoc-gen-go/descriptor"
+	"github.com/jhump/protoreflect/internal/codec"
+	"reflect"
+	"strings"
+
+	"github.com/jhump/protoreflect/internal"
+)
+
+// NB: We use reflection or unknown fields in case we are linked against an older
+// version of the proto runtime which does not know about the proto3_optional field.
+// We don't require linking with newer version (which would greatly simplify this)
+// because that means pulling in v1.4+ of the protobuf runtime, which has some
+// compatibility issues. (We'll be nice to users and not require they upgrade to
+// that latest runtime to upgrade to newer protoreflect.)
+
+func GetProto3Optional(fd *dpb.FieldDescriptorProto) bool {
+	type newerFieldDesc interface {
+		GetProto3Optional() bool
+	}
+	var pm proto.Message = fd
+	if fd, ok := pm.(newerFieldDesc); ok {
+		return fd.GetProto3Optional()
+	}
+
+	// Field does not exist, so we have to examine unknown fields
+	// (we just silently bail if we have problems parsing them)
+	unk := internal.GetUnrecognized(pm)
+	buf := codec.NewBuffer(unk)
+	for {
+		tag, wt, err := buf.DecodeTagAndWireType()
+		if err != nil {
+			return false
+		}
+		if tag == Field_proto3OptionalTag && wt == proto.WireVarint {
+			v, _ := buf.DecodeVarint()
+			return v != 0
+		}
+		if err := buf.SkipField(wt); err != nil {
+			return false
+		}
+	}
+}
+
+func SetProto3Optional(fd *dpb.FieldDescriptorProto) {
+	rv := reflect.ValueOf(fd).Elem()
+	fld := rv.FieldByName("Proto3Optional")
+	if fld.IsValid() {
+		fld.Set(reflect.ValueOf(proto.Bool(true)))
+		return
+	}
+
+	// Field does not exist, so we have to store as unknown field.
+	var buf codec.Buffer
+	if err := buf.EncodeTagAndWireType(Field_proto3OptionalTag, proto.WireVarint); err != nil {
+		// TODO: panic? log?
+		return
+	}
+	if err := buf.EncodeVarint(1); err != nil {
+		// TODO: panic? log?
+		return
+	}
+	internal.SetUnrecognized(fd, buf.Bytes())
+}
+
+// ProcessProto3OptionalFields adds synthetic oneofs to the given message descriptor
+// for each proto3 optional field. It also updates the fields to have the correct
+// oneof index reference.
+func ProcessProto3OptionalFields(msgd *dpb.DescriptorProto) {
+	var allNames map[string]struct{}
+	for _, fd := range msgd.Field {
+		if GetProto3Optional(fd) {
+			// lazy init the set of all names
+			if allNames == nil {
+				allNames = map[string]struct{}{}
+				for _, fd := range msgd.Field {
+					allNames[fd.GetName()] = struct{}{}
+				}
+				for _, fd := range msgd.Extension {
+					allNames[fd.GetName()] = struct{}{}
+				}
+				for _, ed := range msgd.EnumType {
+					allNames[ed.GetName()] = struct{}{}
+					for _, evd := range ed.Value {
+						allNames[evd.GetName()] = struct{}{}
+					}
+				}
+				for _, fd := range msgd.NestedType {
+					allNames[fd.GetName()] = struct{}{}
+				}
+				for _, n := range msgd.ReservedName {
+					allNames[n] = struct{}{}
+				}
+			}
+
+			// Compute a name for the synthetic oneof. This uses the same
+			// algorithm as used in protoc:
+			//  https://github.com/protocolbuffers/protobuf/blob/74ad62759e0a9b5a21094f3fb9bb4ebfaa0d1ab8/src/google/protobuf/compiler/parser.cc#L785-L803
+			ooName := fd.GetName()
+			if !strings.HasPrefix(ooName, "_") {
+				ooName = "_" + ooName
+			}
+			for {
+				_, ok := allNames[ooName]
+				if !ok {
+					// found a unique name
+					allNames[ooName] = struct{}{}
+					break
+				}
+				ooName = "X" + ooName
+			}
+
+			fd.OneofIndex = proto.Int32(int32(len(msgd.OneofDecl)))
+			msgd.OneofDecl = append(msgd.OneofDecl, &dpb.OneofDescriptorProto{Name: proto.String(ooName)})
+		}
+	}
+}
diff --git a/vendor/github.com/jhump/protoreflect/desc/internal/source_info.go b/vendor/github.com/jhump/protoreflect/desc/internal/source_info.go
new file mode 100644
index 0000000..b4150b8
--- /dev/null
+++ b/vendor/github.com/jhump/protoreflect/desc/internal/source_info.go
@@ -0,0 +1,107 @@
+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
new file mode 100644
index 0000000..71855bf
--- /dev/null
+++ b/vendor/github.com/jhump/protoreflect/desc/internal/util.go
@@ -0,0 +1,291 @@
+package internal
+
+import (
+	"math"
+	"unicode"
+	"unicode/utf8"
+)
+
+const (
+	// MaxNormalTag is the maximum allowed tag number for a field in a normal message.
+	MaxNormalTag = 536870911 // 2^29 - 1
+
+	// MaxMessageSetTag is the maximum allowed tag number of a field in a message that
+	// uses the message set wire format.
+	MaxMessageSetTag = math.MaxInt32 - 1
+
+	// MaxTag is the maximum allowed tag number. (It is the same as MaxMessageSetTag
+	// since that is the absolute highest allowed.)
+	MaxTag = MaxMessageSetTag
+
+	// 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
+	// Field_proto3OptionalTag is the tag number of the proto3_optional element
+	// in a descriptor proto.
+	Field_proto3OptionalTag = 17
+	// 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
+}
+
+// GetMaxTag returns the max tag number allowed, based on whether a message uses
+// message set wire format or not.
+func GetMaxTag(isMessageSet bool) int32 {
+	if isMessageSet {
+		return MaxMessageSetTag
+	}
+	return MaxNormalTag
+}
diff --git a/vendor/github.com/jhump/protoreflect/desc/load.go b/vendor/github.com/jhump/protoreflect/desc/load.go
new file mode 100644
index 0000000..4a05830
--- /dev/null
+++ b/vendor/github.com/jhump/protoreflect/desc/load.go
@@ -0,0 +1,341 @@
+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
new file mode 100644
index 0000000..91fd672
--- /dev/null
+++ b/vendor/github.com/jhump/protoreflect/dynamic/binary.go
@@ -0,0 +1,185 @@
+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
new file mode 100644
index 0000000..c329fcd
--- /dev/null
+++ b/vendor/github.com/jhump/protoreflect/dynamic/doc.go
@@ -0,0 +1,163 @@
+// 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
new file mode 100644
index 0000000..de13b92
--- /dev/null
+++ b/vendor/github.com/jhump/protoreflect/dynamic/dynamic_message.go
@@ -0,0 +1,2734 @@
+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"
+	"github.com/jhump/protoreflect/internal"
+)
+
+// 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 m.md.IsProto3() {
+					return nilMessage(md), 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
+}
+
+func nilMessage(md *desc.MessageDescriptor) interface{} {
+	// 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)
+	}
+	// fallback to nil dynamic message pointer
+	return (*Message)(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, false)
+	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, false)
+	if err != nil {
+		return err
+	}
+	vfd := fd.GetMessageType().GetFields()[1]
+	vi, err := validElementFieldValue(vfd, val, true)
+	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, false)
+	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, false)
+	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, false)
+	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(), false)
+				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, false)
+			if err != nil {
+				return nil, err
+			}
+			s[i] = e
+		}
+
+		return s, nil
+	}
+
+	return validElementFieldValueForRv(fd, val, false)
+}
+
+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{}, allowNilMessage bool) (interface{}, error) {
+	return validElementFieldValueForRv(fd, reflect.ValueOf(val), allowNilMessage)
+}
+
+func validElementFieldValueForRv(fd *desc.FieldDescriptor, val reflect.Value, allowNilMessage bool) (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 {
+			if allowNilMessage && dm == nil {
+				// if dm == nil, we'll panic below, so early out if that is allowed
+				// (only allowed for map values, to indicate an entry w/ no value)
+				return m, nil
+			}
+			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, defaultDeterminism)
+}
+
+// ConvertToDeterministic converts this dynamic message into the given message.
+// It is just like ConvertTo, but it attempts to produce deterministic results.
+// That means that if the target is a generated message (not another dynamic
+// message) and the current runtime is unaware of any fields or extensions that
+// are present in m, they will be serialized into the target's unrecognized
+// fields deterministically.
+func (m *Message) ConvertToDeterministic(target proto.Message) error {
+	if err := m.checkType(target); err != nil {
+		return err
+	}
+
+	target.Reset()
+	return m.mergeInto(target, true)
+}
+
+// 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, defaultDeterminism)
+}
+
+// MergeIntoDeterministic merges this dynamic message into the given message.
+// It is just like MergeInto, but it attempts to produce deterministic results.
+// That means that if the target is a generated message (not another dynamic
+// message) and the current runtime is unaware of any fields or extensions that
+// are present in m, they will be serialized into the target's unrecognized
+// fields deterministically.
+func (m *Message) MergeIntoDeterministic(target proto.Message) error {
+	if err := m.checkType(target); err != nil {
+		return err
+	}
+	return m.mergeInto(target, true)
+}
+
+// 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, deterministic bool) 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
+	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, deterministic); 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, deterministic); 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, deterministic); 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 {
+		var b codec.Buffer
+		b.SetDeterministic(deterministic)
+		if deterministic {
+			// if we need to emit things deterministically, sort the
+			// extensions by their tag number
+			sortedUnknownTags := make([]int32, 0, len(unknownTags))
+			for tag := range unknownTags {
+				sortedUnknownTags = append(sortedUnknownTags, tag)
+			}
+			sort.Slice(sortedUnknownTags, func(i, j int) bool {
+				return sortedUnknownTags[i] < sortedUnknownTags[j]
+			})
+			for _, tag := range sortedUnknownTags {
+				fd := m.FindFieldDescriptor(tag)
+				if err := b.EncodeFieldValue(fd, m.values[tag]); err != nil {
+					return err
+				}
+			}
+		} else {
+			for tag := range unknownTags {
+				fd := m.FindFieldDescriptor(tag)
+				if err := b.EncodeFieldValue(fd, m.values[tag]); err != nil {
+					return err
+				}
+			}
+		}
+
+		internal.SetUnrecognized(pm, b.Bytes())
+	}
+
+	// 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, deterministic bool) 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, deterministic); err != nil {
+				return err
+			}
+		}
+	} else if targetType.Kind() == reflect.Map {
+		return mergeMapVal(src, target, targetType, deterministic)
+	} 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, deterministic); 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)
+	for _, ed := range rexts {
+		v, _ := proto.GetExtension(pm, ed)
+		if v == nil {
+			continue
+		}
+		if ed.ExtensionType == nil {
+			// unrecognized extension: we'll handle that below when we
+			// handle other unrecognized fields
+			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 {
+		if err := mergeField(m, fd, v); err != nil {
+			return err
+		}
+	}
+
+	data := internal.GetUnrecognized(pm)
+	if len(data) > 0 {
+		// ignore any error returned: pulling in unknown fields is best-effort
+		_ = m.UnmarshalMerge(data)
+	}
+
+	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 if pm != nil {
+				dm = m.mf.NewDynamicMessage(md)
+				if err := dm.ConvertFrom(pm); err != nil {
+					return nil
+				}
+			}
+			if dm == 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
new file mode 100644
index 0000000..e44c6c5
--- /dev/null
+++ b/vendor/github.com/jhump/protoreflect/dynamic/equal.go
@@ -0,0 +1,157 @@
+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 == b {
+		return true
+	}
+	if (a == nil) != (b == nil) {
+		return false
+	}
+	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 bok {
+		// we want a to be the dynamic one
+		b, da = a, db
+	}
+
+	// Instead of panic'ing below if we have a nil dynamic message, check
+	// now and return false if the input message is not also nil.
+	if da == nil {
+		return isNil(b)
+	}
+
+	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)
+}
diff --git a/vendor/github.com/jhump/protoreflect/dynamic/extension.go b/vendor/github.com/jhump/protoreflect/dynamic/extension.go
new file mode 100644
index 0000000..1d38161
--- /dev/null
+++ b/vendor/github.com/jhump/protoreflect/dynamic/extension.go
@@ -0,0 +1,46 @@
+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
new file mode 100644
index 0000000..6876827
--- /dev/null
+++ b/vendor/github.com/jhump/protoreflect/dynamic/extension_registry.go
@@ -0,0 +1,241 @@
+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/grpcdynamic/stub.go b/vendor/github.com/jhump/protoreflect/dynamic/grpcdynamic/stub.go
new file mode 100644
index 0000000..1eaedfa
--- /dev/null
+++ b/vendor/github.com/jhump/protoreflect/dynamic/grpcdynamic/stub.go
@@ -0,0 +1,303 @@
+// Package grpcdynamic provides a dynamic RPC stub. It can be used to invoke RPC
+// method where only method descriptors are known. The actual request and response
+// messages may be dynamic messages.
+package grpcdynamic
+
+import (
+	"fmt"
+	"io"
+
+	"github.com/golang/protobuf/proto"
+	"golang.org/x/net/context"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/metadata"
+
+	"github.com/jhump/protoreflect/desc"
+	"github.com/jhump/protoreflect/dynamic"
+)
+
+// Stub is an RPC client stub, used for dynamically dispatching RPCs to a server.
+type Stub struct {
+	channel Channel
+	mf      *dynamic.MessageFactory
+}
+
+// Channel represents the operations necessary to issue RPCs via gRPC. The
+// *grpc.ClientConn type provides this interface and will typically the concrete
+// type used to construct Stubs. But the use of this interface allows
+// construction of stubs that use alternate concrete types as the transport for
+// RPC operations.
+type Channel interface {
+	Invoke(ctx context.Context, method string, args, reply interface{}, opts ...grpc.CallOption) error
+	NewStream(ctx context.Context, desc *grpc.StreamDesc, method string, opts ...grpc.CallOption) (grpc.ClientStream, error)
+}
+
+var _ Channel = (*grpc.ClientConn)(nil)
+
+// NewStub creates a new RPC stub that uses the given channel for dispatching RPCs.
+func NewStub(channel Channel) Stub {
+	return NewStubWithMessageFactory(channel, nil)
+}
+
+// NewStubWithMessageFactory creates a new RPC stub that uses the given channel for
+// dispatching RPCs and the given MessageFactory for creating response messages.
+func NewStubWithMessageFactory(channel Channel, mf *dynamic.MessageFactory) Stub {
+	return Stub{channel: channel, mf: mf}
+}
+
+func requestMethod(md *desc.MethodDescriptor) string {
+	return fmt.Sprintf("/%s/%s", md.GetService().GetFullyQualifiedName(), md.GetName())
+}
+
+// InvokeRpc sends a unary RPC and returns the response. Use this for unary methods.
+func (s Stub) InvokeRpc(ctx context.Context, method *desc.MethodDescriptor, request proto.Message, opts ...grpc.CallOption) (proto.Message, error) {
+	if method.IsClientStreaming() || method.IsServerStreaming() {
+		return nil, fmt.Errorf("InvokeRpc is for unary methods; %q is %s", method.GetFullyQualifiedName(), methodType(method))
+	}
+	if err := checkMessageType(method.GetInputType(), request); err != nil {
+		return nil, err
+	}
+	resp := s.mf.NewMessage(method.GetOutputType())
+	if err := s.channel.Invoke(ctx, requestMethod(method), request, resp, opts...); err != nil {
+		return nil, err
+	}
+	return resp, nil
+}
+
+// InvokeRpcServerStream sends a unary RPC and returns the response stream. Use this for server-streaming methods.
+func (s Stub) InvokeRpcServerStream(ctx context.Context, method *desc.MethodDescriptor, request proto.Message, opts ...grpc.CallOption) (*ServerStream, error) {
+	if method.IsClientStreaming() || !method.IsServerStreaming() {
+		return nil, fmt.Errorf("InvokeRpcServerStream is for server-streaming methods; %q is %s", method.GetFullyQualifiedName(), methodType(method))
+	}
+	if err := checkMessageType(method.GetInputType(), request); err != nil {
+		return nil, err
+	}
+	ctx, cancel := context.WithCancel(ctx)
+	sd := grpc.StreamDesc{
+		StreamName:    method.GetName(),
+		ServerStreams: method.IsServerStreaming(),
+		ClientStreams: method.IsClientStreaming(),
+	}
+	if cs, err := s.channel.NewStream(ctx, &sd, requestMethod(method), opts...); err != nil {
+		return nil, err
+	} else {
+		err = cs.SendMsg(request)
+		if err != nil {
+			cancel()
+			return nil, err
+		}
+		err = cs.CloseSend()
+		if err != nil {
+			cancel()
+			return nil, err
+		}
+		return &ServerStream{cs, method.GetOutputType(), s.mf}, nil
+	}
+}
+
+// InvokeRpcClientStream creates a new stream that is used to send request messages and, at the end,
+// receive the response message. Use this for client-streaming methods.
+func (s Stub) InvokeRpcClientStream(ctx context.Context, method *desc.MethodDescriptor, opts ...grpc.CallOption) (*ClientStream, error) {
+	if !method.IsClientStreaming() || method.IsServerStreaming() {
+		return nil, fmt.Errorf("InvokeRpcClientStream is for client-streaming methods; %q is %s", method.GetFullyQualifiedName(), methodType(method))
+	}
+	ctx, cancel := context.WithCancel(ctx)
+	sd := grpc.StreamDesc{
+		StreamName:    method.GetName(),
+		ServerStreams: method.IsServerStreaming(),
+		ClientStreams: method.IsClientStreaming(),
+	}
+	if cs, err := s.channel.NewStream(ctx, &sd, requestMethod(method), opts...); err != nil {
+		return nil, err
+	} else {
+		return &ClientStream{cs, method, s.mf, cancel}, nil
+	}
+}
+
+// InvokeRpcBidiStream creates a new stream that is used to both send request messages and receive response
+// messages. Use this for bidi-streaming methods.
+func (s Stub) InvokeRpcBidiStream(ctx context.Context, method *desc.MethodDescriptor, opts ...grpc.CallOption) (*BidiStream, error) {
+	if !method.IsClientStreaming() || !method.IsServerStreaming() {
+		return nil, fmt.Errorf("InvokeRpcBidiStream is for bidi-streaming methods; %q is %s", method.GetFullyQualifiedName(), methodType(method))
+	}
+	sd := grpc.StreamDesc{
+		StreamName:    method.GetName(),
+		ServerStreams: method.IsServerStreaming(),
+		ClientStreams: method.IsClientStreaming(),
+	}
+	if cs, err := s.channel.NewStream(ctx, &sd, requestMethod(method), opts...); err != nil {
+		return nil, err
+	} else {
+		return &BidiStream{cs, method.GetInputType(), method.GetOutputType(), s.mf}, nil
+	}
+}
+
+func methodType(md *desc.MethodDescriptor) string {
+	if md.IsClientStreaming() && md.IsServerStreaming() {
+		return "bidi-streaming"
+	} else if md.IsClientStreaming() {
+		return "client-streaming"
+	} else if md.IsServerStreaming() {
+		return "server-streaming"
+	} else {
+		return "unary"
+	}
+}
+
+func checkMessageType(md *desc.MessageDescriptor, msg proto.Message) error {
+	var typeName string
+	if dm, ok := msg.(*dynamic.Message); ok {
+		typeName = dm.GetMessageDescriptor().GetFullyQualifiedName()
+	} else {
+		typeName = proto.MessageName(msg)
+	}
+	if typeName != md.GetFullyQualifiedName() {
+		return fmt.Errorf("expecting message of type %s; got %s", md.GetFullyQualifiedName(), typeName)
+	}
+	return nil
+}
+
+// ServerStream represents a response stream from a server. Messages in the stream can be queried
+// as can header and trailer metadata sent by the server.
+type ServerStream struct {
+	stream   grpc.ClientStream
+	respType *desc.MessageDescriptor
+	mf       *dynamic.MessageFactory
+}
+
+// Header returns any header metadata sent by the server (blocks if necessary until headers are
+// received).
+func (s *ServerStream) Header() (metadata.MD, error) {
+	return s.stream.Header()
+}
+
+// Trailer returns the trailer metadata sent by the server. It must only be called after
+// RecvMsg returns a non-nil error (which may be EOF for normal completion of stream).
+func (s *ServerStream) Trailer() metadata.MD {
+	return s.stream.Trailer()
+}
+
+// Context returns the context associated with this streaming operation.
+func (s *ServerStream) Context() context.Context {
+	return s.stream.Context()
+}
+
+// RecvMsg returns the next message in the response stream or an error. If the stream
+// has completed normally, the error is io.EOF. Otherwise, the error indicates the
+// nature of the abnormal termination of the stream.
+func (s *ServerStream) RecvMsg() (proto.Message, error) {
+	resp := s.mf.NewMessage(s.respType)
+	if err := s.stream.RecvMsg(resp); err != nil {
+		return nil, err
+	} else {
+		return resp, nil
+	}
+}
+
+// ClientStream represents a response stream from a client. Messages in the stream can be sent
+// and, when done, the unary server message and header and trailer metadata can be queried.
+type ClientStream struct {
+	stream grpc.ClientStream
+	method *desc.MethodDescriptor
+	mf     *dynamic.MessageFactory
+	cancel context.CancelFunc
+}
+
+// Header returns any header metadata sent by the server (blocks if necessary until headers are
+// received).
+func (s *ClientStream) Header() (metadata.MD, error) {
+	return s.stream.Header()
+}
+
+// Trailer returns the trailer metadata sent by the server. It must only be called after
+// RecvMsg returns a non-nil error (which may be EOF for normal completion of stream).
+func (s *ClientStream) Trailer() metadata.MD {
+	return s.stream.Trailer()
+}
+
+// Context returns the context associated with this streaming operation.
+func (s *ClientStream) Context() context.Context {
+	return s.stream.Context()
+}
+
+// SendMsg sends a request message to the server.
+func (s *ClientStream) SendMsg(m proto.Message) error {
+	if err := checkMessageType(s.method.GetInputType(), m); err != nil {
+		return err
+	}
+	return s.stream.SendMsg(m)
+}
+
+// CloseAndReceive closes the outgoing request stream and then blocks for the server's response.
+func (s *ClientStream) CloseAndReceive() (proto.Message, error) {
+	if err := s.stream.CloseSend(); err != nil {
+		return nil, err
+	}
+	resp := s.mf.NewMessage(s.method.GetOutputType())
+	if err := s.stream.RecvMsg(resp); err != nil {
+		return nil, err
+	}
+	// make sure we get EOF for a second message
+	if err := s.stream.RecvMsg(resp); err != io.EOF {
+		if err == nil {
+			s.cancel()
+			return nil, fmt.Errorf("client-streaming method %q returned more than one response message", s.method.GetFullyQualifiedName())
+		} else {
+			return nil, err
+		}
+	}
+	return resp, nil
+}
+
+// BidiStream represents a bi-directional stream for sending messages to and receiving
+// messages from a server. The header and trailer metadata sent by the server can also be
+// queried.
+type BidiStream struct {
+	stream   grpc.ClientStream
+	reqType  *desc.MessageDescriptor
+	respType *desc.MessageDescriptor
+	mf       *dynamic.MessageFactory
+}
+
+// Header returns any header metadata sent by the server (blocks if necessary until headers are
+// received).
+func (s *BidiStream) Header() (metadata.MD, error) {
+	return s.stream.Header()
+}
+
+// Trailer returns the trailer metadata sent by the server. It must only be called after
+// RecvMsg returns a non-nil error (which may be EOF for normal completion of stream).
+func (s *BidiStream) Trailer() metadata.MD {
+	return s.stream.Trailer()
+}
+
+// Context returns the context associated with this streaming operation.
+func (s *BidiStream) Context() context.Context {
+	return s.stream.Context()
+}
+
+// SendMsg sends a request message to the server.
+func (s *BidiStream) SendMsg(m proto.Message) error {
+	if err := checkMessageType(s.reqType, m); err != nil {
+		return err
+	}
+	return s.stream.SendMsg(m)
+}
+
+// CloseSend indicates the request stream has ended. Invoke this after all request messages
+// are sent (even if there are zero such messages).
+func (s *BidiStream) CloseSend() error {
+	return s.stream.CloseSend()
+}
+
+// RecvMsg returns the next message in the response stream or an error. If the stream
+// has completed normally, the error is io.EOF. Otherwise, the error indicates the
+// nature of the abnormal termination of the stream.
+func (s *BidiStream) RecvMsg() (proto.Message, error) {
+	resp := s.mf.NewMessage(s.respType)
+	if err := s.stream.RecvMsg(resp); err != nil {
+		return nil, err
+	} else {
+		return resp, nil
+	}
+}
diff --git a/vendor/github.com/jhump/protoreflect/dynamic/indent.go b/vendor/github.com/jhump/protoreflect/dynamic/indent.go
new file mode 100644
index 0000000..bd7fcaa
--- /dev/null
+++ b/vendor/github.com/jhump/protoreflect/dynamic/indent.go
@@ -0,0 +1,76 @@
+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
new file mode 100644
index 0000000..02c8298
--- /dev/null
+++ b/vendor/github.com/jhump/protoreflect/dynamic/json.go
@@ -0,0 +1,1256 @@
+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 m == nil {
+		_, err := b.WriteString("null")
+		return err
+	}
+	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 := writeJsonString(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 isNil(v) {
+			_, err := b.WriteString("null")
+			return err
+		}
+
+		if dm, ok := v.(*Message); ok {
+			return dm.marshalJSON(b, opts)
+		}
+
+		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 {
+	// we look for ListValue; but we also look for Value, which can be assigned a ListValue
+	return !fd.IsRepeated() && fd.GetType() == descriptor.FieldDescriptorProto_TYPE_MESSAGE &&
+		(fd.GetMessageType().GetFullyQualifiedName() == "google.protobuf.ListValue" ||
+			fd.GetMessageType().GetFullyQualifiedName() == "google.protobuf.Value")
+}
+
+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, false)
+			if err != nil {
+				return nil, err
+			}
+			vv, err := unmarshalJsFieldElement(valueType, r, mf, opts, true)
+			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, false)
+			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, false)
+		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, allowNilMessage bool) (interface{}, error) {
+	t, err := r.peek()
+	if err != nil {
+		return nil, err
+	}
+
+	switch fd.GetType() {
+	case descriptor.FieldDescriptorProto_TYPE_MESSAGE,
+		descriptor.FieldDescriptorProto_TYPE_GROUP:
+
+		if t == nil && allowNilMessage {
+			// if json is simply "null" return a nil pointer
+			r.poll()
+			return nilMessage(fd.GetMessageType()), nil
+		}
+
+		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
new file mode 100644
index 0000000..03162a4
--- /dev/null
+++ b/vendor/github.com/jhump/protoreflect/dynamic/maps_1.11.go
@@ -0,0 +1,130 @@
+//go:build !go1.12
+// +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 := validElementFieldValueForRv(keyField, k, false)
+		if err != nil {
+			return nil, err
+		}
+		v := val.MapIndex(k)
+		if v.Kind() == reflect.Interface {
+			// unwrap it
+			v = reflect.ValueOf(v.Interface())
+		}
+		vv, err := validElementFieldValueForRv(valField, v, true)
+		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, deterministic bool) 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, deterministic); 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, deterministic); 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
new file mode 100644
index 0000000..ef1b370
--- /dev/null
+++ b/vendor/github.com/jhump/protoreflect/dynamic/maps_1.12.go
@@ -0,0 +1,138 @@
+//go:build go1.12
+// +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 := validElementFieldValueForRv(keyField, k, false)
+		if err != nil {
+			return nil, err
+		}
+		v := iter.Value()
+		if v.Kind() == reflect.Interface {
+			// unwrap it
+			v = reflect.ValueOf(v.Interface())
+		}
+		vv, err := validElementFieldValueForRv(valField, v, true)
+		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, deterministic bool) 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, deterministic); 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, deterministic); 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
new file mode 100644
index 0000000..ce727fd
--- /dev/null
+++ b/vendor/github.com/jhump/protoreflect/dynamic/merge.go
@@ -0,0 +1,100 @@
+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
new file mode 100644
index 0000000..9ab8e61
--- /dev/null
+++ b/vendor/github.com/jhump/protoreflect/dynamic/message_factory.go
@@ -0,0 +1,201 @@
+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)
+	}
+}
+
+func isWellKnownType(t reflect.Type) bool {
+	if t.Implements(typeOfWkt) {
+		return true
+	}
+	if msg, ok := reflect.Zero(t).Interface().(proto.Message); ok {
+		name := proto.MessageName(msg)
+		_, ok := wellKnownTypeNames[name]
+		return ok
+	}
+	return false
+}
+
+// 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 && isWellKnownType(t) {
+			msgType = t
+		}
+	} else {
+		if r.includeDefault {
+			msgType = proto.MessageType(messageName)
+		} else if !r.excludeWkt {
+			t := proto.MessageType(messageName)
+			if t != nil && isWellKnownType(t) {
+				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
new file mode 100644
index 0000000..5784d3e
--- /dev/null
+++ b/vendor/github.com/jhump/protoreflect/dynamic/text.go
@@ -0,0 +1,1177 @@
+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
+	}
+	if !isNil(mv) {
+		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/grpcreflect/client.go b/vendor/github.com/jhump/protoreflect/grpcreflect/client.go
new file mode 100644
index 0000000..3fca3eb
--- /dev/null
+++ b/vendor/github.com/jhump/protoreflect/grpcreflect/client.go
@@ -0,0 +1,666 @@
+package grpcreflect
+
+import (
+	"bytes"
+	"fmt"
+	"io"
+	"reflect"
+	"runtime"
+	"sync"
+
+	"github.com/golang/protobuf/proto"
+	dpb "github.com/golang/protobuf/protoc-gen-go/descriptor"
+	"golang.org/x/net/context"
+	"google.golang.org/grpc/codes"
+	rpb "google.golang.org/grpc/reflection/grpc_reflection_v1alpha"
+	"google.golang.org/grpc/status"
+
+	"github.com/jhump/protoreflect/desc"
+	"github.com/jhump/protoreflect/internal"
+)
+
+// elementNotFoundError is the error returned by reflective operations where the
+// server does not recognize a given file name, symbol name, or extension.
+type elementNotFoundError struct {
+	name    string
+	kind    elementKind
+	symType symbolType // only used when kind == elementKindSymbol
+	tag     int32      // only used when kind == elementKindExtension
+
+	// only errors with a kind of elementKindFile will have a cause, which means
+	// the named file count not be resolved because of a dependency that could
+	// not be found where cause describes the missing dependency
+	cause *elementNotFoundError
+}
+
+type elementKind int
+
+const (
+	elementKindSymbol elementKind = iota
+	elementKindFile
+	elementKindExtension
+)
+
+type symbolType string
+
+const (
+	symbolTypeService = "Service"
+	symbolTypeMessage = "Message"
+	symbolTypeEnum    = "Enum"
+	symbolTypeUnknown = "Symbol"
+)
+
+func symbolNotFound(symbol string, symType symbolType, cause *elementNotFoundError) error {
+	return &elementNotFoundError{name: symbol, symType: symType, kind: elementKindSymbol, cause: cause}
+}
+
+func extensionNotFound(extendee string, tag int32, cause *elementNotFoundError) error {
+	return &elementNotFoundError{name: extendee, tag: tag, kind: elementKindExtension, cause: cause}
+}
+
+func fileNotFound(file string, cause *elementNotFoundError) error {
+	return &elementNotFoundError{name: file, kind: elementKindFile, cause: cause}
+}
+
+func (e *elementNotFoundError) Error() string {
+	first := true
+	var b bytes.Buffer
+	for ; e != nil; e = e.cause {
+		if first {
+			first = false
+		} else {
+			fmt.Fprint(&b, "\ncaused by: ")
+		}
+		switch e.kind {
+		case elementKindSymbol:
+			fmt.Fprintf(&b, "%s not found: %s", e.symType, e.name)
+		case elementKindExtension:
+			fmt.Fprintf(&b, "Extension not found: tag %d for %s", e.tag, e.name)
+		default:
+			fmt.Fprintf(&b, "File not found: %s", e.name)
+		}
+	}
+	return b.String()
+}
+
+// IsElementNotFoundError determines if the given error indicates that a file
+// name, symbol name, or extension field was could not be found by the server.
+func IsElementNotFoundError(err error) bool {
+	_, ok := err.(*elementNotFoundError)
+	return ok
+}
+
+// ProtocolError is an error returned when the server sends a response of the
+// wrong type.
+type ProtocolError struct {
+	missingType reflect.Type
+}
+
+func (p ProtocolError) Error() string {
+	return fmt.Sprintf("Protocol error: response was missing %v", p.missingType)
+}
+
+type extDesc struct {
+	extendedMessageName string
+	extensionNumber     int32
+}
+
+// Client is a client connection to a server for performing reflection calls
+// and resolving remote symbols.
+type Client struct {
+	ctx  context.Context
+	stub rpb.ServerReflectionClient
+
+	connMu sync.Mutex
+	cancel context.CancelFunc
+	stream rpb.ServerReflection_ServerReflectionInfoClient
+
+	cacheMu          sync.RWMutex
+	protosByName     map[string]*dpb.FileDescriptorProto
+	filesByName      map[string]*desc.FileDescriptor
+	filesBySymbol    map[string]*desc.FileDescriptor
+	filesByExtension map[extDesc]*desc.FileDescriptor
+}
+
+// NewClient creates a new Client with the given root context and using the
+// given RPC stub for talking to the server.
+func NewClient(ctx context.Context, stub rpb.ServerReflectionClient) *Client {
+	cr := &Client{
+		ctx:              ctx,
+		stub:             stub,
+		protosByName:     map[string]*dpb.FileDescriptorProto{},
+		filesByName:      map[string]*desc.FileDescriptor{},
+		filesBySymbol:    map[string]*desc.FileDescriptor{},
+		filesByExtension: map[extDesc]*desc.FileDescriptor{},
+	}
+	// don't leak a grpc stream
+	runtime.SetFinalizer(cr, (*Client).Reset)
+	return cr
+}
+
+// FileByFilename asks the server for a file descriptor for the proto file with
+// the given name.
+func (cr *Client) FileByFilename(filename string) (*desc.FileDescriptor, error) {
+	// hit the cache first
+	cr.cacheMu.RLock()
+	if fd, ok := cr.filesByName[filename]; ok {
+		cr.cacheMu.RUnlock()
+		return fd, nil
+	}
+	fdp, ok := cr.protosByName[filename]
+	cr.cacheMu.RUnlock()
+	// not there? see if we've downloaded the proto
+	if ok {
+		return cr.descriptorFromProto(fdp)
+	}
+
+	req := &rpb.ServerReflectionRequest{
+		MessageRequest: &rpb.ServerReflectionRequest_FileByFilename{
+			FileByFilename: filename,
+		},
+	}
+	fd, err := cr.getAndCacheFileDescriptors(req, filename, "")
+	if isNotFound(err) {
+		// file not found? see if we can look up via alternate name
+		if alternate, ok := internal.StdFileAliases[filename]; ok {
+			req := &rpb.ServerReflectionRequest{
+				MessageRequest: &rpb.ServerReflectionRequest_FileByFilename{
+					FileByFilename: alternate,
+				},
+			}
+			fd, err = cr.getAndCacheFileDescriptors(req, alternate, filename)
+			if isNotFound(err) {
+				err = fileNotFound(filename, nil)
+			}
+		} else {
+			err = fileNotFound(filename, nil)
+		}
+	} else if e, ok := err.(*elementNotFoundError); ok {
+		err = fileNotFound(filename, e)
+	}
+	return fd, err
+}
+
+// FileContainingSymbol asks the server for a file descriptor for the proto file
+// that declares the given fully-qualified symbol.
+func (cr *Client) FileContainingSymbol(symbol string) (*desc.FileDescriptor, error) {
+	// hit the cache first
+	cr.cacheMu.RLock()
+	fd, ok := cr.filesBySymbol[symbol]
+	cr.cacheMu.RUnlock()
+	if ok {
+		return fd, nil
+	}
+
+	req := &rpb.ServerReflectionRequest{
+		MessageRequest: &rpb.ServerReflectionRequest_FileContainingSymbol{
+			FileContainingSymbol: symbol,
+		},
+	}
+	fd, err := cr.getAndCacheFileDescriptors(req, "", "")
+	if isNotFound(err) {
+		err = symbolNotFound(symbol, symbolTypeUnknown, nil)
+	} else if e, ok := err.(*elementNotFoundError); ok {
+		err = symbolNotFound(symbol, symbolTypeUnknown, e)
+	}
+	return fd, err
+}
+
+// FileContainingExtension asks the server for a file descriptor for the proto
+// file that declares an extension with the given number for the given
+// fully-qualified message name.
+func (cr *Client) FileContainingExtension(extendedMessageName string, extensionNumber int32) (*desc.FileDescriptor, error) {
+	// hit the cache first
+	cr.cacheMu.RLock()
+	fd, ok := cr.filesByExtension[extDesc{extendedMessageName, extensionNumber}]
+	cr.cacheMu.RUnlock()
+	if ok {
+		return fd, nil
+	}
+
+	req := &rpb.ServerReflectionRequest{
+		MessageRequest: &rpb.ServerReflectionRequest_FileContainingExtension{
+			FileContainingExtension: &rpb.ExtensionRequest{
+				ContainingType:  extendedMessageName,
+				ExtensionNumber: extensionNumber,
+			},
+		},
+	}
+	fd, err := cr.getAndCacheFileDescriptors(req, "", "")
+	if isNotFound(err) {
+		err = extensionNotFound(extendedMessageName, extensionNumber, nil)
+	} else if e, ok := err.(*elementNotFoundError); ok {
+		err = extensionNotFound(extendedMessageName, extensionNumber, e)
+	}
+	return fd, err
+}
+
+func (cr *Client) getAndCacheFileDescriptors(req *rpb.ServerReflectionRequest, expectedName, alias string) (*desc.FileDescriptor, error) {
+	resp, err := cr.send(req)
+	if err != nil {
+		return nil, err
+	}
+
+	fdResp := resp.GetFileDescriptorResponse()
+	if fdResp == nil {
+		return nil, &ProtocolError{reflect.TypeOf(fdResp).Elem()}
+	}
+
+	// Response can contain the result file descriptor, but also its transitive
+	// deps. Furthermore, protocol states that subsequent requests do not need
+	// to send transitive deps that have been sent in prior responses. So we
+	// need to cache all file descriptors and then return the first one (which
+	// should be the answer). If we're looking for a file by name, we can be
+	// smarter and make sure to grab one by name instead of just grabbing the
+	// first one.
+	var firstFd *dpb.FileDescriptorProto
+	for _, fdBytes := range fdResp.FileDescriptorProto {
+		fd := &dpb.FileDescriptorProto{}
+		if err = proto.Unmarshal(fdBytes, fd); err != nil {
+			return nil, err
+		}
+
+		if expectedName != "" && alias != "" && expectedName != alias && fd.GetName() == expectedName {
+			// we found a file was aliased, so we need to update the proto to reflect that
+			fd.Name = proto.String(alias)
+		}
+
+		cr.cacheMu.Lock()
+		// see if this file was created and cached concurrently
+		if firstFd == nil {
+			if d, ok := cr.filesByName[fd.GetName()]; ok {
+				cr.cacheMu.Unlock()
+				return d, nil
+			}
+		}
+		// store in cache of raw descriptor protos, but don't overwrite existing protos
+		if existingFd, ok := cr.protosByName[fd.GetName()]; ok {
+			fd = existingFd
+		} else {
+			cr.protosByName[fd.GetName()] = fd
+		}
+		cr.cacheMu.Unlock()
+		if firstFd == nil {
+			firstFd = fd
+		}
+	}
+	if firstFd == nil {
+		return nil, &ProtocolError{reflect.TypeOf(firstFd).Elem()}
+	}
+
+	return cr.descriptorFromProto(firstFd)
+}
+
+func (cr *Client) descriptorFromProto(fd *dpb.FileDescriptorProto) (*desc.FileDescriptor, error) {
+	deps := make([]*desc.FileDescriptor, len(fd.GetDependency()))
+	for i, depName := range fd.GetDependency() {
+		if dep, err := cr.FileByFilename(depName); err != nil {
+			return nil, err
+		} else {
+			deps[i] = dep
+		}
+	}
+	d, err := desc.CreateFileDescriptor(fd, deps...)
+	if err != nil {
+		return nil, err
+	}
+	d = cr.cacheFile(d)
+	return d, nil
+}
+
+func (cr *Client) cacheFile(fd *desc.FileDescriptor) *desc.FileDescriptor {
+	cr.cacheMu.Lock()
+	defer cr.cacheMu.Unlock()
+
+	// cache file descriptor by name, but don't overwrite existing entry
+	// (existing entry could come from concurrent caller)
+	if existingFd, ok := cr.filesByName[fd.GetName()]; ok {
+		return existingFd
+	}
+	cr.filesByName[fd.GetName()] = fd
+
+	// also cache by symbols and extensions
+	for _, m := range fd.GetMessageTypes() {
+		cr.cacheMessageLocked(fd, m)
+	}
+	for _, e := range fd.GetEnumTypes() {
+		cr.filesBySymbol[e.GetFullyQualifiedName()] = fd
+		for _, v := range e.GetValues() {
+			cr.filesBySymbol[v.GetFullyQualifiedName()] = fd
+		}
+	}
+	for _, e := range fd.GetExtensions() {
+		cr.filesBySymbol[e.GetFullyQualifiedName()] = fd
+		cr.filesByExtension[extDesc{e.GetOwner().GetFullyQualifiedName(), e.GetNumber()}] = fd
+	}
+	for _, s := range fd.GetServices() {
+		cr.filesBySymbol[s.GetFullyQualifiedName()] = fd
+		for _, m := range s.GetMethods() {
+			cr.filesBySymbol[m.GetFullyQualifiedName()] = fd
+		}
+	}
+
+	return fd
+}
+
+func (cr *Client) cacheMessageLocked(fd *desc.FileDescriptor, md *desc.MessageDescriptor) {
+	cr.filesBySymbol[md.GetFullyQualifiedName()] = fd
+	for _, f := range md.GetFields() {
+		cr.filesBySymbol[f.GetFullyQualifiedName()] = fd
+	}
+	for _, o := range md.GetOneOfs() {
+		cr.filesBySymbol[o.GetFullyQualifiedName()] = fd
+	}
+	for _, e := range md.GetNestedEnumTypes() {
+		cr.filesBySymbol[e.GetFullyQualifiedName()] = fd
+		for _, v := range e.GetValues() {
+			cr.filesBySymbol[v.GetFullyQualifiedName()] = fd
+		}
+	}
+	for _, e := range md.GetNestedExtensions() {
+		cr.filesBySymbol[e.GetFullyQualifiedName()] = fd
+		cr.filesByExtension[extDesc{e.GetOwner().GetFullyQualifiedName(), e.GetNumber()}] = fd
+	}
+	for _, m := range md.GetNestedMessageTypes() {
+		cr.cacheMessageLocked(fd, m) // recurse
+	}
+}
+
+// AllExtensionNumbersForType asks the server for all known extension numbers
+// for the given fully-qualified message name.
+func (cr *Client) AllExtensionNumbersForType(extendedMessageName string) ([]int32, error) {
+	req := &rpb.ServerReflectionRequest{
+		MessageRequest: &rpb.ServerReflectionRequest_AllExtensionNumbersOfType{
+			AllExtensionNumbersOfType: extendedMessageName,
+		},
+	}
+	resp, err := cr.send(req)
+	if err != nil {
+		if isNotFound(err) {
+			return nil, symbolNotFound(extendedMessageName, symbolTypeMessage, nil)
+		}
+		return nil, err
+	}
+
+	extResp := resp.GetAllExtensionNumbersResponse()
+	if extResp == nil {
+		return nil, &ProtocolError{reflect.TypeOf(extResp).Elem()}
+	}
+	return extResp.ExtensionNumber, nil
+}
+
+// ListServices asks the server for the fully-qualified names of all exposed
+// services.
+func (cr *Client) ListServices() ([]string, error) {
+	req := &rpb.ServerReflectionRequest{
+		MessageRequest: &rpb.ServerReflectionRequest_ListServices{
+			// proto doesn't indicate any purpose for this value and server impl
+			// doesn't actually use it...
+			ListServices: "*",
+		},
+	}
+	resp, err := cr.send(req)
+	if err != nil {
+		return nil, err
+	}
+
+	listResp := resp.GetListServicesResponse()
+	if listResp == nil {
+		return nil, &ProtocolError{reflect.TypeOf(listResp).Elem()}
+	}
+	serviceNames := make([]string, len(listResp.Service))
+	for i, s := range listResp.Service {
+		serviceNames[i] = s.Name
+	}
+	return serviceNames, nil
+}
+
+func (cr *Client) send(req *rpb.ServerReflectionRequest) (*rpb.ServerReflectionResponse, error) {
+	// we allow one immediate retry, in case we have a stale stream
+	// (e.g. closed by server)
+	resp, err := cr.doSend(true, req)
+	if err != nil {
+		return nil, err
+	}
+
+	// convert error response messages into errors
+	errResp := resp.GetErrorResponse()
+	if errResp != nil {
+		return nil, status.Errorf(codes.Code(errResp.ErrorCode), "%s", errResp.ErrorMessage)
+	}
+
+	return resp, nil
+}
+
+func isNotFound(err error) bool {
+	if err == nil {
+		return false
+	}
+	s, ok := status.FromError(err)
+	return ok && s.Code() == codes.NotFound
+}
+
+func (cr *Client) doSend(retry bool, req *rpb.ServerReflectionRequest) (*rpb.ServerReflectionResponse, error) {
+	// TODO: Streams are thread-safe, so we shouldn't need to lock. But without locking, we'll need more machinery
+	// (goroutines and channels) to ensure that responses are correctly correlated with their requests and thus
+	// delivered in correct oder.
+	cr.connMu.Lock()
+	defer cr.connMu.Unlock()
+	return cr.doSendLocked(retry, req)
+}
+
+func (cr *Client) doSendLocked(retry bool, req *rpb.ServerReflectionRequest) (*rpb.ServerReflectionResponse, error) {
+	if err := cr.initStreamLocked(); err != nil {
+		return nil, err
+	}
+
+	if err := cr.stream.Send(req); err != nil {
+		if err == io.EOF {
+			// if send returns EOF, must call Recv to get real underlying error
+			_, err = cr.stream.Recv()
+		}
+		cr.resetLocked()
+		if retry {
+			return cr.doSendLocked(false, req)
+		}
+		return nil, err
+	}
+
+	if resp, err := cr.stream.Recv(); err != nil {
+		cr.resetLocked()
+		if retry {
+			return cr.doSendLocked(false, req)
+		}
+		return nil, err
+	} else {
+		return resp, nil
+	}
+}
+
+func (cr *Client) initStreamLocked() error {
+	if cr.stream != nil {
+		return nil
+	}
+	var newCtx context.Context
+	newCtx, cr.cancel = context.WithCancel(cr.ctx)
+	var err error
+	cr.stream, err = cr.stub.ServerReflectionInfo(newCtx)
+	return err
+}
+
+// Reset ensures that any active stream with the server is closed, releasing any
+// resources.
+func (cr *Client) Reset() {
+	cr.connMu.Lock()
+	defer cr.connMu.Unlock()
+	cr.resetLocked()
+}
+
+func (cr *Client) resetLocked() {
+	if cr.stream != nil {
+		cr.stream.CloseSend()
+		for {
+			// drain the stream, this covers io.EOF too
+			if _, err := cr.stream.Recv(); err != nil {
+				break
+			}
+		}
+		cr.stream = nil
+	}
+	if cr.cancel != nil {
+		cr.cancel()
+		cr.cancel = nil
+	}
+}
+
+// ResolveService asks the server to resolve the given fully-qualified service
+// name into a service descriptor.
+func (cr *Client) ResolveService(serviceName string) (*desc.ServiceDescriptor, error) {
+	file, err := cr.FileContainingSymbol(serviceName)
+	if err != nil {
+		return nil, setSymbolType(err, serviceName, symbolTypeService)
+	}
+	d := file.FindSymbol(serviceName)
+	if d == nil {
+		return nil, symbolNotFound(serviceName, symbolTypeService, nil)
+	}
+	if s, ok := d.(*desc.ServiceDescriptor); ok {
+		return s, nil
+	} else {
+		return nil, symbolNotFound(serviceName, symbolTypeService, nil)
+	}
+}
+
+// ResolveMessage asks the server to resolve the given fully-qualified message
+// name into a message descriptor.
+func (cr *Client) ResolveMessage(messageName string) (*desc.MessageDescriptor, error) {
+	file, err := cr.FileContainingSymbol(messageName)
+	if err != nil {
+		return nil, setSymbolType(err, messageName, symbolTypeMessage)
+	}
+	d := file.FindSymbol(messageName)
+	if d == nil {
+		return nil, symbolNotFound(messageName, symbolTypeMessage, nil)
+	}
+	if s, ok := d.(*desc.MessageDescriptor); ok {
+		return s, nil
+	} else {
+		return nil, symbolNotFound(messageName, symbolTypeMessage, nil)
+	}
+}
+
+// ResolveEnum asks the server to resolve the given fully-qualified enum name
+// into an enum descriptor.
+func (cr *Client) ResolveEnum(enumName string) (*desc.EnumDescriptor, error) {
+	file, err := cr.FileContainingSymbol(enumName)
+	if err != nil {
+		return nil, setSymbolType(err, enumName, symbolTypeEnum)
+	}
+	d := file.FindSymbol(enumName)
+	if d == nil {
+		return nil, symbolNotFound(enumName, symbolTypeEnum, nil)
+	}
+	if s, ok := d.(*desc.EnumDescriptor); ok {
+		return s, nil
+	} else {
+		return nil, symbolNotFound(enumName, symbolTypeEnum, nil)
+	}
+}
+
+func setSymbolType(err error, name string, symType symbolType) error {
+	if e, ok := err.(*elementNotFoundError); ok {
+		if e.kind == elementKindSymbol && e.name == name && e.symType == symbolTypeUnknown {
+			e.symType = symType
+		}
+	}
+	return err
+}
+
+// ResolveEnumValues asks the server to resolve the given fully-qualified enum
+// name into a map of names to numbers that represents the enum's values.
+func (cr *Client) ResolveEnumValues(enumName string) (map[string]int32, error) {
+	enumDesc, err := cr.ResolveEnum(enumName)
+	if err != nil {
+		return nil, err
+	}
+	vals := map[string]int32{}
+	for _, valDesc := range enumDesc.GetValues() {
+		vals[valDesc.GetName()] = valDesc.GetNumber()
+	}
+	return vals, nil
+}
+
+// ResolveExtension asks the server to resolve the given extension number and
+// fully-qualified message name into a field descriptor.
+func (cr *Client) ResolveExtension(extendedType string, extensionNumber int32) (*desc.FieldDescriptor, error) {
+	file, err := cr.FileContainingExtension(extendedType, extensionNumber)
+	if err != nil {
+		return nil, err
+	}
+	d := findExtension(extendedType, extensionNumber, fileDescriptorExtensions{file})
+	if d == nil {
+		return nil, extensionNotFound(extendedType, extensionNumber, nil)
+	} else {
+		return d, nil
+	}
+}
+
+func findExtension(extendedType string, extensionNumber int32, scope extensionScope) *desc.FieldDescriptor {
+	// search extensions in this scope
+	for _, ext := range scope.extensions() {
+		if ext.GetNumber() == extensionNumber && ext.GetOwner().GetFullyQualifiedName() == extendedType {
+			return ext
+		}
+	}
+
+	// if not found, search nested scopes
+	for _, nested := range scope.nestedScopes() {
+		ext := findExtension(extendedType, extensionNumber, nested)
+		if ext != nil {
+			return ext
+		}
+	}
+
+	return nil
+}
+
+type extensionScope interface {
+	extensions() []*desc.FieldDescriptor
+	nestedScopes() []extensionScope
+}
+
+// fileDescriptorExtensions implements extensionHolder interface on top of
+// FileDescriptorProto
+type fileDescriptorExtensions struct {
+	proto *desc.FileDescriptor
+}
+
+func (fde fileDescriptorExtensions) extensions() []*desc.FieldDescriptor {
+	return fde.proto.GetExtensions()
+}
+
+func (fde fileDescriptorExtensions) nestedScopes() []extensionScope {
+	scopes := make([]extensionScope, len(fde.proto.GetMessageTypes()))
+	for i, m := range fde.proto.GetMessageTypes() {
+		scopes[i] = msgDescriptorExtensions{m}
+	}
+	return scopes
+}
+
+// msgDescriptorExtensions implements extensionHolder interface on top of
+// DescriptorProto
+type msgDescriptorExtensions struct {
+	proto *desc.MessageDescriptor
+}
+
+func (mde msgDescriptorExtensions) extensions() []*desc.FieldDescriptor {
+	return mde.proto.GetNestedExtensions()
+}
+
+func (mde msgDescriptorExtensions) nestedScopes() []extensionScope {
+	scopes := make([]extensionScope, len(mde.proto.GetNestedMessageTypes()))
+	for i, m := range mde.proto.GetNestedMessageTypes() {
+		scopes[i] = msgDescriptorExtensions{m}
+	}
+	return scopes
+}
diff --git a/vendor/github.com/jhump/protoreflect/grpcreflect/doc.go b/vendor/github.com/jhump/protoreflect/grpcreflect/doc.go
new file mode 100644
index 0000000..ec7bd02
--- /dev/null
+++ b/vendor/github.com/jhump/protoreflect/grpcreflect/doc.go
@@ -0,0 +1,10 @@
+// Package grpcreflect provides GRPC-specific extensions to protobuf reflection.
+// This includes a way to access rich service descriptors for all services that
+// a GRPC server exports.
+//
+// Also included is an easy-to-use client for the GRPC reflection service
+// (https://goo.gl/2ILAHf). This client makes it easy to ask a server (that
+// supports the reflection service) for metadata on its exported services, which
+// could be used to construct a dynamic client. (See the grpcdynamic package in
+// this same repo for more on that.)
+package grpcreflect
diff --git a/vendor/github.com/jhump/protoreflect/grpcreflect/server.go b/vendor/github.com/jhump/protoreflect/grpcreflect/server.go
new file mode 100644
index 0000000..c9ef619
--- /dev/null
+++ b/vendor/github.com/jhump/protoreflect/grpcreflect/server.go
@@ -0,0 +1,61 @@
+package grpcreflect
+
+import (
+	"fmt"
+
+	"google.golang.org/grpc"
+
+	"github.com/jhump/protoreflect/desc"
+)
+
+// LoadServiceDescriptors loads the service descriptors for all services exposed by the
+// given GRPC server.
+func LoadServiceDescriptors(s *grpc.Server) (map[string]*desc.ServiceDescriptor, error) {
+	descs := map[string]*desc.ServiceDescriptor{}
+	for name, info := range s.GetServiceInfo() {
+		file, ok := info.Metadata.(string)
+		if !ok {
+			return nil, fmt.Errorf("service %q has unexpected metadata: expecting a string; got %v", name, info.Metadata)
+		}
+		fd, err := desc.LoadFileDescriptor(file)
+		if err != nil {
+			return nil, err
+		}
+		d := fd.FindSymbol(name)
+		if d == nil {
+			return nil, fmt.Errorf("file descriptor for %q has no element named %q", file, name)
+		}
+		sd, ok := d.(*desc.ServiceDescriptor)
+		if !ok {
+			return nil, fmt.Errorf("file descriptor for %q has incorrect element named %q: expecting a service descriptor; got %v", file, name, d)
+		}
+		descs[name] = sd
+	}
+	return descs, nil
+}
+
+// LoadServiceDescriptor loads a rich descriptor for a given service description
+// generated by protoc-gen-go. Generated code contains an unexported symbol with
+// a name like "_<Service>_serviceDesc" which is the service's description. It
+// is used internally to register a service implementation with a GRPC server.
+// But it can also be used by this package to retrieve the rich descriptor for
+// the service.
+func LoadServiceDescriptor(svc *grpc.ServiceDesc) (*desc.ServiceDescriptor, error) {
+	file, ok := svc.Metadata.(string)
+	if !ok {
+		return nil, fmt.Errorf("service %q has unexpected metadata: expecting a string; got %v", svc.ServiceName, svc.Metadata)
+	}
+	fd, err := desc.LoadFileDescriptor(file)
+	if err != nil {
+		return nil, err
+	}
+	d := fd.FindSymbol(svc.ServiceName)
+	if d == nil {
+		return nil, fmt.Errorf("file descriptor for %q has no element named %q", file, svc.ServiceName)
+	}
+	sd, ok := d.(*desc.ServiceDescriptor)
+	if !ok {
+		return nil, fmt.Errorf("file descriptor for %q has incorrect element named %q: expecting a service descriptor; got %v", file, svc.ServiceName, d)
+	}
+	return sd, nil
+}
diff --git a/vendor/github.com/jhump/protoreflect/internal/codec/buffer.go b/vendor/github.com/jhump/protoreflect/internal/codec/buffer.go
new file mode 100644
index 0000000..09f8849
--- /dev/null
+++ b/vendor/github.com/jhump/protoreflect/internal/codec/buffer.go
@@ -0,0 +1,118 @@
+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
+}
+
+// IsDeterministic returns whether or not this buffer is configured to encode
+// messages deterministically.
+func (cb *Buffer) IsDeterministic() bool {
+	return cb.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, io.ErrUnexpectedEOF
+// is returned and the buffer is unchanged. Otherwise, the given number
+// of bytes are skipped and nil 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/internal/codec/decode.go b/vendor/github.com/jhump/protoreflect/internal/codec/decode.go
new file mode 100644
index 0000000..a25f680
--- /dev/null
+++ b/vendor/github.com/jhump/protoreflect/internal/codec/decode.go
@@ -0,0 +1,346 @@
+package codec
+
+import (
+	"errors"
+	"fmt"
+	"io"
+	"math"
+
+	"github.com/golang/protobuf/proto"
+)
+
+// 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")
+
+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
+}
+
+// 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
+}
+
+// SkipField attempts to skip the value of a field with the given wire
+// type. When consuming a protobuf-encoded stream, it can be called immediately
+// after DecodeTagAndWireType to discard the subsequent data for the field.
+func (cb *Buffer) SkipField(wireType int8) error {
+	switch wireType {
+	case proto.WireFixed32:
+		if err := cb.Skip(4); err != nil {
+			return err
+		}
+	case proto.WireFixed64:
+		if err := cb.Skip(8); err != nil {
+			return 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 ErrOverflow
+			}
+			if i >= len(cb.buf) {
+				return io.ErrUnexpectedEOF
+			}
+			if cb.buf[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 err
+		}
+		if err := cb.Skip(int(l)); err != nil {
+			return err
+		}
+	case proto.WireStartGroup:
+		if err := cb.SkipGroup(); err != nil {
+			return err
+		}
+	default:
+		return ErrBadWireType
+	}
+	return nil
+}
+
+func (cb *Buffer) findGroupEnd() (groupEnd int, dataEnd int, err error) {
+	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
+		}
+		if wireType == proto.WireEndGroup {
+			return cb.index, fieldStart, nil
+		}
+		// skip past the field's data
+		if err := cb.SkipField(wireType); err != nil {
+			return 0, 0, err
+		}
+	}
+}
diff --git a/vendor/github.com/jhump/protoreflect/internal/codec/encode.go b/vendor/github.com/jhump/protoreflect/internal/codec/encode.go
new file mode 100644
index 0000000..524f1bc
--- /dev/null
+++ b/vendor/github.com/jhump/protoreflect/internal/codec/encode.go
@@ -0,0 +1,147 @@
+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
+}
+
+// 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.
+
+	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
+		}
+
+		var buf proto.Buffer
+		buf.SetDeterministic(true)
+		if err := buf.Marshal(pm); err != nil {
+			return nil, err
+		}
+		bytes := buf.Bytes()
+		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/internal/standard_files.go b/vendor/github.com/jhump/protoreflect/internal/standard_files.go
new file mode 100644
index 0000000..4a8b47a
--- /dev/null
+++ b/vendor/github.com/jhump/protoreflect/internal/standard_files.go
@@ -0,0 +1,127 @@
+// 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/github.com/jhump/protoreflect/internal/unrecognized.go b/vendor/github.com/jhump/protoreflect/internal/unrecognized.go
new file mode 100644
index 0000000..c903d4b
--- /dev/null
+++ b/vendor/github.com/jhump/protoreflect/internal/unrecognized.go
@@ -0,0 +1,86 @@
+package internal
+
+import (
+	"reflect"
+
+	"github.com/golang/protobuf/proto"
+)
+
+var typeOfBytes = reflect.TypeOf([]byte(nil))
+
+// GetUnrecognized fetches the bytes of unrecognized fields for the given message.
+func GetUnrecognized(msg proto.Message) []byte {
+	val := reflect.Indirect(reflect.ValueOf(msg))
+	u := val.FieldByName("XXX_unrecognized")
+	if u.IsValid() && u.Type() == typeOfBytes {
+		return u.Interface().([]byte)
+	}
+
+	// Fallback to reflection for API v2 messages
+	get, _, _, ok := unrecognizedGetSetMethods(val)
+	if !ok {
+		return nil
+	}
+
+	return get.Call([]reflect.Value(nil))[0].Convert(typeOfBytes).Interface().([]byte)
+}
+
+// SetUnrecognized adds the given bytes to the unrecognized fields for the given message.
+func SetUnrecognized(msg proto.Message, data []byte) {
+	val := reflect.Indirect(reflect.ValueOf(msg))
+	u := val.FieldByName("XXX_unrecognized")
+	if u.IsValid() && u.Type() == typeOfBytes {
+		// Just store the bytes in the unrecognized field
+		ub := u.Interface().([]byte)
+		ub = append(ub, data...)
+		u.Set(reflect.ValueOf(ub))
+		return
+	}
+
+	// Fallback to reflection for API v2 messages
+	get, set, argType, ok := unrecognizedGetSetMethods(val)
+	if !ok {
+		return
+	}
+
+	existing := get.Call([]reflect.Value(nil))[0].Convert(typeOfBytes).Interface().([]byte)
+	if len(existing) > 0 {
+		data = append(existing, data...)
+	}
+	set.Call([]reflect.Value{reflect.ValueOf(data).Convert(argType)})
+}
+
+func unrecognizedGetSetMethods(val reflect.Value) (get reflect.Value, set reflect.Value, argType reflect.Type, ok bool) {
+	// val could be an APIv2 message. We use reflection to interact with
+	// this message so that we don't have a hard dependency on the new
+	// version of the protobuf package.
+	refMethod := val.MethodByName("ProtoReflect")
+	if !refMethod.IsValid() {
+		if val.CanAddr() {
+			refMethod = val.Addr().MethodByName("ProtoReflect")
+		}
+		if !refMethod.IsValid() {
+			return
+		}
+	}
+	refType := refMethod.Type()
+	if refType.NumIn() != 0 || refType.NumOut() != 1 {
+		return
+	}
+	ref := refMethod.Call([]reflect.Value(nil))
+	getMethod, setMethod := ref[0].MethodByName("GetUnknown"), ref[0].MethodByName("SetUnknown")
+	if !getMethod.IsValid() || !setMethod.IsValid() {
+		return
+	}
+	getType := getMethod.Type()
+	setType := setMethod.Type()
+	if getType.NumIn() != 0 || getType.NumOut() != 1 || setType.NumIn() != 1 || setType.NumOut() != 0 {
+		return
+	}
+	arg := setType.In(0)
+	if !arg.ConvertibleTo(typeOfBytes) || getType.Out(0) != arg {
+		return
+	}
+
+	return getMethod, setMethod, arg, true
+}
diff --git a/vendor/github.com/opencord/voltha-lib-go/v7/pkg/grpc/client.go b/vendor/github.com/opencord/voltha-lib-go/v7/pkg/grpc/client.go
new file mode 100644
index 0000000..294983f
--- /dev/null
+++ b/vendor/github.com/opencord/voltha-lib-go/v7/pkg/grpc/client.go
@@ -0,0 +1,667 @@
+/*
+ * Copyright 2021-present Open Networking Foundation
+ *
+ * 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 grpc
+
+import (
+	"context"
+	"fmt"
+	"reflect"
+	"strings"
+	"sync"
+	"time"
+
+	grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware"
+	grpc_opentracing "github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing"
+	"github.com/jhump/protoreflect/dynamic/grpcdynamic"
+	"github.com/jhump/protoreflect/grpcreflect"
+	"github.com/opencord/voltha-lib-go/v7/pkg/log"
+	"github.com/opencord/voltha-lib-go/v7/pkg/probe"
+	"github.com/opencord/voltha-protos/v5/go/adapter_service"
+	"github.com/opencord/voltha-protos/v5/go/common"
+	"github.com/opencord/voltha-protos/v5/go/core_service"
+	"github.com/opencord/voltha-protos/v5/go/olt_inter_adapter_service"
+	"github.com/opencord/voltha-protos/v5/go/onu_inter_adapter_service"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/codes"
+	rpb "google.golang.org/grpc/reflection/grpc_reflection_v1alpha"
+	"google.golang.org/grpc/status"
+)
+
+type event byte
+type state byte
+type GetServiceClient func(context.Context, *grpc.ClientConn) interface{}
+type RestartedHandler func(ctx context.Context, endPoint string) error
+
+const (
+	grpcBackoffInitialInterval = "GRPC_BACKOFF_INITIAL_INTERVAL"
+	grpcBackoffMaxInterval     = "GRPC_BACKOFF_MAX_INTERVAL"
+	grpcBackoffMaxElapsedTime  = "GRPC_BACKOFF_MAX_ELAPSED_TIME"
+	grpcMonitorInterval        = "GRPC_MONITOR_INTERVAL"
+)
+
+const (
+	DefaultBackoffInitialInterval = 100 * time.Millisecond
+	DefaultBackoffMaxInterval     = 5 * time.Second
+	DefaultBackoffMaxElapsedTime  = 0 * time.Second // No time limit
+	DefaultGRPCMonitorInterval    = 5 * time.Second
+)
+
+const (
+	eventConnecting = event(iota)
+	eventValidatingConnection
+	eventConnected
+	eventDisconnected
+	eventStopped
+	eventError
+
+	stateConnected = state(iota)
+	stateValidatingConnection
+	stateConnecting
+	stateDisconnected
+)
+
+type Client struct {
+	clientEndpoint         string
+	clientContextData      string
+	serverEndPoint         string
+	remoteServiceName      string
+	connection             *grpc.ClientConn
+	connectionLock         sync.RWMutex
+	stateLock              sync.RWMutex
+	state                  state
+	service                interface{}
+	events                 chan event
+	onRestart              RestartedHandler
+	backoffInitialInterval time.Duration
+	backoffMaxInterval     time.Duration
+	backoffMaxElapsedTime  time.Duration
+	monitorInterval        time.Duration
+	done                   bool
+	livenessLock           sync.RWMutex
+	livenessCallback       func(timestamp time.Time)
+}
+
+type ClientOption func(*Client)
+
+func ClientContextData(data string) ClientOption {
+	return func(args *Client) {
+		args.clientContextData = data
+	}
+}
+
+func NewClient(clientEndpoint, serverEndpoint, remoteServiceName string, onRestart RestartedHandler,
+	opts ...ClientOption) (*Client, error) {
+	c := &Client{
+		clientEndpoint:         clientEndpoint,
+		serverEndPoint:         serverEndpoint,
+		remoteServiceName:      remoteServiceName,
+		onRestart:              onRestart,
+		events:                 make(chan event, 5),
+		state:                  stateDisconnected,
+		backoffInitialInterval: DefaultBackoffInitialInterval,
+		backoffMaxInterval:     DefaultBackoffMaxInterval,
+		backoffMaxElapsedTime:  DefaultBackoffMaxElapsedTime,
+		monitorInterval:        DefaultGRPCMonitorInterval,
+	}
+	for _, option := range opts {
+		option(c)
+	}
+
+	// Check for environment variables
+	if err := SetFromEnvVariable(grpcBackoffInitialInterval, &c.backoffInitialInterval); err != nil {
+		logger.Warnw(context.Background(), "failure-reading-env-variable", log.Fields{"error": err, "variable": grpcBackoffInitialInterval})
+	}
+
+	if err := SetFromEnvVariable(grpcBackoffMaxInterval, &c.backoffMaxInterval); err != nil {
+		logger.Warnw(context.Background(), "failure-reading-env-variable", log.Fields{"error": err, "variable": grpcBackoffMaxInterval})
+	}
+
+	if err := SetFromEnvVariable(grpcBackoffMaxElapsedTime, &c.backoffMaxElapsedTime); err != nil {
+		logger.Warnw(context.Background(), "failure-reading-env-variable", log.Fields{"error": err, "variable": grpcBackoffMaxElapsedTime})
+	}
+
+	if err := SetFromEnvVariable(grpcMonitorInterval, &c.monitorInterval); err != nil {
+		logger.Warnw(context.Background(), "failure-reading-env-variable", log.Fields{"error": err, "variable": grpcMonitorInterval})
+	}
+
+	logger.Infow(context.Background(), "initialized-client", log.Fields{"client": c})
+
+	// Sanity check
+	if c.backoffInitialInterval > c.backoffMaxInterval {
+		return nil, fmt.Errorf("initial retry delay %v is greater than maximum retry delay %v", c.backoffInitialInterval, c.backoffMaxInterval)
+	}
+
+	grpc.EnableTracing = true
+
+	return c, nil
+}
+
+func (c *Client) GetClient() (interface{}, error) {
+	c.connectionLock.RLock()
+	defer c.connectionLock.RUnlock()
+	if c.service == nil {
+		return nil, fmt.Errorf("no connection to %s", c.serverEndPoint)
+	}
+	return c.service, nil
+}
+
+// GetCoreServiceClient is a helper function that returns a concrete service instead of the GetClient() API
+// which returns an interface
+func (c *Client) GetCoreServiceClient() (core_service.CoreServiceClient, error) {
+	c.connectionLock.RLock()
+	defer c.connectionLock.RUnlock()
+	if c.service == nil {
+		return nil, fmt.Errorf("no core connection to %s", c.serverEndPoint)
+	}
+	client, ok := c.service.(core_service.CoreServiceClient)
+	if ok {
+		return client, nil
+	}
+	return nil, fmt.Errorf("invalid-service-%s", reflect.TypeOf(c.service))
+}
+
+// GetOnuAdapterServiceClient is a helper function that returns a concrete service instead of the GetClient() API
+// which returns an interface
+func (c *Client) GetOnuInterAdapterServiceClient() (onu_inter_adapter_service.OnuInterAdapterServiceClient, error) {
+	c.connectionLock.RLock()
+	defer c.connectionLock.RUnlock()
+	if c.service == nil {
+		return nil, fmt.Errorf("no child adapter connection to %s", c.serverEndPoint)
+	}
+	client, ok := c.service.(onu_inter_adapter_service.OnuInterAdapterServiceClient)
+	if ok {
+		return client, nil
+	}
+	return nil, fmt.Errorf("invalid-service-%s", reflect.TypeOf(c.service))
+}
+
+// GetOltAdapterServiceClient is a helper function that returns a concrete service instead of the GetClient() API
+// which returns an interface
+func (c *Client) GetOltInterAdapterServiceClient() (olt_inter_adapter_service.OltInterAdapterServiceClient, error) {
+	c.connectionLock.RLock()
+	defer c.connectionLock.RUnlock()
+	if c.service == nil {
+		return nil, fmt.Errorf("no parent adapter connection to %s", c.serverEndPoint)
+	}
+	client, ok := c.service.(olt_inter_adapter_service.OltInterAdapterServiceClient)
+	if ok {
+		return client, nil
+	}
+	return nil, fmt.Errorf("invalid-service-%s", reflect.TypeOf(c.service))
+}
+
+// GetAdapterServiceClient is a helper function that returns a concrete service instead of the GetClient() API
+// which returns an interface
+func (c *Client) GetAdapterServiceClient() (adapter_service.AdapterServiceClient, error) {
+	c.connectionLock.RLock()
+	defer c.connectionLock.RUnlock()
+	if c.service == nil {
+		return nil, fmt.Errorf("no adapter service connection to %s", c.serverEndPoint)
+	}
+	client, ok := c.service.(adapter_service.AdapterServiceClient)
+	if ok {
+		return client, nil
+	}
+	return nil, fmt.Errorf("invalid-service-%s", reflect.TypeOf(c.service))
+}
+
+func (c *Client) Reset(ctx context.Context) {
+	logger.Debugw(ctx, "resetting-client-connection", log.Fields{"api-endpoint": c.serverEndPoint, "client": c.clientEndpoint})
+	c.stateLock.Lock()
+	defer c.stateLock.Unlock()
+	if c.state == stateConnected {
+		c.state = stateDisconnected
+		c.events <- eventDisconnected
+	}
+}
+
+// executeWithTimeout runs a sending function (sf) along with a receiving one(rf) and returns an error, if any.
+// If the deadline d elapses first, it returns a grpc DeadlineExceeded error instead.
+func (c *Client) executeWithTimeout(sf func(*common.Connection) error, rf func() (interface{}, error), conn *common.Connection, d time.Duration) error {
+	errChan := make(chan error, 1)
+	go func() {
+		err := sf(conn)
+		logger.Debugw(context.Background(), "message-sent", log.Fields{"error": err, "qpi-endpoint": c.serverEndPoint, "client": c.clientEndpoint})
+		if err == nil {
+			response, err := rf()
+			logger.Debugw(context.Background(), "message-received", log.Fields{"error": err, "qpi-endpoint": c.serverEndPoint, "client": c.clientEndpoint, "health": response})
+		}
+		errChan <- err
+		close(errChan)
+	}()
+	t := time.NewTimer(d)
+	select {
+	case <-t.C:
+		return status.Errorf(codes.DeadlineExceeded, "timeout-on-sending-message")
+	case err := <-errChan:
+		if !t.Stop() {
+			<-t.C
+		}
+		return err
+	}
+}
+
+func (c *Client) monitorConnection(ctx context.Context) {
+	logger.Debugw(ctx, "monitor-connection-started", log.Fields{"qpi-endpoint": c.serverEndPoint, "client": c.clientEndpoint})
+
+	// If we exit, assume disconnected
+	defer func() {
+		c.stateLock.Lock()
+		if !c.done && (c.state == stateConnected || c.state == stateValidatingConnection) {
+			// Handle only connected state here.  We need the validating state to know if we need to backoff before a retry
+			if c.state == stateConnected {
+				c.state = stateDisconnected
+			}
+			logger.Warnw(ctx, "sending-disconnect-event", log.Fields{"api-endpoint": c.serverEndPoint, "client": c.clientEndpoint, "curr-state": stateConnected, "new-state": c.state})
+			c.events <- eventDisconnected
+		} else {
+			logger.Debugw(ctx, "no-state-change-needed", log.Fields{"api-endpoint": c.serverEndPoint, "client": c.clientEndpoint, "state": c.state, "client-done": c.done})
+		}
+		c.stateLock.Unlock()
+		logger.Debugw(ctx, "monitor-connection-ended", log.Fields{"api-endpoint": c.serverEndPoint, "client": c.clientEndpoint})
+	}()
+
+	c.connectionLock.RLock()
+	conn := c.connection
+	c.connectionLock.RUnlock()
+	if conn == nil {
+		logger.Errorw(ctx, "connection-nil", log.Fields{"api-endpoint": c.serverEndPoint, "client": c.clientEndpoint})
+		return
+	}
+
+	// Get a new client using reflection. The server can implement any grpc service, but it
+	// needs to also implement the "StartKeepAliveStream" API
+	grpcReflectClient := grpcreflect.NewClient(ctx, rpb.NewServerReflectionClient(conn))
+	if grpcReflectClient == nil {
+		logger.Errorw(ctx, "grpc-reflect-client-nil", log.Fields{"api-endpoint": c.serverEndPoint, "client": c.clientEndpoint})
+		return
+	}
+
+	// Get the list of services - there should be 2 services: a server reflection and the voltha service we are interested in
+	services, err := grpcReflectClient.ListServices()
+	if err != nil {
+		logger.Errorw(ctx, "list-services-error", log.Fields{"api-endpoint": c.serverEndPoint, "client": c.clientEndpoint, "error": err})
+		return
+	}
+
+	// Filter out the service
+	logger.Debugw(ctx, "services", log.Fields{"services": services})
+	serviceOfInterest := ""
+	for _, service := range services {
+		if strings.EqualFold(service, c.remoteServiceName) {
+			serviceOfInterest = service
+			break
+		}
+	}
+	if serviceOfInterest == "" {
+		logger.Errorw(ctx, "no-service-found", log.Fields{"api-endpoint": c.serverEndPoint, "client": c.clientEndpoint, "services": services, "expected-remote-service": c.remoteServiceName})
+		return
+	}
+
+	// Resolve the service
+	resolvedService, err := grpcReflectClient.ResolveService(serviceOfInterest)
+	if err != nil {
+		logger.Errorw(ctx, "service-error", log.Fields{"api-endpoint": c.serverEndPoint, "client": c.clientEndpoint, "service": resolvedService, "error": err})
+		return
+	}
+
+	// Find the method of interest
+	method := resolvedService.FindMethodByName("GetHealthStatus")
+	if method == nil {
+		logger.Errorw(ctx, "nil-method", log.Fields{"api-endpoint": c.serverEndPoint, "client": c.clientEndpoint, "service": resolvedService})
+		return
+	}
+	logger.Debugw(ctx, "resolved-to-method", log.Fields{"service": resolvedService.GetName(), "method": method.GetName()})
+
+	// Get a dynamic connection
+	dynamicConn := grpcdynamic.NewStub(conn)
+
+	// Get the stream and send this client information
+	streamCtx, streamDone := context.WithCancel(log.WithSpanFromContext(context.Background(), ctx))
+	defer streamDone()
+	stream, err := dynamicConn.InvokeRpcBidiStream(streamCtx, method)
+	if err != nil {
+		logger.Errorw(ctx, "stream-error", log.Fields{"api-endpoint": c.serverEndPoint, "client": c.clientEndpoint, "service": resolvedService, "error": err})
+		return
+	}
+
+	clientInfo := &common.Connection{
+		Endpoint:          c.clientEndpoint,
+		ContextInfo:       c.clientContextData,
+		KeepAliveInterval: int64(c.monitorInterval),
+	}
+
+	initialConnection := true
+loop:
+	for {
+		// Let's send a keep alive message with our info
+		err := c.executeWithTimeout(
+			func(conn *common.Connection) error { return stream.SendMsg(conn) },
+			func() (interface{}, error) { return stream.RecvMsg() },
+			clientInfo,
+			c.monitorInterval)
+
+		if err != nil {
+			// Any error means the far end is gone
+			logger.Errorw(ctx, "sending-stream-error", log.Fields{"error": err, "api-endpoint": c.serverEndPoint, "client": c.clientEndpoint, "context": stream.Context().Err()})
+			break loop
+		}
+		// Send a connect event
+		if initialConnection {
+			logger.Debugw(ctx, "first-stream-data-sent", log.Fields{"api-endpoint": c.serverEndPoint, "client": c.clientEndpoint})
+			c.events <- eventConnected
+			initialConnection = false
+		}
+		logger.Debugw(ctx, "stream-data-sent", log.Fields{"api-endpoint": c.serverEndPoint, "client": c.clientEndpoint})
+		// Update liveness, if configured
+		c.livenessLock.RLock()
+		if c.livenessCallback != nil {
+			go c.livenessCallback(time.Now())
+		}
+		c.livenessLock.RUnlock()
+
+		// Wait to send the next keep alive
+		keepAliveTimer := time.NewTimer(time.Duration(clientInfo.KeepAliveInterval))
+		select {
+		case <-ctx.Done():
+			logger.Warnw(ctx, "context-done", log.Fields{"api-endpont": c.serverEndPoint, "client": c.clientEndpoint})
+			break loop
+		case <-stream.Context().Done():
+			logger.Debugw(ctx, "stream-context-done", log.Fields{"api-endpoint": c.serverEndPoint, "stream-info": stream.Context(), "client": c.clientEndpoint})
+			break loop
+		case <-keepAliveTimer.C:
+			continue
+		}
+	}
+	if stream != nil {
+		if err := stream.CloseSend(); err != nil {
+			logger.Warnw(ctx, "closing-stream-error", log.Fields{"error": err, "api-endpoint": c.serverEndPoint, "client": c.clientEndpoint})
+		}
+	}
+}
+
+// Start kicks off the adapter agent by trying to connect to the adapter
+func (c *Client) Start(ctx context.Context, handler GetServiceClient) {
+	logger.Debugw(ctx, "Starting GRPC - Client", log.Fields{"api-endpoint": c.serverEndPoint})
+
+	// If the context contains a k8s probe then register services
+	p := probe.GetProbeFromContext(ctx)
+	if p != nil {
+		p.RegisterService(ctx, c.serverEndPoint)
+	}
+
+	var monitorConnectionCtx context.Context
+	var monitorConnectionDone func()
+
+	initialConnection := true
+	c.events <- eventConnecting
+	backoff := NewBackoff(c.backoffInitialInterval, c.backoffMaxInterval, c.backoffMaxElapsedTime)
+	attempt := 1
+loop:
+	for {
+		select {
+		case <-ctx.Done():
+			logger.Warnw(ctx, "context-closing", log.Fields{"api_endpoint": c.serverEndPoint, "client": c.clientEndpoint, "context": ctx})
+			c.connectionLock.Lock()
+			if !c.done {
+				c.done = true
+				c.events <- eventStopped
+				close(c.events)
+			}
+			c.connectionLock.Unlock()
+			// break loop
+		case event := <-c.events:
+			logger.Debugw(ctx, "received-event", log.Fields{"event": event, "api-endpoint": c.serverEndPoint, "client": c.clientEndpoint})
+			c.connectionLock.RLock()
+			// On a client stopped, just allow the stop event to go through
+			if c.done && event != eventStopped {
+				c.connectionLock.RUnlock()
+				logger.Debugw(ctx, "ignoring-event-on-client-stop", log.Fields{"event": event, "api-endpoint": c.serverEndPoint, "client": c.clientEndpoint})
+				continue
+			}
+			c.connectionLock.RUnlock()
+			switch event {
+			case eventConnecting:
+				c.stateLock.Lock()
+				logger.Debugw(ctx, "connection-start", log.Fields{"api-endpoint": c.serverEndPoint, "attempts": attempt, "curr-state": c.state, "client": c.clientEndpoint})
+				if c.state == stateConnected {
+					c.state = stateDisconnected
+				}
+				if c.state != stateConnecting {
+					c.state = stateConnecting
+					go func() {
+						if err := c.connectToEndpoint(ctx, p); err != nil {
+							c.stateLock.Lock()
+							c.state = stateDisconnected
+							c.stateLock.Unlock()
+							logger.Errorw(ctx, "connection-failed", log.Fields{"api-endpoint": c.serverEndPoint, "attempt": attempt, "client": c.clientEndpoint, "error": err})
+
+							// Retry connection after a delay
+							if err = backoff.Backoff(ctx); err != nil {
+								// Context has closed or reached maximum elapsed time, if set
+								logger.Errorw(ctx, "retry-aborted", log.Fields{"api-endpoint": c.serverEndPoint, "client": c.clientEndpoint, "error": err})
+								return
+							}
+							attempt += 1
+							c.connectionLock.RLock()
+							if !c.done {
+								c.events <- eventConnecting
+							}
+							c.connectionLock.RUnlock()
+						}
+					}()
+				}
+				c.stateLock.Unlock()
+
+			case eventValidatingConnection:
+				logger.Debugw(ctx, "connection-validation", log.Fields{"api-endpoint": c.serverEndPoint, "client": c.clientEndpoint})
+				c.stateLock.Lock()
+				if c.state != stateConnected {
+					c.state = stateValidatingConnection
+				}
+				c.stateLock.Unlock()
+				monitorConnectionCtx, monitorConnectionDone = context.WithCancel(context.Background())
+				go c.monitorConnection(monitorConnectionCtx)
+
+			case eventConnected:
+				attempt = 1
+				backoff.Reset()
+				c.stateLock.Lock()
+				logger.Debugw(ctx, "endpoint-connected", log.Fields{"api-endpoint": c.serverEndPoint, "curr-state": c.state, "client": c.clientEndpoint})
+				if c.state != stateConnected {
+					// Setup the service
+					c.connectionLock.RLock()
+					conn := c.connection
+					c.connectionLock.RUnlock()
+
+					subCtx, cancel := context.WithTimeout(ctx, c.backoffMaxInterval)
+					svc := handler(subCtx, conn)
+					if svc != nil {
+						c.service = svc
+						if p != nil {
+							p.UpdateStatus(ctx, c.serverEndPoint, probe.ServiceStatusRunning)
+						}
+						logger.Infow(ctx, "connected-to-endpoint", log.Fields{"api-endpoint": c.serverEndPoint, "client": c.clientEndpoint})
+					} else {
+						// Should never happen, but just in case
+						logger.Warnw(ctx, "service-is-nil", log.Fields{"api-endpoint": c.serverEndPoint, "client": c.clientEndpoint})
+						c.events <- eventDisconnected
+					}
+					cancel()
+					c.state = stateConnected
+					if initialConnection {
+						logger.Debugw(ctx, "initial-endpoint-connection", log.Fields{"api-endpoint": c.serverEndPoint, "client": c.clientEndpoint})
+						initialConnection = false
+					} else {
+						logger.Debugw(ctx, "endpoint-reconnection", log.Fields{"api-endpoint": c.serverEndPoint, "client": c.clientEndpoint})
+						// Trigger any callback on a restart
+						go func() {
+							err := c.onRestart(log.WithSpanFromContext(context.Background(), ctx), c.serverEndPoint)
+							if err != nil {
+								logger.Errorw(ctx, "unable-to-restart-endpoint", log.Fields{"error": err, "api-endpoint": c.serverEndPoint, "client": c.clientEndpoint})
+							}
+						}()
+					}
+				}
+				c.stateLock.Unlock()
+
+			case eventDisconnected:
+				if p != nil {
+					p.UpdateStatus(ctx, c.serverEndPoint, probe.ServiceStatusNotReady)
+				}
+				connectionValidationFail := false
+				c.stateLock.Lock()
+				logger.Debugw(ctx, "endpoint-disconnected", log.Fields{"api-endpoint": c.serverEndPoint, "curr-state": c.state, "client": c.clientEndpoint})
+				if c.state == stateValidatingConnection {
+					connectionValidationFail = true
+					c.state = stateDisconnected
+				}
+				c.stateLock.Unlock()
+
+				// Stop the streaming connection
+				if monitorConnectionDone != nil {
+					monitorConnectionDone()
+					monitorConnectionDone = nil
+				}
+
+				if connectionValidationFail {
+					// Retry connection after a delay
+					if err := backoff.Backoff(ctx); err != nil {
+						// Context has closed or reached maximum elapsed time, if set
+						logger.Errorw(ctx, "retry-aborted", log.Fields{"api-endpoint": c.serverEndPoint, "client": c.clientEndpoint, "error": err})
+						return
+					}
+				}
+				c.connectionLock.RLock()
+				if !c.done {
+					c.events <- eventConnecting
+				}
+				c.connectionLock.RUnlock()
+
+			case eventStopped:
+				logger.Debugw(ctx, "endpoint-stopped", log.Fields{"api-endpoint": c.serverEndPoint, "client": c.clientEndpoint})
+
+				if monitorConnectionDone != nil {
+					monitorConnectionDone()
+					monitorConnectionDone = nil
+				}
+				if err := c.closeConnection(ctx, p); err != nil {
+					logger.Errorw(ctx, "endpoint-closing-connection-failed", log.Fields{"api-endpoint": c.serverEndPoint, "client": c.clientEndpoint, "error": err})
+				}
+				break loop
+			case eventError:
+				logger.Errorw(ctx, "endpoint-error-event", log.Fields{"api-endpoint": c.serverEndPoint, "client": c.clientEndpoint})
+			default:
+				logger.Errorw(ctx, "endpoint-unknown-event", log.Fields{"api-endpoint": c.serverEndPoint, "client": c.clientEndpoint, "error": event})
+			}
+		}
+	}
+
+	// Stop the streaming connection
+	if monitorConnectionDone != nil {
+		logger.Debugw(ctx, "closing-connection-monitoring", log.Fields{"api-endpoint": c.serverEndPoint, "client": c.clientEndpoint})
+		monitorConnectionDone()
+	}
+
+	logger.Infow(ctx, "client-stopped", log.Fields{"api-endpoint": c.serverEndPoint, "client": c.clientEndpoint})
+}
+
+func (c *Client) connectToEndpoint(ctx context.Context, p *probe.Probe) error {
+	if p != nil {
+		p.UpdateStatus(ctx, c.serverEndPoint, probe.ServiceStatusPreparing)
+	}
+
+	c.connectionLock.Lock()
+	defer c.connectionLock.Unlock()
+
+	if c.connection != nil {
+		_ = c.connection.Close()
+		c.connection = nil
+	}
+
+	c.service = nil
+
+	// Use Interceptors to:
+	// 1. automatically inject
+	// 2. publish Open Tracing Spans by this GRPC Client
+	// 3. detect connection failure on client calls such that the reconnection process can begin
+	conn, err := grpc.Dial(c.serverEndPoint,
+		grpc.WithInsecure(),
+		grpc.WithStreamInterceptor(grpc_middleware.ChainStreamClient(
+			grpc_opentracing.StreamClientInterceptor(grpc_opentracing.WithTracer(log.ActiveTracerProxy{})),
+		)),
+		grpc.WithUnaryInterceptor(grpc_middleware.ChainUnaryClient(
+			grpc_opentracing.UnaryClientInterceptor(grpc_opentracing.WithTracer(log.ActiveTracerProxy{})),
+		)),
+	)
+
+	if err == nil {
+		c.connection = conn
+		c.events <- eventValidatingConnection
+		return nil
+	} else {
+		logger.Warnw(ctx, "no-connection-to-endpoint", log.Fields{"api-endpoint": c.serverEndPoint, "client": c.clientEndpoint, "error": err})
+	}
+
+	if p != nil {
+		p.UpdateStatus(ctx, c.serverEndPoint, probe.ServiceStatusFailed)
+	}
+	return fmt.Errorf("no connection to api endpoint %s", c.serverEndPoint)
+}
+
+func (c *Client) closeConnection(ctx context.Context, p *probe.Probe) error {
+	if p != nil {
+		p.UpdateStatus(ctx, c.serverEndPoint, probe.ServiceStatusStopped)
+	}
+	logger.Infow(ctx, "client-closing-connection", log.Fields{"api-endpoint": c.serverEndPoint, "client": c.clientEndpoint})
+
+	c.connectionLock.Lock()
+	defer c.connectionLock.Unlock()
+
+	if c.connection != nil {
+		err := c.connection.Close()
+		c.service = nil
+		c.connection = nil
+		return err
+	}
+
+	return nil
+}
+
+func (c *Client) Stop(ctx context.Context) {
+	logger.Infow(ctx, "client-stop-request-event-received", log.Fields{"api-endpoint": c.serverEndPoint, "client": c.clientEndpoint})
+	c.connectionLock.Lock()
+	defer c.connectionLock.Unlock()
+	if !c.done {
+		c.done = true
+		c.events <- eventStopped
+		close(c.events)
+	}
+	logger.Infow(ctx, "client-stop-request-event-sent", log.Fields{"api-endpoint": c.serverEndPoint, "client": c.clientEndpoint})
+}
+
+// SetService is used for testing only
+func (c *Client) SetService(srv interface{}) {
+	c.connectionLock.Lock()
+	defer c.connectionLock.Unlock()
+	c.service = srv
+}
+
+func (c *Client) SubscribeForLiveness(callback func(timestamp time.Time)) {
+	c.livenessLock.Lock()
+	defer c.livenessLock.Unlock()
+	c.livenessCallback = callback
+}
diff --git a/vendor/github.com/opencord/voltha-lib-go/v7/pkg/grpc/common.go b/vendor/github.com/opencord/voltha-lib-go/v7/pkg/grpc/common.go
new file mode 100644
index 0000000..77aad4f
--- /dev/null
+++ b/vendor/github.com/opencord/voltha-lib-go/v7/pkg/grpc/common.go
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+ *
+ * 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 grpc
+
+import (
+	"github.com/opencord/voltha-lib-go/v7/pkg/log"
+)
+
+var logger log.CLogger
+
+func init() {
+	// Setup this package so that it's log level can be modified at run time
+	var err error
+	logger, err = log.RegisterPackage(log.JSON, log.ErrorLevel, log.Fields{})
+	if err != nil {
+		panic(err)
+	}
+}
diff --git a/vendor/github.com/opencord/voltha-lib-go/v7/pkg/grpc/mock_core_service.go b/vendor/github.com/opencord/voltha-lib-go/v7/pkg/grpc/mock_core_service.go
new file mode 100644
index 0000000..8365956
--- /dev/null
+++ b/vendor/github.com/opencord/voltha-lib-go/v7/pkg/grpc/mock_core_service.go
@@ -0,0 +1,189 @@
+/*
+ * Copyright 2021-present Open Networking Foundation
+
+ * 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 grpc
+
+import (
+	"context"
+	"fmt"
+	"strconv"
+	"time"
+
+	"github.com/golang/protobuf/ptypes/empty"
+	"github.com/opencord/voltha-lib-go/v7/pkg/log"
+	"github.com/opencord/voltha-protos/v5/go/common"
+	ca "github.com/opencord/voltha-protos/v5/go/core_adapter"
+	"github.com/opencord/voltha-protos/v5/go/core_service"
+	"github.com/opencord/voltha-protos/v5/go/health"
+	"github.com/opencord/voltha-protos/v5/go/voltha"
+)
+
+//MockCoreServiceHandler implements the methods in the core service
+type MockCoreServiceHandler struct {
+	exitChannel chan struct{}
+}
+
+func NewMockCoreServiceHandler() *MockCoreServiceHandler {
+	return &MockCoreServiceHandler{exitChannel: make(chan struct{})}
+}
+
+func (handler *MockCoreServiceHandler) Start() {
+	logger.Debug(context.Background(), "starting-mock-core-service")
+}
+
+func (handler *MockCoreServiceHandler) Stop() {
+	logger.Debug(context.Background(), "stopping-mock-core-service")
+	close(handler.exitChannel)
+}
+
+func (handler *MockCoreServiceHandler) RegisterAdapter(ctx context.Context, reg *ca.AdapterRegistration) (*empty.Empty, error) {
+	//logger.Debugw(ctx, "registration-received", log.Fields{"input": reg})
+	return &empty.Empty{}, nil
+}
+
+func (handler *MockCoreServiceHandler) DeviceUpdate(context.Context, *voltha.Device) (*empty.Empty, error) {
+	return &empty.Empty{}, nil
+}
+
+func (handler *MockCoreServiceHandler) PortCreated(context.Context, *voltha.Port) (*empty.Empty, error) {
+	return &empty.Empty{}, nil
+}
+
+func (handler *MockCoreServiceHandler) PortsStateUpdate(context.Context, *ca.PortStateFilter) (*empty.Empty, error) {
+	return &empty.Empty{}, nil
+}
+
+func (handler *MockCoreServiceHandler) DeleteAllPorts(context.Context, *common.ID) (*empty.Empty, error) {
+	return &empty.Empty{}, nil
+}
+
+func (handler *MockCoreServiceHandler) GetDevicePort(context.Context, *ca.PortFilter) (*voltha.Port, error) {
+	return &voltha.Port{}, nil
+}
+
+func (handler *MockCoreServiceHandler) ListDevicePorts(context.Context, *common.ID) (*voltha.Ports, error) {
+	return &voltha.Ports{}, nil
+}
+
+func (handler *MockCoreServiceHandler) DeviceStateUpdate(context.Context, *ca.DeviceStateFilter) (*empty.Empty, error) {
+	return &empty.Empty{}, nil
+}
+
+func (handler *MockCoreServiceHandler) DevicePMConfigUpdate(context.Context, *voltha.PmConfigs) (*empty.Empty, error) {
+	return &empty.Empty{}, nil
+}
+
+func (handler *MockCoreServiceHandler) ChildDeviceDetected(context.Context, *ca.DeviceDiscovery) (*voltha.Device, error) {
+	return &voltha.Device{}, nil
+}
+
+func (handler *MockCoreServiceHandler) ChildDevicesLost(context.Context, *common.ID) (*empty.Empty, error) {
+	return &empty.Empty{}, nil
+}
+
+func (handler *MockCoreServiceHandler) ChildDevicesDetected(context.Context, *common.ID) (*empty.Empty, error) {
+	time.Sleep(50 * time.Millisecond)
+	return &empty.Empty{}, nil
+}
+
+func (handler *MockCoreServiceHandler) GetDevice(ctx context.Context, id *common.ID) (*voltha.Device, error) {
+	time.Sleep(50 * time.Millisecond)
+	vlan, _ := strconv.Atoi(id.Id)
+	return &voltha.Device{
+		Id:   id.Id,
+		Type: "test-1234",
+		Vlan: uint32(vlan),
+	}, nil
+}
+
+func (handler *MockCoreServiceHandler) GetChildDevice(context.Context, *ca.ChildDeviceFilter) (*voltha.Device, error) {
+	return nil, nil
+}
+
+func (handler *MockCoreServiceHandler) GetChildDevices(context.Context, *common.ID) (*voltha.Devices, error) {
+	return &voltha.Devices{}, nil
+}
+
+func (handler *MockCoreServiceHandler) SendPacketIn(context.Context, *ca.PacketIn) (*empty.Empty, error) {
+	return &empty.Empty{}, nil
+}
+
+func (handler *MockCoreServiceHandler) DeviceReasonUpdate(context.Context, *ca.DeviceReason) (*empty.Empty, error) {
+	return &empty.Empty{}, nil
+}
+
+func (handler *MockCoreServiceHandler) PortStateUpdate(context.Context, *ca.PortState) (*empty.Empty, error) {
+	return &empty.Empty{}, nil
+}
+
+// Additional API found in the Core - unused?
+func (handler *MockCoreServiceHandler) ReconcileChildDevices(context.Context, *common.ID) (*empty.Empty, error) {
+	return &empty.Empty{}, nil
+}
+
+func (handler *MockCoreServiceHandler) GetChildDeviceWithProxyAddress(context.Context, *voltha.Device_ProxyAddress) (*voltha.Device, error) {
+	return &voltha.Device{}, nil
+}
+
+func (handler *MockCoreServiceHandler) GetPorts(context.Context, *ca.PortFilter) (*voltha.Ports, error) {
+	return &voltha.Ports{}, nil
+}
+
+func (handler *MockCoreServiceHandler) ChildrenStateUpdate(context.Context, *ca.DeviceStateFilter) (*empty.Empty, error) {
+	return &empty.Empty{}, nil
+}
+
+func (handler *MockCoreServiceHandler) UpdateImageDownload(context.Context, *voltha.ImageDownload) (*empty.Empty, error) {
+	return &empty.Empty{}, nil
+}
+
+func (handler *MockCoreServiceHandler) GetHealthStatus(stream core_service.CoreService_GetHealthStatusServer) error {
+	logger.Debugw(context.Background(), "keep-alive-connection", log.Fields{"stream": stream})
+	if stream == nil {
+		return fmt.Errorf("stream-is-nil %v", stream)
+	}
+	var err error
+	var remoteClient *common.Connection
+	var tempClient *common.Connection
+	ctx := context.Background()
+loop:
+	for {
+		tempClient, err = stream.Recv()
+		if err != nil {
+			logger.Warnw(ctx, "received-stream-error", log.Fields{"remote-client": remoteClient, "error": err})
+			break loop
+		}
+		// Send a response back
+		err = stream.Send(&health.HealthStatus{State: health.HealthStatus_HEALTHY})
+		if err != nil {
+			logger.Warnw(ctx, "sending-stream-error", log.Fields{"remote-client": remoteClient, "error": err})
+			break loop
+		}
+
+		remoteClient = tempClient
+		logger.Debugw(ctx, "received-keep-alive", log.Fields{"remote-client": remoteClient})
+		select {
+		case <-stream.Context().Done():
+			logger.Infow(ctx, "stream-keep-alive-context-done", log.Fields{"remote-client": remoteClient, "error": stream.Context().Err()})
+			break loop
+		case <-handler.exitChannel:
+			logger.Warnw(ctx, "received-stop", log.Fields{"remote-client": remoteClient})
+			break loop
+		default:
+		}
+	}
+	logger.Errorw(context.Background(), "connection-down", log.Fields{"remote-client": remoteClient, "error": err})
+	return err
+}
diff --git a/vendor/github.com/opencord/voltha-lib-go/v7/pkg/grpc/security.go b/vendor/github.com/opencord/voltha-lib-go/v7/pkg/grpc/security.go
new file mode 100644
index 0000000..930d2c8
--- /dev/null
+++ b/vendor/github.com/opencord/voltha-lib-go/v7/pkg/grpc/security.go
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * 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 grpc
+
+type GrpcSecurity struct {
+	KeyFile  string
+	CertFile string
+	CaFile   string
+}
diff --git a/vendor/github.com/opencord/voltha-lib-go/v7/pkg/grpc/server.go b/vendor/github.com/opencord/voltha-lib-go/v7/pkg/grpc/server.go
new file mode 100644
index 0000000..bee418d
--- /dev/null
+++ b/vendor/github.com/opencord/voltha-lib-go/v7/pkg/grpc/server.go
@@ -0,0 +1,180 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * 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 grpc
+
+import (
+	"context"
+	"net"
+
+	grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware"
+	grpc_opentracing "github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing"
+	"github.com/opencord/voltha-lib-go/v7/pkg/log"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/codes"
+	"google.golang.org/grpc/credentials"
+	"google.golang.org/grpc/reflection"
+	"google.golang.org/grpc/status"
+)
+
+/*
+To add a GRPC server to your existing component simply follow these steps:
+
+1. Create a server instance by passing the host and port where it should run and optionally add certificate information
+
+	e.g.
+	s.server = server.NewGrpcServer(s.config.GrpcHost, s.config.GrpcPort, nil, false)
+
+2. Create a function that will register your service with the GRPC server
+
+    e.g.
+	f := func(gs *grpc.Server) {
+		voltha.RegisterVolthaReadOnlyServiceServer(
+			gs,
+			core.NewReadOnlyServiceHandler(s.root),
+		)
+	}
+
+3. Add the service to the server
+
+    e.g.
+	s.server.AddService(f)
+
+4. Start the server
+
+	s.server.Start(ctx)
+*/
+
+// Interface allows probes to be attached to server
+// A probe must support the IsReady() method
+type ReadyProbe interface {
+	IsReady() bool
+}
+
+type GrpcServer struct {
+	gs       *grpc.Server
+	address  string
+	secure   bool
+	services []func(*grpc.Server)
+	probe    ReadyProbe // optional
+
+	*GrpcSecurity
+}
+
+/*
+Instantiate a GRPC server data structure
+*/
+func NewGrpcServer(
+	address string,
+	certs *GrpcSecurity,
+	secure bool,
+	probe ReadyProbe,
+) *GrpcServer {
+	server := &GrpcServer{
+		address:      address,
+		secure:       secure,
+		GrpcSecurity: certs,
+		probe:        probe,
+	}
+	return server
+}
+
+/*
+Start prepares the GRPC server and starts servicing requests
+*/
+func (s *GrpcServer) Start(ctx context.Context) {
+
+	lis, err := net.Listen("tcp", s.address)
+	if err != nil {
+		logger.Fatalf(ctx, "failed to listen: %v", err)
+	}
+
+	// Use Intercepters to automatically inject and publish Open Tracing Spans by this GRPC server
+	serverOptions := []grpc.ServerOption{
+		grpc.StreamInterceptor(grpc_middleware.ChainStreamServer(
+			grpc_opentracing.StreamServerInterceptor(grpc_opentracing.WithTracer(log.ActiveTracerProxy{})),
+		)),
+		grpc.UnaryInterceptor(grpc_middleware.ChainUnaryServer(
+			grpc_opentracing.UnaryServerInterceptor(grpc_opentracing.WithTracer(log.ActiveTracerProxy{})),
+			mkServerInterceptor(s),
+		))}
+
+	if s.secure && s.GrpcSecurity != nil {
+		creds, err := credentials.NewServerTLSFromFile(s.CertFile, s.KeyFile)
+		if err != nil {
+			logger.Fatalf(ctx, "could not load TLS keys: %s", err)
+		}
+
+		serverOptions = append(serverOptions, grpc.Creds(creds))
+		s.gs = grpc.NewServer(serverOptions...)
+	} else {
+		logger.Info(ctx, "starting-insecure-grpc-server")
+		s.gs = grpc.NewServer(serverOptions...)
+	}
+
+	// Register all required services
+	for _, service := range s.services {
+		service(s.gs)
+	}
+	reflection.Register(s.gs)
+
+	if err := s.gs.Serve(lis); err != nil {
+		logger.Fatalf(ctx, "failed to serve: %v\n", err)
+	}
+}
+
+// Make a serverInterceptor for the given GrpcServer
+// This interceptor will check whether there is an attached probe,
+// and if that probe indicates NotReady, then an UNAVAILABLE
+// response will be returned.
+func mkServerInterceptor(s *GrpcServer) func(ctx context.Context,
+	req interface{},
+	info *grpc.UnaryServerInfo,
+	handler grpc.UnaryHandler) (interface{}, error) {
+
+	return func(ctx context.Context,
+		req interface{},
+		info *grpc.UnaryServerInfo,
+		handler grpc.UnaryHandler) (interface{}, error) {
+
+		if (s.probe != nil) && (!s.probe.IsReady()) {
+			logger.Warnf(ctx, "Grpc request received while not ready %v", req)
+			return nil, status.Error(codes.Unavailable, "system is not ready")
+		}
+
+		// Calls the handler
+		h, err := handler(ctx, req)
+
+		return h, err
+	}
+}
+
+/*
+Stop servicing GRPC requests
+*/
+func (s *GrpcServer) Stop() {
+	if s.gs != nil {
+		s.gs.Stop()
+	}
+}
+
+/*
+AddService appends a generic service request function
+*/
+func (s *GrpcServer) AddService(
+	registerFunction func(*grpc.Server),
+) {
+	s.services = append(s.services, registerFunction)
+}
diff --git a/vendor/github.com/opencord/voltha-lib-go/v7/pkg/grpc/utils.go b/vendor/github.com/opencord/voltha-lib-go/v7/pkg/grpc/utils.go
new file mode 100644
index 0000000..85686de
--- /dev/null
+++ b/vendor/github.com/opencord/voltha-lib-go/v7/pkg/grpc/utils.go
@@ -0,0 +1,126 @@
+/*
+ * Copyright 2021-present Open Networking Foundation
+
+ * 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 grpc
+
+import (
+	"context"
+	"errors"
+	"fmt"
+	"math"
+	"os"
+	"reflect"
+	"sync"
+	"time"
+)
+
+const (
+	incrementalFactor = 1.5
+	minBackOff        = 10 * time.Millisecond
+)
+
+type Backoff struct {
+	attempt          int
+	initialInterval  time.Duration
+	maxElapsedTime   time.Duration
+	maxInterval      time.Duration
+	totalElapsedTime time.Duration
+	mutex            sync.RWMutex
+}
+
+func NewBackoff(initialInterval, maxInterval, maxElapsedTime time.Duration) *Backoff {
+	bo := &Backoff{}
+	bo.initialInterval = initialInterval
+	bo.maxInterval = maxInterval
+	bo.maxElapsedTime = maxElapsedTime
+	return bo
+}
+
+func (bo *Backoff) Backoff(ctx context.Context) error {
+	duration, err := bo.getBackOffDuration()
+	if err != nil {
+		return err
+	}
+
+	ticker := time.NewTicker(duration)
+	defer ticker.Stop()
+	select {
+	case <-ctx.Done():
+		return ctx.Err()
+	case <-ticker.C:
+	}
+	return nil
+}
+
+func (bo *Backoff) getBackOffDuration() (duration time.Duration, err error) {
+	err = nil
+	defer func() {
+		bo.mutex.Lock()
+		defer bo.mutex.Unlock()
+		bo.attempt += 1
+		bo.totalElapsedTime += duration
+		if bo.maxElapsedTime > 0 && bo.totalElapsedTime > bo.maxElapsedTime {
+			err = errors.New("max elapsed backoff time reached")
+		}
+	}()
+
+	if bo.initialInterval <= minBackOff {
+		bo.initialInterval = minBackOff
+	}
+	if bo.initialInterval > bo.maxInterval {
+		duration = bo.initialInterval
+		return
+	}
+
+	// Calculate incremental duration
+	minf := float64(bo.initialInterval)
+	durf := minf * math.Pow(incrementalFactor, float64(bo.attempt))
+
+	if durf > math.MaxInt64 {
+		duration = bo.maxInterval
+		return
+	}
+	duration = time.Duration(durf)
+
+	//Keep within bounds
+	if duration < bo.initialInterval {
+		duration = bo.initialInterval
+	}
+	if duration > bo.maxInterval {
+		duration = bo.maxInterval
+	}
+	return
+}
+
+func (bo *Backoff) Reset() {
+	bo.mutex.Lock()
+	defer bo.mutex.Unlock()
+	bo.attempt = 0
+	bo.totalElapsedTime = 0
+}
+
+func SetFromEnvVariable(key string, variableToSet interface{}) error {
+	if _, ok := variableToSet.(*time.Duration); !ok {
+		return fmt.Errorf("unsupported type %T", variableToSet)
+	}
+	if valStr, present := os.LookupEnv(key); present {
+		val, err := time.ParseDuration(valStr)
+		if err != nil {
+			return err
+		}
+		reflect.ValueOf(variableToSet).Elem().Set(reflect.ValueOf(val))
+	}
+	return nil
+}
diff --git a/vendor/github.com/opencord/voltha-protos/v5/go/adapter_service/adapter_service.pb.go b/vendor/github.com/opencord/voltha-protos/v5/go/adapter_service/adapter_service.pb.go
new file mode 100644
index 0000000..31f5673
--- /dev/null
+++ b/vendor/github.com/opencord/voltha-protos/v5/go/adapter_service/adapter_service.pb.go
@@ -0,0 +1,1460 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// source: voltha_protos/adapter_service.proto
+
+package adapter_service
+
+import (
+	context "context"
+	fmt "fmt"
+	proto "github.com/golang/protobuf/proto"
+	empty "github.com/golang/protobuf/ptypes/empty"
+	common "github.com/opencord/voltha-protos/v5/go/common"
+	core_adapter "github.com/opencord/voltha-protos/v5/go/core_adapter"
+	extension "github.com/opencord/voltha-protos/v5/go/extension"
+	health "github.com/opencord/voltha-protos/v5/go/health"
+	omci "github.com/opencord/voltha-protos/v5/go/omci"
+	voltha "github.com/opencord/voltha-protos/v5/go/voltha"
+	grpc "google.golang.org/grpc"
+	codes "google.golang.org/grpc/codes"
+	status "google.golang.org/grpc/status"
+	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
+
+func init() {
+	proto.RegisterFile("voltha_protos/adapter_service.proto", fileDescriptor_038e6ec340f67698)
+}
+
+var fileDescriptor_038e6ec340f67698 = []byte{
+	// 853 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x96, 0xdf, 0x6e, 0xdb, 0x36,
+	0x14, 0xc6, 0x91, 0x0d, 0xd8, 0xc5, 0x49, 0x6c, 0x27, 0x6c, 0x96, 0x0e, 0x0a, 0x56, 0x74, 0xed,
+	0xcd, 0x6e, 0x2a, 0x0f, 0x2d, 0xda, 0x6e, 0x18, 0x86, 0xcd, 0xff, 0xea, 0x7a, 0x6b, 0xe1, 0xc0,
+	0x9a, 0x8b, 0x61, 0x37, 0x01, 0x2d, 0x1d, 0xcb, 0x44, 0x29, 0x52, 0x13, 0x8f, 0x9c, 0xf6, 0x0d,
+	0xf6, 0x08, 0x7b, 0xdc, 0x41, 0x12, 0xe5, 0x58, 0xaa, 0xdd, 0xd6, 0x4e, 0xee, 0xac, 0xf3, 0xf1,
+	0xfb, 0xf1, 0xf0, 0x1c, 0x9a, 0x24, 0x3c, 0x5c, 0x6a, 0x49, 0x0b, 0x7e, 0x19, 0x27, 0x9a, 0xb4,
+	0x69, 0xf3, 0x80, 0xc7, 0x84, 0xc9, 0xa5, 0xc1, 0x64, 0x29, 0x7c, 0x74, 0xf3, 0x30, 0x6b, 0xd5,
+	0xc2, 0xce, 0x79, 0xa8, 0x75, 0x28, 0xb1, 0x9d, 0xcb, 0xb3, 0x74, 0xde, 0xc6, 0x28, 0xa6, 0xf7,
+	0xc5, 0x68, 0xc7, 0xa9, 0x22, 0x7d, 0x1d, 0x45, 0x5a, 0x59, 0xed, 0x7e, 0x5d, 0x4b, 0xf0, 0xd2,
+	0xc2, 0x37, 0xbb, 0x03, 0xbc, 0xce, 0xc3, 0xb9, 0x57, 0xd5, 0xf0, 0x1d, 0xa1, 0x32, 0x42, 0x2b,
+	0xb3, 0xd9, 0xbb, 0x40, 0x2e, 0x69, 0xb1, 0x59, 0x2b, 0xbe, 0xac, 0xf6, 0x6d, 0x55, 0xd3, 0x91,
+	0x2f, 0x2e, 0x09, 0x0d, 0x6d, 0xb6, 0xe2, 0x12, 0x15, 0xd9, 0x29, 0x1f, 0xff, 0x77, 0x07, 0x9a,
+	0x9d, 0x62, 0x01, 0x5e, 0x51, 0x1c, 0xf6, 0x2b, 0xb4, 0x86, 0x48, 0x2f, 0xf3, 0xc9, 0x3d, 0xe2,
+	0x94, 0x1a, 0xc6, 0x5c, 0x5b, 0x85, 0x9e, 0x56, 0x0a, 0x7d, 0x12, 0x5a, 0x39, 0xa7, 0xae, 0xcd,
+	0x6f, 0x7d, 0xe4, 0xf7, 0x07, 0x3f, 0x1c, 0xb0, 0xa7, 0x70, 0xd8, 0x09, 0x74, 0x4c, 0xfd, 0x7c,
+	0xed, 0xac, 0xe9, 0xda, 0x22, 0x14, 0xdf, 0xce, 0x99, 0x5b, 0x54, 0xdf, 0x2d, 0xab, 0xef, 0x0e,
+	0xb2, 0xea, 0xb3, 0x9f, 0xa0, 0x35, 0x41, 0x5f, 0x2b, 0x5f, 0x48, 0xdc, 0xd1, 0xfa, 0x0c, 0x8e,
+	0xfa, 0x28, 0x91, 0x76, 0xf5, 0x3d, 0x87, 0x46, 0x5f, 0x18, 0x3e, 0xdb, 0x79, 0xc2, 0x1f, 0xa1,
+	0x39, 0xc1, 0x81, 0xda, 0xc3, 0xf9, 0x0c, 0x8e, 0x26, 0x38, 0xd3, 0x9a, 0x76, 0x9f, 0xd1, 0x43,
+	0x39, 0xff, 0x13, 0xcd, 0xae, 0xce, 0x2e, 0x1c, 0x0f, 0x91, 0xc6, 0xf3, 0xb8, 0x18, 0x37, 0x52,
+	0x73, 0xfd, 0x81, 0xf7, 0x9e, 0x5b, 0xd9, 0xca, 0xde, 0x95, 0x20, 0x7f, 0xd1, 0xe3, 0x31, 0x9f,
+	0x09, 0x29, 0x8a, 0xde, 0xf4, 0x16, 0x42, 0x06, 0xc5, 0xf0, 0x57, 0xda, 0xd0, 0x67, 0x4f, 0xff,
+	0x18, 0xa0, 0x28, 0xd4, 0x85, 0x4e, 0x88, 0x1d, 0x95, 0xae, 0xec, 0x6b, 0xab, 0xe7, 0x09, 0x1c,
+	0xda, 0xbe, 0xec, 0x60, 0xea, 0x42, 0x6b, 0x1a, 0x07, 0x9c, 0xf0, 0x85, 0xd4, 0x57, 0xa6, 0x9b,
+	0xca, 0xb7, 0xec, 0x6e, 0x75, 0x59, 0x59, 0x2c, 0x17, 0xb7, 0x32, 0x26, 0xf0, 0xcd, 0x1a, 0x63,
+	0xa4, 0xfc, 0x04, 0x23, 0x54, 0xc4, 0xa5, 0x7c, 0xcf, 0x6a, 0x35, 0x5a, 0x13, 0x3f, 0xce, 0xfc,
+	0x0d, 0x1a, 0x1e, 0xaa, 0xe0, 0x82, 0xfb, 0x6f, 0x91, 0xc6, 0x29, 0xd5, 0xb3, 0x5a, 0x09, 0x5b,
+	0x09, 0x03, 0x68, 0x16, 0x59, 0x5d, 0x44, 0x3d, 0xad, 0xe6, 0x22, 0x64, 0xe7, 0x35, 0x84, 0x8d,
+	0x9b, 0xac, 0xb9, 0x5b, 0x31, 0x1e, 0x1c, 0xf7, 0xf5, 0x95, 0x92, 0x9a, 0x07, 0x63, 0x95, 0x8e,
+	0x22, 0x1e, 0x22, 0x7b, 0x50, 0xed, 0x62, 0x1e, 0x2c, 0x07, 0x4d, 0xf0, 0x9f, 0x14, 0x0d, 0x39,
+	0xe7, 0x1b, 0xc6, 0x4c, 0xd0, 0xc4, 0x5a, 0x19, 0x64, 0xaf, 0xe0, 0x24, 0xdb, 0x5d, 0x96, 0x67,
+	0xcf, 0x0b, 0x67, 0xa3, 0xe3, 0x33, 0x68, 0x63, 0x38, 0xed, 0xcc, 0x74, 0xb2, 0xe2, 0x4d, 0xe3,
+	0x30, 0xe1, 0x01, 0xee, 0x0f, 0x7c, 0x04, 0x47, 0x6b, 0xe9, 0x19, 0x06, 0xe5, 0x49, 0x36, 0xea,
+	0x3b, 0x27, 0xa5, 0xf1, 0x5a, 0xfe, 0x03, 0x8e, 0x3b, 0x3e, 0x89, 0x25, 0x27, 0x5c, 0x95, 0x68,
+	0xef, 0xb9, 0x47, 0xd0, 0xec, 0xe9, 0x28, 0x12, 0x74, 0x73, 0xd4, 0x18, 0x1a, 0x65, 0x57, 0xca,
+	0xbe, 0x55, 0x37, 0xe3, 0x7a, 0xdf, 0x5e, 0xa3, 0x31, 0x3c, 0x44, 0xe7, 0xeb, 0x92, 0x58, 0x51,
+	0x1f, 0x7c, 0xf9, 0xef, 0x17, 0x07, 0xec, 0x2f, 0x38, 0x1b, 0x22, 0x55, 0x04, 0xdb, 0xbb, 0x9b,
+	0x92, 0xa7, 0x70, 0xa7, 0xc7, 0x95, 0x8f, 0xb2, 0xa2, 0xdd, 0x06, 0xb6, 0xec, 0x8c, 0xdd, 0x19,
+	0xd9, 0x1f, 0xe2, 0xc6, 0x58, 0x0f, 0x4e, 0x26, 0xb8, 0xc4, 0x84, 0x6e, 0x13, 0xfa, 0x33, 0x34,
+	0x3c, 0xe2, 0x09, 0x8d, 0x23, 0x5f, 0x64, 0x07, 0x36, 0x3b, 0xab, 0x02, 0xc7, 0xaf, 0x7b, 0xa3,
+	0x2c, 0xee, 0x30, 0x37, 0xbb, 0xab, 0xdd, 0xec, 0xf7, 0xaa, 0xd5, 0xbf, 0x43, 0xc3, 0x13, 0x51,
+	0x2a, 0x39, 0x61, 0x47, 0xf2, 0x24, 0xaa, 0x67, 0x53, 0x11, 0xaf, 0xb3, 0xb1, 0xdb, 0x7a, 0x1c,
+	0x63, 0xc2, 0xb3, 0xfb, 0x39, 0xe3, 0xe5, 0x89, 0xa4, 0x71, 0x9c, 0xa0, 0x31, 0x83, 0xec, 0xd6,
+	0x67, 0xcc, 0xcd, 0x6f, 0x7f, 0x37, 0xff, 0x7a, 0x21, 0x24, 0x61, 0xb2, 0xf5, 0xb8, 0xf8, 0x05,
+	0x5a, 0x53, 0xb5, 0xbf, 0xfd, 0x25, 0x1c, 0x0e, 0x91, 0x06, 0xef, 0xe8, 0x0d, 0x97, 0x29, 0xb2,
+	0xfb, 0xd5, 0x55, 0xac, 0x49, 0xe5, 0x1a, 0xee, 0xba, 0xab, 0x07, 0x91, 0x3b, 0x41, 0x4a, 0x13,
+	0x95, 0xcb, 0x86, 0x0d, 0xe1, 0xd0, 0xdb, 0x4e, 0xf2, 0x3e, 0x24, 0x6d, 0x4b, 0x69, 0x0a, 0xcd,
+	0x21, 0x92, 0x27, 0x54, 0x28, 0xb1, 0x64, 0x5d, 0xcf, 0x59, 0xc4, 0x87, 0x58, 0xb0, 0xca, 0xbf,
+	0xe5, 0x77, 0x1f, 0x19, 0x61, 0x3b, 0x36, 0xcd, 0xae, 0xe6, 0x4f, 0x60, 0xbd, 0x4f, 0x62, 0xbd,
+	0x1a, 0xb6, 0x4b, 0xf0, 0x50, 0x27, 0xa1, 0xab, 0x63, 0x54, 0xbe, 0x4e, 0x02, 0xd7, 0x3e, 0xf9,
+	0x6a, 0x6f, 0xd9, 0xee, 0xe9, 0x9b, 0x3c, 0x5e, 0x7d, 0xc4, 0xfd, 0xfd, 0x3c, 0x14, 0xb4, 0x48,
+	0x67, 0xd9, 0xb6, 0x68, 0x97, 0x04, 0xfb, 0x68, 0x7c, 0x54, 0x3e, 0x21, 0x9f, 0xb6, 0x43, 0x5d,
+	0x7f, 0x31, 0xcf, 0xbe, 0xca, 0xd5, 0x27, 0xff, 0x07, 0x00, 0x00, 0xff, 0xff, 0xbd, 0x54, 0xa5,
+	0xf6, 0x59, 0x0b, 0x00, 0x00,
+}
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ context.Context
+var _ grpc.ClientConn
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the grpc package it is being compiled against.
+const _ = grpc.SupportPackageIsVersion4
+
+// AdapterServiceClient is the client API for AdapterService service.
+//
+// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
+type AdapterServiceClient interface {
+	// GetHealthStatus is used by an AdapterService client to verify connectivity
+	// to the gRPC server hosting the AdapterService service
+	GetHealthStatus(ctx context.Context, opts ...grpc.CallOption) (AdapterService_GetHealthStatusClient, error)
+	// Device
+	AdoptDevice(ctx context.Context, in *voltha.Device, opts ...grpc.CallOption) (*empty.Empty, error)
+	ReconcileDevice(ctx context.Context, in *voltha.Device, opts ...grpc.CallOption) (*empty.Empty, error)
+	DeleteDevice(ctx context.Context, in *voltha.Device, opts ...grpc.CallOption) (*empty.Empty, error)
+	DisableDevice(ctx context.Context, in *voltha.Device, opts ...grpc.CallOption) (*empty.Empty, error)
+	ReEnableDevice(ctx context.Context, in *voltha.Device, opts ...grpc.CallOption) (*empty.Empty, error)
+	RebootDevice(ctx context.Context, in *voltha.Device, opts ...grpc.CallOption) (*empty.Empty, error)
+	SelfTestDevice(ctx context.Context, in *voltha.Device, opts ...grpc.CallOption) (*empty.Empty, error)
+	GetOfpDeviceInfo(ctx context.Context, in *voltha.Device, opts ...grpc.CallOption) (*core_adapter.SwitchCapability, error)
+	ChildDeviceLost(ctx context.Context, in *voltha.Device, opts ...grpc.CallOption) (*empty.Empty, error)
+	// Ports
+	EnablePort(ctx context.Context, in *voltha.Port, opts ...grpc.CallOption) (*empty.Empty, error)
+	DisablePort(ctx context.Context, in *voltha.Port, opts ...grpc.CallOption) (*empty.Empty, error)
+	// Flows
+	UpdateFlowsBulk(ctx context.Context, in *core_adapter.BulkFlows, opts ...grpc.CallOption) (*empty.Empty, error)
+	UpdateFlowsIncrementally(ctx context.Context, in *core_adapter.IncrementalFlows, opts ...grpc.CallOption) (*empty.Empty, error)
+	//Packets
+	SendPacketOut(ctx context.Context, in *core_adapter.PacketOut, opts ...grpc.CallOption) (*empty.Empty, error)
+	// PM
+	UpdatePmConfig(ctx context.Context, in *core_adapter.PmConfigsInfo, opts ...grpc.CallOption) (*empty.Empty, error)
+	// Image
+	DownloadOnuImage(ctx context.Context, in *voltha.DeviceImageDownloadRequest, opts ...grpc.CallOption) (*voltha.DeviceImageResponse, error)
+	GetOnuImageStatus(ctx context.Context, in *voltha.DeviceImageRequest, opts ...grpc.CallOption) (*voltha.DeviceImageResponse, error)
+	AbortOnuImageUpgrade(ctx context.Context, in *voltha.DeviceImageRequest, opts ...grpc.CallOption) (*voltha.DeviceImageResponse, error)
+	GetOnuImages(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*voltha.OnuImages, error)
+	ActivateOnuImage(ctx context.Context, in *voltha.DeviceImageRequest, opts ...grpc.CallOption) (*voltha.DeviceImageResponse, error)
+	CommitOnuImage(ctx context.Context, in *voltha.DeviceImageRequest, opts ...grpc.CallOption) (*voltha.DeviceImageResponse, error)
+	// Deprecated Image APIs
+	DownloadImage(ctx context.Context, in *core_adapter.ImageDownloadMessage, opts ...grpc.CallOption) (*voltha.ImageDownload, error)
+	GetImageDownloadStatus(ctx context.Context, in *core_adapter.ImageDownloadMessage, opts ...grpc.CallOption) (*voltha.ImageDownload, error)
+	CancelImageDownload(ctx context.Context, in *core_adapter.ImageDownloadMessage, opts ...grpc.CallOption) (*voltha.ImageDownload, error)
+	ActivateImageUpdate(ctx context.Context, in *core_adapter.ImageDownloadMessage, opts ...grpc.CallOption) (*voltha.ImageDownload, error)
+	RevertImageUpdate(ctx context.Context, in *core_adapter.ImageDownloadMessage, opts ...grpc.CallOption) (*voltha.ImageDownload, error)
+	// Tests
+	StartOmciTest(ctx context.Context, in *core_adapter.OMCITest, opts ...grpc.CallOption) (*omci.TestResponse, error)
+	SimulateAlarm(ctx context.Context, in *core_adapter.SimulateAlarmMessage, opts ...grpc.CallOption) (*common.OperationResp, error)
+	// Events
+	SuppressEvent(ctx context.Context, in *voltha.EventFilter, opts ...grpc.CallOption) (*empty.Empty, error)
+	UnSuppressEvent(ctx context.Context, in *voltha.EventFilter, opts ...grpc.CallOption) (*empty.Empty, error)
+	// Get/Set
+	GetExtValue(ctx context.Context, in *core_adapter.GetExtValueMessage, opts ...grpc.CallOption) (*extension.ReturnValues, error)
+	SetExtValue(ctx context.Context, in *core_adapter.SetExtValueMessage, opts ...grpc.CallOption) (*empty.Empty, error)
+	GetSingleValue(ctx context.Context, in *extension.SingleGetValueRequest, opts ...grpc.CallOption) (*extension.SingleGetValueResponse, error)
+	SetSingleValue(ctx context.Context, in *extension.SingleSetValueRequest, opts ...grpc.CallOption) (*extension.SingleSetValueResponse, error)
+}
+
+type adapterServiceClient struct {
+	cc *grpc.ClientConn
+}
+
+func NewAdapterServiceClient(cc *grpc.ClientConn) AdapterServiceClient {
+	return &adapterServiceClient{cc}
+}
+
+func (c *adapterServiceClient) GetHealthStatus(ctx context.Context, opts ...grpc.CallOption) (AdapterService_GetHealthStatusClient, error) {
+	stream, err := c.cc.NewStream(ctx, &_AdapterService_serviceDesc.Streams[0], "/adapter_service.AdapterService/GetHealthStatus", opts...)
+	if err != nil {
+		return nil, err
+	}
+	x := &adapterServiceGetHealthStatusClient{stream}
+	return x, nil
+}
+
+type AdapterService_GetHealthStatusClient interface {
+	Send(*common.Connection) error
+	Recv() (*health.HealthStatus, error)
+	grpc.ClientStream
+}
+
+type adapterServiceGetHealthStatusClient struct {
+	grpc.ClientStream
+}
+
+func (x *adapterServiceGetHealthStatusClient) Send(m *common.Connection) error {
+	return x.ClientStream.SendMsg(m)
+}
+
+func (x *adapterServiceGetHealthStatusClient) Recv() (*health.HealthStatus, error) {
+	m := new(health.HealthStatus)
+	if err := x.ClientStream.RecvMsg(m); err != nil {
+		return nil, err
+	}
+	return m, nil
+}
+
+func (c *adapterServiceClient) AdoptDevice(ctx context.Context, in *voltha.Device, opts ...grpc.CallOption) (*empty.Empty, error) {
+	out := new(empty.Empty)
+	err := c.cc.Invoke(ctx, "/adapter_service.AdapterService/AdoptDevice", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *adapterServiceClient) ReconcileDevice(ctx context.Context, in *voltha.Device, opts ...grpc.CallOption) (*empty.Empty, error) {
+	out := new(empty.Empty)
+	err := c.cc.Invoke(ctx, "/adapter_service.AdapterService/ReconcileDevice", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *adapterServiceClient) DeleteDevice(ctx context.Context, in *voltha.Device, opts ...grpc.CallOption) (*empty.Empty, error) {
+	out := new(empty.Empty)
+	err := c.cc.Invoke(ctx, "/adapter_service.AdapterService/DeleteDevice", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *adapterServiceClient) DisableDevice(ctx context.Context, in *voltha.Device, opts ...grpc.CallOption) (*empty.Empty, error) {
+	out := new(empty.Empty)
+	err := c.cc.Invoke(ctx, "/adapter_service.AdapterService/DisableDevice", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *adapterServiceClient) ReEnableDevice(ctx context.Context, in *voltha.Device, opts ...grpc.CallOption) (*empty.Empty, error) {
+	out := new(empty.Empty)
+	err := c.cc.Invoke(ctx, "/adapter_service.AdapterService/ReEnableDevice", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *adapterServiceClient) RebootDevice(ctx context.Context, in *voltha.Device, opts ...grpc.CallOption) (*empty.Empty, error) {
+	out := new(empty.Empty)
+	err := c.cc.Invoke(ctx, "/adapter_service.AdapterService/RebootDevice", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *adapterServiceClient) SelfTestDevice(ctx context.Context, in *voltha.Device, opts ...grpc.CallOption) (*empty.Empty, error) {
+	out := new(empty.Empty)
+	err := c.cc.Invoke(ctx, "/adapter_service.AdapterService/SelfTestDevice", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *adapterServiceClient) GetOfpDeviceInfo(ctx context.Context, in *voltha.Device, opts ...grpc.CallOption) (*core_adapter.SwitchCapability, error) {
+	out := new(core_adapter.SwitchCapability)
+	err := c.cc.Invoke(ctx, "/adapter_service.AdapterService/GetOfpDeviceInfo", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *adapterServiceClient) ChildDeviceLost(ctx context.Context, in *voltha.Device, opts ...grpc.CallOption) (*empty.Empty, error) {
+	out := new(empty.Empty)
+	err := c.cc.Invoke(ctx, "/adapter_service.AdapterService/ChildDeviceLost", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *adapterServiceClient) EnablePort(ctx context.Context, in *voltha.Port, opts ...grpc.CallOption) (*empty.Empty, error) {
+	out := new(empty.Empty)
+	err := c.cc.Invoke(ctx, "/adapter_service.AdapterService/EnablePort", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *adapterServiceClient) DisablePort(ctx context.Context, in *voltha.Port, opts ...grpc.CallOption) (*empty.Empty, error) {
+	out := new(empty.Empty)
+	err := c.cc.Invoke(ctx, "/adapter_service.AdapterService/DisablePort", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *adapterServiceClient) UpdateFlowsBulk(ctx context.Context, in *core_adapter.BulkFlows, opts ...grpc.CallOption) (*empty.Empty, error) {
+	out := new(empty.Empty)
+	err := c.cc.Invoke(ctx, "/adapter_service.AdapterService/UpdateFlowsBulk", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *adapterServiceClient) UpdateFlowsIncrementally(ctx context.Context, in *core_adapter.IncrementalFlows, opts ...grpc.CallOption) (*empty.Empty, error) {
+	out := new(empty.Empty)
+	err := c.cc.Invoke(ctx, "/adapter_service.AdapterService/UpdateFlowsIncrementally", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *adapterServiceClient) SendPacketOut(ctx context.Context, in *core_adapter.PacketOut, opts ...grpc.CallOption) (*empty.Empty, error) {
+	out := new(empty.Empty)
+	err := c.cc.Invoke(ctx, "/adapter_service.AdapterService/SendPacketOut", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *adapterServiceClient) UpdatePmConfig(ctx context.Context, in *core_adapter.PmConfigsInfo, opts ...grpc.CallOption) (*empty.Empty, error) {
+	out := new(empty.Empty)
+	err := c.cc.Invoke(ctx, "/adapter_service.AdapterService/UpdatePmConfig", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *adapterServiceClient) DownloadOnuImage(ctx context.Context, in *voltha.DeviceImageDownloadRequest, opts ...grpc.CallOption) (*voltha.DeviceImageResponse, error) {
+	out := new(voltha.DeviceImageResponse)
+	err := c.cc.Invoke(ctx, "/adapter_service.AdapterService/DownloadOnuImage", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *adapterServiceClient) GetOnuImageStatus(ctx context.Context, in *voltha.DeviceImageRequest, opts ...grpc.CallOption) (*voltha.DeviceImageResponse, error) {
+	out := new(voltha.DeviceImageResponse)
+	err := c.cc.Invoke(ctx, "/adapter_service.AdapterService/GetOnuImageStatus", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *adapterServiceClient) AbortOnuImageUpgrade(ctx context.Context, in *voltha.DeviceImageRequest, opts ...grpc.CallOption) (*voltha.DeviceImageResponse, error) {
+	out := new(voltha.DeviceImageResponse)
+	err := c.cc.Invoke(ctx, "/adapter_service.AdapterService/AbortOnuImageUpgrade", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *adapterServiceClient) GetOnuImages(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*voltha.OnuImages, error) {
+	out := new(voltha.OnuImages)
+	err := c.cc.Invoke(ctx, "/adapter_service.AdapterService/GetOnuImages", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *adapterServiceClient) ActivateOnuImage(ctx context.Context, in *voltha.DeviceImageRequest, opts ...grpc.CallOption) (*voltha.DeviceImageResponse, error) {
+	out := new(voltha.DeviceImageResponse)
+	err := c.cc.Invoke(ctx, "/adapter_service.AdapterService/ActivateOnuImage", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *adapterServiceClient) CommitOnuImage(ctx context.Context, in *voltha.DeviceImageRequest, opts ...grpc.CallOption) (*voltha.DeviceImageResponse, error) {
+	out := new(voltha.DeviceImageResponse)
+	err := c.cc.Invoke(ctx, "/adapter_service.AdapterService/CommitOnuImage", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+// Deprecated: Do not use.
+func (c *adapterServiceClient) DownloadImage(ctx context.Context, in *core_adapter.ImageDownloadMessage, opts ...grpc.CallOption) (*voltha.ImageDownload, error) {
+	out := new(voltha.ImageDownload)
+	err := c.cc.Invoke(ctx, "/adapter_service.AdapterService/DownloadImage", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+// Deprecated: Do not use.
+func (c *adapterServiceClient) GetImageDownloadStatus(ctx context.Context, in *core_adapter.ImageDownloadMessage, opts ...grpc.CallOption) (*voltha.ImageDownload, error) {
+	out := new(voltha.ImageDownload)
+	err := c.cc.Invoke(ctx, "/adapter_service.AdapterService/GetImageDownloadStatus", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+// Deprecated: Do not use.
+func (c *adapterServiceClient) CancelImageDownload(ctx context.Context, in *core_adapter.ImageDownloadMessage, opts ...grpc.CallOption) (*voltha.ImageDownload, error) {
+	out := new(voltha.ImageDownload)
+	err := c.cc.Invoke(ctx, "/adapter_service.AdapterService/CancelImageDownload", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+// Deprecated: Do not use.
+func (c *adapterServiceClient) ActivateImageUpdate(ctx context.Context, in *core_adapter.ImageDownloadMessage, opts ...grpc.CallOption) (*voltha.ImageDownload, error) {
+	out := new(voltha.ImageDownload)
+	err := c.cc.Invoke(ctx, "/adapter_service.AdapterService/ActivateImageUpdate", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+// Deprecated: Do not use.
+func (c *adapterServiceClient) RevertImageUpdate(ctx context.Context, in *core_adapter.ImageDownloadMessage, opts ...grpc.CallOption) (*voltha.ImageDownload, error) {
+	out := new(voltha.ImageDownload)
+	err := c.cc.Invoke(ctx, "/adapter_service.AdapterService/RevertImageUpdate", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *adapterServiceClient) StartOmciTest(ctx context.Context, in *core_adapter.OMCITest, opts ...grpc.CallOption) (*omci.TestResponse, error) {
+	out := new(omci.TestResponse)
+	err := c.cc.Invoke(ctx, "/adapter_service.AdapterService/StartOmciTest", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *adapterServiceClient) SimulateAlarm(ctx context.Context, in *core_adapter.SimulateAlarmMessage, opts ...grpc.CallOption) (*common.OperationResp, error) {
+	out := new(common.OperationResp)
+	err := c.cc.Invoke(ctx, "/adapter_service.AdapterService/SimulateAlarm", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *adapterServiceClient) SuppressEvent(ctx context.Context, in *voltha.EventFilter, opts ...grpc.CallOption) (*empty.Empty, error) {
+	out := new(empty.Empty)
+	err := c.cc.Invoke(ctx, "/adapter_service.AdapterService/SuppressEvent", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *adapterServiceClient) UnSuppressEvent(ctx context.Context, in *voltha.EventFilter, opts ...grpc.CallOption) (*empty.Empty, error) {
+	out := new(empty.Empty)
+	err := c.cc.Invoke(ctx, "/adapter_service.AdapterService/UnSuppressEvent", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *adapterServiceClient) GetExtValue(ctx context.Context, in *core_adapter.GetExtValueMessage, opts ...grpc.CallOption) (*extension.ReturnValues, error) {
+	out := new(extension.ReturnValues)
+	err := c.cc.Invoke(ctx, "/adapter_service.AdapterService/GetExtValue", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *adapterServiceClient) SetExtValue(ctx context.Context, in *core_adapter.SetExtValueMessage, opts ...grpc.CallOption) (*empty.Empty, error) {
+	out := new(empty.Empty)
+	err := c.cc.Invoke(ctx, "/adapter_service.AdapterService/SetExtValue", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *adapterServiceClient) GetSingleValue(ctx context.Context, in *extension.SingleGetValueRequest, opts ...grpc.CallOption) (*extension.SingleGetValueResponse, error) {
+	out := new(extension.SingleGetValueResponse)
+	err := c.cc.Invoke(ctx, "/adapter_service.AdapterService/GetSingleValue", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *adapterServiceClient) SetSingleValue(ctx context.Context, in *extension.SingleSetValueRequest, opts ...grpc.CallOption) (*extension.SingleSetValueResponse, error) {
+	out := new(extension.SingleSetValueResponse)
+	err := c.cc.Invoke(ctx, "/adapter_service.AdapterService/SetSingleValue", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+// AdapterServiceServer is the server API for AdapterService service.
+type AdapterServiceServer interface {
+	// GetHealthStatus is used by an AdapterService client to verify connectivity
+	// to the gRPC server hosting the AdapterService service
+	GetHealthStatus(AdapterService_GetHealthStatusServer) error
+	// Device
+	AdoptDevice(context.Context, *voltha.Device) (*empty.Empty, error)
+	ReconcileDevice(context.Context, *voltha.Device) (*empty.Empty, error)
+	DeleteDevice(context.Context, *voltha.Device) (*empty.Empty, error)
+	DisableDevice(context.Context, *voltha.Device) (*empty.Empty, error)
+	ReEnableDevice(context.Context, *voltha.Device) (*empty.Empty, error)
+	RebootDevice(context.Context, *voltha.Device) (*empty.Empty, error)
+	SelfTestDevice(context.Context, *voltha.Device) (*empty.Empty, error)
+	GetOfpDeviceInfo(context.Context, *voltha.Device) (*core_adapter.SwitchCapability, error)
+	ChildDeviceLost(context.Context, *voltha.Device) (*empty.Empty, error)
+	// Ports
+	EnablePort(context.Context, *voltha.Port) (*empty.Empty, error)
+	DisablePort(context.Context, *voltha.Port) (*empty.Empty, error)
+	// Flows
+	UpdateFlowsBulk(context.Context, *core_adapter.BulkFlows) (*empty.Empty, error)
+	UpdateFlowsIncrementally(context.Context, *core_adapter.IncrementalFlows) (*empty.Empty, error)
+	//Packets
+	SendPacketOut(context.Context, *core_adapter.PacketOut) (*empty.Empty, error)
+	// PM
+	UpdatePmConfig(context.Context, *core_adapter.PmConfigsInfo) (*empty.Empty, error)
+	// Image
+	DownloadOnuImage(context.Context, *voltha.DeviceImageDownloadRequest) (*voltha.DeviceImageResponse, error)
+	GetOnuImageStatus(context.Context, *voltha.DeviceImageRequest) (*voltha.DeviceImageResponse, error)
+	AbortOnuImageUpgrade(context.Context, *voltha.DeviceImageRequest) (*voltha.DeviceImageResponse, error)
+	GetOnuImages(context.Context, *common.ID) (*voltha.OnuImages, error)
+	ActivateOnuImage(context.Context, *voltha.DeviceImageRequest) (*voltha.DeviceImageResponse, error)
+	CommitOnuImage(context.Context, *voltha.DeviceImageRequest) (*voltha.DeviceImageResponse, error)
+	// Deprecated Image APIs
+	DownloadImage(context.Context, *core_adapter.ImageDownloadMessage) (*voltha.ImageDownload, error)
+	GetImageDownloadStatus(context.Context, *core_adapter.ImageDownloadMessage) (*voltha.ImageDownload, error)
+	CancelImageDownload(context.Context, *core_adapter.ImageDownloadMessage) (*voltha.ImageDownload, error)
+	ActivateImageUpdate(context.Context, *core_adapter.ImageDownloadMessage) (*voltha.ImageDownload, error)
+	RevertImageUpdate(context.Context, *core_adapter.ImageDownloadMessage) (*voltha.ImageDownload, error)
+	// Tests
+	StartOmciTest(context.Context, *core_adapter.OMCITest) (*omci.TestResponse, error)
+	SimulateAlarm(context.Context, *core_adapter.SimulateAlarmMessage) (*common.OperationResp, error)
+	// Events
+	SuppressEvent(context.Context, *voltha.EventFilter) (*empty.Empty, error)
+	UnSuppressEvent(context.Context, *voltha.EventFilter) (*empty.Empty, error)
+	// Get/Set
+	GetExtValue(context.Context, *core_adapter.GetExtValueMessage) (*extension.ReturnValues, error)
+	SetExtValue(context.Context, *core_adapter.SetExtValueMessage) (*empty.Empty, error)
+	GetSingleValue(context.Context, *extension.SingleGetValueRequest) (*extension.SingleGetValueResponse, error)
+	SetSingleValue(context.Context, *extension.SingleSetValueRequest) (*extension.SingleSetValueResponse, error)
+}
+
+// UnimplementedAdapterServiceServer can be embedded to have forward compatible implementations.
+type UnimplementedAdapterServiceServer struct {
+}
+
+func (*UnimplementedAdapterServiceServer) GetHealthStatus(srv AdapterService_GetHealthStatusServer) error {
+	return status.Errorf(codes.Unimplemented, "method GetHealthStatus not implemented")
+}
+func (*UnimplementedAdapterServiceServer) AdoptDevice(ctx context.Context, req *voltha.Device) (*empty.Empty, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method AdoptDevice not implemented")
+}
+func (*UnimplementedAdapterServiceServer) ReconcileDevice(ctx context.Context, req *voltha.Device) (*empty.Empty, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method ReconcileDevice not implemented")
+}
+func (*UnimplementedAdapterServiceServer) DeleteDevice(ctx context.Context, req *voltha.Device) (*empty.Empty, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method DeleteDevice not implemented")
+}
+func (*UnimplementedAdapterServiceServer) DisableDevice(ctx context.Context, req *voltha.Device) (*empty.Empty, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method DisableDevice not implemented")
+}
+func (*UnimplementedAdapterServiceServer) ReEnableDevice(ctx context.Context, req *voltha.Device) (*empty.Empty, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method ReEnableDevice not implemented")
+}
+func (*UnimplementedAdapterServiceServer) RebootDevice(ctx context.Context, req *voltha.Device) (*empty.Empty, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method RebootDevice not implemented")
+}
+func (*UnimplementedAdapterServiceServer) SelfTestDevice(ctx context.Context, req *voltha.Device) (*empty.Empty, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method SelfTestDevice not implemented")
+}
+func (*UnimplementedAdapterServiceServer) GetOfpDeviceInfo(ctx context.Context, req *voltha.Device) (*core_adapter.SwitchCapability, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method GetOfpDeviceInfo not implemented")
+}
+func (*UnimplementedAdapterServiceServer) ChildDeviceLost(ctx context.Context, req *voltha.Device) (*empty.Empty, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method ChildDeviceLost not implemented")
+}
+func (*UnimplementedAdapterServiceServer) EnablePort(ctx context.Context, req *voltha.Port) (*empty.Empty, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method EnablePort not implemented")
+}
+func (*UnimplementedAdapterServiceServer) DisablePort(ctx context.Context, req *voltha.Port) (*empty.Empty, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method DisablePort not implemented")
+}
+func (*UnimplementedAdapterServiceServer) UpdateFlowsBulk(ctx context.Context, req *core_adapter.BulkFlows) (*empty.Empty, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method UpdateFlowsBulk not implemented")
+}
+func (*UnimplementedAdapterServiceServer) UpdateFlowsIncrementally(ctx context.Context, req *core_adapter.IncrementalFlows) (*empty.Empty, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method UpdateFlowsIncrementally not implemented")
+}
+func (*UnimplementedAdapterServiceServer) SendPacketOut(ctx context.Context, req *core_adapter.PacketOut) (*empty.Empty, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method SendPacketOut not implemented")
+}
+func (*UnimplementedAdapterServiceServer) UpdatePmConfig(ctx context.Context, req *core_adapter.PmConfigsInfo) (*empty.Empty, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method UpdatePmConfig not implemented")
+}
+func (*UnimplementedAdapterServiceServer) DownloadOnuImage(ctx context.Context, req *voltha.DeviceImageDownloadRequest) (*voltha.DeviceImageResponse, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method DownloadOnuImage not implemented")
+}
+func (*UnimplementedAdapterServiceServer) GetOnuImageStatus(ctx context.Context, req *voltha.DeviceImageRequest) (*voltha.DeviceImageResponse, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method GetOnuImageStatus not implemented")
+}
+func (*UnimplementedAdapterServiceServer) AbortOnuImageUpgrade(ctx context.Context, req *voltha.DeviceImageRequest) (*voltha.DeviceImageResponse, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method AbortOnuImageUpgrade not implemented")
+}
+func (*UnimplementedAdapterServiceServer) GetOnuImages(ctx context.Context, req *common.ID) (*voltha.OnuImages, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method GetOnuImages not implemented")
+}
+func (*UnimplementedAdapterServiceServer) ActivateOnuImage(ctx context.Context, req *voltha.DeviceImageRequest) (*voltha.DeviceImageResponse, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method ActivateOnuImage not implemented")
+}
+func (*UnimplementedAdapterServiceServer) CommitOnuImage(ctx context.Context, req *voltha.DeviceImageRequest) (*voltha.DeviceImageResponse, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method CommitOnuImage not implemented")
+}
+func (*UnimplementedAdapterServiceServer) DownloadImage(ctx context.Context, req *core_adapter.ImageDownloadMessage) (*voltha.ImageDownload, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method DownloadImage not implemented")
+}
+func (*UnimplementedAdapterServiceServer) GetImageDownloadStatus(ctx context.Context, req *core_adapter.ImageDownloadMessage) (*voltha.ImageDownload, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method GetImageDownloadStatus not implemented")
+}
+func (*UnimplementedAdapterServiceServer) CancelImageDownload(ctx context.Context, req *core_adapter.ImageDownloadMessage) (*voltha.ImageDownload, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method CancelImageDownload not implemented")
+}
+func (*UnimplementedAdapterServiceServer) ActivateImageUpdate(ctx context.Context, req *core_adapter.ImageDownloadMessage) (*voltha.ImageDownload, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method ActivateImageUpdate not implemented")
+}
+func (*UnimplementedAdapterServiceServer) RevertImageUpdate(ctx context.Context, req *core_adapter.ImageDownloadMessage) (*voltha.ImageDownload, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method RevertImageUpdate not implemented")
+}
+func (*UnimplementedAdapterServiceServer) StartOmciTest(ctx context.Context, req *core_adapter.OMCITest) (*omci.TestResponse, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method StartOmciTest not implemented")
+}
+func (*UnimplementedAdapterServiceServer) SimulateAlarm(ctx context.Context, req *core_adapter.SimulateAlarmMessage) (*common.OperationResp, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method SimulateAlarm not implemented")
+}
+func (*UnimplementedAdapterServiceServer) SuppressEvent(ctx context.Context, req *voltha.EventFilter) (*empty.Empty, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method SuppressEvent not implemented")
+}
+func (*UnimplementedAdapterServiceServer) UnSuppressEvent(ctx context.Context, req *voltha.EventFilter) (*empty.Empty, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method UnSuppressEvent not implemented")
+}
+func (*UnimplementedAdapterServiceServer) GetExtValue(ctx context.Context, req *core_adapter.GetExtValueMessage) (*extension.ReturnValues, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method GetExtValue not implemented")
+}
+func (*UnimplementedAdapterServiceServer) SetExtValue(ctx context.Context, req *core_adapter.SetExtValueMessage) (*empty.Empty, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method SetExtValue not implemented")
+}
+func (*UnimplementedAdapterServiceServer) GetSingleValue(ctx context.Context, req *extension.SingleGetValueRequest) (*extension.SingleGetValueResponse, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method GetSingleValue not implemented")
+}
+func (*UnimplementedAdapterServiceServer) SetSingleValue(ctx context.Context, req *extension.SingleSetValueRequest) (*extension.SingleSetValueResponse, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method SetSingleValue not implemented")
+}
+
+func RegisterAdapterServiceServer(s *grpc.Server, srv AdapterServiceServer) {
+	s.RegisterService(&_AdapterService_serviceDesc, srv)
+}
+
+func _AdapterService_GetHealthStatus_Handler(srv interface{}, stream grpc.ServerStream) error {
+	return srv.(AdapterServiceServer).GetHealthStatus(&adapterServiceGetHealthStatusServer{stream})
+}
+
+type AdapterService_GetHealthStatusServer interface {
+	Send(*health.HealthStatus) error
+	Recv() (*common.Connection, error)
+	grpc.ServerStream
+}
+
+type adapterServiceGetHealthStatusServer struct {
+	grpc.ServerStream
+}
+
+func (x *adapterServiceGetHealthStatusServer) Send(m *health.HealthStatus) error {
+	return x.ServerStream.SendMsg(m)
+}
+
+func (x *adapterServiceGetHealthStatusServer) Recv() (*common.Connection, error) {
+	m := new(common.Connection)
+	if err := x.ServerStream.RecvMsg(m); err != nil {
+		return nil, err
+	}
+	return m, nil
+}
+
+func _AdapterService_AdoptDevice_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(voltha.Device)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(AdapterServiceServer).AdoptDevice(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/adapter_service.AdapterService/AdoptDevice",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(AdapterServiceServer).AdoptDevice(ctx, req.(*voltha.Device))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _AdapterService_ReconcileDevice_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(voltha.Device)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(AdapterServiceServer).ReconcileDevice(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/adapter_service.AdapterService/ReconcileDevice",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(AdapterServiceServer).ReconcileDevice(ctx, req.(*voltha.Device))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _AdapterService_DeleteDevice_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(voltha.Device)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(AdapterServiceServer).DeleteDevice(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/adapter_service.AdapterService/DeleteDevice",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(AdapterServiceServer).DeleteDevice(ctx, req.(*voltha.Device))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _AdapterService_DisableDevice_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(voltha.Device)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(AdapterServiceServer).DisableDevice(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/adapter_service.AdapterService/DisableDevice",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(AdapterServiceServer).DisableDevice(ctx, req.(*voltha.Device))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _AdapterService_ReEnableDevice_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(voltha.Device)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(AdapterServiceServer).ReEnableDevice(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/adapter_service.AdapterService/ReEnableDevice",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(AdapterServiceServer).ReEnableDevice(ctx, req.(*voltha.Device))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _AdapterService_RebootDevice_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(voltha.Device)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(AdapterServiceServer).RebootDevice(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/adapter_service.AdapterService/RebootDevice",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(AdapterServiceServer).RebootDevice(ctx, req.(*voltha.Device))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _AdapterService_SelfTestDevice_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(voltha.Device)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(AdapterServiceServer).SelfTestDevice(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/adapter_service.AdapterService/SelfTestDevice",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(AdapterServiceServer).SelfTestDevice(ctx, req.(*voltha.Device))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _AdapterService_GetOfpDeviceInfo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(voltha.Device)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(AdapterServiceServer).GetOfpDeviceInfo(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/adapter_service.AdapterService/GetOfpDeviceInfo",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(AdapterServiceServer).GetOfpDeviceInfo(ctx, req.(*voltha.Device))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _AdapterService_ChildDeviceLost_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(voltha.Device)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(AdapterServiceServer).ChildDeviceLost(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/adapter_service.AdapterService/ChildDeviceLost",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(AdapterServiceServer).ChildDeviceLost(ctx, req.(*voltha.Device))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _AdapterService_EnablePort_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(voltha.Port)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(AdapterServiceServer).EnablePort(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/adapter_service.AdapterService/EnablePort",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(AdapterServiceServer).EnablePort(ctx, req.(*voltha.Port))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _AdapterService_DisablePort_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(voltha.Port)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(AdapterServiceServer).DisablePort(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/adapter_service.AdapterService/DisablePort",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(AdapterServiceServer).DisablePort(ctx, req.(*voltha.Port))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _AdapterService_UpdateFlowsBulk_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(core_adapter.BulkFlows)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(AdapterServiceServer).UpdateFlowsBulk(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/adapter_service.AdapterService/UpdateFlowsBulk",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(AdapterServiceServer).UpdateFlowsBulk(ctx, req.(*core_adapter.BulkFlows))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _AdapterService_UpdateFlowsIncrementally_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(core_adapter.IncrementalFlows)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(AdapterServiceServer).UpdateFlowsIncrementally(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/adapter_service.AdapterService/UpdateFlowsIncrementally",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(AdapterServiceServer).UpdateFlowsIncrementally(ctx, req.(*core_adapter.IncrementalFlows))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _AdapterService_SendPacketOut_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(core_adapter.PacketOut)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(AdapterServiceServer).SendPacketOut(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/adapter_service.AdapterService/SendPacketOut",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(AdapterServiceServer).SendPacketOut(ctx, req.(*core_adapter.PacketOut))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _AdapterService_UpdatePmConfig_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(core_adapter.PmConfigsInfo)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(AdapterServiceServer).UpdatePmConfig(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/adapter_service.AdapterService/UpdatePmConfig",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(AdapterServiceServer).UpdatePmConfig(ctx, req.(*core_adapter.PmConfigsInfo))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _AdapterService_DownloadOnuImage_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(voltha.DeviceImageDownloadRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(AdapterServiceServer).DownloadOnuImage(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/adapter_service.AdapterService/DownloadOnuImage",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(AdapterServiceServer).DownloadOnuImage(ctx, req.(*voltha.DeviceImageDownloadRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _AdapterService_GetOnuImageStatus_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(voltha.DeviceImageRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(AdapterServiceServer).GetOnuImageStatus(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/adapter_service.AdapterService/GetOnuImageStatus",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(AdapterServiceServer).GetOnuImageStatus(ctx, req.(*voltha.DeviceImageRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _AdapterService_AbortOnuImageUpgrade_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(voltha.DeviceImageRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(AdapterServiceServer).AbortOnuImageUpgrade(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/adapter_service.AdapterService/AbortOnuImageUpgrade",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(AdapterServiceServer).AbortOnuImageUpgrade(ctx, req.(*voltha.DeviceImageRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _AdapterService_GetOnuImages_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(common.ID)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(AdapterServiceServer).GetOnuImages(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/adapter_service.AdapterService/GetOnuImages",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(AdapterServiceServer).GetOnuImages(ctx, req.(*common.ID))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _AdapterService_ActivateOnuImage_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(voltha.DeviceImageRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(AdapterServiceServer).ActivateOnuImage(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/adapter_service.AdapterService/ActivateOnuImage",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(AdapterServiceServer).ActivateOnuImage(ctx, req.(*voltha.DeviceImageRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _AdapterService_CommitOnuImage_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(voltha.DeviceImageRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(AdapterServiceServer).CommitOnuImage(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/adapter_service.AdapterService/CommitOnuImage",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(AdapterServiceServer).CommitOnuImage(ctx, req.(*voltha.DeviceImageRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _AdapterService_DownloadImage_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(core_adapter.ImageDownloadMessage)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(AdapterServiceServer).DownloadImage(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/adapter_service.AdapterService/DownloadImage",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(AdapterServiceServer).DownloadImage(ctx, req.(*core_adapter.ImageDownloadMessage))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _AdapterService_GetImageDownloadStatus_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(core_adapter.ImageDownloadMessage)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(AdapterServiceServer).GetImageDownloadStatus(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/adapter_service.AdapterService/GetImageDownloadStatus",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(AdapterServiceServer).GetImageDownloadStatus(ctx, req.(*core_adapter.ImageDownloadMessage))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _AdapterService_CancelImageDownload_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(core_adapter.ImageDownloadMessage)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(AdapterServiceServer).CancelImageDownload(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/adapter_service.AdapterService/CancelImageDownload",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(AdapterServiceServer).CancelImageDownload(ctx, req.(*core_adapter.ImageDownloadMessage))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _AdapterService_ActivateImageUpdate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(core_adapter.ImageDownloadMessage)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(AdapterServiceServer).ActivateImageUpdate(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/adapter_service.AdapterService/ActivateImageUpdate",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(AdapterServiceServer).ActivateImageUpdate(ctx, req.(*core_adapter.ImageDownloadMessage))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _AdapterService_RevertImageUpdate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(core_adapter.ImageDownloadMessage)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(AdapterServiceServer).RevertImageUpdate(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/adapter_service.AdapterService/RevertImageUpdate",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(AdapterServiceServer).RevertImageUpdate(ctx, req.(*core_adapter.ImageDownloadMessage))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _AdapterService_StartOmciTest_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(core_adapter.OMCITest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(AdapterServiceServer).StartOmciTest(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/adapter_service.AdapterService/StartOmciTest",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(AdapterServiceServer).StartOmciTest(ctx, req.(*core_adapter.OMCITest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _AdapterService_SimulateAlarm_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(core_adapter.SimulateAlarmMessage)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(AdapterServiceServer).SimulateAlarm(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/adapter_service.AdapterService/SimulateAlarm",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(AdapterServiceServer).SimulateAlarm(ctx, req.(*core_adapter.SimulateAlarmMessage))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _AdapterService_SuppressEvent_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(voltha.EventFilter)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(AdapterServiceServer).SuppressEvent(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/adapter_service.AdapterService/SuppressEvent",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(AdapterServiceServer).SuppressEvent(ctx, req.(*voltha.EventFilter))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _AdapterService_UnSuppressEvent_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(voltha.EventFilter)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(AdapterServiceServer).UnSuppressEvent(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/adapter_service.AdapterService/UnSuppressEvent",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(AdapterServiceServer).UnSuppressEvent(ctx, req.(*voltha.EventFilter))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _AdapterService_GetExtValue_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(core_adapter.GetExtValueMessage)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(AdapterServiceServer).GetExtValue(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/adapter_service.AdapterService/GetExtValue",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(AdapterServiceServer).GetExtValue(ctx, req.(*core_adapter.GetExtValueMessage))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _AdapterService_SetExtValue_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(core_adapter.SetExtValueMessage)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(AdapterServiceServer).SetExtValue(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/adapter_service.AdapterService/SetExtValue",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(AdapterServiceServer).SetExtValue(ctx, req.(*core_adapter.SetExtValueMessage))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _AdapterService_GetSingleValue_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(extension.SingleGetValueRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(AdapterServiceServer).GetSingleValue(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/adapter_service.AdapterService/GetSingleValue",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(AdapterServiceServer).GetSingleValue(ctx, req.(*extension.SingleGetValueRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _AdapterService_SetSingleValue_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(extension.SingleSetValueRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(AdapterServiceServer).SetSingleValue(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/adapter_service.AdapterService/SetSingleValue",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(AdapterServiceServer).SetSingleValue(ctx, req.(*extension.SingleSetValueRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+var _AdapterService_serviceDesc = grpc.ServiceDesc{
+	ServiceName: "adapter_service.AdapterService",
+	HandlerType: (*AdapterServiceServer)(nil),
+	Methods: []grpc.MethodDesc{
+		{
+			MethodName: "AdoptDevice",
+			Handler:    _AdapterService_AdoptDevice_Handler,
+		},
+		{
+			MethodName: "ReconcileDevice",
+			Handler:    _AdapterService_ReconcileDevice_Handler,
+		},
+		{
+			MethodName: "DeleteDevice",
+			Handler:    _AdapterService_DeleteDevice_Handler,
+		},
+		{
+			MethodName: "DisableDevice",
+			Handler:    _AdapterService_DisableDevice_Handler,
+		},
+		{
+			MethodName: "ReEnableDevice",
+			Handler:    _AdapterService_ReEnableDevice_Handler,
+		},
+		{
+			MethodName: "RebootDevice",
+			Handler:    _AdapterService_RebootDevice_Handler,
+		},
+		{
+			MethodName: "SelfTestDevice",
+			Handler:    _AdapterService_SelfTestDevice_Handler,
+		},
+		{
+			MethodName: "GetOfpDeviceInfo",
+			Handler:    _AdapterService_GetOfpDeviceInfo_Handler,
+		},
+		{
+			MethodName: "ChildDeviceLost",
+			Handler:    _AdapterService_ChildDeviceLost_Handler,
+		},
+		{
+			MethodName: "EnablePort",
+			Handler:    _AdapterService_EnablePort_Handler,
+		},
+		{
+			MethodName: "DisablePort",
+			Handler:    _AdapterService_DisablePort_Handler,
+		},
+		{
+			MethodName: "UpdateFlowsBulk",
+			Handler:    _AdapterService_UpdateFlowsBulk_Handler,
+		},
+		{
+			MethodName: "UpdateFlowsIncrementally",
+			Handler:    _AdapterService_UpdateFlowsIncrementally_Handler,
+		},
+		{
+			MethodName: "SendPacketOut",
+			Handler:    _AdapterService_SendPacketOut_Handler,
+		},
+		{
+			MethodName: "UpdatePmConfig",
+			Handler:    _AdapterService_UpdatePmConfig_Handler,
+		},
+		{
+			MethodName: "DownloadOnuImage",
+			Handler:    _AdapterService_DownloadOnuImage_Handler,
+		},
+		{
+			MethodName: "GetOnuImageStatus",
+			Handler:    _AdapterService_GetOnuImageStatus_Handler,
+		},
+		{
+			MethodName: "AbortOnuImageUpgrade",
+			Handler:    _AdapterService_AbortOnuImageUpgrade_Handler,
+		},
+		{
+			MethodName: "GetOnuImages",
+			Handler:    _AdapterService_GetOnuImages_Handler,
+		},
+		{
+			MethodName: "ActivateOnuImage",
+			Handler:    _AdapterService_ActivateOnuImage_Handler,
+		},
+		{
+			MethodName: "CommitOnuImage",
+			Handler:    _AdapterService_CommitOnuImage_Handler,
+		},
+		{
+			MethodName: "DownloadImage",
+			Handler:    _AdapterService_DownloadImage_Handler,
+		},
+		{
+			MethodName: "GetImageDownloadStatus",
+			Handler:    _AdapterService_GetImageDownloadStatus_Handler,
+		},
+		{
+			MethodName: "CancelImageDownload",
+			Handler:    _AdapterService_CancelImageDownload_Handler,
+		},
+		{
+			MethodName: "ActivateImageUpdate",
+			Handler:    _AdapterService_ActivateImageUpdate_Handler,
+		},
+		{
+			MethodName: "RevertImageUpdate",
+			Handler:    _AdapterService_RevertImageUpdate_Handler,
+		},
+		{
+			MethodName: "StartOmciTest",
+			Handler:    _AdapterService_StartOmciTest_Handler,
+		},
+		{
+			MethodName: "SimulateAlarm",
+			Handler:    _AdapterService_SimulateAlarm_Handler,
+		},
+		{
+			MethodName: "SuppressEvent",
+			Handler:    _AdapterService_SuppressEvent_Handler,
+		},
+		{
+			MethodName: "UnSuppressEvent",
+			Handler:    _AdapterService_UnSuppressEvent_Handler,
+		},
+		{
+			MethodName: "GetExtValue",
+			Handler:    _AdapterService_GetExtValue_Handler,
+		},
+		{
+			MethodName: "SetExtValue",
+			Handler:    _AdapterService_SetExtValue_Handler,
+		},
+		{
+			MethodName: "GetSingleValue",
+			Handler:    _AdapterService_GetSingleValue_Handler,
+		},
+		{
+			MethodName: "SetSingleValue",
+			Handler:    _AdapterService_SetSingleValue_Handler,
+		},
+	},
+	Streams: []grpc.StreamDesc{
+		{
+			StreamName:    "GetHealthStatus",
+			Handler:       _AdapterService_GetHealthStatus_Handler,
+			ServerStreams: true,
+			ClientStreams: true,
+		},
+	},
+	Metadata: "voltha_protos/adapter_service.proto",
+}
diff --git a/vendor/github.com/opencord/voltha-protos/v5/go/core_adapter/core_adapter.pb.go b/vendor/github.com/opencord/voltha-protos/v5/go/core_adapter/core_adapter.pb.go
new file mode 100644
index 0000000..3259b05
--- /dev/null
+++ b/vendor/github.com/opencord/voltha-protos/v5/go/core_adapter/core_adapter.pb.go
@@ -0,0 +1,1177 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// source: voltha_protos/core_adapter.proto
+
+package core_adapter
+
+import (
+	fmt "fmt"
+	proto "github.com/golang/protobuf/proto"
+	common "github.com/opencord/voltha-protos/v5/go/common"
+	extension "github.com/opencord/voltha-protos/v5/go/extension"
+	omci "github.com/opencord/voltha-protos/v5/go/omci"
+	openflow_13 "github.com/opencord/voltha-protos/v5/go/openflow_13"
+	voltha "github.com/opencord/voltha-protos/v5/go/voltha"
+	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
+
+type AdapterRegistration struct {
+	Adapter              *voltha.Adapter     `protobuf:"bytes,1,opt,name=adapter,proto3" json:"adapter,omitempty"`
+	DTypes               *voltha.DeviceTypes `protobuf:"bytes,2,opt,name=dTypes,proto3" json:"dTypes,omitempty"`
+	XXX_NoUnkeyedLiteral struct{}            `json:"-"`
+	XXX_unrecognized     []byte              `json:"-"`
+	XXX_sizecache        int32               `json:"-"`
+}
+
+func (m *AdapterRegistration) Reset()         { *m = AdapterRegistration{} }
+func (m *AdapterRegistration) String() string { return proto.CompactTextString(m) }
+func (*AdapterRegistration) ProtoMessage()    {}
+func (*AdapterRegistration) Descriptor() ([]byte, []int) {
+	return fileDescriptor_b77436fd29d035f0, []int{0}
+}
+
+func (m *AdapterRegistration) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_AdapterRegistration.Unmarshal(m, b)
+}
+func (m *AdapterRegistration) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_AdapterRegistration.Marshal(b, m, deterministic)
+}
+func (m *AdapterRegistration) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_AdapterRegistration.Merge(m, src)
+}
+func (m *AdapterRegistration) XXX_Size() int {
+	return xxx_messageInfo_AdapterRegistration.Size(m)
+}
+func (m *AdapterRegistration) XXX_DiscardUnknown() {
+	xxx_messageInfo_AdapterRegistration.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_AdapterRegistration proto.InternalMessageInfo
+
+func (m *AdapterRegistration) GetAdapter() *voltha.Adapter {
+	if m != nil {
+		return m.Adapter
+	}
+	return nil
+}
+
+func (m *AdapterRegistration) GetDTypes() *voltha.DeviceTypes {
+	if m != nil {
+		return m.DTypes
+	}
+	return nil
+}
+
+type ChildDeviceFilter struct {
+	ParentId             string   `protobuf:"bytes,1,opt,name=parent_id,json=parentId,proto3" json:"parent_id,omitempty"`
+	SerialNumber         string   `protobuf:"bytes,2,opt,name=serial_number,json=serialNumber,proto3" json:"serial_number,omitempty"`
+	OnuId                uint32   `protobuf:"varint,3,opt,name=onu_id,json=onuId,proto3" json:"onu_id,omitempty"`
+	ParentPortNo         uint32   `protobuf:"varint,4,opt,name=parent_port_no,json=parentPortNo,proto3" json:"parent_port_no,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *ChildDeviceFilter) Reset()         { *m = ChildDeviceFilter{} }
+func (m *ChildDeviceFilter) String() string { return proto.CompactTextString(m) }
+func (*ChildDeviceFilter) ProtoMessage()    {}
+func (*ChildDeviceFilter) Descriptor() ([]byte, []int) {
+	return fileDescriptor_b77436fd29d035f0, []int{1}
+}
+
+func (m *ChildDeviceFilter) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_ChildDeviceFilter.Unmarshal(m, b)
+}
+func (m *ChildDeviceFilter) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_ChildDeviceFilter.Marshal(b, m, deterministic)
+}
+func (m *ChildDeviceFilter) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_ChildDeviceFilter.Merge(m, src)
+}
+func (m *ChildDeviceFilter) XXX_Size() int {
+	return xxx_messageInfo_ChildDeviceFilter.Size(m)
+}
+func (m *ChildDeviceFilter) XXX_DiscardUnknown() {
+	xxx_messageInfo_ChildDeviceFilter.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_ChildDeviceFilter proto.InternalMessageInfo
+
+func (m *ChildDeviceFilter) GetParentId() string {
+	if m != nil {
+		return m.ParentId
+	}
+	return ""
+}
+
+func (m *ChildDeviceFilter) GetSerialNumber() string {
+	if m != nil {
+		return m.SerialNumber
+	}
+	return ""
+}
+
+func (m *ChildDeviceFilter) GetOnuId() uint32 {
+	if m != nil {
+		return m.OnuId
+	}
+	return 0
+}
+
+func (m *ChildDeviceFilter) GetParentPortNo() uint32 {
+	if m != nil {
+		return m.ParentPortNo
+	}
+	return 0
+}
+
+type PortFilter struct {
+	DeviceId             string               `protobuf:"bytes,1,opt,name=device_id,json=deviceId,proto3" json:"device_id,omitempty"`
+	Port                 uint32               `protobuf:"varint,2,opt,name=port,proto3" json:"port,omitempty"`
+	PortType             voltha.Port_PortType `protobuf:"varint,3,opt,name=port_type,json=portType,proto3,enum=device.Port_PortType" json:"port_type,omitempty"`
+	XXX_NoUnkeyedLiteral struct{}             `json:"-"`
+	XXX_unrecognized     []byte               `json:"-"`
+	XXX_sizecache        int32                `json:"-"`
+}
+
+func (m *PortFilter) Reset()         { *m = PortFilter{} }
+func (m *PortFilter) String() string { return proto.CompactTextString(m) }
+func (*PortFilter) ProtoMessage()    {}
+func (*PortFilter) Descriptor() ([]byte, []int) {
+	return fileDescriptor_b77436fd29d035f0, []int{2}
+}
+
+func (m *PortFilter) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_PortFilter.Unmarshal(m, b)
+}
+func (m *PortFilter) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_PortFilter.Marshal(b, m, deterministic)
+}
+func (m *PortFilter) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_PortFilter.Merge(m, src)
+}
+func (m *PortFilter) XXX_Size() int {
+	return xxx_messageInfo_PortFilter.Size(m)
+}
+func (m *PortFilter) XXX_DiscardUnknown() {
+	xxx_messageInfo_PortFilter.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_PortFilter proto.InternalMessageInfo
+
+func (m *PortFilter) GetDeviceId() string {
+	if m != nil {
+		return m.DeviceId
+	}
+	return ""
+}
+
+func (m *PortFilter) GetPort() uint32 {
+	if m != nil {
+		return m.Port
+	}
+	return 0
+}
+
+func (m *PortFilter) GetPortType() voltha.Port_PortType {
+	if m != nil {
+		return m.PortType
+	}
+	return voltha.Port_UNKNOWN
+}
+
+type DeviceDiscovery struct {
+	ParentId             string   `protobuf:"bytes,1,opt,name=parent_id,json=parentId,proto3" json:"parent_id,omitempty"`
+	ParentPortNo         uint32   `protobuf:"varint,2,opt,name=parent_port_no,json=parentPortNo,proto3" json:"parent_port_no,omitempty"`
+	ChildDeviceType      string   `protobuf:"bytes,3,opt,name=child_device_type,json=childDeviceType,proto3" json:"child_device_type,omitempty"`
+	ChannelId            uint32   `protobuf:"varint,4,opt,name=channel_id,json=channelId,proto3" json:"channel_id,omitempty"`
+	VendorId             string   `protobuf:"bytes,5,opt,name=vendor_id,json=vendorId,proto3" json:"vendor_id,omitempty"`
+	SerialNumber         string   `protobuf:"bytes,6,opt,name=serial_number,json=serialNumber,proto3" json:"serial_number,omitempty"`
+	OnuId                uint32   `protobuf:"varint,7,opt,name=onu_id,json=onuId,proto3" json:"onu_id,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *DeviceDiscovery) Reset()         { *m = DeviceDiscovery{} }
+func (m *DeviceDiscovery) String() string { return proto.CompactTextString(m) }
+func (*DeviceDiscovery) ProtoMessage()    {}
+func (*DeviceDiscovery) Descriptor() ([]byte, []int) {
+	return fileDescriptor_b77436fd29d035f0, []int{3}
+}
+
+func (m *DeviceDiscovery) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_DeviceDiscovery.Unmarshal(m, b)
+}
+func (m *DeviceDiscovery) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_DeviceDiscovery.Marshal(b, m, deterministic)
+}
+func (m *DeviceDiscovery) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_DeviceDiscovery.Merge(m, src)
+}
+func (m *DeviceDiscovery) XXX_Size() int {
+	return xxx_messageInfo_DeviceDiscovery.Size(m)
+}
+func (m *DeviceDiscovery) XXX_DiscardUnknown() {
+	xxx_messageInfo_DeviceDiscovery.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_DeviceDiscovery proto.InternalMessageInfo
+
+func (m *DeviceDiscovery) GetParentId() string {
+	if m != nil {
+		return m.ParentId
+	}
+	return ""
+}
+
+func (m *DeviceDiscovery) GetParentPortNo() uint32 {
+	if m != nil {
+		return m.ParentPortNo
+	}
+	return 0
+}
+
+func (m *DeviceDiscovery) GetChildDeviceType() string {
+	if m != nil {
+		return m.ChildDeviceType
+	}
+	return ""
+}
+
+func (m *DeviceDiscovery) GetChannelId() uint32 {
+	if m != nil {
+		return m.ChannelId
+	}
+	return 0
+}
+
+func (m *DeviceDiscovery) GetVendorId() string {
+	if m != nil {
+		return m.VendorId
+	}
+	return ""
+}
+
+func (m *DeviceDiscovery) GetSerialNumber() string {
+	if m != nil {
+		return m.SerialNumber
+	}
+	return ""
+}
+
+func (m *DeviceDiscovery) GetOnuId() uint32 {
+	if m != nil {
+		return m.OnuId
+	}
+	return 0
+}
+
+type DeviceStateFilter struct {
+	DeviceId             string                     `protobuf:"bytes,1,opt,name=device_id,json=deviceId,proto3" json:"device_id,omitempty"`
+	ParentDeviceId       string                     `protobuf:"bytes,2,opt,name=parent_device_id,json=parentDeviceId,proto3" json:"parent_device_id,omitempty"`
+	OperStatus           common.OperStatus_Types    `protobuf:"varint,3,opt,name=oper_status,json=operStatus,proto3,enum=common.OperStatus_Types" json:"oper_status,omitempty"`
+	ConnStatus           common.ConnectStatus_Types `protobuf:"varint,4,opt,name=conn_status,json=connStatus,proto3,enum=common.ConnectStatus_Types" json:"conn_status,omitempty"`
+	XXX_NoUnkeyedLiteral struct{}                   `json:"-"`
+	XXX_unrecognized     []byte                     `json:"-"`
+	XXX_sizecache        int32                      `json:"-"`
+}
+
+func (m *DeviceStateFilter) Reset()         { *m = DeviceStateFilter{} }
+func (m *DeviceStateFilter) String() string { return proto.CompactTextString(m) }
+func (*DeviceStateFilter) ProtoMessage()    {}
+func (*DeviceStateFilter) Descriptor() ([]byte, []int) {
+	return fileDescriptor_b77436fd29d035f0, []int{4}
+}
+
+func (m *DeviceStateFilter) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_DeviceStateFilter.Unmarshal(m, b)
+}
+func (m *DeviceStateFilter) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_DeviceStateFilter.Marshal(b, m, deterministic)
+}
+func (m *DeviceStateFilter) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_DeviceStateFilter.Merge(m, src)
+}
+func (m *DeviceStateFilter) XXX_Size() int {
+	return xxx_messageInfo_DeviceStateFilter.Size(m)
+}
+func (m *DeviceStateFilter) XXX_DiscardUnknown() {
+	xxx_messageInfo_DeviceStateFilter.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_DeviceStateFilter proto.InternalMessageInfo
+
+func (m *DeviceStateFilter) GetDeviceId() string {
+	if m != nil {
+		return m.DeviceId
+	}
+	return ""
+}
+
+func (m *DeviceStateFilter) GetParentDeviceId() string {
+	if m != nil {
+		return m.ParentDeviceId
+	}
+	return ""
+}
+
+func (m *DeviceStateFilter) GetOperStatus() common.OperStatus_Types {
+	if m != nil {
+		return m.OperStatus
+	}
+	return common.OperStatus_UNKNOWN
+}
+
+func (m *DeviceStateFilter) GetConnStatus() common.ConnectStatus_Types {
+	if m != nil {
+		return m.ConnStatus
+	}
+	return common.ConnectStatus_UNKNOWN
+}
+
+type PortState struct {
+	DeviceId             string                  `protobuf:"bytes,1,opt,name=device_id,json=deviceId,proto3" json:"device_id,omitempty"`
+	PortType             voltha.Port_PortType    `protobuf:"varint,2,opt,name=port_type,json=portType,proto3,enum=device.Port_PortType" json:"port_type,omitempty"`
+	PortNo               uint32                  `protobuf:"varint,3,opt,name=port_no,json=portNo,proto3" json:"port_no,omitempty"`
+	OperStatus           common.OperStatus_Types `protobuf:"varint,4,opt,name=oper_status,json=operStatus,proto3,enum=common.OperStatus_Types" json:"oper_status,omitempty"`
+	XXX_NoUnkeyedLiteral struct{}                `json:"-"`
+	XXX_unrecognized     []byte                  `json:"-"`
+	XXX_sizecache        int32                   `json:"-"`
+}
+
+func (m *PortState) Reset()         { *m = PortState{} }
+func (m *PortState) String() string { return proto.CompactTextString(m) }
+func (*PortState) ProtoMessage()    {}
+func (*PortState) Descriptor() ([]byte, []int) {
+	return fileDescriptor_b77436fd29d035f0, []int{5}
+}
+
+func (m *PortState) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_PortState.Unmarshal(m, b)
+}
+func (m *PortState) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_PortState.Marshal(b, m, deterministic)
+}
+func (m *PortState) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_PortState.Merge(m, src)
+}
+func (m *PortState) XXX_Size() int {
+	return xxx_messageInfo_PortState.Size(m)
+}
+func (m *PortState) XXX_DiscardUnknown() {
+	xxx_messageInfo_PortState.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_PortState proto.InternalMessageInfo
+
+func (m *PortState) GetDeviceId() string {
+	if m != nil {
+		return m.DeviceId
+	}
+	return ""
+}
+
+func (m *PortState) GetPortType() voltha.Port_PortType {
+	if m != nil {
+		return m.PortType
+	}
+	return voltha.Port_UNKNOWN
+}
+
+func (m *PortState) GetPortNo() uint32 {
+	if m != nil {
+		return m.PortNo
+	}
+	return 0
+}
+
+func (m *PortState) GetOperStatus() common.OperStatus_Types {
+	if m != nil {
+		return m.OperStatus
+	}
+	return common.OperStatus_UNKNOWN
+}
+
+type PortStateFilter struct {
+	DeviceId             string                  `protobuf:"bytes,1,opt,name=device_id,json=deviceId,proto3" json:"device_id,omitempty"`
+	PortTypeFilter       uint32                  `protobuf:"varint,2,opt,name=port_type_filter,json=portTypeFilter,proto3" json:"port_type_filter,omitempty"`
+	OperStatus           common.OperStatus_Types `protobuf:"varint,4,opt,name=oper_status,json=operStatus,proto3,enum=common.OperStatus_Types" json:"oper_status,omitempty"`
+	XXX_NoUnkeyedLiteral struct{}                `json:"-"`
+	XXX_unrecognized     []byte                  `json:"-"`
+	XXX_sizecache        int32                   `json:"-"`
+}
+
+func (m *PortStateFilter) Reset()         { *m = PortStateFilter{} }
+func (m *PortStateFilter) String() string { return proto.CompactTextString(m) }
+func (*PortStateFilter) ProtoMessage()    {}
+func (*PortStateFilter) Descriptor() ([]byte, []int) {
+	return fileDescriptor_b77436fd29d035f0, []int{6}
+}
+
+func (m *PortStateFilter) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_PortStateFilter.Unmarshal(m, b)
+}
+func (m *PortStateFilter) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_PortStateFilter.Marshal(b, m, deterministic)
+}
+func (m *PortStateFilter) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_PortStateFilter.Merge(m, src)
+}
+func (m *PortStateFilter) XXX_Size() int {
+	return xxx_messageInfo_PortStateFilter.Size(m)
+}
+func (m *PortStateFilter) XXX_DiscardUnknown() {
+	xxx_messageInfo_PortStateFilter.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_PortStateFilter proto.InternalMessageInfo
+
+func (m *PortStateFilter) GetDeviceId() string {
+	if m != nil {
+		return m.DeviceId
+	}
+	return ""
+}
+
+func (m *PortStateFilter) GetPortTypeFilter() uint32 {
+	if m != nil {
+		return m.PortTypeFilter
+	}
+	return 0
+}
+
+func (m *PortStateFilter) GetOperStatus() common.OperStatus_Types {
+	if m != nil {
+		return m.OperStatus
+	}
+	return common.OperStatus_UNKNOWN
+}
+
+type PacketIn struct {
+	DeviceId             string   `protobuf:"bytes,1,opt,name=device_id,json=deviceId,proto3" json:"device_id,omitempty"`
+	Port                 uint32   `protobuf:"varint,2,opt,name=port,proto3" json:"port,omitempty"`
+	Packet               []byte   `protobuf:"bytes,3,opt,name=packet,proto3" json:"packet,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *PacketIn) Reset()         { *m = PacketIn{} }
+func (m *PacketIn) String() string { return proto.CompactTextString(m) }
+func (*PacketIn) ProtoMessage()    {}
+func (*PacketIn) Descriptor() ([]byte, []int) {
+	return fileDescriptor_b77436fd29d035f0, []int{7}
+}
+
+func (m *PacketIn) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_PacketIn.Unmarshal(m, b)
+}
+func (m *PacketIn) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_PacketIn.Marshal(b, m, deterministic)
+}
+func (m *PacketIn) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_PacketIn.Merge(m, src)
+}
+func (m *PacketIn) XXX_Size() int {
+	return xxx_messageInfo_PacketIn.Size(m)
+}
+func (m *PacketIn) XXX_DiscardUnknown() {
+	xxx_messageInfo_PacketIn.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_PacketIn proto.InternalMessageInfo
+
+func (m *PacketIn) GetDeviceId() string {
+	if m != nil {
+		return m.DeviceId
+	}
+	return ""
+}
+
+func (m *PacketIn) GetPort() uint32 {
+	if m != nil {
+		return m.Port
+	}
+	return 0
+}
+
+func (m *PacketIn) GetPacket() []byte {
+	if m != nil {
+		return m.Packet
+	}
+	return nil
+}
+
+type PacketOut struct {
+	DeviceId             string                    `protobuf:"bytes,1,opt,name=device_id,json=deviceId,proto3" json:"device_id,omitempty"`
+	EgressPortNo         uint32                    `protobuf:"varint,2,opt,name=egress_port_no,json=egressPortNo,proto3" json:"egress_port_no,omitempty"`
+	Packet               *openflow_13.OfpPacketOut `protobuf:"bytes,3,opt,name=packet,proto3" json:"packet,omitempty"`
+	XXX_NoUnkeyedLiteral struct{}                  `json:"-"`
+	XXX_unrecognized     []byte                    `json:"-"`
+	XXX_sizecache        int32                     `json:"-"`
+}
+
+func (m *PacketOut) Reset()         { *m = PacketOut{} }
+func (m *PacketOut) String() string { return proto.CompactTextString(m) }
+func (*PacketOut) ProtoMessage()    {}
+func (*PacketOut) Descriptor() ([]byte, []int) {
+	return fileDescriptor_b77436fd29d035f0, []int{8}
+}
+
+func (m *PacketOut) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_PacketOut.Unmarshal(m, b)
+}
+func (m *PacketOut) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_PacketOut.Marshal(b, m, deterministic)
+}
+func (m *PacketOut) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_PacketOut.Merge(m, src)
+}
+func (m *PacketOut) XXX_Size() int {
+	return xxx_messageInfo_PacketOut.Size(m)
+}
+func (m *PacketOut) XXX_DiscardUnknown() {
+	xxx_messageInfo_PacketOut.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_PacketOut proto.InternalMessageInfo
+
+func (m *PacketOut) GetDeviceId() string {
+	if m != nil {
+		return m.DeviceId
+	}
+	return ""
+}
+
+func (m *PacketOut) GetEgressPortNo() uint32 {
+	if m != nil {
+		return m.EgressPortNo
+	}
+	return 0
+}
+
+func (m *PacketOut) GetPacket() *openflow_13.OfpPacketOut {
+	if m != nil {
+		return m.Packet
+	}
+	return nil
+}
+
+type DeviceReason struct {
+	DeviceId             string   `protobuf:"bytes,1,opt,name=device_id,json=deviceId,proto3" json:"device_id,omitempty"`
+	Reason               string   `protobuf:"bytes,2,opt,name=reason,proto3" json:"reason,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *DeviceReason) Reset()         { *m = DeviceReason{} }
+func (m *DeviceReason) String() string { return proto.CompactTextString(m) }
+func (*DeviceReason) ProtoMessage()    {}
+func (*DeviceReason) Descriptor() ([]byte, []int) {
+	return fileDescriptor_b77436fd29d035f0, []int{9}
+}
+
+func (m *DeviceReason) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_DeviceReason.Unmarshal(m, b)
+}
+func (m *DeviceReason) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_DeviceReason.Marshal(b, m, deterministic)
+}
+func (m *DeviceReason) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_DeviceReason.Merge(m, src)
+}
+func (m *DeviceReason) XXX_Size() int {
+	return xxx_messageInfo_DeviceReason.Size(m)
+}
+func (m *DeviceReason) XXX_DiscardUnknown() {
+	xxx_messageInfo_DeviceReason.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_DeviceReason proto.InternalMessageInfo
+
+func (m *DeviceReason) GetDeviceId() string {
+	if m != nil {
+		return m.DeviceId
+	}
+	return ""
+}
+
+func (m *DeviceReason) GetReason() string {
+	if m != nil {
+		return m.Reason
+	}
+	return ""
+}
+
+type BulkFlows struct {
+	Device               *voltha.Device            `protobuf:"bytes,1,opt,name=device,proto3" json:"device,omitempty"`
+	Flows                *openflow_13.Flows        `protobuf:"bytes,2,opt,name=flows,proto3" json:"flows,omitempty"`
+	Groups               *openflow_13.FlowGroups   `protobuf:"bytes,3,opt,name=groups,proto3" json:"groups,omitempty"`
+	FlowMetadata         *openflow_13.FlowMetadata `protobuf:"bytes,4,opt,name=flow_metadata,json=flowMetadata,proto3" json:"flow_metadata,omitempty"`
+	XXX_NoUnkeyedLiteral struct{}                  `json:"-"`
+	XXX_unrecognized     []byte                    `json:"-"`
+	XXX_sizecache        int32                     `json:"-"`
+}
+
+func (m *BulkFlows) Reset()         { *m = BulkFlows{} }
+func (m *BulkFlows) String() string { return proto.CompactTextString(m) }
+func (*BulkFlows) ProtoMessage()    {}
+func (*BulkFlows) Descriptor() ([]byte, []int) {
+	return fileDescriptor_b77436fd29d035f0, []int{10}
+}
+
+func (m *BulkFlows) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_BulkFlows.Unmarshal(m, b)
+}
+func (m *BulkFlows) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_BulkFlows.Marshal(b, m, deterministic)
+}
+func (m *BulkFlows) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_BulkFlows.Merge(m, src)
+}
+func (m *BulkFlows) XXX_Size() int {
+	return xxx_messageInfo_BulkFlows.Size(m)
+}
+func (m *BulkFlows) XXX_DiscardUnknown() {
+	xxx_messageInfo_BulkFlows.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_BulkFlows proto.InternalMessageInfo
+
+func (m *BulkFlows) GetDevice() *voltha.Device {
+	if m != nil {
+		return m.Device
+	}
+	return nil
+}
+
+func (m *BulkFlows) GetFlows() *openflow_13.Flows {
+	if m != nil {
+		return m.Flows
+	}
+	return nil
+}
+
+func (m *BulkFlows) GetGroups() *openflow_13.FlowGroups {
+	if m != nil {
+		return m.Groups
+	}
+	return nil
+}
+
+func (m *BulkFlows) GetFlowMetadata() *openflow_13.FlowMetadata {
+	if m != nil {
+		return m.FlowMetadata
+	}
+	return nil
+}
+
+type IncrementalFlows struct {
+	Device               *voltha.Device                `protobuf:"bytes,1,opt,name=device,proto3" json:"device,omitempty"`
+	Flows                *openflow_13.FlowChanges      `protobuf:"bytes,2,opt,name=flows,proto3" json:"flows,omitempty"`
+	Groups               *openflow_13.FlowGroupChanges `protobuf:"bytes,3,opt,name=groups,proto3" json:"groups,omitempty"`
+	FlowMetadata         *openflow_13.FlowMetadata     `protobuf:"bytes,4,opt,name=flow_metadata,json=flowMetadata,proto3" json:"flow_metadata,omitempty"`
+	XXX_NoUnkeyedLiteral struct{}                      `json:"-"`
+	XXX_unrecognized     []byte                        `json:"-"`
+	XXX_sizecache        int32                         `json:"-"`
+}
+
+func (m *IncrementalFlows) Reset()         { *m = IncrementalFlows{} }
+func (m *IncrementalFlows) String() string { return proto.CompactTextString(m) }
+func (*IncrementalFlows) ProtoMessage()    {}
+func (*IncrementalFlows) Descriptor() ([]byte, []int) {
+	return fileDescriptor_b77436fd29d035f0, []int{11}
+}
+
+func (m *IncrementalFlows) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_IncrementalFlows.Unmarshal(m, b)
+}
+func (m *IncrementalFlows) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_IncrementalFlows.Marshal(b, m, deterministic)
+}
+func (m *IncrementalFlows) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_IncrementalFlows.Merge(m, src)
+}
+func (m *IncrementalFlows) XXX_Size() int {
+	return xxx_messageInfo_IncrementalFlows.Size(m)
+}
+func (m *IncrementalFlows) XXX_DiscardUnknown() {
+	xxx_messageInfo_IncrementalFlows.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_IncrementalFlows proto.InternalMessageInfo
+
+func (m *IncrementalFlows) GetDevice() *voltha.Device {
+	if m != nil {
+		return m.Device
+	}
+	return nil
+}
+
+func (m *IncrementalFlows) GetFlows() *openflow_13.FlowChanges {
+	if m != nil {
+		return m.Flows
+	}
+	return nil
+}
+
+func (m *IncrementalFlows) GetGroups() *openflow_13.FlowGroupChanges {
+	if m != nil {
+		return m.Groups
+	}
+	return nil
+}
+
+func (m *IncrementalFlows) GetFlowMetadata() *openflow_13.FlowMetadata {
+	if m != nil {
+		return m.FlowMetadata
+	}
+	return nil
+}
+
+type PmConfigsInfo struct {
+	DeviceId             string            `protobuf:"bytes,1,opt,name=device_id,json=deviceId,proto3" json:"device_id,omitempty"`
+	PmConfigs            *voltha.PmConfigs `protobuf:"bytes,2,opt,name=pm_configs,json=pmConfigs,proto3" json:"pm_configs,omitempty"`
+	XXX_NoUnkeyedLiteral struct{}          `json:"-"`
+	XXX_unrecognized     []byte            `json:"-"`
+	XXX_sizecache        int32             `json:"-"`
+}
+
+func (m *PmConfigsInfo) Reset()         { *m = PmConfigsInfo{} }
+func (m *PmConfigsInfo) String() string { return proto.CompactTextString(m) }
+func (*PmConfigsInfo) ProtoMessage()    {}
+func (*PmConfigsInfo) Descriptor() ([]byte, []int) {
+	return fileDescriptor_b77436fd29d035f0, []int{12}
+}
+
+func (m *PmConfigsInfo) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_PmConfigsInfo.Unmarshal(m, b)
+}
+func (m *PmConfigsInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_PmConfigsInfo.Marshal(b, m, deterministic)
+}
+func (m *PmConfigsInfo) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_PmConfigsInfo.Merge(m, src)
+}
+func (m *PmConfigsInfo) XXX_Size() int {
+	return xxx_messageInfo_PmConfigsInfo.Size(m)
+}
+func (m *PmConfigsInfo) XXX_DiscardUnknown() {
+	xxx_messageInfo_PmConfigsInfo.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_PmConfigsInfo proto.InternalMessageInfo
+
+func (m *PmConfigsInfo) GetDeviceId() string {
+	if m != nil {
+		return m.DeviceId
+	}
+	return ""
+}
+
+func (m *PmConfigsInfo) GetPmConfigs() *voltha.PmConfigs {
+	if m != nil {
+		return m.PmConfigs
+	}
+	return nil
+}
+
+type SwitchCapability struct {
+	Desc                 *openflow_13.OfpDesc           `protobuf:"bytes,1,opt,name=desc,proto3" json:"desc,omitempty"`
+	SwitchFeatures       *openflow_13.OfpSwitchFeatures `protobuf:"bytes,2,opt,name=switch_features,json=switchFeatures,proto3" json:"switch_features,omitempty"`
+	XXX_NoUnkeyedLiteral struct{}                       `json:"-"`
+	XXX_unrecognized     []byte                         `json:"-"`
+	XXX_sizecache        int32                          `json:"-"`
+}
+
+func (m *SwitchCapability) Reset()         { *m = SwitchCapability{} }
+func (m *SwitchCapability) String() string { return proto.CompactTextString(m) }
+func (*SwitchCapability) ProtoMessage()    {}
+func (*SwitchCapability) Descriptor() ([]byte, []int) {
+	return fileDescriptor_b77436fd29d035f0, []int{13}
+}
+
+func (m *SwitchCapability) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_SwitchCapability.Unmarshal(m, b)
+}
+func (m *SwitchCapability) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_SwitchCapability.Marshal(b, m, deterministic)
+}
+func (m *SwitchCapability) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_SwitchCapability.Merge(m, src)
+}
+func (m *SwitchCapability) XXX_Size() int {
+	return xxx_messageInfo_SwitchCapability.Size(m)
+}
+func (m *SwitchCapability) XXX_DiscardUnknown() {
+	xxx_messageInfo_SwitchCapability.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_SwitchCapability proto.InternalMessageInfo
+
+func (m *SwitchCapability) GetDesc() *openflow_13.OfpDesc {
+	if m != nil {
+		return m.Desc
+	}
+	return nil
+}
+
+func (m *SwitchCapability) GetSwitchFeatures() *openflow_13.OfpSwitchFeatures {
+	if m != nil {
+		return m.SwitchFeatures
+	}
+	return nil
+}
+
+type ImageDownloadMessage struct {
+	Device               *voltha.Device        `protobuf:"bytes,1,opt,name=device,proto3" json:"device,omitempty"`
+	Image                *voltha.ImageDownload `protobuf:"bytes,2,opt,name=image,proto3" json:"image,omitempty"`
+	XXX_NoUnkeyedLiteral struct{}              `json:"-"`
+	XXX_unrecognized     []byte                `json:"-"`
+	XXX_sizecache        int32                 `json:"-"`
+}
+
+func (m *ImageDownloadMessage) Reset()         { *m = ImageDownloadMessage{} }
+func (m *ImageDownloadMessage) String() string { return proto.CompactTextString(m) }
+func (*ImageDownloadMessage) ProtoMessage()    {}
+func (*ImageDownloadMessage) Descriptor() ([]byte, []int) {
+	return fileDescriptor_b77436fd29d035f0, []int{14}
+}
+
+func (m *ImageDownloadMessage) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_ImageDownloadMessage.Unmarshal(m, b)
+}
+func (m *ImageDownloadMessage) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_ImageDownloadMessage.Marshal(b, m, deterministic)
+}
+func (m *ImageDownloadMessage) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_ImageDownloadMessage.Merge(m, src)
+}
+func (m *ImageDownloadMessage) XXX_Size() int {
+	return xxx_messageInfo_ImageDownloadMessage.Size(m)
+}
+func (m *ImageDownloadMessage) XXX_DiscardUnknown() {
+	xxx_messageInfo_ImageDownloadMessage.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_ImageDownloadMessage proto.InternalMessageInfo
+
+func (m *ImageDownloadMessage) GetDevice() *voltha.Device {
+	if m != nil {
+		return m.Device
+	}
+	return nil
+}
+
+func (m *ImageDownloadMessage) GetImage() *voltha.ImageDownload {
+	if m != nil {
+		return m.Image
+	}
+	return nil
+}
+
+type OMCITest struct {
+	Device               *voltha.Device        `protobuf:"bytes,1,opt,name=device,proto3" json:"device,omitempty"`
+	Request              *omci.OmciTestRequest `protobuf:"bytes,2,opt,name=request,proto3" json:"request,omitempty"`
+	XXX_NoUnkeyedLiteral struct{}              `json:"-"`
+	XXX_unrecognized     []byte                `json:"-"`
+	XXX_sizecache        int32                 `json:"-"`
+}
+
+func (m *OMCITest) Reset()         { *m = OMCITest{} }
+func (m *OMCITest) String() string { return proto.CompactTextString(m) }
+func (*OMCITest) ProtoMessage()    {}
+func (*OMCITest) Descriptor() ([]byte, []int) {
+	return fileDescriptor_b77436fd29d035f0, []int{15}
+}
+
+func (m *OMCITest) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_OMCITest.Unmarshal(m, b)
+}
+func (m *OMCITest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_OMCITest.Marshal(b, m, deterministic)
+}
+func (m *OMCITest) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_OMCITest.Merge(m, src)
+}
+func (m *OMCITest) XXX_Size() int {
+	return xxx_messageInfo_OMCITest.Size(m)
+}
+func (m *OMCITest) XXX_DiscardUnknown() {
+	xxx_messageInfo_OMCITest.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_OMCITest proto.InternalMessageInfo
+
+func (m *OMCITest) GetDevice() *voltha.Device {
+	if m != nil {
+		return m.Device
+	}
+	return nil
+}
+
+func (m *OMCITest) GetRequest() *omci.OmciTestRequest {
+	if m != nil {
+		return m.Request
+	}
+	return nil
+}
+
+type SimulateAlarmMessage struct {
+	Device               *voltha.Device               `protobuf:"bytes,1,opt,name=device,proto3" json:"device,omitempty"`
+	Request              *voltha.SimulateAlarmRequest `protobuf:"bytes,2,opt,name=request,proto3" json:"request,omitempty"`
+	XXX_NoUnkeyedLiteral struct{}                     `json:"-"`
+	XXX_unrecognized     []byte                       `json:"-"`
+	XXX_sizecache        int32                        `json:"-"`
+}
+
+func (m *SimulateAlarmMessage) Reset()         { *m = SimulateAlarmMessage{} }
+func (m *SimulateAlarmMessage) String() string { return proto.CompactTextString(m) }
+func (*SimulateAlarmMessage) ProtoMessage()    {}
+func (*SimulateAlarmMessage) Descriptor() ([]byte, []int) {
+	return fileDescriptor_b77436fd29d035f0, []int{16}
+}
+
+func (m *SimulateAlarmMessage) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_SimulateAlarmMessage.Unmarshal(m, b)
+}
+func (m *SimulateAlarmMessage) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_SimulateAlarmMessage.Marshal(b, m, deterministic)
+}
+func (m *SimulateAlarmMessage) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_SimulateAlarmMessage.Merge(m, src)
+}
+func (m *SimulateAlarmMessage) XXX_Size() int {
+	return xxx_messageInfo_SimulateAlarmMessage.Size(m)
+}
+func (m *SimulateAlarmMessage) XXX_DiscardUnknown() {
+	xxx_messageInfo_SimulateAlarmMessage.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_SimulateAlarmMessage proto.InternalMessageInfo
+
+func (m *SimulateAlarmMessage) GetDevice() *voltha.Device {
+	if m != nil {
+		return m.Device
+	}
+	return nil
+}
+
+func (m *SimulateAlarmMessage) GetRequest() *voltha.SimulateAlarmRequest {
+	if m != nil {
+		return m.Request
+	}
+	return nil
+}
+
+type GetExtValueMessage struct {
+	ParentDevice         *voltha.Device           `protobuf:"bytes,1,opt,name=parent_device,json=parentDevice,proto3" json:"parent_device,omitempty"`
+	ChildDevice          *voltha.Device           `protobuf:"bytes,2,opt,name=child_device,json=childDevice,proto3" json:"child_device,omitempty"`
+	ValueType            extension.ValueType_Type `protobuf:"varint,3,opt,name=value_type,json=valueType,proto3,enum=extension.ValueType_Type" json:"value_type,omitempty"`
+	XXX_NoUnkeyedLiteral struct{}                 `json:"-"`
+	XXX_unrecognized     []byte                   `json:"-"`
+	XXX_sizecache        int32                    `json:"-"`
+}
+
+func (m *GetExtValueMessage) Reset()         { *m = GetExtValueMessage{} }
+func (m *GetExtValueMessage) String() string { return proto.CompactTextString(m) }
+func (*GetExtValueMessage) ProtoMessage()    {}
+func (*GetExtValueMessage) Descriptor() ([]byte, []int) {
+	return fileDescriptor_b77436fd29d035f0, []int{17}
+}
+
+func (m *GetExtValueMessage) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_GetExtValueMessage.Unmarshal(m, b)
+}
+func (m *GetExtValueMessage) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_GetExtValueMessage.Marshal(b, m, deterministic)
+}
+func (m *GetExtValueMessage) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_GetExtValueMessage.Merge(m, src)
+}
+func (m *GetExtValueMessage) XXX_Size() int {
+	return xxx_messageInfo_GetExtValueMessage.Size(m)
+}
+func (m *GetExtValueMessage) XXX_DiscardUnknown() {
+	xxx_messageInfo_GetExtValueMessage.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_GetExtValueMessage proto.InternalMessageInfo
+
+func (m *GetExtValueMessage) GetParentDevice() *voltha.Device {
+	if m != nil {
+		return m.ParentDevice
+	}
+	return nil
+}
+
+func (m *GetExtValueMessage) GetChildDevice() *voltha.Device {
+	if m != nil {
+		return m.ChildDevice
+	}
+	return nil
+}
+
+func (m *GetExtValueMessage) GetValueType() extension.ValueType_Type {
+	if m != nil {
+		return m.ValueType
+	}
+	return extension.ValueType_EMPTY
+}
+
+type SetExtValueMessage struct {
+	Device               *voltha.Device      `protobuf:"bytes,1,opt,name=device,proto3" json:"device,omitempty"`
+	Value                *extension.ValueSet `protobuf:"bytes,3,opt,name=value,proto3" json:"value,omitempty"`
+	XXX_NoUnkeyedLiteral struct{}            `json:"-"`
+	XXX_unrecognized     []byte              `json:"-"`
+	XXX_sizecache        int32               `json:"-"`
+}
+
+func (m *SetExtValueMessage) Reset()         { *m = SetExtValueMessage{} }
+func (m *SetExtValueMessage) String() string { return proto.CompactTextString(m) }
+func (*SetExtValueMessage) ProtoMessage()    {}
+func (*SetExtValueMessage) Descriptor() ([]byte, []int) {
+	return fileDescriptor_b77436fd29d035f0, []int{18}
+}
+
+func (m *SetExtValueMessage) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_SetExtValueMessage.Unmarshal(m, b)
+}
+func (m *SetExtValueMessage) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_SetExtValueMessage.Marshal(b, m, deterministic)
+}
+func (m *SetExtValueMessage) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_SetExtValueMessage.Merge(m, src)
+}
+func (m *SetExtValueMessage) XXX_Size() int {
+	return xxx_messageInfo_SetExtValueMessage.Size(m)
+}
+func (m *SetExtValueMessage) XXX_DiscardUnknown() {
+	xxx_messageInfo_SetExtValueMessage.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_SetExtValueMessage proto.InternalMessageInfo
+
+func (m *SetExtValueMessage) GetDevice() *voltha.Device {
+	if m != nil {
+		return m.Device
+	}
+	return nil
+}
+
+func (m *SetExtValueMessage) GetValue() *extension.ValueSet {
+	if m != nil {
+		return m.Value
+	}
+	return nil
+}
+
+func init() {
+	proto.RegisterType((*AdapterRegistration)(nil), "core_adapter.AdapterRegistration")
+	proto.RegisterType((*ChildDeviceFilter)(nil), "core_adapter.ChildDeviceFilter")
+	proto.RegisterType((*PortFilter)(nil), "core_adapter.PortFilter")
+	proto.RegisterType((*DeviceDiscovery)(nil), "core_adapter.DeviceDiscovery")
+	proto.RegisterType((*DeviceStateFilter)(nil), "core_adapter.DeviceStateFilter")
+	proto.RegisterType((*PortState)(nil), "core_adapter.PortState")
+	proto.RegisterType((*PortStateFilter)(nil), "core_adapter.PortStateFilter")
+	proto.RegisterType((*PacketIn)(nil), "core_adapter.PacketIn")
+	proto.RegisterType((*PacketOut)(nil), "core_adapter.PacketOut")
+	proto.RegisterType((*DeviceReason)(nil), "core_adapter.DeviceReason")
+	proto.RegisterType((*BulkFlows)(nil), "core_adapter.BulkFlows")
+	proto.RegisterType((*IncrementalFlows)(nil), "core_adapter.IncrementalFlows")
+	proto.RegisterType((*PmConfigsInfo)(nil), "core_adapter.PmConfigsInfo")
+	proto.RegisterType((*SwitchCapability)(nil), "core_adapter.SwitchCapability")
+	proto.RegisterType((*ImageDownloadMessage)(nil), "core_adapter.ImageDownloadMessage")
+	proto.RegisterType((*OMCITest)(nil), "core_adapter.OMCITest")
+	proto.RegisterType((*SimulateAlarmMessage)(nil), "core_adapter.SimulateAlarmMessage")
+	proto.RegisterType((*GetExtValueMessage)(nil), "core_adapter.GetExtValueMessage")
+	proto.RegisterType((*SetExtValueMessage)(nil), "core_adapter.SetExtValueMessage")
+}
+
+func init() { proto.RegisterFile("voltha_protos/core_adapter.proto", fileDescriptor_b77436fd29d035f0) }
+
+var fileDescriptor_b77436fd29d035f0 = []byte{
+	// 1107 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x56, 0x4f, 0x6f, 0x1b, 0x45,
+	0x14, 0xd7, 0x86, 0xc4, 0x89, 0x9f, 0xff, 0x24, 0x99, 0x34, 0x6d, 0xda, 0x10, 0x88, 0x96, 0x0a,
+	0xa5, 0xad, 0x70, 0x68, 0x42, 0x11, 0x48, 0x08, 0xa9, 0x75, 0x48, 0xe5, 0x43, 0x9a, 0x68, 0x5c,
+	0x21, 0xc4, 0x81, 0xd5, 0x64, 0x77, 0x6c, 0xaf, 0xb2, 0x3b, 0xb3, 0x9d, 0x99, 0x75, 0x9a, 0x33,
+	0x17, 0xce, 0xf0, 0x45, 0x38, 0xf1, 0x31, 0xb8, 0xf0, 0x09, 0xf8, 0x16, 0x1c, 0xd1, 0xfc, 0x59,
+	0xc7, 0xbb, 0x2e, 0xc1, 0x11, 0x5c, 0xec, 0x9d, 0xf7, 0x7e, 0xef, 0xbd, 0xdf, 0xef, 0xbd, 0xd9,
+	0xd9, 0x81, 0xdd, 0x31, 0x4f, 0xd4, 0x88, 0x04, 0x99, 0xe0, 0x8a, 0xcb, 0xfd, 0x90, 0x0b, 0x1a,
+	0x90, 0x88, 0x64, 0x8a, 0x8a, 0x8e, 0xb1, 0xa1, 0xe6, 0xb4, 0xed, 0xc1, 0x83, 0x2a, 0x3e, 0x4d,
+	0x39, 0xb3, 0xc8, 0xaa, 0xcf, 0xae, 0x9c, 0xef, 0xc3, 0xb2, 0x8f, 0x67, 0x94, 0x0d, 0x12, 0x7e,
+	0x19, 0x3c, 0x3d, 0x74, 0x80, 0xed, 0x32, 0xa0, 0xc4, 0xa1, 0x9a, 0x39, 0xa2, 0xe3, 0x38, 0xa4,
+	0xce, 0xf7, 0x41, 0xd9, 0x47, 0xdf, 0x2a, 0xca, 0x64, 0xcc, 0x99, 0x74, 0xfe, 0x9d, 0x4a, 0xe5,
+	0x34, 0x8c, 0x03, 0x45, 0xa5, 0xb2, 0x6e, 0x9f, 0xc1, 0xc6, 0x73, 0x5b, 0x0b, 0xd3, 0x61, 0x2c,
+	0x95, 0x20, 0x2a, 0xe6, 0x0c, 0x3d, 0x86, 0x65, 0x47, 0x61, 0xcb, 0xdb, 0xf5, 0xf6, 0x1a, 0x07,
+	0x6b, 0x9d, 0x82, 0x52, 0x01, 0x2f, 0x00, 0xe8, 0x09, 0xd4, 0xa2, 0xd7, 0x57, 0x19, 0x95, 0x5b,
+	0x0b, 0x06, 0xba, 0xd1, 0x71, 0x04, 0x8f, 0xcc, 0x9f, 0x71, 0x61, 0x07, 0xf1, 0x7f, 0xf6, 0x60,
+	0xbd, 0x3b, 0x8a, 0x93, 0xc8, 0x3a, 0x8f, 0xe3, 0x44, 0xa7, 0xd8, 0x86, 0x7a, 0x46, 0x04, 0x65,
+	0x2a, 0x88, 0x23, 0x53, 0xb0, 0x8e, 0x57, 0xac, 0xa1, 0x17, 0xa1, 0x8f, 0xa0, 0x25, 0xa9, 0x88,
+	0x49, 0x12, 0xb0, 0x3c, 0x3d, 0xa7, 0xc2, 0x94, 0xa9, 0xe3, 0xa6, 0x35, 0xbe, 0x32, 0x36, 0xb4,
+	0x09, 0x35, 0xce, 0x72, 0x1d, 0xfe, 0xde, 0xae, 0xb7, 0xd7, 0xc2, 0x4b, 0x9c, 0xe5, 0xbd, 0x08,
+	0x3d, 0x84, 0xb6, 0x4b, 0x9c, 0x71, 0xa1, 0x02, 0xc6, 0xb7, 0x16, 0x8d, 0xbb, 0x69, 0xad, 0x67,
+	0x5c, 0xa8, 0x57, 0xdc, 0x7f, 0x03, 0xa0, 0x9f, 0xae, 0xc9, 0x58, 0x01, 0x53, 0x64, 0xac, 0xa1,
+	0x17, 0x21, 0x04, 0x8b, 0x3a, 0x93, 0xe1, 0xd0, 0xc2, 0xe6, 0x19, 0x1d, 0x40, 0xdd, 0x64, 0x57,
+	0x57, 0x19, 0x35, 0xe5, 0xdb, 0x07, 0x9b, 0x45, 0x0f, 0x74, 0x5e, 0xf3, 0xa3, 0xe5, 0xe3, 0x95,
+	0xcc, 0x3d, 0xf9, 0x7f, 0x79, 0xb0, 0x6a, 0x5b, 0x70, 0x14, 0xcb, 0x90, 0x8f, 0xa9, 0xb8, 0xba,
+	0xb9, 0x0b, 0xb3, 0x4a, 0x16, 0x66, 0x95, 0xa0, 0xc7, 0xb0, 0x1e, 0xea, 0xee, 0x06, 0x4e, 0xc1,
+	0x84, 0x52, 0x1d, 0xaf, 0x86, 0xd7, 0x6d, 0xd7, 0x14, 0xd0, 0x0e, 0x40, 0x38, 0x22, 0x8c, 0xd1,
+	0x44, 0xd7, 0xb3, 0x7d, 0xa9, 0x3b, 0x4b, 0x2f, 0xd2, 0x6c, 0xc6, 0x94, 0x45, 0x5c, 0x68, 0xef,
+	0x92, 0x65, 0x63, 0x0d, 0xef, 0x9a, 0x49, 0xed, 0xc6, 0x99, 0x2c, 0x4f, 0xcd, 0xc4, 0xff, 0xc3,
+	0x83, 0x75, 0x4b, 0xa3, 0xaf, 0x88, 0xa2, 0xf3, 0x74, 0x7d, 0x0f, 0xd6, 0x9c, 0xf8, 0x6b, 0x8c,
+	0xdd, 0x05, 0xae, 0x29, 0x47, 0x05, 0xf2, 0x4b, 0x68, 0xf0, 0x8c, 0x8a, 0x40, 0x2a, 0xa2, 0x72,
+	0xe9, 0xa6, 0xb1, 0xd5, 0x71, 0x2f, 0xea, 0x69, 0x46, 0x45, 0xdf, 0x78, 0x3a, 0x76, 0x5b, 0x02,
+	0x9f, 0x58, 0xd0, 0x57, 0xd0, 0x08, 0x39, 0x63, 0x45, 0xe8, 0xa2, 0x09, 0xdd, 0x2e, 0x42, 0xbb,
+	0x9c, 0x31, 0x1a, 0xaa, 0x72, 0xb4, 0xc6, 0x5b, 0x8b, 0xff, 0xab, 0x07, 0x75, 0x3d, 0x04, 0xa3,
+	0xe9, 0x66, 0x35, 0xa5, 0xfd, 0xb2, 0x30, 0xd7, 0x7e, 0x41, 0xf7, 0x60, 0xb9, 0x98, 0xbb, 0xdd,
+	0xe0, 0xb5, 0xcc, 0x4e, 0xbc, 0x22, 0x78, 0x71, 0x7e, 0xc1, 0xfe, 0x2f, 0x1e, 0xac, 0x4e, 0x28,
+	0xcf, 0x3b, 0x86, 0x82, 0x78, 0x30, 0x30, 0x01, 0x6e, 0x17, 0xb6, 0x0b, 0xa2, 0x2e, 0xcd, 0x7f,
+	0x60, 0xd5, 0x87, 0x95, 0x33, 0x12, 0x5e, 0x50, 0xd5, 0x63, 0xb7, 0x7f, 0x15, 0xef, 0x42, 0x2d,
+	0x33, 0xc1, 0xa6, 0x4b, 0x4d, 0xec, 0x56, 0xfe, 0x8f, 0x7a, 0x3a, 0xe6, 0xf1, 0x34, 0x57, 0x37,
+	0xa7, 0x7d, 0x08, 0x6d, 0x3a, 0x14, 0x54, 0xca, 0xea, 0x8b, 0x66, 0xad, 0xee, 0x45, 0x3b, 0x2c,
+	0x15, 0x6a, 0x1c, 0x6c, 0x77, 0xa6, 0xcf, 0x74, 0x3e, 0xc8, 0x02, 0xeb, 0x0e, 0x78, 0xae, 0x26,
+	0x2c, 0xba, 0xd0, 0xb4, 0x1b, 0x15, 0x53, 0x22, 0xf9, 0xbf, 0xc8, 0xbb, 0x0b, 0x35, 0x61, 0x60,
+	0x6e, 0xa7, 0xbb, 0x95, 0xff, 0xbb, 0x07, 0xf5, 0x17, 0x79, 0x72, 0x71, 0x9c, 0xf0, 0x4b, 0x89,
+	0x3e, 0x86, 0x9a, 0x8d, 0x70, 0xe7, 0x74, 0xbb, 0x7c, 0xf8, 0x62, 0xe7, 0x45, 0x7b, 0xb0, 0xa4,
+	0xc9, 0x15, 0x67, 0x34, 0x2a, 0xd1, 0x35, 0xa9, 0xb0, 0x05, 0xa0, 0x7d, 0xa8, 0x0d, 0x05, 0xcf,
+	0x33, 0xe9, 0x94, 0xdd, 0x9b, 0x81, 0xbe, 0x34, 0x6e, 0xec, 0x60, 0xe8, 0x6b, 0x68, 0x19, 0x6f,
+	0x4a, 0x15, 0x89, 0x88, 0x22, 0x66, 0xda, 0x8d, 0x83, 0xfb, 0x33, 0x71, 0x27, 0x0e, 0x80, 0x9b,
+	0x83, 0xa9, 0x95, 0xff, 0xa7, 0x07, 0x6b, 0x3d, 0x16, 0x0a, 0x9a, 0x52, 0xa6, 0x48, 0x72, 0x3b,
+	0x5d, 0x9d, 0xb2, 0xae, 0xad, 0x99, 0xa2, 0xdd, 0x11, 0x61, 0x43, 0x3a, 0x51, 0xf7, 0xac, 0xa2,
+	0x6e, 0xe7, 0xdd, 0xea, 0x8a, 0xa8, 0xff, 0x4b, 0xe3, 0x0f, 0xd0, 0x3a, 0x4b, 0xbb, 0x9c, 0x0d,
+	0xe2, 0xa1, 0xec, 0xb1, 0x01, 0xbf, 0x79, 0xf4, 0x9f, 0x02, 0x64, 0x69, 0x10, 0x5a, 0xb8, 0x53,
+	0xb6, 0x3e, 0x39, 0x21, 0x8a, 0x3c, 0xb8, 0x9e, 0x15, 0x8f, 0xfe, 0x4f, 0x1e, 0xac, 0xf5, 0x2f,
+	0x63, 0x15, 0x8e, 0xba, 0x24, 0x23, 0xe7, 0x71, 0x12, 0xab, 0x2b, 0xf4, 0x08, 0x16, 0x23, 0x2a,
+	0x43, 0xd7, 0xc1, 0xcd, 0x99, 0x1d, 0xaa, 0x9d, 0xd8, 0x40, 0x50, 0x0f, 0x56, 0xa5, 0x09, 0x0f,
+	0x06, 0x94, 0xa8, 0x5c, 0x4c, 0x3e, 0xe6, 0xbb, 0x33, 0x51, 0x15, 0x1c, 0x6e, 0x5b, 0xc3, 0xb1,
+	0x5b, 0xfb, 0x17, 0x70, 0xa7, 0x97, 0x92, 0x21, 0x3d, 0xe2, 0x97, 0x2c, 0xe1, 0x24, 0x3a, 0xa1,
+	0x52, 0x92, 0x21, 0x9d, 0x7b, 0xa2, 0x4f, 0x60, 0x29, 0xd6, 0xf1, 0x8e, 0xc0, 0xe4, 0x64, 0x2c,
+	0x25, 0xc5, 0x16, 0xe3, 0x87, 0xb0, 0x72, 0x7a, 0xd2, 0xed, 0xbd, 0xa6, 0x52, 0xcd, 0x5d, 0x60,
+	0x1f, 0x96, 0x05, 0x7d, 0x93, 0x53, 0xa9, 0x26, 0x25, 0xf4, 0xad, 0xa8, 0x73, 0x9a, 0x86, 0xb1,
+	0x4e, 0x84, 0xad, 0x13, 0x17, 0x28, 0x7f, 0x0c, 0x77, 0xfa, 0x71, 0x9a, 0x27, 0x44, 0xd1, 0xe7,
+	0x09, 0x11, 0xe9, 0x6d, 0x15, 0x7d, 0x5e, 0x2d, 0xf8, 0x7e, 0x01, 0x2c, 0xa5, 0x9d, 0xa9, 0xfb,
+	0x9b, 0x07, 0xe8, 0x25, 0x55, 0xdf, 0xbc, 0x55, 0xdf, 0x92, 0x24, 0xa7, 0x45, 0xd9, 0x43, 0x68,
+	0x95, 0x3e, 0x86, 0xff, 0x50, 0xbd, 0x39, 0xfd, 0x65, 0x44, 0x4f, 0xa1, 0x39, 0x7d, 0x31, 0x70,
+	0x44, 0xaa, 0x31, 0x8d, 0xa9, 0x3b, 0x02, 0xfa, 0x02, 0x60, 0xac, 0xeb, 0x4e, 0xdf, 0x6b, 0xee,
+	0x77, 0x26, 0x17, 0xcc, 0x8e, 0x21, 0xa5, 0xcf, 0x6f, 0x73, 0x88, 0xe3, 0xfa, 0xb8, 0x58, 0xfb,
+	0x43, 0x40, 0xfd, 0x59, 0xde, 0xf3, 0xb6, 0xeb, 0x11, 0x2c, 0x99, 0x54, 0xee, 0x0d, 0xdd, 0xa8,
+	0x96, 0xec, 0x53, 0x85, 0x2d, 0xe2, 0xc5, 0x77, 0xb0, 0xcb, 0xc5, 0xd0, 0x6c, 0xd1, 0x90, 0x8b,
+	0xa8, 0xe3, 0xee, 0xdc, 0xd3, 0x57, 0xf6, 0xef, 0x3f, 0x1b, 0xc6, 0x6a, 0x94, 0x9f, 0xeb, 0x6f,
+	0xcf, 0x7e, 0x01, 0x74, 0x97, 0xf3, 0x4f, 0x8a, 0xab, 0xfa, 0xb3, 0xfd, 0x21, 0x2f, 0x5d, 0xfe,
+	0xcf, 0x6b, 0xc6, 0x75, 0xf8, 0x77, 0x00, 0x00, 0x00, 0xff, 0xff, 0xbc, 0xbf, 0xfc, 0xfe, 0x21,
+	0x0c, 0x00, 0x00,
+}
diff --git a/vendor/github.com/opencord/voltha-protos/v5/go/core_service/core_services.pb.go b/vendor/github.com/opencord/voltha-protos/v5/go/core_service/core_services.pb.go
new file mode 100644
index 0000000..265d0c8
--- /dev/null
+++ b/vendor/github.com/opencord/voltha-protos/v5/go/core_service/core_services.pb.go
@@ -0,0 +1,1023 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// source: voltha_protos/core_services.proto
+
+package core_service
+
+import (
+	context "context"
+	fmt "fmt"
+	proto "github.com/golang/protobuf/proto"
+	empty "github.com/golang/protobuf/ptypes/empty"
+	common "github.com/opencord/voltha-protos/v5/go/common"
+	core_adapter "github.com/opencord/voltha-protos/v5/go/core_adapter"
+	health "github.com/opencord/voltha-protos/v5/go/health"
+	voltha "github.com/opencord/voltha-protos/v5/go/voltha"
+	grpc "google.golang.org/grpc"
+	codes "google.golang.org/grpc/codes"
+	status "google.golang.org/grpc/status"
+	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
+
+func init() { proto.RegisterFile("voltha_protos/core_services.proto", fileDescriptor_979c43850713f141) }
+
+var fileDescriptor_979c43850713f141 = []byte{
+	// 625 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x55, 0xcd, 0x4f, 0x14, 0x31,
+	0x14, 0x0f, 0x17, 0xa3, 0x8f, 0x85, 0x85, 0xf2, 0xa1, 0x59, 0x82, 0xc2, 0x49, 0x0f, 0xda, 0x35,
+	0x82, 0x98, 0x68, 0xa2, 0x59, 0x76, 0x74, 0xd9, 0x64, 0x31, 0x04, 0xa2, 0x26, 0x5e, 0x48, 0x99,
+	0x79, 0xcc, 0x4c, 0x98, 0x6d, 0x37, 0x6d, 0x59, 0xdd, 0x3f, 0xde, 0xc4, 0xcc, 0xb4, 0xb3, 0x69,
+	0x87, 0x6d, 0xe4, 0xe0, 0xf5, 0xbd, 0xdf, 0x47, 0xdf, 0xaf, 0x7d, 0x29, 0xec, 0x4f, 0x45, 0xa1,
+	0x33, 0x76, 0x39, 0x91, 0x42, 0x0b, 0xd5, 0x8d, 0x85, 0xc4, 0x4b, 0x85, 0x72, 0x9a, 0xc7, 0xa8,
+	0x68, 0x55, 0x24, 0x2d, 0xb7, 0xd8, 0xd9, 0x49, 0x85, 0x48, 0x0b, 0xec, 0x56, 0xbd, 0xab, 0xdb,
+	0xeb, 0x2e, 0x8e, 0x27, 0x7a, 0x66, 0xa0, 0x9d, 0xbd, 0x05, 0x6a, 0x2c, 0x61, 0x13, 0x8d, 0xd2,
+	0x22, 0x3a, 0x4d, 0xc4, 0x78, 0x2c, 0xf8, 0xe2, 0x5e, 0x82, 0xa5, 0xe1, 0xe2, 0x5e, 0x86, 0xac,
+	0xd0, 0x99, 0xe9, 0xbd, 0xf9, 0xb3, 0x0c, 0xcb, 0x7d, 0x21, 0xf1, 0xc2, 0x1c, 0x91, 0x7c, 0x82,
+	0xf6, 0x00, 0xf5, 0x49, 0x05, 0xb9, 0xd0, 0x4c, 0xdf, 0x2a, 0x42, 0xa8, 0x75, 0xea, 0x0b, 0xce,
+	0x31, 0xd6, 0xb9, 0xe0, 0x9d, 0x4d, 0x6a, 0x55, 0x5c, 0xe4, 0x8b, 0xa5, 0xd7, 0x4b, 0x64, 0x04,
+	0xed, 0x73, 0x4c, 0x73, 0xa5, 0x51, 0xf6, 0xcc, 0xe9, 0xc9, 0x3e, 0xf5, 0x86, 0xb1, 0x65, 0x83,
+	0x92, 0xac, 0xd2, 0xdb, 0xa6, 0x26, 0x1a, 0x5a, 0x47, 0x43, 0x3f, 0x97, 0xd1, 0x90, 0x23, 0x68,
+	0x45, 0xd5, 0x28, 0xdf, 0x26, 0x09, 0xd3, 0x48, 0x56, 0xa9, 0x9d, 0xcc, 0x54, 0x83, 0xbc, 0x03,
+	0x58, 0x3e, 0x13, 0x52, 0xf7, 0x25, 0x32, 0x8d, 0x09, 0x69, 0xd5, 0xb4, 0xb2, 0x18, 0x24, 0x0d,
+	0x61, 0xad, 0xec, 0xab, 0x72, 0x9a, 0xda, 0x70, 0xd7, 0x3f, 0x7b, 0xd9, 0xaf, 0xda, 0x5f, 0xf2,
+	0x42, 0xa3, 0x0c, 0x4a, 0x1d, 0xc2, 0x6a, 0x84, 0x05, 0x6a, 0xec, 0x15, 0x45, 0xa5, 0x49, 0xa0,
+	0x4e, 0x71, 0x18, 0x05, 0x59, 0xef, 0x60, 0x65, 0x80, 0xda, 0x8c, 0x56, 0xb2, 0xc8, 0x93, 0xbb,
+	0xee, 0xd6, 0xd8, 0x9b, 0x88, 0xbc, 0x84, 0xf6, 0x28, 0x57, 0x0e, 0xd3, 0xf7, 0x5b, 0x71, 0xc1,
+	0x8a, 0x8c, 0x60, 0xdd, 0x20, 0xdd, 0x41, 0x9f, 0xf9, 0x56, 0x0e, 0xe0, 0x1f, 0xa3, 0xf6, 0x60,
+	0xd3, 0xfa, 0x9e, 0xf6, 0x05, 0xbf, 0xce, 0x53, 0x2b, 0xb8, 0x3e, 0x37, 0x1d, 0x9b, 0xba, 0x0a,
+	0x4a, 0x44, 0xb0, 0xd1, 0xcf, 0xf2, 0x22, 0x31, 0x3a, 0x11, 0x6a, 0x8c, 0xcb, 0x5b, 0xdb, 0x5d,
+	0x74, 0xa4, 0x28, 0x57, 0xb1, 0x98, 0xa2, 0x9c, 0x75, 0x1a, 0x6f, 0x81, 0x1c, 0xc1, 0x9a, 0xa3,
+	0xa2, 0x46, 0x42, 0xe9, 0x7b, 0xa5, 0xfe, 0x1e, 0x36, 0x5d, 0xde, 0xdc, 0xfe, 0x3e, 0xdc, 0xe7,
+	0xf0, 0x68, 0x7e, 0x63, 0x1e, 0xa1, 0x79, 0xb8, 0x1e, 0xac, 0x0e, 0x50, 0x3b, 0x3e, 0xcd, 0xc0,
+	0x9d, 0x96, 0x0d, 0xbc, 0x29, 0x41, 0xab, 0xd5, 0x74, 0x8f, 0xea, 0x39, 0xb6, 0x7d, 0xb8, 0x22,
+	0x1f, 0xa1, 0x75, 0x81, 0x3c, 0x39, 0x63, 0xf1, 0x0d, 0xea, 0x21, 0x27, 0xdb, 0x8d, 0xc7, 0x64,
+	0xeb, 0xc1, 0xd9, 0x4e, 0x80, 0x18, 0xa9, 0x73, 0x64, 0x4a, 0x70, 0x7b, 0xad, 0x9d, 0x45, 0x97,
+	0x62, 0x10, 0x41, 0xa5, 0x63, 0x68, 0xcf, 0x17, 0xc7, 0xca, 0x3c, 0x0e, 0xec, 0x55, 0x50, 0xe3,
+	0x03, 0x6c, 0x9d, 0x63, 0x2c, 0x78, 0x9c, 0x17, 0x18, 0xcc, 0x20, 0x44, 0x3e, 0x85, 0xa7, 0x7e,
+	0x74, 0x3f, 0x72, 0x9d, 0x9d, 0x49, 0xf1, 0x7b, 0xd6, 0x4b, 0x12, 0x89, 0x4a, 0x91, 0x1d, 0x3f,
+	0x3d, 0xea, 0x36, 0xef, 0xdc, 0xc4, 0x01, 0x3c, 0x1c, 0xa0, 0x36, 0xcb, 0x14, 0x5e, 0xd1, 0xc6,
+	0xd6, 0x7d, 0xb5, 0x8f, 0x5c, 0x22, 0xff, 0x2f, 0x7b, 0x17, 0xc1, 0x86, 0x91, 0x18, 0x8e, 0x59,
+	0x8a, 0x91, 0xf8, 0xc5, 0x0b, 0xc1, 0x12, 0xb2, 0x55, 0xbb, 0x7a, 0xe5, 0x90, 0xca, 0xf1, 0x0d,
+	0xec, 0x09, 0x99, 0x52, 0x31, 0x41, 0x1e, 0x0b, 0x99, 0x50, 0xf3, 0x55, 0x50, 0xf7, 0xdb, 0x3a,
+	0x5e, 0xff, 0x5e, 0x15, 0x9d, 0x6f, 0xe2, 0xe7, 0x61, 0x9a, 0xeb, 0xec, 0xf6, 0xaa, 0x8c, 0xbe,
+	0x5b, 0x73, 0xbb, 0x86, 0xfb, 0xca, 0x7e, 0x33, 0xd3, 0xb7, 0xdd, 0x54, 0x78, 0x9f, 0xe2, 0xd5,
+	0x83, 0xaa, 0x75, 0xf0, 0x37, 0x00, 0x00, 0xff, 0xff, 0x7f, 0x44, 0xa5, 0x7d, 0x39, 0x07, 0x00,
+	0x00,
+}
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ context.Context
+var _ grpc.ClientConn
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the grpc package it is being compiled against.
+const _ = grpc.SupportPackageIsVersion4
+
+// CoreServiceClient is the client API for CoreService service.
+//
+// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
+type CoreServiceClient interface {
+	// GetHealthStatus is used by a CoreService client to verify connectivity
+	// to the gRPC server hosting the CoreService service
+	GetHealthStatus(ctx context.Context, opts ...grpc.CallOption) (CoreService_GetHealthStatusClient, error)
+	RegisterAdapter(ctx context.Context, in *core_adapter.AdapterRegistration, opts ...grpc.CallOption) (*empty.Empty, error)
+	DeviceUpdate(ctx context.Context, in *voltha.Device, opts ...grpc.CallOption) (*empty.Empty, error)
+	PortCreated(ctx context.Context, in *voltha.Port, opts ...grpc.CallOption) (*empty.Empty, error)
+	PortsStateUpdate(ctx context.Context, in *core_adapter.PortStateFilter, opts ...grpc.CallOption) (*empty.Empty, error)
+	DeleteAllPorts(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*empty.Empty, error)
+	GetDevicePort(ctx context.Context, in *core_adapter.PortFilter, opts ...grpc.CallOption) (*voltha.Port, error)
+	ListDevicePorts(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*voltha.Ports, error)
+	DeviceStateUpdate(ctx context.Context, in *core_adapter.DeviceStateFilter, opts ...grpc.CallOption) (*empty.Empty, error)
+	DevicePMConfigUpdate(ctx context.Context, in *voltha.PmConfigs, opts ...grpc.CallOption) (*empty.Empty, error)
+	ChildDeviceDetected(ctx context.Context, in *core_adapter.DeviceDiscovery, opts ...grpc.CallOption) (*voltha.Device, error)
+	ChildDevicesLost(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*empty.Empty, error)
+	ChildDevicesDetected(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*empty.Empty, error)
+	GetDevice(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*voltha.Device, error)
+	GetChildDevice(ctx context.Context, in *core_adapter.ChildDeviceFilter, opts ...grpc.CallOption) (*voltha.Device, error)
+	GetChildDevices(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*voltha.Devices, error)
+	SendPacketIn(ctx context.Context, in *core_adapter.PacketIn, opts ...grpc.CallOption) (*empty.Empty, error)
+	DeviceReasonUpdate(ctx context.Context, in *core_adapter.DeviceReason, opts ...grpc.CallOption) (*empty.Empty, error)
+	PortStateUpdate(ctx context.Context, in *core_adapter.PortState, opts ...grpc.CallOption) (*empty.Empty, error)
+	// Additional API found in the Core - unused?
+	ReconcileChildDevices(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*empty.Empty, error)
+	GetChildDeviceWithProxyAddress(ctx context.Context, in *voltha.Device_ProxyAddress, opts ...grpc.CallOption) (*voltha.Device, error)
+	GetPorts(ctx context.Context, in *core_adapter.PortFilter, opts ...grpc.CallOption) (*voltha.Ports, error)
+	ChildrenStateUpdate(ctx context.Context, in *core_adapter.DeviceStateFilter, opts ...grpc.CallOption) (*empty.Empty, error)
+	UpdateImageDownload(ctx context.Context, in *voltha.ImageDownload, opts ...grpc.CallOption) (*empty.Empty, error)
+}
+
+type coreServiceClient struct {
+	cc *grpc.ClientConn
+}
+
+func NewCoreServiceClient(cc *grpc.ClientConn) CoreServiceClient {
+	return &coreServiceClient{cc}
+}
+
+func (c *coreServiceClient) GetHealthStatus(ctx context.Context, opts ...grpc.CallOption) (CoreService_GetHealthStatusClient, error) {
+	stream, err := c.cc.NewStream(ctx, &_CoreService_serviceDesc.Streams[0], "/core_service.CoreService/GetHealthStatus", opts...)
+	if err != nil {
+		return nil, err
+	}
+	x := &coreServiceGetHealthStatusClient{stream}
+	return x, nil
+}
+
+type CoreService_GetHealthStatusClient interface {
+	Send(*common.Connection) error
+	Recv() (*health.HealthStatus, error)
+	grpc.ClientStream
+}
+
+type coreServiceGetHealthStatusClient struct {
+	grpc.ClientStream
+}
+
+func (x *coreServiceGetHealthStatusClient) Send(m *common.Connection) error {
+	return x.ClientStream.SendMsg(m)
+}
+
+func (x *coreServiceGetHealthStatusClient) Recv() (*health.HealthStatus, error) {
+	m := new(health.HealthStatus)
+	if err := x.ClientStream.RecvMsg(m); err != nil {
+		return nil, err
+	}
+	return m, nil
+}
+
+func (c *coreServiceClient) RegisterAdapter(ctx context.Context, in *core_adapter.AdapterRegistration, opts ...grpc.CallOption) (*empty.Empty, error) {
+	out := new(empty.Empty)
+	err := c.cc.Invoke(ctx, "/core_service.CoreService/RegisterAdapter", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *coreServiceClient) DeviceUpdate(ctx context.Context, in *voltha.Device, opts ...grpc.CallOption) (*empty.Empty, error) {
+	out := new(empty.Empty)
+	err := c.cc.Invoke(ctx, "/core_service.CoreService/DeviceUpdate", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *coreServiceClient) PortCreated(ctx context.Context, in *voltha.Port, opts ...grpc.CallOption) (*empty.Empty, error) {
+	out := new(empty.Empty)
+	err := c.cc.Invoke(ctx, "/core_service.CoreService/PortCreated", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *coreServiceClient) PortsStateUpdate(ctx context.Context, in *core_adapter.PortStateFilter, opts ...grpc.CallOption) (*empty.Empty, error) {
+	out := new(empty.Empty)
+	err := c.cc.Invoke(ctx, "/core_service.CoreService/PortsStateUpdate", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *coreServiceClient) DeleteAllPorts(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*empty.Empty, error) {
+	out := new(empty.Empty)
+	err := c.cc.Invoke(ctx, "/core_service.CoreService/DeleteAllPorts", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *coreServiceClient) GetDevicePort(ctx context.Context, in *core_adapter.PortFilter, opts ...grpc.CallOption) (*voltha.Port, error) {
+	out := new(voltha.Port)
+	err := c.cc.Invoke(ctx, "/core_service.CoreService/GetDevicePort", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *coreServiceClient) ListDevicePorts(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*voltha.Ports, error) {
+	out := new(voltha.Ports)
+	err := c.cc.Invoke(ctx, "/core_service.CoreService/ListDevicePorts", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *coreServiceClient) DeviceStateUpdate(ctx context.Context, in *core_adapter.DeviceStateFilter, opts ...grpc.CallOption) (*empty.Empty, error) {
+	out := new(empty.Empty)
+	err := c.cc.Invoke(ctx, "/core_service.CoreService/DeviceStateUpdate", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *coreServiceClient) DevicePMConfigUpdate(ctx context.Context, in *voltha.PmConfigs, opts ...grpc.CallOption) (*empty.Empty, error) {
+	out := new(empty.Empty)
+	err := c.cc.Invoke(ctx, "/core_service.CoreService/DevicePMConfigUpdate", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *coreServiceClient) ChildDeviceDetected(ctx context.Context, in *core_adapter.DeviceDiscovery, opts ...grpc.CallOption) (*voltha.Device, error) {
+	out := new(voltha.Device)
+	err := c.cc.Invoke(ctx, "/core_service.CoreService/ChildDeviceDetected", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *coreServiceClient) ChildDevicesLost(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*empty.Empty, error) {
+	out := new(empty.Empty)
+	err := c.cc.Invoke(ctx, "/core_service.CoreService/ChildDevicesLost", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *coreServiceClient) ChildDevicesDetected(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*empty.Empty, error) {
+	out := new(empty.Empty)
+	err := c.cc.Invoke(ctx, "/core_service.CoreService/ChildDevicesDetected", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *coreServiceClient) GetDevice(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*voltha.Device, error) {
+	out := new(voltha.Device)
+	err := c.cc.Invoke(ctx, "/core_service.CoreService/GetDevice", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *coreServiceClient) GetChildDevice(ctx context.Context, in *core_adapter.ChildDeviceFilter, opts ...grpc.CallOption) (*voltha.Device, error) {
+	out := new(voltha.Device)
+	err := c.cc.Invoke(ctx, "/core_service.CoreService/GetChildDevice", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *coreServiceClient) GetChildDevices(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*voltha.Devices, error) {
+	out := new(voltha.Devices)
+	err := c.cc.Invoke(ctx, "/core_service.CoreService/GetChildDevices", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *coreServiceClient) SendPacketIn(ctx context.Context, in *core_adapter.PacketIn, opts ...grpc.CallOption) (*empty.Empty, error) {
+	out := new(empty.Empty)
+	err := c.cc.Invoke(ctx, "/core_service.CoreService/SendPacketIn", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *coreServiceClient) DeviceReasonUpdate(ctx context.Context, in *core_adapter.DeviceReason, opts ...grpc.CallOption) (*empty.Empty, error) {
+	out := new(empty.Empty)
+	err := c.cc.Invoke(ctx, "/core_service.CoreService/DeviceReasonUpdate", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *coreServiceClient) PortStateUpdate(ctx context.Context, in *core_adapter.PortState, opts ...grpc.CallOption) (*empty.Empty, error) {
+	out := new(empty.Empty)
+	err := c.cc.Invoke(ctx, "/core_service.CoreService/PortStateUpdate", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *coreServiceClient) ReconcileChildDevices(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*empty.Empty, error) {
+	out := new(empty.Empty)
+	err := c.cc.Invoke(ctx, "/core_service.CoreService/ReconcileChildDevices", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *coreServiceClient) GetChildDeviceWithProxyAddress(ctx context.Context, in *voltha.Device_ProxyAddress, opts ...grpc.CallOption) (*voltha.Device, error) {
+	out := new(voltha.Device)
+	err := c.cc.Invoke(ctx, "/core_service.CoreService/GetChildDeviceWithProxyAddress", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *coreServiceClient) GetPorts(ctx context.Context, in *core_adapter.PortFilter, opts ...grpc.CallOption) (*voltha.Ports, error) {
+	out := new(voltha.Ports)
+	err := c.cc.Invoke(ctx, "/core_service.CoreService/GetPorts", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *coreServiceClient) ChildrenStateUpdate(ctx context.Context, in *core_adapter.DeviceStateFilter, opts ...grpc.CallOption) (*empty.Empty, error) {
+	out := new(empty.Empty)
+	err := c.cc.Invoke(ctx, "/core_service.CoreService/ChildrenStateUpdate", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *coreServiceClient) UpdateImageDownload(ctx context.Context, in *voltha.ImageDownload, opts ...grpc.CallOption) (*empty.Empty, error) {
+	out := new(empty.Empty)
+	err := c.cc.Invoke(ctx, "/core_service.CoreService/UpdateImageDownload", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+// CoreServiceServer is the server API for CoreService service.
+type CoreServiceServer interface {
+	// GetHealthStatus is used by a CoreService client to verify connectivity
+	// to the gRPC server hosting the CoreService service
+	GetHealthStatus(CoreService_GetHealthStatusServer) error
+	RegisterAdapter(context.Context, *core_adapter.AdapterRegistration) (*empty.Empty, error)
+	DeviceUpdate(context.Context, *voltha.Device) (*empty.Empty, error)
+	PortCreated(context.Context, *voltha.Port) (*empty.Empty, error)
+	PortsStateUpdate(context.Context, *core_adapter.PortStateFilter) (*empty.Empty, error)
+	DeleteAllPorts(context.Context, *common.ID) (*empty.Empty, error)
+	GetDevicePort(context.Context, *core_adapter.PortFilter) (*voltha.Port, error)
+	ListDevicePorts(context.Context, *common.ID) (*voltha.Ports, error)
+	DeviceStateUpdate(context.Context, *core_adapter.DeviceStateFilter) (*empty.Empty, error)
+	DevicePMConfigUpdate(context.Context, *voltha.PmConfigs) (*empty.Empty, error)
+	ChildDeviceDetected(context.Context, *core_adapter.DeviceDiscovery) (*voltha.Device, error)
+	ChildDevicesLost(context.Context, *common.ID) (*empty.Empty, error)
+	ChildDevicesDetected(context.Context, *common.ID) (*empty.Empty, error)
+	GetDevice(context.Context, *common.ID) (*voltha.Device, error)
+	GetChildDevice(context.Context, *core_adapter.ChildDeviceFilter) (*voltha.Device, error)
+	GetChildDevices(context.Context, *common.ID) (*voltha.Devices, error)
+	SendPacketIn(context.Context, *core_adapter.PacketIn) (*empty.Empty, error)
+	DeviceReasonUpdate(context.Context, *core_adapter.DeviceReason) (*empty.Empty, error)
+	PortStateUpdate(context.Context, *core_adapter.PortState) (*empty.Empty, error)
+	// Additional API found in the Core - unused?
+	ReconcileChildDevices(context.Context, *common.ID) (*empty.Empty, error)
+	GetChildDeviceWithProxyAddress(context.Context, *voltha.Device_ProxyAddress) (*voltha.Device, error)
+	GetPorts(context.Context, *core_adapter.PortFilter) (*voltha.Ports, error)
+	ChildrenStateUpdate(context.Context, *core_adapter.DeviceStateFilter) (*empty.Empty, error)
+	UpdateImageDownload(context.Context, *voltha.ImageDownload) (*empty.Empty, error)
+}
+
+// UnimplementedCoreServiceServer can be embedded to have forward compatible implementations.
+type UnimplementedCoreServiceServer struct {
+}
+
+func (*UnimplementedCoreServiceServer) GetHealthStatus(srv CoreService_GetHealthStatusServer) error {
+	return status.Errorf(codes.Unimplemented, "method GetHealthStatus not implemented")
+}
+func (*UnimplementedCoreServiceServer) RegisterAdapter(ctx context.Context, req *core_adapter.AdapterRegistration) (*empty.Empty, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method RegisterAdapter not implemented")
+}
+func (*UnimplementedCoreServiceServer) DeviceUpdate(ctx context.Context, req *voltha.Device) (*empty.Empty, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method DeviceUpdate not implemented")
+}
+func (*UnimplementedCoreServiceServer) PortCreated(ctx context.Context, req *voltha.Port) (*empty.Empty, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method PortCreated not implemented")
+}
+func (*UnimplementedCoreServiceServer) PortsStateUpdate(ctx context.Context, req *core_adapter.PortStateFilter) (*empty.Empty, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method PortsStateUpdate not implemented")
+}
+func (*UnimplementedCoreServiceServer) DeleteAllPorts(ctx context.Context, req *common.ID) (*empty.Empty, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method DeleteAllPorts not implemented")
+}
+func (*UnimplementedCoreServiceServer) GetDevicePort(ctx context.Context, req *core_adapter.PortFilter) (*voltha.Port, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method GetDevicePort not implemented")
+}
+func (*UnimplementedCoreServiceServer) ListDevicePorts(ctx context.Context, req *common.ID) (*voltha.Ports, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method ListDevicePorts not implemented")
+}
+func (*UnimplementedCoreServiceServer) DeviceStateUpdate(ctx context.Context, req *core_adapter.DeviceStateFilter) (*empty.Empty, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method DeviceStateUpdate not implemented")
+}
+func (*UnimplementedCoreServiceServer) DevicePMConfigUpdate(ctx context.Context, req *voltha.PmConfigs) (*empty.Empty, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method DevicePMConfigUpdate not implemented")
+}
+func (*UnimplementedCoreServiceServer) ChildDeviceDetected(ctx context.Context, req *core_adapter.DeviceDiscovery) (*voltha.Device, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method ChildDeviceDetected not implemented")
+}
+func (*UnimplementedCoreServiceServer) ChildDevicesLost(ctx context.Context, req *common.ID) (*empty.Empty, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method ChildDevicesLost not implemented")
+}
+func (*UnimplementedCoreServiceServer) ChildDevicesDetected(ctx context.Context, req *common.ID) (*empty.Empty, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method ChildDevicesDetected not implemented")
+}
+func (*UnimplementedCoreServiceServer) GetDevice(ctx context.Context, req *common.ID) (*voltha.Device, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method GetDevice not implemented")
+}
+func (*UnimplementedCoreServiceServer) GetChildDevice(ctx context.Context, req *core_adapter.ChildDeviceFilter) (*voltha.Device, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method GetChildDevice not implemented")
+}
+func (*UnimplementedCoreServiceServer) GetChildDevices(ctx context.Context, req *common.ID) (*voltha.Devices, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method GetChildDevices not implemented")
+}
+func (*UnimplementedCoreServiceServer) SendPacketIn(ctx context.Context, req *core_adapter.PacketIn) (*empty.Empty, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method SendPacketIn not implemented")
+}
+func (*UnimplementedCoreServiceServer) DeviceReasonUpdate(ctx context.Context, req *core_adapter.DeviceReason) (*empty.Empty, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method DeviceReasonUpdate not implemented")
+}
+func (*UnimplementedCoreServiceServer) PortStateUpdate(ctx context.Context, req *core_adapter.PortState) (*empty.Empty, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method PortStateUpdate not implemented")
+}
+func (*UnimplementedCoreServiceServer) ReconcileChildDevices(ctx context.Context, req *common.ID) (*empty.Empty, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method ReconcileChildDevices not implemented")
+}
+func (*UnimplementedCoreServiceServer) GetChildDeviceWithProxyAddress(ctx context.Context, req *voltha.Device_ProxyAddress) (*voltha.Device, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method GetChildDeviceWithProxyAddress not implemented")
+}
+func (*UnimplementedCoreServiceServer) GetPorts(ctx context.Context, req *core_adapter.PortFilter) (*voltha.Ports, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method GetPorts not implemented")
+}
+func (*UnimplementedCoreServiceServer) ChildrenStateUpdate(ctx context.Context, req *core_adapter.DeviceStateFilter) (*empty.Empty, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method ChildrenStateUpdate not implemented")
+}
+func (*UnimplementedCoreServiceServer) UpdateImageDownload(ctx context.Context, req *voltha.ImageDownload) (*empty.Empty, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method UpdateImageDownload not implemented")
+}
+
+func RegisterCoreServiceServer(s *grpc.Server, srv CoreServiceServer) {
+	s.RegisterService(&_CoreService_serviceDesc, srv)
+}
+
+func _CoreService_GetHealthStatus_Handler(srv interface{}, stream grpc.ServerStream) error {
+	return srv.(CoreServiceServer).GetHealthStatus(&coreServiceGetHealthStatusServer{stream})
+}
+
+type CoreService_GetHealthStatusServer interface {
+	Send(*health.HealthStatus) error
+	Recv() (*common.Connection, error)
+	grpc.ServerStream
+}
+
+type coreServiceGetHealthStatusServer struct {
+	grpc.ServerStream
+}
+
+func (x *coreServiceGetHealthStatusServer) Send(m *health.HealthStatus) error {
+	return x.ServerStream.SendMsg(m)
+}
+
+func (x *coreServiceGetHealthStatusServer) Recv() (*common.Connection, error) {
+	m := new(common.Connection)
+	if err := x.ServerStream.RecvMsg(m); err != nil {
+		return nil, err
+	}
+	return m, nil
+}
+
+func _CoreService_RegisterAdapter_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(core_adapter.AdapterRegistration)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(CoreServiceServer).RegisterAdapter(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/core_service.CoreService/RegisterAdapter",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(CoreServiceServer).RegisterAdapter(ctx, req.(*core_adapter.AdapterRegistration))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _CoreService_DeviceUpdate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(voltha.Device)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(CoreServiceServer).DeviceUpdate(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/core_service.CoreService/DeviceUpdate",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(CoreServiceServer).DeviceUpdate(ctx, req.(*voltha.Device))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _CoreService_PortCreated_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(voltha.Port)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(CoreServiceServer).PortCreated(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/core_service.CoreService/PortCreated",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(CoreServiceServer).PortCreated(ctx, req.(*voltha.Port))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _CoreService_PortsStateUpdate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(core_adapter.PortStateFilter)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(CoreServiceServer).PortsStateUpdate(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/core_service.CoreService/PortsStateUpdate",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(CoreServiceServer).PortsStateUpdate(ctx, req.(*core_adapter.PortStateFilter))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _CoreService_DeleteAllPorts_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(common.ID)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(CoreServiceServer).DeleteAllPorts(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/core_service.CoreService/DeleteAllPorts",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(CoreServiceServer).DeleteAllPorts(ctx, req.(*common.ID))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _CoreService_GetDevicePort_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(core_adapter.PortFilter)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(CoreServiceServer).GetDevicePort(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/core_service.CoreService/GetDevicePort",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(CoreServiceServer).GetDevicePort(ctx, req.(*core_adapter.PortFilter))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _CoreService_ListDevicePorts_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(common.ID)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(CoreServiceServer).ListDevicePorts(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/core_service.CoreService/ListDevicePorts",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(CoreServiceServer).ListDevicePorts(ctx, req.(*common.ID))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _CoreService_DeviceStateUpdate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(core_adapter.DeviceStateFilter)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(CoreServiceServer).DeviceStateUpdate(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/core_service.CoreService/DeviceStateUpdate",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(CoreServiceServer).DeviceStateUpdate(ctx, req.(*core_adapter.DeviceStateFilter))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _CoreService_DevicePMConfigUpdate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(voltha.PmConfigs)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(CoreServiceServer).DevicePMConfigUpdate(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/core_service.CoreService/DevicePMConfigUpdate",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(CoreServiceServer).DevicePMConfigUpdate(ctx, req.(*voltha.PmConfigs))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _CoreService_ChildDeviceDetected_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(core_adapter.DeviceDiscovery)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(CoreServiceServer).ChildDeviceDetected(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/core_service.CoreService/ChildDeviceDetected",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(CoreServiceServer).ChildDeviceDetected(ctx, req.(*core_adapter.DeviceDiscovery))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _CoreService_ChildDevicesLost_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(common.ID)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(CoreServiceServer).ChildDevicesLost(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/core_service.CoreService/ChildDevicesLost",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(CoreServiceServer).ChildDevicesLost(ctx, req.(*common.ID))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _CoreService_ChildDevicesDetected_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(common.ID)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(CoreServiceServer).ChildDevicesDetected(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/core_service.CoreService/ChildDevicesDetected",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(CoreServiceServer).ChildDevicesDetected(ctx, req.(*common.ID))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _CoreService_GetDevice_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(common.ID)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(CoreServiceServer).GetDevice(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/core_service.CoreService/GetDevice",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(CoreServiceServer).GetDevice(ctx, req.(*common.ID))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _CoreService_GetChildDevice_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(core_adapter.ChildDeviceFilter)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(CoreServiceServer).GetChildDevice(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/core_service.CoreService/GetChildDevice",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(CoreServiceServer).GetChildDevice(ctx, req.(*core_adapter.ChildDeviceFilter))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _CoreService_GetChildDevices_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(common.ID)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(CoreServiceServer).GetChildDevices(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/core_service.CoreService/GetChildDevices",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(CoreServiceServer).GetChildDevices(ctx, req.(*common.ID))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _CoreService_SendPacketIn_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(core_adapter.PacketIn)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(CoreServiceServer).SendPacketIn(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/core_service.CoreService/SendPacketIn",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(CoreServiceServer).SendPacketIn(ctx, req.(*core_adapter.PacketIn))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _CoreService_DeviceReasonUpdate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(core_adapter.DeviceReason)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(CoreServiceServer).DeviceReasonUpdate(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/core_service.CoreService/DeviceReasonUpdate",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(CoreServiceServer).DeviceReasonUpdate(ctx, req.(*core_adapter.DeviceReason))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _CoreService_PortStateUpdate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(core_adapter.PortState)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(CoreServiceServer).PortStateUpdate(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/core_service.CoreService/PortStateUpdate",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(CoreServiceServer).PortStateUpdate(ctx, req.(*core_adapter.PortState))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _CoreService_ReconcileChildDevices_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(common.ID)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(CoreServiceServer).ReconcileChildDevices(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/core_service.CoreService/ReconcileChildDevices",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(CoreServiceServer).ReconcileChildDevices(ctx, req.(*common.ID))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _CoreService_GetChildDeviceWithProxyAddress_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(voltha.Device_ProxyAddress)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(CoreServiceServer).GetChildDeviceWithProxyAddress(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/core_service.CoreService/GetChildDeviceWithProxyAddress",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(CoreServiceServer).GetChildDeviceWithProxyAddress(ctx, req.(*voltha.Device_ProxyAddress))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _CoreService_GetPorts_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(core_adapter.PortFilter)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(CoreServiceServer).GetPorts(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/core_service.CoreService/GetPorts",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(CoreServiceServer).GetPorts(ctx, req.(*core_adapter.PortFilter))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _CoreService_ChildrenStateUpdate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(core_adapter.DeviceStateFilter)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(CoreServiceServer).ChildrenStateUpdate(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/core_service.CoreService/ChildrenStateUpdate",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(CoreServiceServer).ChildrenStateUpdate(ctx, req.(*core_adapter.DeviceStateFilter))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _CoreService_UpdateImageDownload_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(voltha.ImageDownload)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(CoreServiceServer).UpdateImageDownload(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/core_service.CoreService/UpdateImageDownload",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(CoreServiceServer).UpdateImageDownload(ctx, req.(*voltha.ImageDownload))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+var _CoreService_serviceDesc = grpc.ServiceDesc{
+	ServiceName: "core_service.CoreService",
+	HandlerType: (*CoreServiceServer)(nil),
+	Methods: []grpc.MethodDesc{
+		{
+			MethodName: "RegisterAdapter",
+			Handler:    _CoreService_RegisterAdapter_Handler,
+		},
+		{
+			MethodName: "DeviceUpdate",
+			Handler:    _CoreService_DeviceUpdate_Handler,
+		},
+		{
+			MethodName: "PortCreated",
+			Handler:    _CoreService_PortCreated_Handler,
+		},
+		{
+			MethodName: "PortsStateUpdate",
+			Handler:    _CoreService_PortsStateUpdate_Handler,
+		},
+		{
+			MethodName: "DeleteAllPorts",
+			Handler:    _CoreService_DeleteAllPorts_Handler,
+		},
+		{
+			MethodName: "GetDevicePort",
+			Handler:    _CoreService_GetDevicePort_Handler,
+		},
+		{
+			MethodName: "ListDevicePorts",
+			Handler:    _CoreService_ListDevicePorts_Handler,
+		},
+		{
+			MethodName: "DeviceStateUpdate",
+			Handler:    _CoreService_DeviceStateUpdate_Handler,
+		},
+		{
+			MethodName: "DevicePMConfigUpdate",
+			Handler:    _CoreService_DevicePMConfigUpdate_Handler,
+		},
+		{
+			MethodName: "ChildDeviceDetected",
+			Handler:    _CoreService_ChildDeviceDetected_Handler,
+		},
+		{
+			MethodName: "ChildDevicesLost",
+			Handler:    _CoreService_ChildDevicesLost_Handler,
+		},
+		{
+			MethodName: "ChildDevicesDetected",
+			Handler:    _CoreService_ChildDevicesDetected_Handler,
+		},
+		{
+			MethodName: "GetDevice",
+			Handler:    _CoreService_GetDevice_Handler,
+		},
+		{
+			MethodName: "GetChildDevice",
+			Handler:    _CoreService_GetChildDevice_Handler,
+		},
+		{
+			MethodName: "GetChildDevices",
+			Handler:    _CoreService_GetChildDevices_Handler,
+		},
+		{
+			MethodName: "SendPacketIn",
+			Handler:    _CoreService_SendPacketIn_Handler,
+		},
+		{
+			MethodName: "DeviceReasonUpdate",
+			Handler:    _CoreService_DeviceReasonUpdate_Handler,
+		},
+		{
+			MethodName: "PortStateUpdate",
+			Handler:    _CoreService_PortStateUpdate_Handler,
+		},
+		{
+			MethodName: "ReconcileChildDevices",
+			Handler:    _CoreService_ReconcileChildDevices_Handler,
+		},
+		{
+			MethodName: "GetChildDeviceWithProxyAddress",
+			Handler:    _CoreService_GetChildDeviceWithProxyAddress_Handler,
+		},
+		{
+			MethodName: "GetPorts",
+			Handler:    _CoreService_GetPorts_Handler,
+		},
+		{
+			MethodName: "ChildrenStateUpdate",
+			Handler:    _CoreService_ChildrenStateUpdate_Handler,
+		},
+		{
+			MethodName: "UpdateImageDownload",
+			Handler:    _CoreService_UpdateImageDownload_Handler,
+		},
+	},
+	Streams: []grpc.StreamDesc{
+		{
+			StreamName:    "GetHealthStatus",
+			Handler:       _CoreService_GetHealthStatus_Handler,
+			ServerStreams: true,
+			ClientStreams: true,
+		},
+	},
+	Metadata: "voltha_protos/core_services.proto",
+}
diff --git a/vendor/github.com/opencord/voltha-protos/v5/go/inter_adapter/inter_adapter.pb.go b/vendor/github.com/opencord/voltha-protos/v5/go/inter_adapter/inter_adapter.pb.go
new file mode 100644
index 0000000..fd76f67
--- /dev/null
+++ b/vendor/github.com/opencord/voltha-protos/v5/go/inter_adapter/inter_adapter.pb.go
@@ -0,0 +1,579 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// source: voltha_protos/inter_adapter.proto
+
+package inter_adapter
+
+import (
+	fmt "fmt"
+	proto "github.com/golang/protobuf/proto"
+	common "github.com/opencord/voltha-protos/v5/go/common"
+	openolt "github.com/opencord/voltha-protos/v5/go/openolt"
+	tech_profile "github.com/opencord/voltha-protos/v5/go/tech_profile"
+	voltha "github.com/opencord/voltha-protos/v5/go/voltha"
+	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
+
+type OmciMessage struct {
+	Message              []byte                      `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"`
+	ConnectStatus        common.ConnectStatus_Types  `protobuf:"varint,2,opt,name=connect_status,json=connectStatus,proto3,enum=common.ConnectStatus_Types" json:"connect_status,omitempty"`
+	ProxyAddress         *voltha.Device_ProxyAddress `protobuf:"bytes,3,opt,name=proxy_address,json=proxyAddress,proto3" json:"proxy_address,omitempty"`
+	ParentDeviceId       string                      `protobuf:"bytes,4,opt,name=parent_device_id,json=parentDeviceId,proto3" json:"parent_device_id,omitempty"`
+	ChildDeviceId        string                      `protobuf:"bytes,5,opt,name=child_device_id,json=childDeviceId,proto3" json:"child_device_id,omitempty"`
+	XXX_NoUnkeyedLiteral struct{}                    `json:"-"`
+	XXX_unrecognized     []byte                      `json:"-"`
+	XXX_sizecache        int32                       `json:"-"`
+}
+
+func (m *OmciMessage) Reset()         { *m = OmciMessage{} }
+func (m *OmciMessage) String() string { return proto.CompactTextString(m) }
+func (*OmciMessage) ProtoMessage()    {}
+func (*OmciMessage) Descriptor() ([]byte, []int) {
+	return fileDescriptor_a316e60f0a1fb837, []int{0}
+}
+
+func (m *OmciMessage) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_OmciMessage.Unmarshal(m, b)
+}
+func (m *OmciMessage) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_OmciMessage.Marshal(b, m, deterministic)
+}
+func (m *OmciMessage) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_OmciMessage.Merge(m, src)
+}
+func (m *OmciMessage) XXX_Size() int {
+	return xxx_messageInfo_OmciMessage.Size(m)
+}
+func (m *OmciMessage) XXX_DiscardUnknown() {
+	xxx_messageInfo_OmciMessage.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_OmciMessage proto.InternalMessageInfo
+
+func (m *OmciMessage) GetMessage() []byte {
+	if m != nil {
+		return m.Message
+	}
+	return nil
+}
+
+func (m *OmciMessage) GetConnectStatus() common.ConnectStatus_Types {
+	if m != nil {
+		return m.ConnectStatus
+	}
+	return common.ConnectStatus_UNKNOWN
+}
+
+func (m *OmciMessage) GetProxyAddress() *voltha.Device_ProxyAddress {
+	if m != nil {
+		return m.ProxyAddress
+	}
+	return nil
+}
+
+func (m *OmciMessage) GetParentDeviceId() string {
+	if m != nil {
+		return m.ParentDeviceId
+	}
+	return ""
+}
+
+func (m *OmciMessage) GetChildDeviceId() string {
+	if m != nil {
+		return m.ChildDeviceId
+	}
+	return ""
+}
+
+type OmciMessages struct {
+	Messages             [][]byte                    `protobuf:"bytes,1,rep,name=messages,proto3" json:"messages,omitempty"`
+	ConnectStatus        common.ConnectStatus_Types  `protobuf:"varint,2,opt,name=connect_status,json=connectStatus,proto3,enum=common.ConnectStatus_Types" json:"connect_status,omitempty"`
+	ProxyAddress         *voltha.Device_ProxyAddress `protobuf:"bytes,3,opt,name=proxy_address,json=proxyAddress,proto3" json:"proxy_address,omitempty"`
+	ParentDeviceId       string                      `protobuf:"bytes,4,opt,name=parent_device_id,json=parentDeviceId,proto3" json:"parent_device_id,omitempty"`
+	ChildDeviceId        string                      `protobuf:"bytes,5,opt,name=child_device_id,json=childDeviceId,proto3" json:"child_device_id,omitempty"`
+	XXX_NoUnkeyedLiteral struct{}                    `json:"-"`
+	XXX_unrecognized     []byte                      `json:"-"`
+	XXX_sizecache        int32                       `json:"-"`
+}
+
+func (m *OmciMessages) Reset()         { *m = OmciMessages{} }
+func (m *OmciMessages) String() string { return proto.CompactTextString(m) }
+func (*OmciMessages) ProtoMessage()    {}
+func (*OmciMessages) Descriptor() ([]byte, []int) {
+	return fileDescriptor_a316e60f0a1fb837, []int{1}
+}
+
+func (m *OmciMessages) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_OmciMessages.Unmarshal(m, b)
+}
+func (m *OmciMessages) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_OmciMessages.Marshal(b, m, deterministic)
+}
+func (m *OmciMessages) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_OmciMessages.Merge(m, src)
+}
+func (m *OmciMessages) XXX_Size() int {
+	return xxx_messageInfo_OmciMessages.Size(m)
+}
+func (m *OmciMessages) XXX_DiscardUnknown() {
+	xxx_messageInfo_OmciMessages.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_OmciMessages proto.InternalMessageInfo
+
+func (m *OmciMessages) GetMessages() [][]byte {
+	if m != nil {
+		return m.Messages
+	}
+	return nil
+}
+
+func (m *OmciMessages) GetConnectStatus() common.ConnectStatus_Types {
+	if m != nil {
+		return m.ConnectStatus
+	}
+	return common.ConnectStatus_UNKNOWN
+}
+
+func (m *OmciMessages) GetProxyAddress() *voltha.Device_ProxyAddress {
+	if m != nil {
+		return m.ProxyAddress
+	}
+	return nil
+}
+
+func (m *OmciMessages) GetParentDeviceId() string {
+	if m != nil {
+		return m.ParentDeviceId
+	}
+	return ""
+}
+
+func (m *OmciMessages) GetChildDeviceId() string {
+	if m != nil {
+		return m.ChildDeviceId
+	}
+	return ""
+}
+
+type TechProfileDownloadMessage struct {
+	DeviceId       string `protobuf:"bytes,1,opt,name=device_id,json=deviceId,proto3" json:"device_id,omitempty"`
+	UniId          uint32 `protobuf:"varint,2,opt,name=uni_id,json=uniId,proto3" json:"uni_id,omitempty"`
+	TpInstancePath string `protobuf:"bytes,3,opt,name=tp_instance_path,json=tpInstancePath,proto3" json:"tp_instance_path,omitempty"`
+	// Types that are valid to be assigned to TechTpInstance:
+	//	*TechProfileDownloadMessage_TpInstance
+	//	*TechProfileDownloadMessage_EponTpInstance
+	TechTpInstance       isTechProfileDownloadMessage_TechTpInstance `protobuf_oneof:"tech_tp_instance"`
+	XXX_NoUnkeyedLiteral struct{}                                    `json:"-"`
+	XXX_unrecognized     []byte                                      `json:"-"`
+	XXX_sizecache        int32                                       `json:"-"`
+}
+
+func (m *TechProfileDownloadMessage) Reset()         { *m = TechProfileDownloadMessage{} }
+func (m *TechProfileDownloadMessage) String() string { return proto.CompactTextString(m) }
+func (*TechProfileDownloadMessage) ProtoMessage()    {}
+func (*TechProfileDownloadMessage) Descriptor() ([]byte, []int) {
+	return fileDescriptor_a316e60f0a1fb837, []int{2}
+}
+
+func (m *TechProfileDownloadMessage) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_TechProfileDownloadMessage.Unmarshal(m, b)
+}
+func (m *TechProfileDownloadMessage) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_TechProfileDownloadMessage.Marshal(b, m, deterministic)
+}
+func (m *TechProfileDownloadMessage) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_TechProfileDownloadMessage.Merge(m, src)
+}
+func (m *TechProfileDownloadMessage) XXX_Size() int {
+	return xxx_messageInfo_TechProfileDownloadMessage.Size(m)
+}
+func (m *TechProfileDownloadMessage) XXX_DiscardUnknown() {
+	xxx_messageInfo_TechProfileDownloadMessage.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_TechProfileDownloadMessage proto.InternalMessageInfo
+
+func (m *TechProfileDownloadMessage) GetDeviceId() string {
+	if m != nil {
+		return m.DeviceId
+	}
+	return ""
+}
+
+func (m *TechProfileDownloadMessage) GetUniId() uint32 {
+	if m != nil {
+		return m.UniId
+	}
+	return 0
+}
+
+func (m *TechProfileDownloadMessage) GetTpInstancePath() string {
+	if m != nil {
+		return m.TpInstancePath
+	}
+	return ""
+}
+
+type isTechProfileDownloadMessage_TechTpInstance interface {
+	isTechProfileDownloadMessage_TechTpInstance()
+}
+
+type TechProfileDownloadMessage_TpInstance struct {
+	TpInstance *tech_profile.TechProfileInstance `protobuf:"bytes,4,opt,name=tp_instance,json=tpInstance,proto3,oneof"`
+}
+
+type TechProfileDownloadMessage_EponTpInstance struct {
+	EponTpInstance *tech_profile.EponTechProfileInstance `protobuf:"bytes,5,opt,name=epon_tp_instance,json=eponTpInstance,proto3,oneof"`
+}
+
+func (*TechProfileDownloadMessage_TpInstance) isTechProfileDownloadMessage_TechTpInstance() {}
+
+func (*TechProfileDownloadMessage_EponTpInstance) isTechProfileDownloadMessage_TechTpInstance() {}
+
+func (m *TechProfileDownloadMessage) GetTechTpInstance() isTechProfileDownloadMessage_TechTpInstance {
+	if m != nil {
+		return m.TechTpInstance
+	}
+	return nil
+}
+
+func (m *TechProfileDownloadMessage) GetTpInstance() *tech_profile.TechProfileInstance {
+	if x, ok := m.GetTechTpInstance().(*TechProfileDownloadMessage_TpInstance); ok {
+		return x.TpInstance
+	}
+	return nil
+}
+
+func (m *TechProfileDownloadMessage) GetEponTpInstance() *tech_profile.EponTechProfileInstance {
+	if x, ok := m.GetTechTpInstance().(*TechProfileDownloadMessage_EponTpInstance); ok {
+		return x.EponTpInstance
+	}
+	return nil
+}
+
+// XXX_OneofWrappers is for the internal use of the proto package.
+func (*TechProfileDownloadMessage) XXX_OneofWrappers() []interface{} {
+	return []interface{}{
+		(*TechProfileDownloadMessage_TpInstance)(nil),
+		(*TechProfileDownloadMessage_EponTpInstance)(nil),
+	}
+}
+
+type DeleteGemPortMessage struct {
+	DeviceId             string   `protobuf:"bytes,1,opt,name=device_id,json=deviceId,proto3" json:"device_id,omitempty"`
+	UniId                uint32   `protobuf:"varint,2,opt,name=uni_id,json=uniId,proto3" json:"uni_id,omitempty"`
+	TpInstancePath       string   `protobuf:"bytes,3,opt,name=tp_instance_path,json=tpInstancePath,proto3" json:"tp_instance_path,omitempty"`
+	GemPortId            uint32   `protobuf:"varint,4,opt,name=gem_port_id,json=gemPortId,proto3" json:"gem_port_id,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *DeleteGemPortMessage) Reset()         { *m = DeleteGemPortMessage{} }
+func (m *DeleteGemPortMessage) String() string { return proto.CompactTextString(m) }
+func (*DeleteGemPortMessage) ProtoMessage()    {}
+func (*DeleteGemPortMessage) Descriptor() ([]byte, []int) {
+	return fileDescriptor_a316e60f0a1fb837, []int{3}
+}
+
+func (m *DeleteGemPortMessage) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_DeleteGemPortMessage.Unmarshal(m, b)
+}
+func (m *DeleteGemPortMessage) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_DeleteGemPortMessage.Marshal(b, m, deterministic)
+}
+func (m *DeleteGemPortMessage) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_DeleteGemPortMessage.Merge(m, src)
+}
+func (m *DeleteGemPortMessage) XXX_Size() int {
+	return xxx_messageInfo_DeleteGemPortMessage.Size(m)
+}
+func (m *DeleteGemPortMessage) XXX_DiscardUnknown() {
+	xxx_messageInfo_DeleteGemPortMessage.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_DeleteGemPortMessage proto.InternalMessageInfo
+
+func (m *DeleteGemPortMessage) GetDeviceId() string {
+	if m != nil {
+		return m.DeviceId
+	}
+	return ""
+}
+
+func (m *DeleteGemPortMessage) GetUniId() uint32 {
+	if m != nil {
+		return m.UniId
+	}
+	return 0
+}
+
+func (m *DeleteGemPortMessage) GetTpInstancePath() string {
+	if m != nil {
+		return m.TpInstancePath
+	}
+	return ""
+}
+
+func (m *DeleteGemPortMessage) GetGemPortId() uint32 {
+	if m != nil {
+		return m.GemPortId
+	}
+	return 0
+}
+
+type DeleteTcontMessage struct {
+	DeviceId             string   `protobuf:"bytes,1,opt,name=device_id,json=deviceId,proto3" json:"device_id,omitempty"`
+	UniId                uint32   `protobuf:"varint,2,opt,name=uni_id,json=uniId,proto3" json:"uni_id,omitempty"`
+	TpInstancePath       string   `protobuf:"bytes,3,opt,name=tp_instance_path,json=tpInstancePath,proto3" json:"tp_instance_path,omitempty"`
+	AllocId              uint32   `protobuf:"varint,4,opt,name=alloc_id,json=allocId,proto3" json:"alloc_id,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *DeleteTcontMessage) Reset()         { *m = DeleteTcontMessage{} }
+func (m *DeleteTcontMessage) String() string { return proto.CompactTextString(m) }
+func (*DeleteTcontMessage) ProtoMessage()    {}
+func (*DeleteTcontMessage) Descriptor() ([]byte, []int) {
+	return fileDescriptor_a316e60f0a1fb837, []int{4}
+}
+
+func (m *DeleteTcontMessage) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_DeleteTcontMessage.Unmarshal(m, b)
+}
+func (m *DeleteTcontMessage) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_DeleteTcontMessage.Marshal(b, m, deterministic)
+}
+func (m *DeleteTcontMessage) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_DeleteTcontMessage.Merge(m, src)
+}
+func (m *DeleteTcontMessage) XXX_Size() int {
+	return xxx_messageInfo_DeleteTcontMessage.Size(m)
+}
+func (m *DeleteTcontMessage) XXX_DiscardUnknown() {
+	xxx_messageInfo_DeleteTcontMessage.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_DeleteTcontMessage proto.InternalMessageInfo
+
+func (m *DeleteTcontMessage) GetDeviceId() string {
+	if m != nil {
+		return m.DeviceId
+	}
+	return ""
+}
+
+func (m *DeleteTcontMessage) GetUniId() uint32 {
+	if m != nil {
+		return m.UniId
+	}
+	return 0
+}
+
+func (m *DeleteTcontMessage) GetTpInstancePath() string {
+	if m != nil {
+		return m.TpInstancePath
+	}
+	return ""
+}
+
+func (m *DeleteTcontMessage) GetAllocId() uint32 {
+	if m != nil {
+		return m.AllocId
+	}
+	return 0
+}
+
+type OnuIndicationMessage struct {
+	DeviceId             string                 `protobuf:"bytes,1,opt,name=device_id,json=deviceId,proto3" json:"device_id,omitempty"`
+	OnuIndication        *openolt.OnuIndication `protobuf:"bytes,2,opt,name=onu_indication,json=onuIndication,proto3" json:"onu_indication,omitempty"`
+	XXX_NoUnkeyedLiteral struct{}               `json:"-"`
+	XXX_unrecognized     []byte                 `json:"-"`
+	XXX_sizecache        int32                  `json:"-"`
+}
+
+func (m *OnuIndicationMessage) Reset()         { *m = OnuIndicationMessage{} }
+func (m *OnuIndicationMessage) String() string { return proto.CompactTextString(m) }
+func (*OnuIndicationMessage) ProtoMessage()    {}
+func (*OnuIndicationMessage) Descriptor() ([]byte, []int) {
+	return fileDescriptor_a316e60f0a1fb837, []int{5}
+}
+
+func (m *OnuIndicationMessage) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_OnuIndicationMessage.Unmarshal(m, b)
+}
+func (m *OnuIndicationMessage) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_OnuIndicationMessage.Marshal(b, m, deterministic)
+}
+func (m *OnuIndicationMessage) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_OnuIndicationMessage.Merge(m, src)
+}
+func (m *OnuIndicationMessage) XXX_Size() int {
+	return xxx_messageInfo_OnuIndicationMessage.Size(m)
+}
+func (m *OnuIndicationMessage) XXX_DiscardUnknown() {
+	xxx_messageInfo_OnuIndicationMessage.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_OnuIndicationMessage proto.InternalMessageInfo
+
+func (m *OnuIndicationMessage) GetDeviceId() string {
+	if m != nil {
+		return m.DeviceId
+	}
+	return ""
+}
+
+func (m *OnuIndicationMessage) GetOnuIndication() *openolt.OnuIndication {
+	if m != nil {
+		return m.OnuIndication
+	}
+	return nil
+}
+
+type TechProfileInstanceRequestMessage struct {
+	DeviceId             string   `protobuf:"bytes,1,opt,name=device_id,json=deviceId,proto3" json:"device_id,omitempty"`
+	TpInstancePath       string   `protobuf:"bytes,2,opt,name=tp_instance_path,json=tpInstancePath,proto3" json:"tp_instance_path,omitempty"`
+	ParentDeviceId       string   `protobuf:"bytes,3,opt,name=parent_device_id,json=parentDeviceId,proto3" json:"parent_device_id,omitempty"`
+	ParentPonPort        uint32   `protobuf:"varint,4,opt,name=parent_pon_port,json=parentPonPort,proto3" json:"parent_pon_port,omitempty"`
+	OnuId                uint32   `protobuf:"varint,5,opt,name=onu_id,json=onuId,proto3" json:"onu_id,omitempty"`
+	UniId                uint32   `protobuf:"varint,6,opt,name=uni_id,json=uniId,proto3" json:"uni_id,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *TechProfileInstanceRequestMessage) Reset()         { *m = TechProfileInstanceRequestMessage{} }
+func (m *TechProfileInstanceRequestMessage) String() string { return proto.CompactTextString(m) }
+func (*TechProfileInstanceRequestMessage) ProtoMessage()    {}
+func (*TechProfileInstanceRequestMessage) Descriptor() ([]byte, []int) {
+	return fileDescriptor_a316e60f0a1fb837, []int{6}
+}
+
+func (m *TechProfileInstanceRequestMessage) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_TechProfileInstanceRequestMessage.Unmarshal(m, b)
+}
+func (m *TechProfileInstanceRequestMessage) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_TechProfileInstanceRequestMessage.Marshal(b, m, deterministic)
+}
+func (m *TechProfileInstanceRequestMessage) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_TechProfileInstanceRequestMessage.Merge(m, src)
+}
+func (m *TechProfileInstanceRequestMessage) XXX_Size() int {
+	return xxx_messageInfo_TechProfileInstanceRequestMessage.Size(m)
+}
+func (m *TechProfileInstanceRequestMessage) XXX_DiscardUnknown() {
+	xxx_messageInfo_TechProfileInstanceRequestMessage.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_TechProfileInstanceRequestMessage proto.InternalMessageInfo
+
+func (m *TechProfileInstanceRequestMessage) GetDeviceId() string {
+	if m != nil {
+		return m.DeviceId
+	}
+	return ""
+}
+
+func (m *TechProfileInstanceRequestMessage) GetTpInstancePath() string {
+	if m != nil {
+		return m.TpInstancePath
+	}
+	return ""
+}
+
+func (m *TechProfileInstanceRequestMessage) GetParentDeviceId() string {
+	if m != nil {
+		return m.ParentDeviceId
+	}
+	return ""
+}
+
+func (m *TechProfileInstanceRequestMessage) GetParentPonPort() uint32 {
+	if m != nil {
+		return m.ParentPonPort
+	}
+	return 0
+}
+
+func (m *TechProfileInstanceRequestMessage) GetOnuId() uint32 {
+	if m != nil {
+		return m.OnuId
+	}
+	return 0
+}
+
+func (m *TechProfileInstanceRequestMessage) GetUniId() uint32 {
+	if m != nil {
+		return m.UniId
+	}
+	return 0
+}
+
+func init() {
+	proto.RegisterType((*OmciMessage)(nil), "inter_adapter.OmciMessage")
+	proto.RegisterType((*OmciMessages)(nil), "inter_adapter.OmciMessages")
+	proto.RegisterType((*TechProfileDownloadMessage)(nil), "inter_adapter.TechProfileDownloadMessage")
+	proto.RegisterType((*DeleteGemPortMessage)(nil), "inter_adapter.DeleteGemPortMessage")
+	proto.RegisterType((*DeleteTcontMessage)(nil), "inter_adapter.DeleteTcontMessage")
+	proto.RegisterType((*OnuIndicationMessage)(nil), "inter_adapter.OnuIndicationMessage")
+	proto.RegisterType((*TechProfileInstanceRequestMessage)(nil), "inter_adapter.TechProfileInstanceRequestMessage")
+}
+
+func init() { proto.RegisterFile("voltha_protos/inter_adapter.proto", fileDescriptor_a316e60f0a1fb837) }
+
+var fileDescriptor_a316e60f0a1fb837 = []byte{
+	// 632 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x55, 0xc1, 0x6e, 0xd3, 0x4c,
+	0x10, 0xfe, 0x9d, 0xfe, 0x69, 0x9b, 0x49, 0x1c, 0x2a, 0xab, 0xa0, 0x90, 0x48, 0x28, 0x89, 0x04,
+	0xca, 0x05, 0x57, 0x0a, 0xea, 0x11, 0x09, 0x4a, 0x10, 0xe4, 0x80, 0x1a, 0x4c, 0x4e, 0xbd, 0x58,
+	0xdb, 0xdd, 0x25, 0x5e, 0xc9, 0xd9, 0x59, 0xec, 0x75, 0xa1, 0x57, 0xee, 0xdc, 0x78, 0x07, 0xde,
+	0x8d, 0x97, 0x00, 0x79, 0xd7, 0x6e, 0x6c, 0x64, 0xa4, 0x9e, 0x7a, 0xe0, 0x14, 0xcf, 0xcc, 0x37,
+	0x5f, 0xbe, 0x99, 0xd9, 0xdd, 0x81, 0xc9, 0x15, 0xc6, 0x3a, 0x22, 0xa1, 0x4a, 0x50, 0x63, 0x7a,
+	0x22, 0xa4, 0xe6, 0x49, 0x48, 0x18, 0x51, 0x9a, 0x27, 0xbe, 0x71, 0x7a, 0x6e, 0xcd, 0x39, 0x1c,
+	0xd6, 0x33, 0x28, 0x6e, 0xb7, 0x28, 0x2d, 0xf4, 0xcf, 0x98, 0xb5, 0x8a, 0xd8, 0xb8, 0x1e, 0xd3,
+	0x9c, 0x46, 0xf9, 0xf7, 0x47, 0x11, 0xf3, 0x02, 0x31, 0xaa, 0x23, 0x50, 0x71, 0x89, 0xb1, 0x6e,
+	0xa6, 0x66, 0xfc, 0x4a, 0xd0, 0x22, 0x71, 0xfa, 0xcb, 0x81, 0xee, 0xf9, 0x96, 0x8a, 0x77, 0x3c,
+	0x4d, 0xc9, 0x86, 0x7b, 0x03, 0x38, 0xd8, 0xda, 0xcf, 0x81, 0x33, 0x76, 0x66, 0xbd, 0xa0, 0x34,
+	0xbd, 0x33, 0xe8, 0x53, 0x94, 0x92, 0x53, 0x1d, 0xa6, 0x9a, 0xe8, 0x2c, 0x1d, 0xb4, 0xc6, 0xce,
+	0xac, 0x3f, 0x1f, 0xf9, 0x45, 0x1d, 0xaf, 0x6c, 0xf4, 0x83, 0x09, 0xfa, 0xeb, 0x6b, 0xc5, 0xd3,
+	0xc0, 0xa5, 0x55, 0xa7, 0xf7, 0x02, 0x5c, 0x95, 0xe0, 0x97, 0xeb, 0x90, 0x30, 0x96, 0xf0, 0x34,
+	0x1d, 0xec, 0x8d, 0x9d, 0x59, 0x77, 0x3e, 0xf2, 0x0b, 0x4d, 0x0b, 0xfb, 0xb3, 0xca, 0x31, 0x2f,
+	0x2d, 0x24, 0xe8, 0xa9, 0x8a, 0xe5, 0xcd, 0xe0, 0x48, 0x91, 0x84, 0x4b, 0x1d, 0xda, 0x94, 0x50,
+	0xb0, 0xc1, 0xff, 0x63, 0x67, 0xd6, 0x09, 0xfa, 0xd6, 0x6f, 0x29, 0x96, 0xcc, 0x7b, 0x02, 0xf7,
+	0x68, 0x24, 0x62, 0x56, 0x01, 0xb6, 0x0d, 0xd0, 0x35, 0xee, 0x12, 0x37, 0xfd, 0xda, 0x82, 0x5e,
+	0xa5, 0x03, 0xa9, 0x37, 0x84, 0xc3, 0xa2, 0xe6, 0x74, 0xe0, 0x8c, 0xf7, 0x66, 0xbd, 0xe0, 0xc6,
+	0xfe, 0x67, 0x9b, 0xf0, 0xa3, 0x05, 0xc3, 0x35, 0xa7, 0xd1, 0xca, 0x9e, 0xaa, 0x05, 0x7e, 0x96,
+	0x31, 0x12, 0x56, 0x9e, 0x8a, 0x11, 0x74, 0x76, 0x04, 0x8e, 0x21, 0x38, 0x64, 0xe5, 0x7f, 0xdc,
+	0x87, 0xfd, 0x4c, 0x8a, 0x3c, 0x92, 0xf7, 0xc2, 0x0d, 0xda, 0x99, 0x14, 0x4b, 0x96, 0x8b, 0xd4,
+	0x2a, 0x14, 0x32, 0xd5, 0x44, 0x52, 0x1e, 0x2a, 0xa2, 0x23, 0x53, 0x69, 0x27, 0xe8, 0x6b, 0xb5,
+	0x2c, 0xdc, 0x2b, 0xa2, 0x23, 0x6f, 0x01, 0xdd, 0x0a, 0xd2, 0x54, 0xd2, 0x9d, 0x4f, 0xfc, 0xda,
+	0x31, 0xaf, 0x88, 0x2b, 0x73, 0xdf, 0xfe, 0x17, 0xc0, 0x8e, 0xc9, 0x7b, 0x0f, 0x47, 0x5c, 0xa1,
+	0x0c, 0xab, 0x54, 0x6d, 0x43, 0xf5, 0xb8, 0x4e, 0xf5, 0x5a, 0xa1, 0x6c, 0xa6, 0xeb, 0xe7, 0x04,
+	0xeb, 0x1b, 0xca, 0x33, 0x0f, 0x8e, 0x4c, 0x66, 0x85, 0x72, 0xfa, 0xdd, 0x81, 0xe3, 0x05, 0x8f,
+	0xb9, 0xe6, 0x6f, 0xf8, 0x76, 0x85, 0x89, 0xbe, 0x9b, 0x1e, 0x3d, 0x82, 0xee, 0x86, 0x6f, 0x43,
+	0x85, 0x89, 0x2e, 0xa7, 0xed, 0x06, 0x9d, 0x8d, 0x95, 0xb0, 0x64, 0xd3, 0x6f, 0x0e, 0x78, 0x56,
+	0xd6, 0x9a, 0xa2, 0xbc, 0x23, 0x51, 0x0f, 0xe1, 0x90, 0xc4, 0x31, 0xd2, 0x9d, 0xa2, 0x03, 0x63,
+	0x2f, 0xd9, 0x34, 0x81, 0xe3, 0x73, 0x99, 0x2d, 0x25, 0x13, 0x94, 0x68, 0x81, 0xf2, 0x56, 0x82,
+	0x9e, 0x43, 0x1f, 0x65, 0x16, 0x8a, 0x9b, 0x2c, 0x23, 0xac, 0x3b, 0x7f, 0xe0, 0x97, 0x0f, 0x5a,
+	0x8d, 0x33, 0x70, 0xb1, 0x6a, 0x4e, 0x7f, 0x3a, 0x30, 0x69, 0x18, 0x6c, 0xc0, 0x3f, 0x65, 0x3c,
+	0xbd, 0x5d, 0x4b, 0x9a, 0x6a, 0x6f, 0x35, 0xd6, 0xde, 0x74, 0x07, 0xf7, 0xfe, 0x76, 0x07, 0x0b,
+	0x64, 0x7e, 0x3c, 0xf3, 0x09, 0x16, 0xcd, 0x72, 0xad, 0x7b, 0x85, 0x32, 0x1f, 0x62, 0x3e, 0x0e,
+	0x53, 0xbd, 0xbd, 0xa2, 0x6e, 0xd0, 0xce, 0xab, 0xab, 0x4e, 0x69, 0xbf, 0x32, 0xa5, 0xb3, 0x0b,
+	0x98, 0x60, 0xb2, 0x31, 0x8d, 0xa1, 0x98, 0x30, 0xbf, 0x58, 0x18, 0xb5, 0x85, 0x73, 0x71, 0xba,
+	0x11, 0x3a, 0xca, 0x2e, 0xf3, 0xc7, 0xe9, 0xa4, 0x44, 0x16, 0xab, 0xe5, 0x69, 0xb9, 0x68, 0x4e,
+	0x4f, 0x36, 0x58, 0x5f, 0x5e, 0x97, 0xfb, 0x26, 0xf6, 0xec, 0x77, 0x00, 0x00, 0x00, 0xff, 0xff,
+	0xeb, 0x5f, 0xd8, 0xf3, 0xe2, 0x06, 0x00, 0x00,
+}
diff --git a/vendor/github.com/opencord/voltha-protos/v5/go/olt_inter_adapter_service/olt_inter_adapter_service.pb.go b/vendor/github.com/opencord/voltha-protos/v5/go/olt_inter_adapter_service/olt_inter_adapter_service.pb.go
new file mode 100644
index 0000000..1e5c21c
--- /dev/null
+++ b/vendor/github.com/opencord/voltha-protos/v5/go/olt_inter_adapter_service/olt_inter_adapter_service.pb.go
@@ -0,0 +1,284 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// source: voltha_protos/olt_inter_adapter_service.proto
+
+package olt_inter_adapter_service
+
+import (
+	context "context"
+	fmt "fmt"
+	proto "github.com/golang/protobuf/proto"
+	empty "github.com/golang/protobuf/ptypes/empty"
+	common "github.com/opencord/voltha-protos/v5/go/common"
+	health "github.com/opencord/voltha-protos/v5/go/health"
+	inter_adapter "github.com/opencord/voltha-protos/v5/go/inter_adapter"
+	grpc "google.golang.org/grpc"
+	codes "google.golang.org/grpc/codes"
+	status "google.golang.org/grpc/status"
+	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
+
+func init() {
+	proto.RegisterFile("voltha_protos/olt_inter_adapter_service.proto", fileDescriptor_3ddb40a5aae0f6e1)
+}
+
+var fileDescriptor_3ddb40a5aae0f6e1 = []byte{
+	// 337 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x92, 0xcf, 0x4e, 0xe3, 0x30,
+	0x10, 0x87, 0xd5, 0x3d, 0xec, 0xc1, 0x97, 0xdd, 0xb5, 0x56, 0x95, 0x48, 0xb9, 0x70, 0x83, 0x43,
+	0x9d, 0x0a, 0xc4, 0x19, 0xb5, 0xfc, 0x69, 0x7b, 0x40, 0xad, 0x28, 0xe2, 0xc0, 0xa5, 0x72, 0xdd,
+	0x69, 0x12, 0xc9, 0xf1, 0x04, 0x7b, 0x52, 0xe8, 0x5b, 0xf0, 0x8c, 0x3c, 0x09, 0x4a, 0xec, 0x4a,
+	0xa4, 0x6a, 0x4e, 0x51, 0x34, 0xdf, 0xef, 0xf3, 0x8c, 0x66, 0x58, 0x7f, 0x8b, 0x9a, 0x52, 0xb9,
+	0x2c, 0x2c, 0x12, 0xba, 0x18, 0x35, 0x2d, 0x33, 0x43, 0x60, 0x97, 0x72, 0x2d, 0x8b, 0xea, 0xeb,
+	0xc0, 0x6e, 0x33, 0x05, 0xa2, 0x06, 0xf8, 0x49, 0x2b, 0x10, 0x45, 0x4d, 0x93, 0xc2, 0x3c, 0x47,
+	0xe3, 0x63, 0x51, 0x2f, 0x41, 0x4c, 0x34, 0xc4, 0xf5, 0xdf, 0xaa, 0xdc, 0xc4, 0x90, 0x17, 0xb4,
+	0x0b, 0xc5, 0xb3, 0x66, 0xb0, 0x61, 0x0f, 0xc8, 0x81, 0x3b, 0x05, 0xa9, 0x29, 0xf5, 0xb5, 0xcb,
+	0xaf, 0x5f, 0xac, 0x3b, 0xd3, 0x34, 0xad, 0x62, 0x43, 0x9f, 0x5a, 0xf8, 0x96, 0xf8, 0x0d, 0xfb,
+	0x33, 0x06, 0x9a, 0xd4, 0xf4, 0x82, 0x24, 0x95, 0x8e, 0x73, 0x11, 0x1a, 0xbb, 0x45, 0x63, 0x40,
+	0x51, 0x86, 0x26, 0xfa, 0x2f, 0x82, 0xf0, 0x27, 0x79, 0xde, 0x19, 0x74, 0xf8, 0x03, 0xfb, 0x3b,
+	0xb7, 0xf8, 0xb1, 0x9b, 0xe5, 0x2a, 0x7b, 0x82, 0xb7, 0x12, 0x1c, 0xf1, 0x48, 0x34, 0x3b, 0xac,
+	0x6a, 0x8f, 0xe0, 0x9c, 0x4c, 0x20, 0xea, 0x0a, 0x3f, 0xa8, 0xd8, 0x0f, 0x2a, 0xee, 0xab, 0x41,
+	0xf9, 0x84, 0xfd, 0x3b, 0xf4, 0x38, 0xde, 0x6b, 0x17, 0xb9, 0x56, 0x53, 0xc9, 0xba, 0x63, 0xa0,
+	0x67, 0x50, 0xe9, 0xdc, 0xe2, 0x26, 0xd3, 0x30, 0x35, 0x8e, 0xa4, 0x51, 0xc0, 0x07, 0x07, 0xba,
+	0x23, 0x4c, 0x78, 0x7a, 0xdf, 0xed, 0x45, 0x7b, 0xe2, 0x0e, 0xdf, 0x8d, 0x46, 0xb9, 0x0e, 0xe8,
+	0xe8, 0xb3, 0xc3, 0xfa, 0x68, 0x13, 0x81, 0x05, 0x18, 0x85, 0x76, 0x2d, 0xfc, 0x42, 0x44, 0xeb,
+	0x39, 0x8c, 0x4e, 0x5f, 0x6a, 0xe2, 0xf8, 0x66, 0x5e, 0x87, 0x49, 0x46, 0x69, 0xb9, 0xaa, 0x96,
+	0x11, 0xef, 0x9d, 0xb1, 0x77, 0xf6, 0xc3, 0x92, 0xb7, 0xd7, 0x71, 0x82, 0xed, 0x07, 0xb9, 0xfa,
+	0x5d, 0x73, 0x57, 0xdf, 0x01, 0x00, 0x00, 0xff, 0xff, 0xd0, 0x9f, 0xd5, 0x8e, 0xc2, 0x02, 0x00,
+	0x00,
+}
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ context.Context
+var _ grpc.ClientConn
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the grpc package it is being compiled against.
+const _ = grpc.SupportPackageIsVersion4
+
+// OltInterAdapterServiceClient is the client API for OltInterAdapterService service.
+//
+// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
+type OltInterAdapterServiceClient interface {
+	// GetHealthStatus is used by a OltInterAdapterService client to detect a connection
+	// lost with the gRPC server hosting the OltInterAdapterService service
+	GetHealthStatus(ctx context.Context, opts ...grpc.CallOption) (OltInterAdapterService_GetHealthStatusClient, error)
+	ProxyOmciRequest(ctx context.Context, in *inter_adapter.OmciMessage, opts ...grpc.CallOption) (*empty.Empty, error)
+	ProxyOmciRequests(ctx context.Context, in *inter_adapter.OmciMessages, opts ...grpc.CallOption) (*empty.Empty, error)
+	GetTechProfileInstance(ctx context.Context, in *inter_adapter.TechProfileInstanceRequestMessage, opts ...grpc.CallOption) (*inter_adapter.TechProfileDownloadMessage, error)
+}
+
+type oltInterAdapterServiceClient struct {
+	cc *grpc.ClientConn
+}
+
+func NewOltInterAdapterServiceClient(cc *grpc.ClientConn) OltInterAdapterServiceClient {
+	return &oltInterAdapterServiceClient{cc}
+}
+
+func (c *oltInterAdapterServiceClient) GetHealthStatus(ctx context.Context, opts ...grpc.CallOption) (OltInterAdapterService_GetHealthStatusClient, error) {
+	stream, err := c.cc.NewStream(ctx, &_OltInterAdapterService_serviceDesc.Streams[0], "/olt_inter_adapter_service.OltInterAdapterService/GetHealthStatus", opts...)
+	if err != nil {
+		return nil, err
+	}
+	x := &oltInterAdapterServiceGetHealthStatusClient{stream}
+	return x, nil
+}
+
+type OltInterAdapterService_GetHealthStatusClient interface {
+	Send(*common.Connection) error
+	Recv() (*health.HealthStatus, error)
+	grpc.ClientStream
+}
+
+type oltInterAdapterServiceGetHealthStatusClient struct {
+	grpc.ClientStream
+}
+
+func (x *oltInterAdapterServiceGetHealthStatusClient) Send(m *common.Connection) error {
+	return x.ClientStream.SendMsg(m)
+}
+
+func (x *oltInterAdapterServiceGetHealthStatusClient) Recv() (*health.HealthStatus, error) {
+	m := new(health.HealthStatus)
+	if err := x.ClientStream.RecvMsg(m); err != nil {
+		return nil, err
+	}
+	return m, nil
+}
+
+func (c *oltInterAdapterServiceClient) ProxyOmciRequest(ctx context.Context, in *inter_adapter.OmciMessage, opts ...grpc.CallOption) (*empty.Empty, error) {
+	out := new(empty.Empty)
+	err := c.cc.Invoke(ctx, "/olt_inter_adapter_service.OltInterAdapterService/ProxyOmciRequest", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *oltInterAdapterServiceClient) ProxyOmciRequests(ctx context.Context, in *inter_adapter.OmciMessages, opts ...grpc.CallOption) (*empty.Empty, error) {
+	out := new(empty.Empty)
+	err := c.cc.Invoke(ctx, "/olt_inter_adapter_service.OltInterAdapterService/ProxyOmciRequests", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *oltInterAdapterServiceClient) GetTechProfileInstance(ctx context.Context, in *inter_adapter.TechProfileInstanceRequestMessage, opts ...grpc.CallOption) (*inter_adapter.TechProfileDownloadMessage, error) {
+	out := new(inter_adapter.TechProfileDownloadMessage)
+	err := c.cc.Invoke(ctx, "/olt_inter_adapter_service.OltInterAdapterService/GetTechProfileInstance", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+// OltInterAdapterServiceServer is the server API for OltInterAdapterService service.
+type OltInterAdapterServiceServer interface {
+	// GetHealthStatus is used by a OltInterAdapterService client to detect a connection
+	// lost with the gRPC server hosting the OltInterAdapterService service
+	GetHealthStatus(OltInterAdapterService_GetHealthStatusServer) error
+	ProxyOmciRequest(context.Context, *inter_adapter.OmciMessage) (*empty.Empty, error)
+	ProxyOmciRequests(context.Context, *inter_adapter.OmciMessages) (*empty.Empty, error)
+	GetTechProfileInstance(context.Context, *inter_adapter.TechProfileInstanceRequestMessage) (*inter_adapter.TechProfileDownloadMessage, error)
+}
+
+// UnimplementedOltInterAdapterServiceServer can be embedded to have forward compatible implementations.
+type UnimplementedOltInterAdapterServiceServer struct {
+}
+
+func (*UnimplementedOltInterAdapterServiceServer) GetHealthStatus(srv OltInterAdapterService_GetHealthStatusServer) error {
+	return status.Errorf(codes.Unimplemented, "method GetHealthStatus not implemented")
+}
+func (*UnimplementedOltInterAdapterServiceServer) ProxyOmciRequest(ctx context.Context, req *inter_adapter.OmciMessage) (*empty.Empty, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method ProxyOmciRequest not implemented")
+}
+func (*UnimplementedOltInterAdapterServiceServer) ProxyOmciRequests(ctx context.Context, req *inter_adapter.OmciMessages) (*empty.Empty, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method ProxyOmciRequests not implemented")
+}
+func (*UnimplementedOltInterAdapterServiceServer) GetTechProfileInstance(ctx context.Context, req *inter_adapter.TechProfileInstanceRequestMessage) (*inter_adapter.TechProfileDownloadMessage, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method GetTechProfileInstance not implemented")
+}
+
+func RegisterOltInterAdapterServiceServer(s *grpc.Server, srv OltInterAdapterServiceServer) {
+	s.RegisterService(&_OltInterAdapterService_serviceDesc, srv)
+}
+
+func _OltInterAdapterService_GetHealthStatus_Handler(srv interface{}, stream grpc.ServerStream) error {
+	return srv.(OltInterAdapterServiceServer).GetHealthStatus(&oltInterAdapterServiceGetHealthStatusServer{stream})
+}
+
+type OltInterAdapterService_GetHealthStatusServer interface {
+	Send(*health.HealthStatus) error
+	Recv() (*common.Connection, error)
+	grpc.ServerStream
+}
+
+type oltInterAdapterServiceGetHealthStatusServer struct {
+	grpc.ServerStream
+}
+
+func (x *oltInterAdapterServiceGetHealthStatusServer) Send(m *health.HealthStatus) error {
+	return x.ServerStream.SendMsg(m)
+}
+
+func (x *oltInterAdapterServiceGetHealthStatusServer) Recv() (*common.Connection, error) {
+	m := new(common.Connection)
+	if err := x.ServerStream.RecvMsg(m); err != nil {
+		return nil, err
+	}
+	return m, nil
+}
+
+func _OltInterAdapterService_ProxyOmciRequest_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(inter_adapter.OmciMessage)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(OltInterAdapterServiceServer).ProxyOmciRequest(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/olt_inter_adapter_service.OltInterAdapterService/ProxyOmciRequest",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(OltInterAdapterServiceServer).ProxyOmciRequest(ctx, req.(*inter_adapter.OmciMessage))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _OltInterAdapterService_ProxyOmciRequests_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(inter_adapter.OmciMessages)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(OltInterAdapterServiceServer).ProxyOmciRequests(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/olt_inter_adapter_service.OltInterAdapterService/ProxyOmciRequests",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(OltInterAdapterServiceServer).ProxyOmciRequests(ctx, req.(*inter_adapter.OmciMessages))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _OltInterAdapterService_GetTechProfileInstance_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(inter_adapter.TechProfileInstanceRequestMessage)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(OltInterAdapterServiceServer).GetTechProfileInstance(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/olt_inter_adapter_service.OltInterAdapterService/GetTechProfileInstance",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(OltInterAdapterServiceServer).GetTechProfileInstance(ctx, req.(*inter_adapter.TechProfileInstanceRequestMessage))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+var _OltInterAdapterService_serviceDesc = grpc.ServiceDesc{
+	ServiceName: "olt_inter_adapter_service.OltInterAdapterService",
+	HandlerType: (*OltInterAdapterServiceServer)(nil),
+	Methods: []grpc.MethodDesc{
+		{
+			MethodName: "ProxyOmciRequest",
+			Handler:    _OltInterAdapterService_ProxyOmciRequest_Handler,
+		},
+		{
+			MethodName: "ProxyOmciRequests",
+			Handler:    _OltInterAdapterService_ProxyOmciRequests_Handler,
+		},
+		{
+			MethodName: "GetTechProfileInstance",
+			Handler:    _OltInterAdapterService_GetTechProfileInstance_Handler,
+		},
+	},
+	Streams: []grpc.StreamDesc{
+		{
+			StreamName:    "GetHealthStatus",
+			Handler:       _OltInterAdapterService_GetHealthStatus_Handler,
+			ServerStreams: true,
+			ClientStreams: true,
+		},
+	},
+	Metadata: "voltha_protos/olt_inter_adapter_service.proto",
+}
diff --git a/vendor/github.com/opencord/voltha-protos/v5/go/onu_inter_adapter_service/onu_inter_adapter_service.pb.go b/vendor/github.com/opencord/voltha-protos/v5/go/onu_inter_adapter_service/onu_inter_adapter_service.pb.go
new file mode 100644
index 0000000..9094c10
--- /dev/null
+++ b/vendor/github.com/opencord/voltha-protos/v5/go/onu_inter_adapter_service/onu_inter_adapter_service.pb.go
@@ -0,0 +1,357 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// source: voltha_protos/onu_inter_adapter_service.proto
+
+package onu_inter_adapter_service
+
+import (
+	context "context"
+	fmt "fmt"
+	proto "github.com/golang/protobuf/proto"
+	empty "github.com/golang/protobuf/ptypes/empty"
+	common "github.com/opencord/voltha-protos/v5/go/common"
+	health "github.com/opencord/voltha-protos/v5/go/health"
+	inter_adapter "github.com/opencord/voltha-protos/v5/go/inter_adapter"
+	grpc "google.golang.org/grpc"
+	codes "google.golang.org/grpc/codes"
+	status "google.golang.org/grpc/status"
+	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
+
+func init() {
+	proto.RegisterFile("voltha_protos/onu_inter_adapter_service.proto", fileDescriptor_f951f30caeee9ccd)
+}
+
+var fileDescriptor_f951f30caeee9ccd = []byte{
+	// 354 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x93, 0xcf, 0x4a, 0xc3, 0x40,
+	0x10, 0xc6, 0x29, 0x82, 0x87, 0x95, 0x2a, 0xac, 0x52, 0x30, 0x7a, 0x29, 0x5e, 0xf4, 0xd0, 0x8d,
+	0x28, 0x9e, 0xa5, 0x7f, 0xa4, 0x15, 0x2a, 0x2d, 0xb4, 0x88, 0x78, 0x29, 0xdb, 0xcd, 0x34, 0x59,
+	0x48, 0x76, 0x42, 0x32, 0xa9, 0xf8, 0x16, 0xbe, 0xa1, 0xaf, 0x22, 0xc9, 0xa6, 0xd0, 0xd4, 0x96,
+	0x9c, 0x42, 0xf8, 0x7e, 0xf3, 0x63, 0x06, 0xbe, 0x65, 0x9d, 0x35, 0x86, 0x14, 0xc8, 0x45, 0x9c,
+	0x20, 0x61, 0xea, 0xa2, 0xc9, 0x16, 0xda, 0x10, 0x24, 0x0b, 0xe9, 0xc9, 0x38, 0xff, 0xa6, 0x90,
+	0xac, 0xb5, 0x02, 0x51, 0x00, 0xfc, 0xf2, 0x20, 0xe0, 0x38, 0x55, 0x93, 0xc2, 0x28, 0x42, 0x63,
+	0xc7, 0x9c, 0x2b, 0x1f, 0xd1, 0x0f, 0xc1, 0x2d, 0xfe, 0x96, 0xd9, 0xca, 0x85, 0x28, 0xa6, 0xef,
+	0x32, 0x6c, 0x57, 0x07, 0x2b, 0xf6, 0x12, 0xd9, 0x71, 0x07, 0x20, 0x43, 0x0a, 0x6c, 0xf6, 0xf0,
+	0x7b, 0xc4, 0x5a, 0x13, 0x93, 0xbd, 0xe6, 0x63, 0x5d, 0x3b, 0x35, 0xb3, 0x2b, 0xf1, 0x67, 0x76,
+	0x36, 0x04, 0x1a, 0x15, 0xf4, 0x8c, 0x24, 0x65, 0x29, 0xe7, 0xa2, 0x5c, 0xac, 0x8f, 0xc6, 0x80,
+	0x22, 0x8d, 0xc6, 0xb9, 0x10, 0xa5, 0x70, 0x9b, 0xbc, 0x6d, 0xdc, 0x37, 0xf8, 0x98, 0x35, 0x0b,
+	0xb5, 0xa7, 0x95, 0xcc, 0x51, 0x7e, 0x23, 0xaa, 0xeb, 0x55, 0xd2, 0x37, 0x48, 0x53, 0xe9, 0x83,
+	0xd3, 0x12, 0xf6, 0x5c, 0xb1, 0x39, 0x57, 0xbc, 0xe4, 0xe7, 0xf2, 0x01, 0x3b, 0x9d, 0x44, 0x4a,
+	0x6f, 0xe9, 0x9c, 0x5d, 0x5d, 0xa4, 0x74, 0x9d, 0xe5, 0x83, 0x9d, 0x0f, 0xf0, 0xcb, 0x84, 0x28,
+	0xbd, 0x39, 0xa8, 0x60, 0x9a, 0xe0, 0x4a, 0x87, 0xc0, 0xef, 0x76, 0x54, 0x5b, 0xd9, 0x06, 0xaf,
+	0x33, 0x8f, 0x59, 0x73, 0x00, 0x21, 0x10, 0x0c, 0x21, 0x9a, 0x62, 0x42, 0xff, 0xae, 0xad, 0xa4,
+	0x75, 0xb6, 0x11, 0x3b, 0xb1, 0xfc, 0xbc, 0x8f, 0x86, 0x78, 0x7b, 0xaf, 0x6b, 0xae, 0xd0, 0xd4,
+	0x99, 0x7a, 0x3f, 0x0d, 0xd6, 0xc1, 0xc4, 0x17, 0x18, 0x83, 0x51, 0x98, 0x78, 0xc2, 0xb6, 0x41,
+	0x1c, 0xec, 0x62, 0xef, 0xfa, 0xbd, 0x20, 0xf6, 0xd7, 0xe2, 0xb3, 0xeb, 0x6b, 0x0a, 0xb2, 0x65,
+	0xde, 0x04, 0x77, 0xe3, 0x74, 0xad, 0xb3, 0x53, 0x36, 0x6c, 0xfd, 0xe4, 0xfa, 0x78, 0xf8, 0x35,
+	0x2c, 0x8f, 0x0b, 0xee, 0xf1, 0x2f, 0x00, 0x00, 0xff, 0xff, 0xc4, 0x5f, 0x8c, 0x88, 0x3f, 0x03,
+	0x00, 0x00,
+}
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ context.Context
+var _ grpc.ClientConn
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the grpc package it is being compiled against.
+const _ = grpc.SupportPackageIsVersion4
+
+// OnuInterAdapterServiceClient is the client API for OnuInterAdapterService service.
+//
+// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
+type OnuInterAdapterServiceClient interface {
+	// GetHealthStatus is used by a OnuInterAdapterService client to detect a connection
+	// lost with the gRPC server hosting the OnuInterAdapterService service
+	GetHealthStatus(ctx context.Context, opts ...grpc.CallOption) (OnuInterAdapterService_GetHealthStatusClient, error)
+	OnuIndication(ctx context.Context, in *inter_adapter.OnuIndicationMessage, opts ...grpc.CallOption) (*empty.Empty, error)
+	OmciIndication(ctx context.Context, in *inter_adapter.OmciMessage, opts ...grpc.CallOption) (*empty.Empty, error)
+	DownloadTechProfile(ctx context.Context, in *inter_adapter.TechProfileDownloadMessage, opts ...grpc.CallOption) (*empty.Empty, error)
+	DeleteGemPort(ctx context.Context, in *inter_adapter.DeleteGemPortMessage, opts ...grpc.CallOption) (*empty.Empty, error)
+	DeleteTCont(ctx context.Context, in *inter_adapter.DeleteTcontMessage, opts ...grpc.CallOption) (*empty.Empty, error)
+}
+
+type onuInterAdapterServiceClient struct {
+	cc *grpc.ClientConn
+}
+
+func NewOnuInterAdapterServiceClient(cc *grpc.ClientConn) OnuInterAdapterServiceClient {
+	return &onuInterAdapterServiceClient{cc}
+}
+
+func (c *onuInterAdapterServiceClient) GetHealthStatus(ctx context.Context, opts ...grpc.CallOption) (OnuInterAdapterService_GetHealthStatusClient, error) {
+	stream, err := c.cc.NewStream(ctx, &_OnuInterAdapterService_serviceDesc.Streams[0], "/onu_inter_adapter_service.OnuInterAdapterService/GetHealthStatus", opts...)
+	if err != nil {
+		return nil, err
+	}
+	x := &onuInterAdapterServiceGetHealthStatusClient{stream}
+	return x, nil
+}
+
+type OnuInterAdapterService_GetHealthStatusClient interface {
+	Send(*common.Connection) error
+	Recv() (*health.HealthStatus, error)
+	grpc.ClientStream
+}
+
+type onuInterAdapterServiceGetHealthStatusClient struct {
+	grpc.ClientStream
+}
+
+func (x *onuInterAdapterServiceGetHealthStatusClient) Send(m *common.Connection) error {
+	return x.ClientStream.SendMsg(m)
+}
+
+func (x *onuInterAdapterServiceGetHealthStatusClient) Recv() (*health.HealthStatus, error) {
+	m := new(health.HealthStatus)
+	if err := x.ClientStream.RecvMsg(m); err != nil {
+		return nil, err
+	}
+	return m, nil
+}
+
+func (c *onuInterAdapterServiceClient) OnuIndication(ctx context.Context, in *inter_adapter.OnuIndicationMessage, opts ...grpc.CallOption) (*empty.Empty, error) {
+	out := new(empty.Empty)
+	err := c.cc.Invoke(ctx, "/onu_inter_adapter_service.OnuInterAdapterService/OnuIndication", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *onuInterAdapterServiceClient) OmciIndication(ctx context.Context, in *inter_adapter.OmciMessage, opts ...grpc.CallOption) (*empty.Empty, error) {
+	out := new(empty.Empty)
+	err := c.cc.Invoke(ctx, "/onu_inter_adapter_service.OnuInterAdapterService/OmciIndication", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *onuInterAdapterServiceClient) DownloadTechProfile(ctx context.Context, in *inter_adapter.TechProfileDownloadMessage, opts ...grpc.CallOption) (*empty.Empty, error) {
+	out := new(empty.Empty)
+	err := c.cc.Invoke(ctx, "/onu_inter_adapter_service.OnuInterAdapterService/DownloadTechProfile", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *onuInterAdapterServiceClient) DeleteGemPort(ctx context.Context, in *inter_adapter.DeleteGemPortMessage, opts ...grpc.CallOption) (*empty.Empty, error) {
+	out := new(empty.Empty)
+	err := c.cc.Invoke(ctx, "/onu_inter_adapter_service.OnuInterAdapterService/DeleteGemPort", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *onuInterAdapterServiceClient) DeleteTCont(ctx context.Context, in *inter_adapter.DeleteTcontMessage, opts ...grpc.CallOption) (*empty.Empty, error) {
+	out := new(empty.Empty)
+	err := c.cc.Invoke(ctx, "/onu_inter_adapter_service.OnuInterAdapterService/DeleteTCont", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+// OnuInterAdapterServiceServer is the server API for OnuInterAdapterService service.
+type OnuInterAdapterServiceServer interface {
+	// GetHealthStatus is used by a OnuInterAdapterService client to detect a connection
+	// lost with the gRPC server hosting the OnuInterAdapterService service
+	GetHealthStatus(OnuInterAdapterService_GetHealthStatusServer) error
+	OnuIndication(context.Context, *inter_adapter.OnuIndicationMessage) (*empty.Empty, error)
+	OmciIndication(context.Context, *inter_adapter.OmciMessage) (*empty.Empty, error)
+	DownloadTechProfile(context.Context, *inter_adapter.TechProfileDownloadMessage) (*empty.Empty, error)
+	DeleteGemPort(context.Context, *inter_adapter.DeleteGemPortMessage) (*empty.Empty, error)
+	DeleteTCont(context.Context, *inter_adapter.DeleteTcontMessage) (*empty.Empty, error)
+}
+
+// UnimplementedOnuInterAdapterServiceServer can be embedded to have forward compatible implementations.
+type UnimplementedOnuInterAdapterServiceServer struct {
+}
+
+func (*UnimplementedOnuInterAdapterServiceServer) GetHealthStatus(srv OnuInterAdapterService_GetHealthStatusServer) error {
+	return status.Errorf(codes.Unimplemented, "method GetHealthStatus not implemented")
+}
+func (*UnimplementedOnuInterAdapterServiceServer) OnuIndication(ctx context.Context, req *inter_adapter.OnuIndicationMessage) (*empty.Empty, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method OnuIndication not implemented")
+}
+func (*UnimplementedOnuInterAdapterServiceServer) OmciIndication(ctx context.Context, req *inter_adapter.OmciMessage) (*empty.Empty, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method OmciIndication not implemented")
+}
+func (*UnimplementedOnuInterAdapterServiceServer) DownloadTechProfile(ctx context.Context, req *inter_adapter.TechProfileDownloadMessage) (*empty.Empty, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method DownloadTechProfile not implemented")
+}
+func (*UnimplementedOnuInterAdapterServiceServer) DeleteGemPort(ctx context.Context, req *inter_adapter.DeleteGemPortMessage) (*empty.Empty, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method DeleteGemPort not implemented")
+}
+func (*UnimplementedOnuInterAdapterServiceServer) DeleteTCont(ctx context.Context, req *inter_adapter.DeleteTcontMessage) (*empty.Empty, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method DeleteTCont not implemented")
+}
+
+func RegisterOnuInterAdapterServiceServer(s *grpc.Server, srv OnuInterAdapterServiceServer) {
+	s.RegisterService(&_OnuInterAdapterService_serviceDesc, srv)
+}
+
+func _OnuInterAdapterService_GetHealthStatus_Handler(srv interface{}, stream grpc.ServerStream) error {
+	return srv.(OnuInterAdapterServiceServer).GetHealthStatus(&onuInterAdapterServiceGetHealthStatusServer{stream})
+}
+
+type OnuInterAdapterService_GetHealthStatusServer interface {
+	Send(*health.HealthStatus) error
+	Recv() (*common.Connection, error)
+	grpc.ServerStream
+}
+
+type onuInterAdapterServiceGetHealthStatusServer struct {
+	grpc.ServerStream
+}
+
+func (x *onuInterAdapterServiceGetHealthStatusServer) Send(m *health.HealthStatus) error {
+	return x.ServerStream.SendMsg(m)
+}
+
+func (x *onuInterAdapterServiceGetHealthStatusServer) Recv() (*common.Connection, error) {
+	m := new(common.Connection)
+	if err := x.ServerStream.RecvMsg(m); err != nil {
+		return nil, err
+	}
+	return m, nil
+}
+
+func _OnuInterAdapterService_OnuIndication_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(inter_adapter.OnuIndicationMessage)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(OnuInterAdapterServiceServer).OnuIndication(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/onu_inter_adapter_service.OnuInterAdapterService/OnuIndication",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(OnuInterAdapterServiceServer).OnuIndication(ctx, req.(*inter_adapter.OnuIndicationMessage))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _OnuInterAdapterService_OmciIndication_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(inter_adapter.OmciMessage)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(OnuInterAdapterServiceServer).OmciIndication(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/onu_inter_adapter_service.OnuInterAdapterService/OmciIndication",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(OnuInterAdapterServiceServer).OmciIndication(ctx, req.(*inter_adapter.OmciMessage))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _OnuInterAdapterService_DownloadTechProfile_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(inter_adapter.TechProfileDownloadMessage)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(OnuInterAdapterServiceServer).DownloadTechProfile(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/onu_inter_adapter_service.OnuInterAdapterService/DownloadTechProfile",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(OnuInterAdapterServiceServer).DownloadTechProfile(ctx, req.(*inter_adapter.TechProfileDownloadMessage))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _OnuInterAdapterService_DeleteGemPort_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(inter_adapter.DeleteGemPortMessage)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(OnuInterAdapterServiceServer).DeleteGemPort(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/onu_inter_adapter_service.OnuInterAdapterService/DeleteGemPort",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(OnuInterAdapterServiceServer).DeleteGemPort(ctx, req.(*inter_adapter.DeleteGemPortMessage))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _OnuInterAdapterService_DeleteTCont_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(inter_adapter.DeleteTcontMessage)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(OnuInterAdapterServiceServer).DeleteTCont(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/onu_inter_adapter_service.OnuInterAdapterService/DeleteTCont",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(OnuInterAdapterServiceServer).DeleteTCont(ctx, req.(*inter_adapter.DeleteTcontMessage))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+var _OnuInterAdapterService_serviceDesc = grpc.ServiceDesc{
+	ServiceName: "onu_inter_adapter_service.OnuInterAdapterService",
+	HandlerType: (*OnuInterAdapterServiceServer)(nil),
+	Methods: []grpc.MethodDesc{
+		{
+			MethodName: "OnuIndication",
+			Handler:    _OnuInterAdapterService_OnuIndication_Handler,
+		},
+		{
+			MethodName: "OmciIndication",
+			Handler:    _OnuInterAdapterService_OmciIndication_Handler,
+		},
+		{
+			MethodName: "DownloadTechProfile",
+			Handler:    _OnuInterAdapterService_DownloadTechProfile_Handler,
+		},
+		{
+			MethodName: "DeleteGemPort",
+			Handler:    _OnuInterAdapterService_DeleteGemPort_Handler,
+		},
+		{
+			MethodName: "DeleteTCont",
+			Handler:    _OnuInterAdapterService_DeleteTCont_Handler,
+		},
+	},
+	Streams: []grpc.StreamDesc{
+		{
+			StreamName:    "GetHealthStatus",
+			Handler:       _OnuInterAdapterService_GetHealthStatus_Handler,
+			ServerStreams: true,
+			ClientStreams: true,
+		},
+	},
+	Metadata: "voltha_protos/onu_inter_adapter_service.proto",
+}
diff --git a/vendor/github.com/opencord/voltha-protos/v5/go/openolt/openolt.pb.go b/vendor/github.com/opencord/voltha-protos/v5/go/openolt/openolt.pb.go
new file mode 100644
index 0000000..6ea5a05
--- /dev/null
+++ b/vendor/github.com/opencord/voltha-protos/v5/go/openolt/openolt.pb.go
@@ -0,0 +1,6127 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// source: voltha_protos/openolt.proto
+
+package openolt
+
+import (
+	context "context"
+	fmt "fmt"
+	proto "github.com/golang/protobuf/proto"
+	config "github.com/opencord/voltha-protos/v5/go/ext/config"
+	extension "github.com/opencord/voltha-protos/v5/go/extension"
+	tech_profile "github.com/opencord/voltha-protos/v5/go/tech_profile"
+	_ "google.golang.org/genproto/googleapis/api/annotations"
+	grpc "google.golang.org/grpc"
+	codes "google.golang.org/grpc/codes"
+	status "google.golang.org/grpc/status"
+	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
+
+//* activation fail reason.
+type OnuIndication_ActivationFailReason int32
+
+const (
+	OnuIndication_ONU_ACTIVATION_FAIL_REASON_NONE                    OnuIndication_ActivationFailReason = 0
+	OnuIndication_ONU_ACTIVATION_FAIL_REASON_RANGING                 OnuIndication_ActivationFailReason = 1
+	OnuIndication_ONU_ACTIVATION_FAIL_REASON_PASSWORD_AUTHENTICATION OnuIndication_ActivationFailReason = 2
+	OnuIndication_ONU_ACTIVATION_FAIL_REASON_LOS                     OnuIndication_ActivationFailReason = 3
+	OnuIndication_ONU_ACTIVATION_FAIL_ONU_ALARM                      OnuIndication_ActivationFailReason = 4
+	OnuIndication_ONU_ACTIVATION_FAIL_SWITCH_OVER                    OnuIndication_ActivationFailReason = 5
+)
+
+var OnuIndication_ActivationFailReason_name = map[int32]string{
+	0: "ONU_ACTIVATION_FAIL_REASON_NONE",
+	1: "ONU_ACTIVATION_FAIL_REASON_RANGING",
+	2: "ONU_ACTIVATION_FAIL_REASON_PASSWORD_AUTHENTICATION",
+	3: "ONU_ACTIVATION_FAIL_REASON_LOS",
+	4: "ONU_ACTIVATION_FAIL_ONU_ALARM",
+	5: "ONU_ACTIVATION_FAIL_SWITCH_OVER",
+}
+
+var OnuIndication_ActivationFailReason_value = map[string]int32{
+	"ONU_ACTIVATION_FAIL_REASON_NONE":                    0,
+	"ONU_ACTIVATION_FAIL_REASON_RANGING":                 1,
+	"ONU_ACTIVATION_FAIL_REASON_PASSWORD_AUTHENTICATION": 2,
+	"ONU_ACTIVATION_FAIL_REASON_LOS":                     3,
+	"ONU_ACTIVATION_FAIL_ONU_ALARM":                      4,
+	"ONU_ACTIVATION_FAIL_SWITCH_OVER":                    5,
+}
+
+func (x OnuIndication_ActivationFailReason) String() string {
+	return proto.EnumName(OnuIndication_ActivationFailReason_name, int32(x))
+}
+
+func (OnuIndication_ActivationFailReason) EnumDescriptor() ([]byte, []int) {
+	return fileDescriptor_c072e7aa0dfd74d5, []int{5, 0}
+}
+
+type DeviceInfo_DeviceResourceRanges_Pool_PoolType int32
+
+const (
+	DeviceInfo_DeviceResourceRanges_Pool_ONU_ID     DeviceInfo_DeviceResourceRanges_Pool_PoolType = 0
+	DeviceInfo_DeviceResourceRanges_Pool_ALLOC_ID   DeviceInfo_DeviceResourceRanges_Pool_PoolType = 1
+	DeviceInfo_DeviceResourceRanges_Pool_GEMPORT_ID DeviceInfo_DeviceResourceRanges_Pool_PoolType = 2
+	DeviceInfo_DeviceResourceRanges_Pool_FLOW_ID    DeviceInfo_DeviceResourceRanges_Pool_PoolType = 3
+)
+
+var DeviceInfo_DeviceResourceRanges_Pool_PoolType_name = map[int32]string{
+	0: "ONU_ID",
+	1: "ALLOC_ID",
+	2: "GEMPORT_ID",
+	3: "FLOW_ID",
+}
+
+var DeviceInfo_DeviceResourceRanges_Pool_PoolType_value = map[string]int32{
+	"ONU_ID":     0,
+	"ALLOC_ID":   1,
+	"GEMPORT_ID": 2,
+	"FLOW_ID":    3,
+}
+
+func (x DeviceInfo_DeviceResourceRanges_Pool_PoolType) String() string {
+	return proto.EnumName(DeviceInfo_DeviceResourceRanges_Pool_PoolType_name, int32(x))
+}
+
+func (DeviceInfo_DeviceResourceRanges_Pool_PoolType) EnumDescriptor() ([]byte, []int) {
+	return fileDescriptor_c072e7aa0dfd74d5, []int{16, 0, 0, 0}
+}
+
+type DeviceInfo_DeviceResourceRanges_Pool_SharingType int32
+
+const (
+	DeviceInfo_DeviceResourceRanges_Pool_DEDICATED_PER_INTF           DeviceInfo_DeviceResourceRanges_Pool_SharingType = 0
+	DeviceInfo_DeviceResourceRanges_Pool_SHARED_BY_ALL_INTF_ALL_TECH  DeviceInfo_DeviceResourceRanges_Pool_SharingType = 1
+	DeviceInfo_DeviceResourceRanges_Pool_SHARED_BY_ALL_INTF_SAME_TECH DeviceInfo_DeviceResourceRanges_Pool_SharingType = 2
+)
+
+var DeviceInfo_DeviceResourceRanges_Pool_SharingType_name = map[int32]string{
+	0: "DEDICATED_PER_INTF",
+	1: "SHARED_BY_ALL_INTF_ALL_TECH",
+	2: "SHARED_BY_ALL_INTF_SAME_TECH",
+}
+
+var DeviceInfo_DeviceResourceRanges_Pool_SharingType_value = map[string]int32{
+	"DEDICATED_PER_INTF":           0,
+	"SHARED_BY_ALL_INTF_ALL_TECH":  1,
+	"SHARED_BY_ALL_INTF_SAME_TECH": 2,
+}
+
+func (x DeviceInfo_DeviceResourceRanges_Pool_SharingType) String() string {
+	return proto.EnumName(DeviceInfo_DeviceResourceRanges_Pool_SharingType_name, int32(x))
+}
+
+func (DeviceInfo_DeviceResourceRanges_Pool_SharingType) EnumDescriptor() ([]byte, []int) {
+	return fileDescriptor_c072e7aa0dfd74d5, []int{16, 0, 0, 1}
+}
+
+type GroupMember_InterfaceType int32
+
+const (
+	GroupMember_PON           GroupMember_InterfaceType = 0
+	GroupMember_EPON_1G_PATH  GroupMember_InterfaceType = 1
+	GroupMember_EPON_10G_PATH GroupMember_InterfaceType = 2
+)
+
+var GroupMember_InterfaceType_name = map[int32]string{
+	0: "PON",
+	1: "EPON_1G_PATH",
+	2: "EPON_10G_PATH",
+}
+
+var GroupMember_InterfaceType_value = map[string]int32{
+	"PON":           0,
+	"EPON_1G_PATH":  1,
+	"EPON_10G_PATH": 2,
+}
+
+func (x GroupMember_InterfaceType) String() string {
+	return proto.EnumName(GroupMember_InterfaceType_name, int32(x))
+}
+
+func (GroupMember_InterfaceType) EnumDescriptor() ([]byte, []int) {
+	return fileDescriptor_c072e7aa0dfd74d5, []int{46, 0}
+}
+
+type Group_GroupMembersCommand int32
+
+const (
+	Group_ADD_MEMBERS    Group_GroupMembersCommand = 0
+	Group_REMOVE_MEMBERS Group_GroupMembersCommand = 1
+	Group_SET_MEMBERS    Group_GroupMembersCommand = 2
+)
+
+var Group_GroupMembersCommand_name = map[int32]string{
+	0: "ADD_MEMBERS",
+	1: "REMOVE_MEMBERS",
+	2: "SET_MEMBERS",
+}
+
+var Group_GroupMembersCommand_value = map[string]int32{
+	"ADD_MEMBERS":    0,
+	"REMOVE_MEMBERS": 1,
+	"SET_MEMBERS":    2,
+}
+
+func (x Group_GroupMembersCommand) String() string {
+	return proto.EnumName(Group_GroupMembersCommand_name, int32(x))
+}
+
+func (Group_GroupMembersCommand) EnumDescriptor() ([]byte, []int) {
+	return fileDescriptor_c072e7aa0dfd74d5, []int{47, 0}
+}
+
+type PonRxPowerData_RssiMeasurementFailReason int32
+
+const (
+	PonRxPowerData_FAIL_REASON_NONE         PonRxPowerData_RssiMeasurementFailReason = 0
+	PonRxPowerData_FAIL_REASON_NO_DELIMITER PonRxPowerData_RssiMeasurementFailReason = 1
+	PonRxPowerData_FAIL_REASON_NO_ACCESS    PonRxPowerData_RssiMeasurementFailReason = 2
+)
+
+var PonRxPowerData_RssiMeasurementFailReason_name = map[int32]string{
+	0: "FAIL_REASON_NONE",
+	1: "FAIL_REASON_NO_DELIMITER",
+	2: "FAIL_REASON_NO_ACCESS",
+}
+
+var PonRxPowerData_RssiMeasurementFailReason_value = map[string]int32{
+	"FAIL_REASON_NONE":         0,
+	"FAIL_REASON_NO_DELIMITER": 1,
+	"FAIL_REASON_NO_ACCESS":    2,
+}
+
+func (x PonRxPowerData_RssiMeasurementFailReason) String() string {
+	return proto.EnumName(PonRxPowerData_RssiMeasurementFailReason_name, int32(x))
+}
+
+func (PonRxPowerData_RssiMeasurementFailReason) EnumDescriptor() ([]byte, []int) {
+	return fileDescriptor_c072e7aa0dfd74d5, []int{49, 0}
+}
+
+type Indication struct {
+	// Types that are valid to be assigned to Data:
+	//	*Indication_OltInd
+	//	*Indication_IntfInd
+	//	*Indication_IntfOperInd
+	//	*Indication_OnuDiscInd
+	//	*Indication_OnuInd
+	//	*Indication_OmciInd
+	//	*Indication_PktInd
+	//	*Indication_PortStats
+	//	*Indication_FlowStats
+	//	*Indication_AlarmInd
+	Data                 isIndication_Data `protobuf_oneof:"data"`
+	XXX_NoUnkeyedLiteral struct{}          `json:"-"`
+	XXX_unrecognized     []byte            `json:"-"`
+	XXX_sizecache        int32             `json:"-"`
+}
+
+func (m *Indication) Reset()         { *m = Indication{} }
+func (m *Indication) String() string { return proto.CompactTextString(m) }
+func (*Indication) ProtoMessage()    {}
+func (*Indication) Descriptor() ([]byte, []int) {
+	return fileDescriptor_c072e7aa0dfd74d5, []int{0}
+}
+
+func (m *Indication) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_Indication.Unmarshal(m, b)
+}
+func (m *Indication) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_Indication.Marshal(b, m, deterministic)
+}
+func (m *Indication) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_Indication.Merge(m, src)
+}
+func (m *Indication) XXX_Size() int {
+	return xxx_messageInfo_Indication.Size(m)
+}
+func (m *Indication) XXX_DiscardUnknown() {
+	xxx_messageInfo_Indication.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Indication proto.InternalMessageInfo
+
+type isIndication_Data interface {
+	isIndication_Data()
+}
+
+type Indication_OltInd struct {
+	OltInd *OltIndication `protobuf:"bytes,1,opt,name=olt_ind,json=oltInd,proto3,oneof"`
+}
+
+type Indication_IntfInd struct {
+	IntfInd *IntfIndication `protobuf:"bytes,2,opt,name=intf_ind,json=intfInd,proto3,oneof"`
+}
+
+type Indication_IntfOperInd struct {
+	IntfOperInd *IntfOperIndication `protobuf:"bytes,3,opt,name=intf_oper_ind,json=intfOperInd,proto3,oneof"`
+}
+
+type Indication_OnuDiscInd struct {
+	OnuDiscInd *OnuDiscIndication `protobuf:"bytes,4,opt,name=onu_disc_ind,json=onuDiscInd,proto3,oneof"`
+}
+
+type Indication_OnuInd struct {
+	OnuInd *OnuIndication `protobuf:"bytes,5,opt,name=onu_ind,json=onuInd,proto3,oneof"`
+}
+
+type Indication_OmciInd struct {
+	OmciInd *OmciIndication `protobuf:"bytes,6,opt,name=omci_ind,json=omciInd,proto3,oneof"`
+}
+
+type Indication_PktInd struct {
+	PktInd *PacketIndication `protobuf:"bytes,7,opt,name=pkt_ind,json=pktInd,proto3,oneof"`
+}
+
+type Indication_PortStats struct {
+	PortStats *PortStatistics `protobuf:"bytes,8,opt,name=port_stats,json=portStats,proto3,oneof"`
+}
+
+type Indication_FlowStats struct {
+	FlowStats *FlowStatistics `protobuf:"bytes,9,opt,name=flow_stats,json=flowStats,proto3,oneof"`
+}
+
+type Indication_AlarmInd struct {
+	AlarmInd *AlarmIndication `protobuf:"bytes,10,opt,name=alarm_ind,json=alarmInd,proto3,oneof"`
+}
+
+func (*Indication_OltInd) isIndication_Data() {}
+
+func (*Indication_IntfInd) isIndication_Data() {}
+
+func (*Indication_IntfOperInd) isIndication_Data() {}
+
+func (*Indication_OnuDiscInd) isIndication_Data() {}
+
+func (*Indication_OnuInd) isIndication_Data() {}
+
+func (*Indication_OmciInd) isIndication_Data() {}
+
+func (*Indication_PktInd) isIndication_Data() {}
+
+func (*Indication_PortStats) isIndication_Data() {}
+
+func (*Indication_FlowStats) isIndication_Data() {}
+
+func (*Indication_AlarmInd) isIndication_Data() {}
+
+func (m *Indication) GetData() isIndication_Data {
+	if m != nil {
+		return m.Data
+	}
+	return nil
+}
+
+func (m *Indication) GetOltInd() *OltIndication {
+	if x, ok := m.GetData().(*Indication_OltInd); ok {
+		return x.OltInd
+	}
+	return nil
+}
+
+func (m *Indication) GetIntfInd() *IntfIndication {
+	if x, ok := m.GetData().(*Indication_IntfInd); ok {
+		return x.IntfInd
+	}
+	return nil
+}
+
+func (m *Indication) GetIntfOperInd() *IntfOperIndication {
+	if x, ok := m.GetData().(*Indication_IntfOperInd); ok {
+		return x.IntfOperInd
+	}
+	return nil
+}
+
+func (m *Indication) GetOnuDiscInd() *OnuDiscIndication {
+	if x, ok := m.GetData().(*Indication_OnuDiscInd); ok {
+		return x.OnuDiscInd
+	}
+	return nil
+}
+
+func (m *Indication) GetOnuInd() *OnuIndication {
+	if x, ok := m.GetData().(*Indication_OnuInd); ok {
+		return x.OnuInd
+	}
+	return nil
+}
+
+func (m *Indication) GetOmciInd() *OmciIndication {
+	if x, ok := m.GetData().(*Indication_OmciInd); ok {
+		return x.OmciInd
+	}
+	return nil
+}
+
+func (m *Indication) GetPktInd() *PacketIndication {
+	if x, ok := m.GetData().(*Indication_PktInd); ok {
+		return x.PktInd
+	}
+	return nil
+}
+
+func (m *Indication) GetPortStats() *PortStatistics {
+	if x, ok := m.GetData().(*Indication_PortStats); ok {
+		return x.PortStats
+	}
+	return nil
+}
+
+func (m *Indication) GetFlowStats() *FlowStatistics {
+	if x, ok := m.GetData().(*Indication_FlowStats); ok {
+		return x.FlowStats
+	}
+	return nil
+}
+
+func (m *Indication) GetAlarmInd() *AlarmIndication {
+	if x, ok := m.GetData().(*Indication_AlarmInd); ok {
+		return x.AlarmInd
+	}
+	return nil
+}
+
+// XXX_OneofWrappers is for the internal use of the proto package.
+func (*Indication) XXX_OneofWrappers() []interface{} {
+	return []interface{}{
+		(*Indication_OltInd)(nil),
+		(*Indication_IntfInd)(nil),
+		(*Indication_IntfOperInd)(nil),
+		(*Indication_OnuDiscInd)(nil),
+		(*Indication_OnuInd)(nil),
+		(*Indication_OmciInd)(nil),
+		(*Indication_PktInd)(nil),
+		(*Indication_PortStats)(nil),
+		(*Indication_FlowStats)(nil),
+		(*Indication_AlarmInd)(nil),
+	}
+}
+
+type AlarmIndication struct {
+	// Types that are valid to be assigned to Data:
+	//	*AlarmIndication_LosInd
+	//	*AlarmIndication_DyingGaspInd
+	//	*AlarmIndication_OnuAlarmInd
+	//	*AlarmIndication_OnuStartupFailInd
+	//	*AlarmIndication_OnuSignalDegradeInd
+	//	*AlarmIndication_OnuDriftOfWindowInd
+	//	*AlarmIndication_OnuLossOmciInd
+	//	*AlarmIndication_OnuSignalsFailInd
+	//	*AlarmIndication_OnuTiwiInd
+	//	*AlarmIndication_OnuActivationFailInd
+	//	*AlarmIndication_OnuProcessingErrorInd
+	//	*AlarmIndication_OnuLossOfSyncFailInd
+	//	*AlarmIndication_OnuItuPonStatsInd
+	//	*AlarmIndication_OnuDeactivationFailureInd
+	//	*AlarmIndication_OnuRemoteDefectInd
+	//	*AlarmIndication_OnuLossGemDelineationInd
+	//	*AlarmIndication_OnuPhysicalEquipmentErrorInd
+	//	*AlarmIndication_OnuLossOfAckInd
+	//	*AlarmIndication_OnuDiffReachExceededInd
+	Data                 isAlarmIndication_Data `protobuf_oneof:"data"`
+	XXX_NoUnkeyedLiteral struct{}               `json:"-"`
+	XXX_unrecognized     []byte                 `json:"-"`
+	XXX_sizecache        int32                  `json:"-"`
+}
+
+func (m *AlarmIndication) Reset()         { *m = AlarmIndication{} }
+func (m *AlarmIndication) String() string { return proto.CompactTextString(m) }
+func (*AlarmIndication) ProtoMessage()    {}
+func (*AlarmIndication) Descriptor() ([]byte, []int) {
+	return fileDescriptor_c072e7aa0dfd74d5, []int{1}
+}
+
+func (m *AlarmIndication) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_AlarmIndication.Unmarshal(m, b)
+}
+func (m *AlarmIndication) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_AlarmIndication.Marshal(b, m, deterministic)
+}
+func (m *AlarmIndication) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_AlarmIndication.Merge(m, src)
+}
+func (m *AlarmIndication) XXX_Size() int {
+	return xxx_messageInfo_AlarmIndication.Size(m)
+}
+func (m *AlarmIndication) XXX_DiscardUnknown() {
+	xxx_messageInfo_AlarmIndication.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_AlarmIndication proto.InternalMessageInfo
+
+type isAlarmIndication_Data interface {
+	isAlarmIndication_Data()
+}
+
+type AlarmIndication_LosInd struct {
+	LosInd *LosIndication `protobuf:"bytes,1,opt,name=los_ind,json=losInd,proto3,oneof"`
+}
+
+type AlarmIndication_DyingGaspInd struct {
+	DyingGaspInd *DyingGaspIndication `protobuf:"bytes,2,opt,name=dying_gasp_ind,json=dyingGaspInd,proto3,oneof"`
+}
+
+type AlarmIndication_OnuAlarmInd struct {
+	OnuAlarmInd *OnuAlarmIndication `protobuf:"bytes,3,opt,name=onu_alarm_ind,json=onuAlarmInd,proto3,oneof"`
+}
+
+type AlarmIndication_OnuStartupFailInd struct {
+	OnuStartupFailInd *OnuStartupFailureIndication `protobuf:"bytes,4,opt,name=onu_startup_fail_ind,json=onuStartupFailInd,proto3,oneof"`
+}
+
+type AlarmIndication_OnuSignalDegradeInd struct {
+	OnuSignalDegradeInd *OnuSignalDegradeIndication `protobuf:"bytes,5,opt,name=onu_signal_degrade_ind,json=onuSignalDegradeInd,proto3,oneof"`
+}
+
+type AlarmIndication_OnuDriftOfWindowInd struct {
+	OnuDriftOfWindowInd *OnuDriftOfWindowIndication `protobuf:"bytes,6,opt,name=onu_drift_of_window_ind,json=onuDriftOfWindowInd,proto3,oneof"`
+}
+
+type AlarmIndication_OnuLossOmciInd struct {
+	OnuLossOmciInd *OnuLossOfOmciChannelIndication `protobuf:"bytes,7,opt,name=onu_loss_omci_ind,json=onuLossOmciInd,proto3,oneof"`
+}
+
+type AlarmIndication_OnuSignalsFailInd struct {
+	OnuSignalsFailInd *OnuSignalsFailureIndication `protobuf:"bytes,8,opt,name=onu_signals_fail_ind,json=onuSignalsFailInd,proto3,oneof"`
+}
+
+type AlarmIndication_OnuTiwiInd struct {
+	OnuTiwiInd *OnuTransmissionInterferenceWarning `protobuf:"bytes,9,opt,name=onu_tiwi_ind,json=onuTiwiInd,proto3,oneof"`
+}
+
+type AlarmIndication_OnuActivationFailInd struct {
+	OnuActivationFailInd *OnuActivationFailureIndication `protobuf:"bytes,10,opt,name=onu_activation_fail_ind,json=onuActivationFailInd,proto3,oneof"`
+}
+
+type AlarmIndication_OnuProcessingErrorInd struct {
+	OnuProcessingErrorInd *OnuProcessingErrorIndication `protobuf:"bytes,11,opt,name=onu_processing_error_ind,json=onuProcessingErrorInd,proto3,oneof"`
+}
+
+type AlarmIndication_OnuLossOfSyncFailInd struct {
+	OnuLossOfSyncFailInd *OnuLossOfKeySyncFailureIndication `protobuf:"bytes,12,opt,name=onu_loss_of_sync_fail_ind,json=onuLossOfSyncFailInd,proto3,oneof"`
+}
+
+type AlarmIndication_OnuItuPonStatsInd struct {
+	OnuItuPonStatsInd *OnuItuPonStatsIndication `protobuf:"bytes,13,opt,name=onu_itu_pon_stats_ind,json=onuItuPonStatsInd,proto3,oneof"`
+}
+
+type AlarmIndication_OnuDeactivationFailureInd struct {
+	OnuDeactivationFailureInd *OnuDeactivationFailureIndication `protobuf:"bytes,14,opt,name=onu_deactivation_failure_ind,json=onuDeactivationFailureInd,proto3,oneof"`
+}
+
+type AlarmIndication_OnuRemoteDefectInd struct {
+	OnuRemoteDefectInd *OnuRemoteDefectIndication `protobuf:"bytes,15,opt,name=onu_remote_defect_ind,json=onuRemoteDefectInd,proto3,oneof"`
+}
+
+type AlarmIndication_OnuLossGemDelineationInd struct {
+	OnuLossGemDelineationInd *OnuLossOfGEMChannelDelineationIndication `protobuf:"bytes,16,opt,name=onu_loss_gem_delineation_ind,json=onuLossGemDelineationInd,proto3,oneof"`
+}
+
+type AlarmIndication_OnuPhysicalEquipmentErrorInd struct {
+	OnuPhysicalEquipmentErrorInd *OnuPhysicalEquipmentErrorIndication `protobuf:"bytes,17,opt,name=onu_physical_equipment_error_ind,json=onuPhysicalEquipmentErrorInd,proto3,oneof"`
+}
+
+type AlarmIndication_OnuLossOfAckInd struct {
+	OnuLossOfAckInd *OnuLossOfAcknowledgementIndication `protobuf:"bytes,18,opt,name=onu_loss_of_ack_ind,json=onuLossOfAckInd,proto3,oneof"`
+}
+
+type AlarmIndication_OnuDiffReachExceededInd struct {
+	OnuDiffReachExceededInd *OnuDifferentialReachExceededIndication `protobuf:"bytes,19,opt,name=onu_diff_reach_exceeded_ind,json=onuDiffReachExceededInd,proto3,oneof"`
+}
+
+func (*AlarmIndication_LosInd) isAlarmIndication_Data() {}
+
+func (*AlarmIndication_DyingGaspInd) isAlarmIndication_Data() {}
+
+func (*AlarmIndication_OnuAlarmInd) isAlarmIndication_Data() {}
+
+func (*AlarmIndication_OnuStartupFailInd) isAlarmIndication_Data() {}
+
+func (*AlarmIndication_OnuSignalDegradeInd) isAlarmIndication_Data() {}
+
+func (*AlarmIndication_OnuDriftOfWindowInd) isAlarmIndication_Data() {}
+
+func (*AlarmIndication_OnuLossOmciInd) isAlarmIndication_Data() {}
+
+func (*AlarmIndication_OnuSignalsFailInd) isAlarmIndication_Data() {}
+
+func (*AlarmIndication_OnuTiwiInd) isAlarmIndication_Data() {}
+
+func (*AlarmIndication_OnuActivationFailInd) isAlarmIndication_Data() {}
+
+func (*AlarmIndication_OnuProcessingErrorInd) isAlarmIndication_Data() {}
+
+func (*AlarmIndication_OnuLossOfSyncFailInd) isAlarmIndication_Data() {}
+
+func (*AlarmIndication_OnuItuPonStatsInd) isAlarmIndication_Data() {}
+
+func (*AlarmIndication_OnuDeactivationFailureInd) isAlarmIndication_Data() {}
+
+func (*AlarmIndication_OnuRemoteDefectInd) isAlarmIndication_Data() {}
+
+func (*AlarmIndication_OnuLossGemDelineationInd) isAlarmIndication_Data() {}
+
+func (*AlarmIndication_OnuPhysicalEquipmentErrorInd) isAlarmIndication_Data() {}
+
+func (*AlarmIndication_OnuLossOfAckInd) isAlarmIndication_Data() {}
+
+func (*AlarmIndication_OnuDiffReachExceededInd) isAlarmIndication_Data() {}
+
+func (m *AlarmIndication) GetData() isAlarmIndication_Data {
+	if m != nil {
+		return m.Data
+	}
+	return nil
+}
+
+func (m *AlarmIndication) GetLosInd() *LosIndication {
+	if x, ok := m.GetData().(*AlarmIndication_LosInd); ok {
+		return x.LosInd
+	}
+	return nil
+}
+
+func (m *AlarmIndication) GetDyingGaspInd() *DyingGaspIndication {
+	if x, ok := m.GetData().(*AlarmIndication_DyingGaspInd); ok {
+		return x.DyingGaspInd
+	}
+	return nil
+}
+
+func (m *AlarmIndication) GetOnuAlarmInd() *OnuAlarmIndication {
+	if x, ok := m.GetData().(*AlarmIndication_OnuAlarmInd); ok {
+		return x.OnuAlarmInd
+	}
+	return nil
+}
+
+func (m *AlarmIndication) GetOnuStartupFailInd() *OnuStartupFailureIndication {
+	if x, ok := m.GetData().(*AlarmIndication_OnuStartupFailInd); ok {
+		return x.OnuStartupFailInd
+	}
+	return nil
+}
+
+func (m *AlarmIndication) GetOnuSignalDegradeInd() *OnuSignalDegradeIndication {
+	if x, ok := m.GetData().(*AlarmIndication_OnuSignalDegradeInd); ok {
+		return x.OnuSignalDegradeInd
+	}
+	return nil
+}
+
+func (m *AlarmIndication) GetOnuDriftOfWindowInd() *OnuDriftOfWindowIndication {
+	if x, ok := m.GetData().(*AlarmIndication_OnuDriftOfWindowInd); ok {
+		return x.OnuDriftOfWindowInd
+	}
+	return nil
+}
+
+func (m *AlarmIndication) GetOnuLossOmciInd() *OnuLossOfOmciChannelIndication {
+	if x, ok := m.GetData().(*AlarmIndication_OnuLossOmciInd); ok {
+		return x.OnuLossOmciInd
+	}
+	return nil
+}
+
+func (m *AlarmIndication) GetOnuSignalsFailInd() *OnuSignalsFailureIndication {
+	if x, ok := m.GetData().(*AlarmIndication_OnuSignalsFailInd); ok {
+		return x.OnuSignalsFailInd
+	}
+	return nil
+}
+
+func (m *AlarmIndication) GetOnuTiwiInd() *OnuTransmissionInterferenceWarning {
+	if x, ok := m.GetData().(*AlarmIndication_OnuTiwiInd); ok {
+		return x.OnuTiwiInd
+	}
+	return nil
+}
+
+func (m *AlarmIndication) GetOnuActivationFailInd() *OnuActivationFailureIndication {
+	if x, ok := m.GetData().(*AlarmIndication_OnuActivationFailInd); ok {
+		return x.OnuActivationFailInd
+	}
+	return nil
+}
+
+func (m *AlarmIndication) GetOnuProcessingErrorInd() *OnuProcessingErrorIndication {
+	if x, ok := m.GetData().(*AlarmIndication_OnuProcessingErrorInd); ok {
+		return x.OnuProcessingErrorInd
+	}
+	return nil
+}
+
+func (m *AlarmIndication) GetOnuLossOfSyncFailInd() *OnuLossOfKeySyncFailureIndication {
+	if x, ok := m.GetData().(*AlarmIndication_OnuLossOfSyncFailInd); ok {
+		return x.OnuLossOfSyncFailInd
+	}
+	return nil
+}
+
+func (m *AlarmIndication) GetOnuItuPonStatsInd() *OnuItuPonStatsIndication {
+	if x, ok := m.GetData().(*AlarmIndication_OnuItuPonStatsInd); ok {
+		return x.OnuItuPonStatsInd
+	}
+	return nil
+}
+
+func (m *AlarmIndication) GetOnuDeactivationFailureInd() *OnuDeactivationFailureIndication {
+	if x, ok := m.GetData().(*AlarmIndication_OnuDeactivationFailureInd); ok {
+		return x.OnuDeactivationFailureInd
+	}
+	return nil
+}
+
+func (m *AlarmIndication) GetOnuRemoteDefectInd() *OnuRemoteDefectIndication {
+	if x, ok := m.GetData().(*AlarmIndication_OnuRemoteDefectInd); ok {
+		return x.OnuRemoteDefectInd
+	}
+	return nil
+}
+
+func (m *AlarmIndication) GetOnuLossGemDelineationInd() *OnuLossOfGEMChannelDelineationIndication {
+	if x, ok := m.GetData().(*AlarmIndication_OnuLossGemDelineationInd); ok {
+		return x.OnuLossGemDelineationInd
+	}
+	return nil
+}
+
+func (m *AlarmIndication) GetOnuPhysicalEquipmentErrorInd() *OnuPhysicalEquipmentErrorIndication {
+	if x, ok := m.GetData().(*AlarmIndication_OnuPhysicalEquipmentErrorInd); ok {
+		return x.OnuPhysicalEquipmentErrorInd
+	}
+	return nil
+}
+
+func (m *AlarmIndication) GetOnuLossOfAckInd() *OnuLossOfAcknowledgementIndication {
+	if x, ok := m.GetData().(*AlarmIndication_OnuLossOfAckInd); ok {
+		return x.OnuLossOfAckInd
+	}
+	return nil
+}
+
+func (m *AlarmIndication) GetOnuDiffReachExceededInd() *OnuDifferentialReachExceededIndication {
+	if x, ok := m.GetData().(*AlarmIndication_OnuDiffReachExceededInd); ok {
+		return x.OnuDiffReachExceededInd
+	}
+	return nil
+}
+
+// XXX_OneofWrappers is for the internal use of the proto package.
+func (*AlarmIndication) XXX_OneofWrappers() []interface{} {
+	return []interface{}{
+		(*AlarmIndication_LosInd)(nil),
+		(*AlarmIndication_DyingGaspInd)(nil),
+		(*AlarmIndication_OnuAlarmInd)(nil),
+		(*AlarmIndication_OnuStartupFailInd)(nil),
+		(*AlarmIndication_OnuSignalDegradeInd)(nil),
+		(*AlarmIndication_OnuDriftOfWindowInd)(nil),
+		(*AlarmIndication_OnuLossOmciInd)(nil),
+		(*AlarmIndication_OnuSignalsFailInd)(nil),
+		(*AlarmIndication_OnuTiwiInd)(nil),
+		(*AlarmIndication_OnuActivationFailInd)(nil),
+		(*AlarmIndication_OnuProcessingErrorInd)(nil),
+		(*AlarmIndication_OnuLossOfSyncFailInd)(nil),
+		(*AlarmIndication_OnuItuPonStatsInd)(nil),
+		(*AlarmIndication_OnuDeactivationFailureInd)(nil),
+		(*AlarmIndication_OnuRemoteDefectInd)(nil),
+		(*AlarmIndication_OnuLossGemDelineationInd)(nil),
+		(*AlarmIndication_OnuPhysicalEquipmentErrorInd)(nil),
+		(*AlarmIndication_OnuLossOfAckInd)(nil),
+		(*AlarmIndication_OnuDiffReachExceededInd)(nil),
+	}
+}
+
+type OltIndication struct {
+	OperState            string   `protobuf:"bytes,1,opt,name=oper_state,json=operState,proto3" json:"oper_state,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *OltIndication) Reset()         { *m = OltIndication{} }
+func (m *OltIndication) String() string { return proto.CompactTextString(m) }
+func (*OltIndication) ProtoMessage()    {}
+func (*OltIndication) Descriptor() ([]byte, []int) {
+	return fileDescriptor_c072e7aa0dfd74d5, []int{2}
+}
+
+func (m *OltIndication) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_OltIndication.Unmarshal(m, b)
+}
+func (m *OltIndication) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_OltIndication.Marshal(b, m, deterministic)
+}
+func (m *OltIndication) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_OltIndication.Merge(m, src)
+}
+func (m *OltIndication) XXX_Size() int {
+	return xxx_messageInfo_OltIndication.Size(m)
+}
+func (m *OltIndication) XXX_DiscardUnknown() {
+	xxx_messageInfo_OltIndication.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_OltIndication proto.InternalMessageInfo
+
+func (m *OltIndication) GetOperState() string {
+	if m != nil {
+		return m.OperState
+	}
+	return ""
+}
+
+type IntfIndication struct {
+	IntfId               uint32   `protobuf:"fixed32,1,opt,name=intf_id,json=intfId,proto3" json:"intf_id,omitempty"`
+	OperState            string   `protobuf:"bytes,2,opt,name=oper_state,json=operState,proto3" json:"oper_state,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *IntfIndication) Reset()         { *m = IntfIndication{} }
+func (m *IntfIndication) String() string { return proto.CompactTextString(m) }
+func (*IntfIndication) ProtoMessage()    {}
+func (*IntfIndication) Descriptor() ([]byte, []int) {
+	return fileDescriptor_c072e7aa0dfd74d5, []int{3}
+}
+
+func (m *IntfIndication) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_IntfIndication.Unmarshal(m, b)
+}
+func (m *IntfIndication) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_IntfIndication.Marshal(b, m, deterministic)
+}
+func (m *IntfIndication) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_IntfIndication.Merge(m, src)
+}
+func (m *IntfIndication) XXX_Size() int {
+	return xxx_messageInfo_IntfIndication.Size(m)
+}
+func (m *IntfIndication) XXX_DiscardUnknown() {
+	xxx_messageInfo_IntfIndication.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_IntfIndication proto.InternalMessageInfo
+
+func (m *IntfIndication) GetIntfId() uint32 {
+	if m != nil {
+		return m.IntfId
+	}
+	return 0
+}
+
+func (m *IntfIndication) GetOperState() string {
+	if m != nil {
+		return m.OperState
+	}
+	return ""
+}
+
+type OnuDiscIndication struct {
+	IntfId               uint32        `protobuf:"fixed32,1,opt,name=intf_id,json=intfId,proto3" json:"intf_id,omitempty"`
+	SerialNumber         *SerialNumber `protobuf:"bytes,2,opt,name=serial_number,json=serialNumber,proto3" json:"serial_number,omitempty"`
+	XXX_NoUnkeyedLiteral struct{}      `json:"-"`
+	XXX_unrecognized     []byte        `json:"-"`
+	XXX_sizecache        int32         `json:"-"`
+}
+
+func (m *OnuDiscIndication) Reset()         { *m = OnuDiscIndication{} }
+func (m *OnuDiscIndication) String() string { return proto.CompactTextString(m) }
+func (*OnuDiscIndication) ProtoMessage()    {}
+func (*OnuDiscIndication) Descriptor() ([]byte, []int) {
+	return fileDescriptor_c072e7aa0dfd74d5, []int{4}
+}
+
+func (m *OnuDiscIndication) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_OnuDiscIndication.Unmarshal(m, b)
+}
+func (m *OnuDiscIndication) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_OnuDiscIndication.Marshal(b, m, deterministic)
+}
+func (m *OnuDiscIndication) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_OnuDiscIndication.Merge(m, src)
+}
+func (m *OnuDiscIndication) XXX_Size() int {
+	return xxx_messageInfo_OnuDiscIndication.Size(m)
+}
+func (m *OnuDiscIndication) XXX_DiscardUnknown() {
+	xxx_messageInfo_OnuDiscIndication.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_OnuDiscIndication proto.InternalMessageInfo
+
+func (m *OnuDiscIndication) GetIntfId() uint32 {
+	if m != nil {
+		return m.IntfId
+	}
+	return 0
+}
+
+func (m *OnuDiscIndication) GetSerialNumber() *SerialNumber {
+	if m != nil {
+		return m.SerialNumber
+	}
+	return nil
+}
+
+type OnuIndication struct {
+	IntfId               uint32                             `protobuf:"fixed32,1,opt,name=intf_id,json=intfId,proto3" json:"intf_id,omitempty"`
+	OnuId                uint32                             `protobuf:"fixed32,2,opt,name=onu_id,json=onuId,proto3" json:"onu_id,omitempty"`
+	OperState            string                             `protobuf:"bytes,3,opt,name=oper_state,json=operState,proto3" json:"oper_state,omitempty"`
+	AdminState           string                             `protobuf:"bytes,5,opt,name=admin_state,json=adminState,proto3" json:"admin_state,omitempty"`
+	SerialNumber         *SerialNumber                      `protobuf:"bytes,4,opt,name=serial_number,json=serialNumber,proto3" json:"serial_number,omitempty"`
+	FailReason           OnuIndication_ActivationFailReason `protobuf:"varint,6,opt,name=fail_reason,json=failReason,proto3,enum=openolt.OnuIndication_ActivationFailReason" json:"fail_reason,omitempty"`
+	XXX_NoUnkeyedLiteral struct{}                           `json:"-"`
+	XXX_unrecognized     []byte                             `json:"-"`
+	XXX_sizecache        int32                              `json:"-"`
+}
+
+func (m *OnuIndication) Reset()         { *m = OnuIndication{} }
+func (m *OnuIndication) String() string { return proto.CompactTextString(m) }
+func (*OnuIndication) ProtoMessage()    {}
+func (*OnuIndication) Descriptor() ([]byte, []int) {
+	return fileDescriptor_c072e7aa0dfd74d5, []int{5}
+}
+
+func (m *OnuIndication) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_OnuIndication.Unmarshal(m, b)
+}
+func (m *OnuIndication) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_OnuIndication.Marshal(b, m, deterministic)
+}
+func (m *OnuIndication) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_OnuIndication.Merge(m, src)
+}
+func (m *OnuIndication) XXX_Size() int {
+	return xxx_messageInfo_OnuIndication.Size(m)
+}
+func (m *OnuIndication) XXX_DiscardUnknown() {
+	xxx_messageInfo_OnuIndication.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_OnuIndication proto.InternalMessageInfo
+
+func (m *OnuIndication) GetIntfId() uint32 {
+	if m != nil {
+		return m.IntfId
+	}
+	return 0
+}
+
+func (m *OnuIndication) GetOnuId() uint32 {
+	if m != nil {
+		return m.OnuId
+	}
+	return 0
+}
+
+func (m *OnuIndication) GetOperState() string {
+	if m != nil {
+		return m.OperState
+	}
+	return ""
+}
+
+func (m *OnuIndication) GetAdminState() string {
+	if m != nil {
+		return m.AdminState
+	}
+	return ""
+}
+
+func (m *OnuIndication) GetSerialNumber() *SerialNumber {
+	if m != nil {
+		return m.SerialNumber
+	}
+	return nil
+}
+
+func (m *OnuIndication) GetFailReason() OnuIndication_ActivationFailReason {
+	if m != nil {
+		return m.FailReason
+	}
+	return OnuIndication_ONU_ACTIVATION_FAIL_REASON_NONE
+}
+
+type IntfOperIndication struct {
+	Type                 string   `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"`
+	IntfId               uint32   `protobuf:"fixed32,2,opt,name=intf_id,json=intfId,proto3" json:"intf_id,omitempty"`
+	OperState            string   `protobuf:"bytes,3,opt,name=oper_state,json=operState,proto3" json:"oper_state,omitempty"`
+	Speed                uint32   `protobuf:"fixed32,4,opt,name=speed,proto3" json:"speed,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *IntfOperIndication) Reset()         { *m = IntfOperIndication{} }
+func (m *IntfOperIndication) String() string { return proto.CompactTextString(m) }
+func (*IntfOperIndication) ProtoMessage()    {}
+func (*IntfOperIndication) Descriptor() ([]byte, []int) {
+	return fileDescriptor_c072e7aa0dfd74d5, []int{6}
+}
+
+func (m *IntfOperIndication) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_IntfOperIndication.Unmarshal(m, b)
+}
+func (m *IntfOperIndication) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_IntfOperIndication.Marshal(b, m, deterministic)
+}
+func (m *IntfOperIndication) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_IntfOperIndication.Merge(m, src)
+}
+func (m *IntfOperIndication) XXX_Size() int {
+	return xxx_messageInfo_IntfOperIndication.Size(m)
+}
+func (m *IntfOperIndication) XXX_DiscardUnknown() {
+	xxx_messageInfo_IntfOperIndication.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_IntfOperIndication proto.InternalMessageInfo
+
+func (m *IntfOperIndication) GetType() string {
+	if m != nil {
+		return m.Type
+	}
+	return ""
+}
+
+func (m *IntfOperIndication) GetIntfId() uint32 {
+	if m != nil {
+		return m.IntfId
+	}
+	return 0
+}
+
+func (m *IntfOperIndication) GetOperState() string {
+	if m != nil {
+		return m.OperState
+	}
+	return ""
+}
+
+func (m *IntfOperIndication) GetSpeed() uint32 {
+	if m != nil {
+		return m.Speed
+	}
+	return 0
+}
+
+type OmciIndication struct {
+	IntfId               uint32   `protobuf:"fixed32,1,opt,name=intf_id,json=intfId,proto3" json:"intf_id,omitempty"`
+	OnuId                uint32   `protobuf:"fixed32,2,opt,name=onu_id,json=onuId,proto3" json:"onu_id,omitempty"`
+	Pkt                  []byte   `protobuf:"bytes,3,opt,name=pkt,proto3" json:"pkt,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *OmciIndication) Reset()         { *m = OmciIndication{} }
+func (m *OmciIndication) String() string { return proto.CompactTextString(m) }
+func (*OmciIndication) ProtoMessage()    {}
+func (*OmciIndication) Descriptor() ([]byte, []int) {
+	return fileDescriptor_c072e7aa0dfd74d5, []int{7}
+}
+
+func (m *OmciIndication) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_OmciIndication.Unmarshal(m, b)
+}
+func (m *OmciIndication) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_OmciIndication.Marshal(b, m, deterministic)
+}
+func (m *OmciIndication) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_OmciIndication.Merge(m, src)
+}
+func (m *OmciIndication) XXX_Size() int {
+	return xxx_messageInfo_OmciIndication.Size(m)
+}
+func (m *OmciIndication) XXX_DiscardUnknown() {
+	xxx_messageInfo_OmciIndication.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_OmciIndication proto.InternalMessageInfo
+
+func (m *OmciIndication) GetIntfId() uint32 {
+	if m != nil {
+		return m.IntfId
+	}
+	return 0
+}
+
+func (m *OmciIndication) GetOnuId() uint32 {
+	if m != nil {
+		return m.OnuId
+	}
+	return 0
+}
+
+func (m *OmciIndication) GetPkt() []byte {
+	if m != nil {
+		return m.Pkt
+	}
+	return nil
+}
+
+type PacketIndication struct {
+	IntfType             string   `protobuf:"bytes,5,opt,name=intf_type,json=intfType,proto3" json:"intf_type,omitempty"`
+	IntfId               uint32   `protobuf:"fixed32,1,opt,name=intf_id,json=intfId,proto3" json:"intf_id,omitempty"`
+	OnuId                uint32   `protobuf:"fixed32,8,opt,name=onu_id,json=onuId,proto3" json:"onu_id,omitempty"`
+	UniId                uint32   `protobuf:"fixed32,9,opt,name=uni_id,json=uniId,proto3" json:"uni_id,omitempty"`
+	GemportId            uint32   `protobuf:"fixed32,2,opt,name=gemport_id,json=gemportId,proto3" json:"gemport_id,omitempty"`
+	FlowId               uint32   `protobuf:"fixed32,3,opt,name=flow_id,json=flowId,proto3" json:"flow_id,omitempty"`
+	PortNo               uint32   `protobuf:"fixed32,6,opt,name=port_no,json=portNo,proto3" json:"port_no,omitempty"`
+	Cookie               uint64   `protobuf:"fixed64,7,opt,name=cookie,proto3" json:"cookie,omitempty"`
+	Pkt                  []byte   `protobuf:"bytes,4,opt,name=pkt,proto3" json:"pkt,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *PacketIndication) Reset()         { *m = PacketIndication{} }
+func (m *PacketIndication) String() string { return proto.CompactTextString(m) }
+func (*PacketIndication) ProtoMessage()    {}
+func (*PacketIndication) Descriptor() ([]byte, []int) {
+	return fileDescriptor_c072e7aa0dfd74d5, []int{8}
+}
+
+func (m *PacketIndication) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_PacketIndication.Unmarshal(m, b)
+}
+func (m *PacketIndication) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_PacketIndication.Marshal(b, m, deterministic)
+}
+func (m *PacketIndication) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_PacketIndication.Merge(m, src)
+}
+func (m *PacketIndication) XXX_Size() int {
+	return xxx_messageInfo_PacketIndication.Size(m)
+}
+func (m *PacketIndication) XXX_DiscardUnknown() {
+	xxx_messageInfo_PacketIndication.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_PacketIndication proto.InternalMessageInfo
+
+func (m *PacketIndication) GetIntfType() string {
+	if m != nil {
+		return m.IntfType
+	}
+	return ""
+}
+
+func (m *PacketIndication) GetIntfId() uint32 {
+	if m != nil {
+		return m.IntfId
+	}
+	return 0
+}
+
+func (m *PacketIndication) GetOnuId() uint32 {
+	if m != nil {
+		return m.OnuId
+	}
+	return 0
+}
+
+func (m *PacketIndication) GetUniId() uint32 {
+	if m != nil {
+		return m.UniId
+	}
+	return 0
+}
+
+func (m *PacketIndication) GetGemportId() uint32 {
+	if m != nil {
+		return m.GemportId
+	}
+	return 0
+}
+
+func (m *PacketIndication) GetFlowId() uint32 {
+	if m != nil {
+		return m.FlowId
+	}
+	return 0
+}
+
+func (m *PacketIndication) GetPortNo() uint32 {
+	if m != nil {
+		return m.PortNo
+	}
+	return 0
+}
+
+func (m *PacketIndication) GetCookie() uint64 {
+	if m != nil {
+		return m.Cookie
+	}
+	return 0
+}
+
+func (m *PacketIndication) GetPkt() []byte {
+	if m != nil {
+		return m.Pkt
+	}
+	return nil
+}
+
+type Interface struct {
+	IntfId               uint32   `protobuf:"fixed32,1,opt,name=intf_id,json=intfId,proto3" json:"intf_id,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *Interface) Reset()         { *m = Interface{} }
+func (m *Interface) String() string { return proto.CompactTextString(m) }
+func (*Interface) ProtoMessage()    {}
+func (*Interface) Descriptor() ([]byte, []int) {
+	return fileDescriptor_c072e7aa0dfd74d5, []int{9}
+}
+
+func (m *Interface) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_Interface.Unmarshal(m, b)
+}
+func (m *Interface) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_Interface.Marshal(b, m, deterministic)
+}
+func (m *Interface) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_Interface.Merge(m, src)
+}
+func (m *Interface) XXX_Size() int {
+	return xxx_messageInfo_Interface.Size(m)
+}
+func (m *Interface) XXX_DiscardUnknown() {
+	xxx_messageInfo_Interface.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Interface proto.InternalMessageInfo
+
+func (m *Interface) GetIntfId() uint32 {
+	if m != nil {
+		return m.IntfId
+	}
+	return 0
+}
+
+type Heartbeat struct {
+	HeartbeatSignature   uint32   `protobuf:"fixed32,1,opt,name=heartbeat_signature,json=heartbeatSignature,proto3" json:"heartbeat_signature,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *Heartbeat) Reset()         { *m = Heartbeat{} }
+func (m *Heartbeat) String() string { return proto.CompactTextString(m) }
+func (*Heartbeat) ProtoMessage()    {}
+func (*Heartbeat) Descriptor() ([]byte, []int) {
+	return fileDescriptor_c072e7aa0dfd74d5, []int{10}
+}
+
+func (m *Heartbeat) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_Heartbeat.Unmarshal(m, b)
+}
+func (m *Heartbeat) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_Heartbeat.Marshal(b, m, deterministic)
+}
+func (m *Heartbeat) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_Heartbeat.Merge(m, src)
+}
+func (m *Heartbeat) XXX_Size() int {
+	return xxx_messageInfo_Heartbeat.Size(m)
+}
+func (m *Heartbeat) XXX_DiscardUnknown() {
+	xxx_messageInfo_Heartbeat.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Heartbeat proto.InternalMessageInfo
+
+func (m *Heartbeat) GetHeartbeatSignature() uint32 {
+	if m != nil {
+		return m.HeartbeatSignature
+	}
+	return 0
+}
+
+type Onu struct {
+	IntfId               uint32        `protobuf:"fixed32,1,opt,name=intf_id,json=intfId,proto3" json:"intf_id,omitempty"`
+	OnuId                uint32        `protobuf:"fixed32,2,opt,name=onu_id,json=onuId,proto3" json:"onu_id,omitempty"`
+	SerialNumber         *SerialNumber `protobuf:"bytes,3,opt,name=serial_number,json=serialNumber,proto3" json:"serial_number,omitempty"`
+	Pir                  uint32        `protobuf:"fixed32,4,opt,name=pir,proto3" json:"pir,omitempty"`
+	OmccEncryption       bool          `protobuf:"varint,5,opt,name=omcc_encryption,json=omccEncryption,proto3" json:"omcc_encryption,omitempty"`
+	XXX_NoUnkeyedLiteral struct{}      `json:"-"`
+	XXX_unrecognized     []byte        `json:"-"`
+	XXX_sizecache        int32         `json:"-"`
+}
+
+func (m *Onu) Reset()         { *m = Onu{} }
+func (m *Onu) String() string { return proto.CompactTextString(m) }
+func (*Onu) ProtoMessage()    {}
+func (*Onu) Descriptor() ([]byte, []int) {
+	return fileDescriptor_c072e7aa0dfd74d5, []int{11}
+}
+
+func (m *Onu) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_Onu.Unmarshal(m, b)
+}
+func (m *Onu) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_Onu.Marshal(b, m, deterministic)
+}
+func (m *Onu) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_Onu.Merge(m, src)
+}
+func (m *Onu) XXX_Size() int {
+	return xxx_messageInfo_Onu.Size(m)
+}
+func (m *Onu) XXX_DiscardUnknown() {
+	xxx_messageInfo_Onu.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Onu proto.InternalMessageInfo
+
+func (m *Onu) GetIntfId() uint32 {
+	if m != nil {
+		return m.IntfId
+	}
+	return 0
+}
+
+func (m *Onu) GetOnuId() uint32 {
+	if m != nil {
+		return m.OnuId
+	}
+	return 0
+}
+
+func (m *Onu) GetSerialNumber() *SerialNumber {
+	if m != nil {
+		return m.SerialNumber
+	}
+	return nil
+}
+
+func (m *Onu) GetPir() uint32 {
+	if m != nil {
+		return m.Pir
+	}
+	return 0
+}
+
+func (m *Onu) GetOmccEncryption() bool {
+	if m != nil {
+		return m.OmccEncryption
+	}
+	return false
+}
+
+type OnuLogicalDistance struct {
+	IntfId                 uint32   `protobuf:"fixed32,1,opt,name=intf_id,json=intfId,proto3" json:"intf_id,omitempty"`
+	OnuId                  uint32   `protobuf:"fixed32,2,opt,name=onu_id,json=onuId,proto3" json:"onu_id,omitempty"`
+	LogicalOnuDistanceZero uint32   `protobuf:"fixed32,3,opt,name=logical_onu_distance_zero,json=logicalOnuDistanceZero,proto3" json:"logical_onu_distance_zero,omitempty"`
+	LogicalOnuDistance     uint32   `protobuf:"fixed32,4,opt,name=logical_onu_distance,json=logicalOnuDistance,proto3" json:"logical_onu_distance,omitempty"`
+	XXX_NoUnkeyedLiteral   struct{} `json:"-"`
+	XXX_unrecognized       []byte   `json:"-"`
+	XXX_sizecache          int32    `json:"-"`
+}
+
+func (m *OnuLogicalDistance) Reset()         { *m = OnuLogicalDistance{} }
+func (m *OnuLogicalDistance) String() string { return proto.CompactTextString(m) }
+func (*OnuLogicalDistance) ProtoMessage()    {}
+func (*OnuLogicalDistance) Descriptor() ([]byte, []int) {
+	return fileDescriptor_c072e7aa0dfd74d5, []int{12}
+}
+
+func (m *OnuLogicalDistance) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_OnuLogicalDistance.Unmarshal(m, b)
+}
+func (m *OnuLogicalDistance) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_OnuLogicalDistance.Marshal(b, m, deterministic)
+}
+func (m *OnuLogicalDistance) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_OnuLogicalDistance.Merge(m, src)
+}
+func (m *OnuLogicalDistance) XXX_Size() int {
+	return xxx_messageInfo_OnuLogicalDistance.Size(m)
+}
+func (m *OnuLogicalDistance) XXX_DiscardUnknown() {
+	xxx_messageInfo_OnuLogicalDistance.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_OnuLogicalDistance proto.InternalMessageInfo
+
+func (m *OnuLogicalDistance) GetIntfId() uint32 {
+	if m != nil {
+		return m.IntfId
+	}
+	return 0
+}
+
+func (m *OnuLogicalDistance) GetOnuId() uint32 {
+	if m != nil {
+		return m.OnuId
+	}
+	return 0
+}
+
+func (m *OnuLogicalDistance) GetLogicalOnuDistanceZero() uint32 {
+	if m != nil {
+		return m.LogicalOnuDistanceZero
+	}
+	return 0
+}
+
+func (m *OnuLogicalDistance) GetLogicalOnuDistance() uint32 {
+	if m != nil {
+		return m.LogicalOnuDistance
+	}
+	return 0
+}
+
+type OmciMsg struct {
+	IntfId               uint32   `protobuf:"fixed32,1,opt,name=intf_id,json=intfId,proto3" json:"intf_id,omitempty"`
+	OnuId                uint32   `protobuf:"fixed32,2,opt,name=onu_id,json=onuId,proto3" json:"onu_id,omitempty"`
+	Pkt                  []byte   `protobuf:"bytes,3,opt,name=pkt,proto3" json:"pkt,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *OmciMsg) Reset()         { *m = OmciMsg{} }
+func (m *OmciMsg) String() string { return proto.CompactTextString(m) }
+func (*OmciMsg) ProtoMessage()    {}
+func (*OmciMsg) Descriptor() ([]byte, []int) {
+	return fileDescriptor_c072e7aa0dfd74d5, []int{13}
+}
+
+func (m *OmciMsg) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_OmciMsg.Unmarshal(m, b)
+}
+func (m *OmciMsg) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_OmciMsg.Marshal(b, m, deterministic)
+}
+func (m *OmciMsg) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_OmciMsg.Merge(m, src)
+}
+func (m *OmciMsg) XXX_Size() int {
+	return xxx_messageInfo_OmciMsg.Size(m)
+}
+func (m *OmciMsg) XXX_DiscardUnknown() {
+	xxx_messageInfo_OmciMsg.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_OmciMsg proto.InternalMessageInfo
+
+func (m *OmciMsg) GetIntfId() uint32 {
+	if m != nil {
+		return m.IntfId
+	}
+	return 0
+}
+
+func (m *OmciMsg) GetOnuId() uint32 {
+	if m != nil {
+		return m.OnuId
+	}
+	return 0
+}
+
+func (m *OmciMsg) GetPkt() []byte {
+	if m != nil {
+		return m.Pkt
+	}
+	return nil
+}
+
+type OnuPacket struct {
+	IntfId               uint32   `protobuf:"fixed32,1,opt,name=intf_id,json=intfId,proto3" json:"intf_id,omitempty"`
+	OnuId                uint32   `protobuf:"fixed32,2,opt,name=onu_id,json=onuId,proto3" json:"onu_id,omitempty"`
+	PortNo               uint32   `protobuf:"fixed32,4,opt,name=port_no,json=portNo,proto3" json:"port_no,omitempty"`
+	GemportId            uint32   `protobuf:"fixed32,5,opt,name=gemport_id,json=gemportId,proto3" json:"gemport_id,omitempty"`
+	Pkt                  []byte   `protobuf:"bytes,3,opt,name=pkt,proto3" json:"pkt,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *OnuPacket) Reset()         { *m = OnuPacket{} }
+func (m *OnuPacket) String() string { return proto.CompactTextString(m) }
+func (*OnuPacket) ProtoMessage()    {}
+func (*OnuPacket) Descriptor() ([]byte, []int) {
+	return fileDescriptor_c072e7aa0dfd74d5, []int{14}
+}
+
+func (m *OnuPacket) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_OnuPacket.Unmarshal(m, b)
+}
+func (m *OnuPacket) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_OnuPacket.Marshal(b, m, deterministic)
+}
+func (m *OnuPacket) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_OnuPacket.Merge(m, src)
+}
+func (m *OnuPacket) XXX_Size() int {
+	return xxx_messageInfo_OnuPacket.Size(m)
+}
+func (m *OnuPacket) XXX_DiscardUnknown() {
+	xxx_messageInfo_OnuPacket.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_OnuPacket proto.InternalMessageInfo
+
+func (m *OnuPacket) GetIntfId() uint32 {
+	if m != nil {
+		return m.IntfId
+	}
+	return 0
+}
+
+func (m *OnuPacket) GetOnuId() uint32 {
+	if m != nil {
+		return m.OnuId
+	}
+	return 0
+}
+
+func (m *OnuPacket) GetPortNo() uint32 {
+	if m != nil {
+		return m.PortNo
+	}
+	return 0
+}
+
+func (m *OnuPacket) GetGemportId() uint32 {
+	if m != nil {
+		return m.GemportId
+	}
+	return 0
+}
+
+func (m *OnuPacket) GetPkt() []byte {
+	if m != nil {
+		return m.Pkt
+	}
+	return nil
+}
+
+type UplinkPacket struct {
+	IntfId               uint32   `protobuf:"fixed32,1,opt,name=intf_id,json=intfId,proto3" json:"intf_id,omitempty"`
+	Pkt                  []byte   `protobuf:"bytes,2,opt,name=pkt,proto3" json:"pkt,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *UplinkPacket) Reset()         { *m = UplinkPacket{} }
+func (m *UplinkPacket) String() string { return proto.CompactTextString(m) }
+func (*UplinkPacket) ProtoMessage()    {}
+func (*UplinkPacket) Descriptor() ([]byte, []int) {
+	return fileDescriptor_c072e7aa0dfd74d5, []int{15}
+}
+
+func (m *UplinkPacket) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_UplinkPacket.Unmarshal(m, b)
+}
+func (m *UplinkPacket) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_UplinkPacket.Marshal(b, m, deterministic)
+}
+func (m *UplinkPacket) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_UplinkPacket.Merge(m, src)
+}
+func (m *UplinkPacket) XXX_Size() int {
+	return xxx_messageInfo_UplinkPacket.Size(m)
+}
+func (m *UplinkPacket) XXX_DiscardUnknown() {
+	xxx_messageInfo_UplinkPacket.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_UplinkPacket proto.InternalMessageInfo
+
+func (m *UplinkPacket) GetIntfId() uint32 {
+	if m != nil {
+		return m.IntfId
+	}
+	return 0
+}
+
+func (m *UplinkPacket) GetPkt() []byte {
+	if m != nil {
+		return m.Pkt
+	}
+	return nil
+}
+
+type DeviceInfo struct {
+	Vendor              string `protobuf:"bytes,1,opt,name=vendor,proto3" json:"vendor,omitempty"`
+	Model               string `protobuf:"bytes,2,opt,name=model,proto3" json:"model,omitempty"`
+	HardwareVersion     string `protobuf:"bytes,3,opt,name=hardware_version,json=hardwareVersion,proto3" json:"hardware_version,omitempty"`
+	FirmwareVersion     string `protobuf:"bytes,4,opt,name=firmware_version,json=firmwareVersion,proto3" json:"firmware_version,omitempty"`
+	DeviceId            string `protobuf:"bytes,16,opt,name=device_id,json=deviceId,proto3" json:"device_id,omitempty"`
+	DeviceSerialNumber  string `protobuf:"bytes,17,opt,name=device_serial_number,json=deviceSerialNumber,proto3" json:"device_serial_number,omitempty"`
+	PreviouslyConnected bool   `protobuf:"varint,19,opt,name=previously_connected,json=previouslyConnected,proto3" json:"previously_connected,omitempty"`
+	// Total number of pon intf ports on the device
+	PonPorts             uint32                             `protobuf:"fixed32,12,opt,name=pon_ports,json=ponPorts,proto3" json:"pon_ports,omitempty"`
+	Ranges               []*DeviceInfo_DeviceResourceRanges `protobuf:"bytes,15,rep,name=ranges,proto3" json:"ranges,omitempty"`
+	XXX_NoUnkeyedLiteral struct{}                           `json:"-"`
+	XXX_unrecognized     []byte                             `json:"-"`
+	XXX_sizecache        int32                              `json:"-"`
+}
+
+func (m *DeviceInfo) Reset()         { *m = DeviceInfo{} }
+func (m *DeviceInfo) String() string { return proto.CompactTextString(m) }
+func (*DeviceInfo) ProtoMessage()    {}
+func (*DeviceInfo) Descriptor() ([]byte, []int) {
+	return fileDescriptor_c072e7aa0dfd74d5, []int{16}
+}
+
+func (m *DeviceInfo) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_DeviceInfo.Unmarshal(m, b)
+}
+func (m *DeviceInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_DeviceInfo.Marshal(b, m, deterministic)
+}
+func (m *DeviceInfo) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_DeviceInfo.Merge(m, src)
+}
+func (m *DeviceInfo) XXX_Size() int {
+	return xxx_messageInfo_DeviceInfo.Size(m)
+}
+func (m *DeviceInfo) XXX_DiscardUnknown() {
+	xxx_messageInfo_DeviceInfo.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_DeviceInfo proto.InternalMessageInfo
+
+func (m *DeviceInfo) GetVendor() string {
+	if m != nil {
+		return m.Vendor
+	}
+	return ""
+}
+
+func (m *DeviceInfo) GetModel() string {
+	if m != nil {
+		return m.Model
+	}
+	return ""
+}
+
+func (m *DeviceInfo) GetHardwareVersion() string {
+	if m != nil {
+		return m.HardwareVersion
+	}
+	return ""
+}
+
+func (m *DeviceInfo) GetFirmwareVersion() string {
+	if m != nil {
+		return m.FirmwareVersion
+	}
+	return ""
+}
+
+func (m *DeviceInfo) GetDeviceId() string {
+	if m != nil {
+		return m.DeviceId
+	}
+	return ""
+}
+
+func (m *DeviceInfo) GetDeviceSerialNumber() string {
+	if m != nil {
+		return m.DeviceSerialNumber
+	}
+	return ""
+}
+
+func (m *DeviceInfo) GetPreviouslyConnected() bool {
+	if m != nil {
+		return m.PreviouslyConnected
+	}
+	return false
+}
+
+func (m *DeviceInfo) GetPonPorts() uint32 {
+	if m != nil {
+		return m.PonPorts
+	}
+	return 0
+}
+
+func (m *DeviceInfo) GetRanges() []*DeviceInfo_DeviceResourceRanges {
+	if m != nil {
+		return m.Ranges
+	}
+	return nil
+}
+
+type DeviceInfo_DeviceResourceRanges struct {
+	// List of 0 or more intf_ids that use the same technology and pools.
+	// If 0 intf_ids supplied, it implies ALL interfaces
+	IntfIds []uint32 `protobuf:"fixed32,1,rep,packed,name=intf_ids,json=intfIds,proto3" json:"intf_ids,omitempty"`
+	// Technology profile for this pool
+	Technology           string                                  `protobuf:"bytes,2,opt,name=technology,proto3" json:"technology,omitempty"`
+	Pools                []*DeviceInfo_DeviceResourceRanges_Pool `protobuf:"bytes,3,rep,name=pools,proto3" json:"pools,omitempty"`
+	XXX_NoUnkeyedLiteral struct{}                                `json:"-"`
+	XXX_unrecognized     []byte                                  `json:"-"`
+	XXX_sizecache        int32                                   `json:"-"`
+}
+
+func (m *DeviceInfo_DeviceResourceRanges) Reset()         { *m = DeviceInfo_DeviceResourceRanges{} }
+func (m *DeviceInfo_DeviceResourceRanges) String() string { return proto.CompactTextString(m) }
+func (*DeviceInfo_DeviceResourceRanges) ProtoMessage()    {}
+func (*DeviceInfo_DeviceResourceRanges) Descriptor() ([]byte, []int) {
+	return fileDescriptor_c072e7aa0dfd74d5, []int{16, 0}
+}
+
+func (m *DeviceInfo_DeviceResourceRanges) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_DeviceInfo_DeviceResourceRanges.Unmarshal(m, b)
+}
+func (m *DeviceInfo_DeviceResourceRanges) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_DeviceInfo_DeviceResourceRanges.Marshal(b, m, deterministic)
+}
+func (m *DeviceInfo_DeviceResourceRanges) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_DeviceInfo_DeviceResourceRanges.Merge(m, src)
+}
+func (m *DeviceInfo_DeviceResourceRanges) XXX_Size() int {
+	return xxx_messageInfo_DeviceInfo_DeviceResourceRanges.Size(m)
+}
+func (m *DeviceInfo_DeviceResourceRanges) XXX_DiscardUnknown() {
+	xxx_messageInfo_DeviceInfo_DeviceResourceRanges.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_DeviceInfo_DeviceResourceRanges proto.InternalMessageInfo
+
+func (m *DeviceInfo_DeviceResourceRanges) GetIntfIds() []uint32 {
+	if m != nil {
+		return m.IntfIds
+	}
+	return nil
+}
+
+func (m *DeviceInfo_DeviceResourceRanges) GetTechnology() string {
+	if m != nil {
+		return m.Technology
+	}
+	return ""
+}
+
+func (m *DeviceInfo_DeviceResourceRanges) GetPools() []*DeviceInfo_DeviceResourceRanges_Pool {
+	if m != nil {
+		return m.Pools
+	}
+	return nil
+}
+
+type DeviceInfo_DeviceResourceRanges_Pool struct {
+	Type                 DeviceInfo_DeviceResourceRanges_Pool_PoolType    `protobuf:"varint,1,opt,name=type,proto3,enum=openolt.DeviceInfo_DeviceResourceRanges_Pool_PoolType" json:"type,omitempty"`
+	Sharing              DeviceInfo_DeviceResourceRanges_Pool_SharingType `protobuf:"varint,2,opt,name=sharing,proto3,enum=openolt.DeviceInfo_DeviceResourceRanges_Pool_SharingType" json:"sharing,omitempty"`
+	Start                uint32                                           `protobuf:"fixed32,3,opt,name=start,proto3" json:"start,omitempty"`
+	End                  uint32                                           `protobuf:"fixed32,4,opt,name=end,proto3" json:"end,omitempty"`
+	XXX_NoUnkeyedLiteral struct{}                                         `json:"-"`
+	XXX_unrecognized     []byte                                           `json:"-"`
+	XXX_sizecache        int32                                            `json:"-"`
+}
+
+func (m *DeviceInfo_DeviceResourceRanges_Pool) Reset()         { *m = DeviceInfo_DeviceResourceRanges_Pool{} }
+func (m *DeviceInfo_DeviceResourceRanges_Pool) String() string { return proto.CompactTextString(m) }
+func (*DeviceInfo_DeviceResourceRanges_Pool) ProtoMessage()    {}
+func (*DeviceInfo_DeviceResourceRanges_Pool) Descriptor() ([]byte, []int) {
+	return fileDescriptor_c072e7aa0dfd74d5, []int{16, 0, 0}
+}
+
+func (m *DeviceInfo_DeviceResourceRanges_Pool) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_DeviceInfo_DeviceResourceRanges_Pool.Unmarshal(m, b)
+}
+func (m *DeviceInfo_DeviceResourceRanges_Pool) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_DeviceInfo_DeviceResourceRanges_Pool.Marshal(b, m, deterministic)
+}
+func (m *DeviceInfo_DeviceResourceRanges_Pool) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_DeviceInfo_DeviceResourceRanges_Pool.Merge(m, src)
+}
+func (m *DeviceInfo_DeviceResourceRanges_Pool) XXX_Size() int {
+	return xxx_messageInfo_DeviceInfo_DeviceResourceRanges_Pool.Size(m)
+}
+func (m *DeviceInfo_DeviceResourceRanges_Pool) XXX_DiscardUnknown() {
+	xxx_messageInfo_DeviceInfo_DeviceResourceRanges_Pool.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_DeviceInfo_DeviceResourceRanges_Pool proto.InternalMessageInfo
+
+func (m *DeviceInfo_DeviceResourceRanges_Pool) GetType() DeviceInfo_DeviceResourceRanges_Pool_PoolType {
+	if m != nil {
+		return m.Type
+	}
+	return DeviceInfo_DeviceResourceRanges_Pool_ONU_ID
+}
+
+func (m *DeviceInfo_DeviceResourceRanges_Pool) GetSharing() DeviceInfo_DeviceResourceRanges_Pool_SharingType {
+	if m != nil {
+		return m.Sharing
+	}
+	return DeviceInfo_DeviceResourceRanges_Pool_DEDICATED_PER_INTF
+}
+
+func (m *DeviceInfo_DeviceResourceRanges_Pool) GetStart() uint32 {
+	if m != nil {
+		return m.Start
+	}
+	return 0
+}
+
+func (m *DeviceInfo_DeviceResourceRanges_Pool) GetEnd() uint32 {
+	if m != nil {
+		return m.End
+	}
+	return 0
+}
+
+type Classifier struct {
+	OTpid                uint32   `protobuf:"fixed32,1,opt,name=o_tpid,json=oTpid,proto3" json:"o_tpid,omitempty"`
+	OVid                 uint32   `protobuf:"fixed32,2,opt,name=o_vid,json=oVid,proto3" json:"o_vid,omitempty"`
+	ITpid                uint32   `protobuf:"fixed32,3,opt,name=i_tpid,json=iTpid,proto3" json:"i_tpid,omitempty"`
+	IVid                 uint32   `protobuf:"fixed32,4,opt,name=i_vid,json=iVid,proto3" json:"i_vid,omitempty"`
+	OPbits               uint32   `protobuf:"fixed32,5,opt,name=o_pbits,json=oPbits,proto3" json:"o_pbits,omitempty"`
+	IPbits               uint32   `protobuf:"fixed32,6,opt,name=i_pbits,json=iPbits,proto3" json:"i_pbits,omitempty"`
+	EthType              uint32   `protobuf:"fixed32,7,opt,name=eth_type,json=ethType,proto3" json:"eth_type,omitempty"`
+	DstMac               []byte   `protobuf:"bytes,8,opt,name=dst_mac,json=dstMac,proto3" json:"dst_mac,omitempty"`
+	SrcMac               []byte   `protobuf:"bytes,9,opt,name=src_mac,json=srcMac,proto3" json:"src_mac,omitempty"`
+	IpProto              uint32   `protobuf:"fixed32,10,opt,name=ip_proto,json=ipProto,proto3" json:"ip_proto,omitempty"`
+	DstIp                uint32   `protobuf:"fixed32,11,opt,name=dst_ip,json=dstIp,proto3" json:"dst_ip,omitempty"`
+	SrcIp                uint32   `protobuf:"fixed32,12,opt,name=src_ip,json=srcIp,proto3" json:"src_ip,omitempty"`
+	SrcPort              uint32   `protobuf:"fixed32,13,opt,name=src_port,json=srcPort,proto3" json:"src_port,omitempty"`
+	DstPort              uint32   `protobuf:"fixed32,14,opt,name=dst_port,json=dstPort,proto3" json:"dst_port,omitempty"`
+	PktTagType           string   `protobuf:"bytes,15,opt,name=pkt_tag_type,json=pktTagType,proto3" json:"pkt_tag_type,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *Classifier) Reset()         { *m = Classifier{} }
+func (m *Classifier) String() string { return proto.CompactTextString(m) }
+func (*Classifier) ProtoMessage()    {}
+func (*Classifier) Descriptor() ([]byte, []int) {
+	return fileDescriptor_c072e7aa0dfd74d5, []int{17}
+}
+
+func (m *Classifier) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_Classifier.Unmarshal(m, b)
+}
+func (m *Classifier) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_Classifier.Marshal(b, m, deterministic)
+}
+func (m *Classifier) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_Classifier.Merge(m, src)
+}
+func (m *Classifier) XXX_Size() int {
+	return xxx_messageInfo_Classifier.Size(m)
+}
+func (m *Classifier) XXX_DiscardUnknown() {
+	xxx_messageInfo_Classifier.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Classifier proto.InternalMessageInfo
+
+func (m *Classifier) GetOTpid() uint32 {
+	if m != nil {
+		return m.OTpid
+	}
+	return 0
+}
+
+func (m *Classifier) GetOVid() uint32 {
+	if m != nil {
+		return m.OVid
+	}
+	return 0
+}
+
+func (m *Classifier) GetITpid() uint32 {
+	if m != nil {
+		return m.ITpid
+	}
+	return 0
+}
+
+func (m *Classifier) GetIVid() uint32 {
+	if m != nil {
+		return m.IVid
+	}
+	return 0
+}
+
+func (m *Classifier) GetOPbits() uint32 {
+	if m != nil {
+		return m.OPbits
+	}
+	return 0
+}
+
+func (m *Classifier) GetIPbits() uint32 {
+	if m != nil {
+		return m.IPbits
+	}
+	return 0
+}
+
+func (m *Classifier) GetEthType() uint32 {
+	if m != nil {
+		return m.EthType
+	}
+	return 0
+}
+
+func (m *Classifier) GetDstMac() []byte {
+	if m != nil {
+		return m.DstMac
+	}
+	return nil
+}
+
+func (m *Classifier) GetSrcMac() []byte {
+	if m != nil {
+		return m.SrcMac
+	}
+	return nil
+}
+
+func (m *Classifier) GetIpProto() uint32 {
+	if m != nil {
+		return m.IpProto
+	}
+	return 0
+}
+
+func (m *Classifier) GetDstIp() uint32 {
+	if m != nil {
+		return m.DstIp
+	}
+	return 0
+}
+
+func (m *Classifier) GetSrcIp() uint32 {
+	if m != nil {
+		return m.SrcIp
+	}
+	return 0
+}
+
+func (m *Classifier) GetSrcPort() uint32 {
+	if m != nil {
+		return m.SrcPort
+	}
+	return 0
+}
+
+func (m *Classifier) GetDstPort() uint32 {
+	if m != nil {
+		return m.DstPort
+	}
+	return 0
+}
+
+func (m *Classifier) GetPktTagType() string {
+	if m != nil {
+		return m.PktTagType
+	}
+	return ""
+}
+
+type ActionCmd struct {
+	AddOuterTag          bool     `protobuf:"varint,1,opt,name=add_outer_tag,json=addOuterTag,proto3" json:"add_outer_tag,omitempty"`
+	RemoveOuterTag       bool     `protobuf:"varint,2,opt,name=remove_outer_tag,json=removeOuterTag,proto3" json:"remove_outer_tag,omitempty"`
+	TrapToHost           bool     `protobuf:"varint,3,opt,name=trap_to_host,json=trapToHost,proto3" json:"trap_to_host,omitempty"`
+	RemarkOuterPbits     bool     `protobuf:"varint,4,opt,name=remark_outer_pbits,json=remarkOuterPbits,proto3" json:"remark_outer_pbits,omitempty"`
+	RemarkInnerPbits     bool     `protobuf:"varint,5,opt,name=remark_inner_pbits,json=remarkInnerPbits,proto3" json:"remark_inner_pbits,omitempty"`
+	AddInnerTag          bool     `protobuf:"varint,6,opt,name=add_inner_tag,json=addInnerTag,proto3" json:"add_inner_tag,omitempty"`
+	RemoveInnerTag       bool     `protobuf:"varint,7,opt,name=remove_inner_tag,json=removeInnerTag,proto3" json:"remove_inner_tag,omitempty"`
+	TranslateInnerTag    bool     `protobuf:"varint,8,opt,name=translate_inner_tag,json=translateInnerTag,proto3" json:"translate_inner_tag,omitempty"`
+	TranslateOuterTag    bool     `protobuf:"varint,9,opt,name=translate_outer_tag,json=translateOuterTag,proto3" json:"translate_outer_tag,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *ActionCmd) Reset()         { *m = ActionCmd{} }
+func (m *ActionCmd) String() string { return proto.CompactTextString(m) }
+func (*ActionCmd) ProtoMessage()    {}
+func (*ActionCmd) Descriptor() ([]byte, []int) {
+	return fileDescriptor_c072e7aa0dfd74d5, []int{18}
+}
+
+func (m *ActionCmd) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_ActionCmd.Unmarshal(m, b)
+}
+func (m *ActionCmd) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_ActionCmd.Marshal(b, m, deterministic)
+}
+func (m *ActionCmd) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_ActionCmd.Merge(m, src)
+}
+func (m *ActionCmd) XXX_Size() int {
+	return xxx_messageInfo_ActionCmd.Size(m)
+}
+func (m *ActionCmd) XXX_DiscardUnknown() {
+	xxx_messageInfo_ActionCmd.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_ActionCmd proto.InternalMessageInfo
+
+func (m *ActionCmd) GetAddOuterTag() bool {
+	if m != nil {
+		return m.AddOuterTag
+	}
+	return false
+}
+
+func (m *ActionCmd) GetRemoveOuterTag() bool {
+	if m != nil {
+		return m.RemoveOuterTag
+	}
+	return false
+}
+
+func (m *ActionCmd) GetTrapToHost() bool {
+	if m != nil {
+		return m.TrapToHost
+	}
+	return false
+}
+
+func (m *ActionCmd) GetRemarkOuterPbits() bool {
+	if m != nil {
+		return m.RemarkOuterPbits
+	}
+	return false
+}
+
+func (m *ActionCmd) GetRemarkInnerPbits() bool {
+	if m != nil {
+		return m.RemarkInnerPbits
+	}
+	return false
+}
+
+func (m *ActionCmd) GetAddInnerTag() bool {
+	if m != nil {
+		return m.AddInnerTag
+	}
+	return false
+}
+
+func (m *ActionCmd) GetRemoveInnerTag() bool {
+	if m != nil {
+		return m.RemoveInnerTag
+	}
+	return false
+}
+
+func (m *ActionCmd) GetTranslateInnerTag() bool {
+	if m != nil {
+		return m.TranslateInnerTag
+	}
+	return false
+}
+
+func (m *ActionCmd) GetTranslateOuterTag() bool {
+	if m != nil {
+		return m.TranslateOuterTag
+	}
+	return false
+}
+
+type Action struct {
+	Cmd                  *ActionCmd `protobuf:"bytes,1,opt,name=cmd,proto3" json:"cmd,omitempty"`
+	OVid                 uint32     `protobuf:"fixed32,2,opt,name=o_vid,json=oVid,proto3" json:"o_vid,omitempty"`
+	OPbits               uint32     `protobuf:"fixed32,3,opt,name=o_pbits,json=oPbits,proto3" json:"o_pbits,omitempty"`
+	OTpid                uint32     `protobuf:"fixed32,4,opt,name=o_tpid,json=oTpid,proto3" json:"o_tpid,omitempty"`
+	IVid                 uint32     `protobuf:"fixed32,5,opt,name=i_vid,json=iVid,proto3" json:"i_vid,omitempty"`
+	IPbits               uint32     `protobuf:"fixed32,6,opt,name=i_pbits,json=iPbits,proto3" json:"i_pbits,omitempty"`
+	ITpid                uint32     `protobuf:"fixed32,7,opt,name=i_tpid,json=iTpid,proto3" json:"i_tpid,omitempty"`
+	XXX_NoUnkeyedLiteral struct{}   `json:"-"`
+	XXX_unrecognized     []byte     `json:"-"`
+	XXX_sizecache        int32      `json:"-"`
+}
+
+func (m *Action) Reset()         { *m = Action{} }
+func (m *Action) String() string { return proto.CompactTextString(m) }
+func (*Action) ProtoMessage()    {}
+func (*Action) Descriptor() ([]byte, []int) {
+	return fileDescriptor_c072e7aa0dfd74d5, []int{19}
+}
+
+func (m *Action) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_Action.Unmarshal(m, b)
+}
+func (m *Action) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_Action.Marshal(b, m, deterministic)
+}
+func (m *Action) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_Action.Merge(m, src)
+}
+func (m *Action) XXX_Size() int {
+	return xxx_messageInfo_Action.Size(m)
+}
+func (m *Action) XXX_DiscardUnknown() {
+	xxx_messageInfo_Action.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Action proto.InternalMessageInfo
+
+func (m *Action) GetCmd() *ActionCmd {
+	if m != nil {
+		return m.Cmd
+	}
+	return nil
+}
+
+func (m *Action) GetOVid() uint32 {
+	if m != nil {
+		return m.OVid
+	}
+	return 0
+}
+
+func (m *Action) GetOPbits() uint32 {
+	if m != nil {
+		return m.OPbits
+	}
+	return 0
+}
+
+func (m *Action) GetOTpid() uint32 {
+	if m != nil {
+		return m.OTpid
+	}
+	return 0
+}
+
+func (m *Action) GetIVid() uint32 {
+	if m != nil {
+		return m.IVid
+	}
+	return 0
+}
+
+func (m *Action) GetIPbits() uint32 {
+	if m != nil {
+		return m.IPbits
+	}
+	return 0
+}
+
+func (m *Action) GetITpid() uint32 {
+	if m != nil {
+		return m.ITpid
+	}
+	return 0
+}
+
+type Flow struct {
+	AccessIntfId         int32             `protobuf:"fixed32,1,opt,name=access_intf_id,json=accessIntfId,proto3" json:"access_intf_id,omitempty"`
+	OnuId                int32             `protobuf:"fixed32,2,opt,name=onu_id,json=onuId,proto3" json:"onu_id,omitempty"`
+	UniId                int32             `protobuf:"fixed32,11,opt,name=uni_id,json=uniId,proto3" json:"uni_id,omitempty"`
+	FlowId               uint64            `protobuf:"fixed64,3,opt,name=flow_id,json=flowId,proto3" json:"flow_id,omitempty"`
+	SymmetricFlowId      uint64            `protobuf:"fixed64,18,opt,name=symmetric_flow_id,json=symmetricFlowId,proto3" json:"symmetric_flow_id,omitempty"`
+	FlowType             string            `protobuf:"bytes,4,opt,name=flow_type,json=flowType,proto3" json:"flow_type,omitempty"`
+	AllocId              int32             `protobuf:"fixed32,10,opt,name=alloc_id,json=allocId,proto3" json:"alloc_id,omitempty"`
+	NetworkIntfId        int32             `protobuf:"fixed32,5,opt,name=network_intf_id,json=networkIntfId,proto3" json:"network_intf_id,omitempty"`
+	GemportId            int32             `protobuf:"fixed32,6,opt,name=gemport_id,json=gemportId,proto3" json:"gemport_id,omitempty"`
+	Classifier           *Classifier       `protobuf:"bytes,7,opt,name=classifier,proto3" json:"classifier,omitempty"`
+	Action               *Action           `protobuf:"bytes,8,opt,name=action,proto3" json:"action,omitempty"`
+	Priority             int32             `protobuf:"fixed32,9,opt,name=priority,proto3" json:"priority,omitempty"`
+	Cookie               uint64            `protobuf:"fixed64,12,opt,name=cookie,proto3" json:"cookie,omitempty"`
+	PortNo               uint32            `protobuf:"fixed32,13,opt,name=port_no,json=portNo,proto3" json:"port_no,omitempty"`
+	GroupId              uint32            `protobuf:"fixed32,14,opt,name=group_id,json=groupId,proto3" json:"group_id,omitempty"`
+	TechProfileId        uint32            `protobuf:"fixed32,15,opt,name=tech_profile_id,json=techProfileId,proto3" json:"tech_profile_id,omitempty"`
+	ReplicateFlow        bool              `protobuf:"varint,16,opt,name=replicate_flow,json=replicateFlow,proto3" json:"replicate_flow,omitempty"`
+	PbitToGemport        map[uint32]uint32 `protobuf:"bytes,17,rep,name=pbit_to_gemport,json=pbitToGemport,proto3" json:"pbit_to_gemport,omitempty" protobuf_key:"fixed32,1,opt,name=key,proto3" protobuf_val:"fixed32,2,opt,name=value,proto3"`
+	GemportToAes         map[uint32]bool   `protobuf:"bytes,19,rep,name=gemport_to_aes,json=gemportToAes,proto3" json:"gemport_to_aes,omitempty" protobuf_key:"fixed32,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"`
+	XXX_NoUnkeyedLiteral struct{}          `json:"-"`
+	XXX_unrecognized     []byte            `json:"-"`
+	XXX_sizecache        int32             `json:"-"`
+}
+
+func (m *Flow) Reset()         { *m = Flow{} }
+func (m *Flow) String() string { return proto.CompactTextString(m) }
+func (*Flow) ProtoMessage()    {}
+func (*Flow) Descriptor() ([]byte, []int) {
+	return fileDescriptor_c072e7aa0dfd74d5, []int{20}
+}
+
+func (m *Flow) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_Flow.Unmarshal(m, b)
+}
+func (m *Flow) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_Flow.Marshal(b, m, deterministic)
+}
+func (m *Flow) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_Flow.Merge(m, src)
+}
+func (m *Flow) XXX_Size() int {
+	return xxx_messageInfo_Flow.Size(m)
+}
+func (m *Flow) XXX_DiscardUnknown() {
+	xxx_messageInfo_Flow.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Flow proto.InternalMessageInfo
+
+func (m *Flow) GetAccessIntfId() int32 {
+	if m != nil {
+		return m.AccessIntfId
+	}
+	return 0
+}
+
+func (m *Flow) GetOnuId() int32 {
+	if m != nil {
+		return m.OnuId
+	}
+	return 0
+}
+
+func (m *Flow) GetUniId() int32 {
+	if m != nil {
+		return m.UniId
+	}
+	return 0
+}
+
+func (m *Flow) GetFlowId() uint64 {
+	if m != nil {
+		return m.FlowId
+	}
+	return 0
+}
+
+func (m *Flow) GetSymmetricFlowId() uint64 {
+	if m != nil {
+		return m.SymmetricFlowId
+	}
+	return 0
+}
+
+func (m *Flow) GetFlowType() string {
+	if m != nil {
+		return m.FlowType
+	}
+	return ""
+}
+
+func (m *Flow) GetAllocId() int32 {
+	if m != nil {
+		return m.AllocId
+	}
+	return 0
+}
+
+func (m *Flow) GetNetworkIntfId() int32 {
+	if m != nil {
+		return m.NetworkIntfId
+	}
+	return 0
+}
+
+func (m *Flow) GetGemportId() int32 {
+	if m != nil {
+		return m.GemportId
+	}
+	return 0
+}
+
+func (m *Flow) GetClassifier() *Classifier {
+	if m != nil {
+		return m.Classifier
+	}
+	return nil
+}
+
+func (m *Flow) GetAction() *Action {
+	if m != nil {
+		return m.Action
+	}
+	return nil
+}
+
+func (m *Flow) GetPriority() int32 {
+	if m != nil {
+		return m.Priority
+	}
+	return 0
+}
+
+func (m *Flow) GetCookie() uint64 {
+	if m != nil {
+		return m.Cookie
+	}
+	return 0
+}
+
+func (m *Flow) GetPortNo() uint32 {
+	if m != nil {
+		return m.PortNo
+	}
+	return 0
+}
+
+func (m *Flow) GetGroupId() uint32 {
+	if m != nil {
+		return m.GroupId
+	}
+	return 0
+}
+
+func (m *Flow) GetTechProfileId() uint32 {
+	if m != nil {
+		return m.TechProfileId
+	}
+	return 0
+}
+
+func (m *Flow) GetReplicateFlow() bool {
+	if m != nil {
+		return m.ReplicateFlow
+	}
+	return false
+}
+
+func (m *Flow) GetPbitToGemport() map[uint32]uint32 {
+	if m != nil {
+		return m.PbitToGemport
+	}
+	return nil
+}
+
+func (m *Flow) GetGemportToAes() map[uint32]bool {
+	if m != nil {
+		return m.GemportToAes
+	}
+	return nil
+}
+
+type SerialNumber struct {
+	VendorId             []byte   `protobuf:"bytes,1,opt,name=vendor_id,json=vendorId,proto3" json:"vendor_id,omitempty"`
+	VendorSpecific       []byte   `protobuf:"bytes,2,opt,name=vendor_specific,json=vendorSpecific,proto3" json:"vendor_specific,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *SerialNumber) Reset()         { *m = SerialNumber{} }
+func (m *SerialNumber) String() string { return proto.CompactTextString(m) }
+func (*SerialNumber) ProtoMessage()    {}
+func (*SerialNumber) Descriptor() ([]byte, []int) {
+	return fileDescriptor_c072e7aa0dfd74d5, []int{21}
+}
+
+func (m *SerialNumber) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_SerialNumber.Unmarshal(m, b)
+}
+func (m *SerialNumber) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_SerialNumber.Marshal(b, m, deterministic)
+}
+func (m *SerialNumber) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_SerialNumber.Merge(m, src)
+}
+func (m *SerialNumber) XXX_Size() int {
+	return xxx_messageInfo_SerialNumber.Size(m)
+}
+func (m *SerialNumber) XXX_DiscardUnknown() {
+	xxx_messageInfo_SerialNumber.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_SerialNumber proto.InternalMessageInfo
+
+func (m *SerialNumber) GetVendorId() []byte {
+	if m != nil {
+		return m.VendorId
+	}
+	return nil
+}
+
+func (m *SerialNumber) GetVendorSpecific() []byte {
+	if m != nil {
+		return m.VendorSpecific
+	}
+	return nil
+}
+
+type PortStatistics struct {
+	IntfId               uint32   `protobuf:"fixed32,1,opt,name=intf_id,json=intfId,proto3" json:"intf_id,omitempty"`
+	RxBytes              uint64   `protobuf:"fixed64,2,opt,name=rx_bytes,json=rxBytes,proto3" json:"rx_bytes,omitempty"`
+	RxPackets            uint64   `protobuf:"fixed64,3,opt,name=rx_packets,json=rxPackets,proto3" json:"rx_packets,omitempty"`
+	RxUcastPackets       uint64   `protobuf:"fixed64,4,opt,name=rx_ucast_packets,json=rxUcastPackets,proto3" json:"rx_ucast_packets,omitempty"`
+	RxMcastPackets       uint64   `protobuf:"fixed64,5,opt,name=rx_mcast_packets,json=rxMcastPackets,proto3" json:"rx_mcast_packets,omitempty"`
+	RxBcastPackets       uint64   `protobuf:"fixed64,6,opt,name=rx_bcast_packets,json=rxBcastPackets,proto3" json:"rx_bcast_packets,omitempty"`
+	RxErrorPackets       uint64   `protobuf:"fixed64,7,opt,name=rx_error_packets,json=rxErrorPackets,proto3" json:"rx_error_packets,omitempty"`
+	RxFrames             uint64   `protobuf:"fixed64,17,opt,name=rx_frames,json=rxFrames,proto3" json:"rx_frames,omitempty"`
+	RxFrames_64          uint64   `protobuf:"fixed64,18,opt,name=rx_frames_64,json=rxFrames64,proto3" json:"rx_frames_64,omitempty"`
+	RxFrames_65_127      uint64   `protobuf:"fixed64,19,opt,name=rx_frames_65_127,json=rxFrames65127,proto3" json:"rx_frames_65_127,omitempty"`
+	RxFrames_128_255     uint64   `protobuf:"fixed64,20,opt,name=rx_frames_128_255,json=rxFrames128255,proto3" json:"rx_frames_128_255,omitempty"`
+	RxFrames_256_511     uint64   `protobuf:"fixed64,21,opt,name=rx_frames_256_511,json=rxFrames256511,proto3" json:"rx_frames_256_511,omitempty"`
+	RxFrames_512_1023    uint64   `protobuf:"fixed64,22,opt,name=rx_frames_512_1023,json=rxFrames5121023,proto3" json:"rx_frames_512_1023,omitempty"`
+	RxFrames_1024_1518   uint64   `protobuf:"fixed64,23,opt,name=rx_frames_1024_1518,json=rxFrames10241518,proto3" json:"rx_frames_1024_1518,omitempty"`
+	RxFrames_1519_2047   uint64   `protobuf:"fixed64,24,opt,name=rx_frames_1519_2047,json=rxFrames15192047,proto3" json:"rx_frames_1519_2047,omitempty"`
+	RxFrames_2048_4095   uint64   `protobuf:"fixed64,25,opt,name=rx_frames_2048_4095,json=rxFrames20484095,proto3" json:"rx_frames_2048_4095,omitempty"`
+	RxFrames_4096_9216   uint64   `protobuf:"fixed64,26,opt,name=rx_frames_4096_9216,json=rxFrames40969216,proto3" json:"rx_frames_4096_9216,omitempty"`
+	RxFrames_9217_16383  uint64   `protobuf:"fixed64,27,opt,name=rx_frames_9217_16383,json=rxFrames921716383,proto3" json:"rx_frames_9217_16383,omitempty"`
+	RxCrcErrors          uint64   `protobuf:"fixed64,14,opt,name=rx_crc_errors,json=rxCrcErrors,proto3" json:"rx_crc_errors,omitempty"`
+	TxBytes              uint64   `protobuf:"fixed64,8,opt,name=tx_bytes,json=txBytes,proto3" json:"tx_bytes,omitempty"`
+	TxPackets            uint64   `protobuf:"fixed64,9,opt,name=tx_packets,json=txPackets,proto3" json:"tx_packets,omitempty"`
+	TxUcastPackets       uint64   `protobuf:"fixed64,10,opt,name=tx_ucast_packets,json=txUcastPackets,proto3" json:"tx_ucast_packets,omitempty"`
+	TxMcastPackets       uint64   `protobuf:"fixed64,11,opt,name=tx_mcast_packets,json=txMcastPackets,proto3" json:"tx_mcast_packets,omitempty"`
+	TxBcastPackets       uint64   `protobuf:"fixed64,12,opt,name=tx_bcast_packets,json=txBcastPackets,proto3" json:"tx_bcast_packets,omitempty"`
+	TxErrorPackets       uint64   `protobuf:"fixed64,13,opt,name=tx_error_packets,json=txErrorPackets,proto3" json:"tx_error_packets,omitempty"`
+	TxFrames             uint64   `protobuf:"fixed64,28,opt,name=tx_frames,json=txFrames,proto3" json:"tx_frames,omitempty"`
+	TxFrames_64          uint64   `protobuf:"fixed64,29,opt,name=tx_frames_64,json=txFrames64,proto3" json:"tx_frames_64,omitempty"`
+	TxFrames_65_127      uint64   `protobuf:"fixed64,30,opt,name=tx_frames_65_127,json=txFrames65127,proto3" json:"tx_frames_65_127,omitempty"`
+	TxFrames_128_255     uint64   `protobuf:"fixed64,31,opt,name=tx_frames_128_255,json=txFrames128255,proto3" json:"tx_frames_128_255,omitempty"`
+	TxFrames_256_511     uint64   `protobuf:"fixed64,32,opt,name=tx_frames_256_511,json=txFrames256511,proto3" json:"tx_frames_256_511,omitempty"`
+	TxFrames_512_1023    uint64   `protobuf:"fixed64,33,opt,name=tx_frames_512_1023,json=txFrames5121023,proto3" json:"tx_frames_512_1023,omitempty"`
+	TxFrames_1024_1518   uint64   `protobuf:"fixed64,34,opt,name=tx_frames_1024_1518,json=txFrames10241518,proto3" json:"tx_frames_1024_1518,omitempty"`
+	TxFrames_1519_2047   uint64   `protobuf:"fixed64,35,opt,name=tx_frames_1519_2047,json=txFrames15192047,proto3" json:"tx_frames_1519_2047,omitempty"`
+	TxFrames_2048_4095   uint64   `protobuf:"fixed64,36,opt,name=tx_frames_2048_4095,json=txFrames20484095,proto3" json:"tx_frames_2048_4095,omitempty"`
+	TxFrames_4096_9216   uint64   `protobuf:"fixed64,37,opt,name=tx_frames_4096_9216,json=txFrames40969216,proto3" json:"tx_frames_4096_9216,omitempty"`
+	TxFrames_9217_16383  uint64   `protobuf:"fixed64,38,opt,name=tx_frames_9217_16383,json=txFrames921716383,proto3" json:"tx_frames_9217_16383,omitempty"`
+	BipErrors            uint64   `protobuf:"fixed64,15,opt,name=bip_errors,json=bipErrors,proto3" json:"bip_errors,omitempty"`
+	Timestamp            uint32   `protobuf:"fixed32,16,opt,name=timestamp,proto3" json:"timestamp,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *PortStatistics) Reset()         { *m = PortStatistics{} }
+func (m *PortStatistics) String() string { return proto.CompactTextString(m) }
+func (*PortStatistics) ProtoMessage()    {}
+func (*PortStatistics) Descriptor() ([]byte, []int) {
+	return fileDescriptor_c072e7aa0dfd74d5, []int{22}
+}
+
+func (m *PortStatistics) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_PortStatistics.Unmarshal(m, b)
+}
+func (m *PortStatistics) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_PortStatistics.Marshal(b, m, deterministic)
+}
+func (m *PortStatistics) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_PortStatistics.Merge(m, src)
+}
+func (m *PortStatistics) XXX_Size() int {
+	return xxx_messageInfo_PortStatistics.Size(m)
+}
+func (m *PortStatistics) XXX_DiscardUnknown() {
+	xxx_messageInfo_PortStatistics.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_PortStatistics proto.InternalMessageInfo
+
+func (m *PortStatistics) GetIntfId() uint32 {
+	if m != nil {
+		return m.IntfId
+	}
+	return 0
+}
+
+func (m *PortStatistics) GetRxBytes() uint64 {
+	if m != nil {
+		return m.RxBytes
+	}
+	return 0
+}
+
+func (m *PortStatistics) GetRxPackets() uint64 {
+	if m != nil {
+		return m.RxPackets
+	}
+	return 0
+}
+
+func (m *PortStatistics) GetRxUcastPackets() uint64 {
+	if m != nil {
+		return m.RxUcastPackets
+	}
+	return 0
+}
+
+func (m *PortStatistics) GetRxMcastPackets() uint64 {
+	if m != nil {
+		return m.RxMcastPackets
+	}
+	return 0
+}
+
+func (m *PortStatistics) GetRxBcastPackets() uint64 {
+	if m != nil {
+		return m.RxBcastPackets
+	}
+	return 0
+}
+
+func (m *PortStatistics) GetRxErrorPackets() uint64 {
+	if m != nil {
+		return m.RxErrorPackets
+	}
+	return 0
+}
+
+func (m *PortStatistics) GetRxFrames() uint64 {
+	if m != nil {
+		return m.RxFrames
+	}
+	return 0
+}
+
+func (m *PortStatistics) GetRxFrames_64() uint64 {
+	if m != nil {
+		return m.RxFrames_64
+	}
+	return 0
+}
+
+func (m *PortStatistics) GetRxFrames_65_127() uint64 {
+	if m != nil {
+		return m.RxFrames_65_127
+	}
+	return 0
+}
+
+func (m *PortStatistics) GetRxFrames_128_255() uint64 {
+	if m != nil {
+		return m.RxFrames_128_255
+	}
+	return 0
+}
+
+func (m *PortStatistics) GetRxFrames_256_511() uint64 {
+	if m != nil {
+		return m.RxFrames_256_511
+	}
+	return 0
+}
+
+func (m *PortStatistics) GetRxFrames_512_1023() uint64 {
+	if m != nil {
+		return m.RxFrames_512_1023
+	}
+	return 0
+}
+
+func (m *PortStatistics) GetRxFrames_1024_1518() uint64 {
+	if m != nil {
+		return m.RxFrames_1024_1518
+	}
+	return 0
+}
+
+func (m *PortStatistics) GetRxFrames_1519_2047() uint64 {
+	if m != nil {
+		return m.RxFrames_1519_2047
+	}
+	return 0
+}
+
+func (m *PortStatistics) GetRxFrames_2048_4095() uint64 {
+	if m != nil {
+		return m.RxFrames_2048_4095
+	}
+	return 0
+}
+
+func (m *PortStatistics) GetRxFrames_4096_9216() uint64 {
+	if m != nil {
+		return m.RxFrames_4096_9216
+	}
+	return 0
+}
+
+func (m *PortStatistics) GetRxFrames_9217_16383() uint64 {
+	if m != nil {
+		return m.RxFrames_9217_16383
+	}
+	return 0
+}
+
+func (m *PortStatistics) GetRxCrcErrors() uint64 {
+	if m != nil {
+		return m.RxCrcErrors
+	}
+	return 0
+}
+
+func (m *PortStatistics) GetTxBytes() uint64 {
+	if m != nil {
+		return m.TxBytes
+	}
+	return 0
+}
+
+func (m *PortStatistics) GetTxPackets() uint64 {
+	if m != nil {
+		return m.TxPackets
+	}
+	return 0
+}
+
+func (m *PortStatistics) GetTxUcastPackets() uint64 {
+	if m != nil {
+		return m.TxUcastPackets
+	}
+	return 0
+}
+
+func (m *PortStatistics) GetTxMcastPackets() uint64 {
+	if m != nil {
+		return m.TxMcastPackets
+	}
+	return 0
+}
+
+func (m *PortStatistics) GetTxBcastPackets() uint64 {
+	if m != nil {
+		return m.TxBcastPackets
+	}
+	return 0
+}
+
+func (m *PortStatistics) GetTxErrorPackets() uint64 {
+	if m != nil {
+		return m.TxErrorPackets
+	}
+	return 0
+}
+
+func (m *PortStatistics) GetTxFrames() uint64 {
+	if m != nil {
+		return m.TxFrames
+	}
+	return 0
+}
+
+func (m *PortStatistics) GetTxFrames_64() uint64 {
+	if m != nil {
+		return m.TxFrames_64
+	}
+	return 0
+}
+
+func (m *PortStatistics) GetTxFrames_65_127() uint64 {
+	if m != nil {
+		return m.TxFrames_65_127
+	}
+	return 0
+}
+
+func (m *PortStatistics) GetTxFrames_128_255() uint64 {
+	if m != nil {
+		return m.TxFrames_128_255
+	}
+	return 0
+}
+
+func (m *PortStatistics) GetTxFrames_256_511() uint64 {
+	if m != nil {
+		return m.TxFrames_256_511
+	}
+	return 0
+}
+
+func (m *PortStatistics) GetTxFrames_512_1023() uint64 {
+	if m != nil {
+		return m.TxFrames_512_1023
+	}
+	return 0
+}
+
+func (m *PortStatistics) GetTxFrames_1024_1518() uint64 {
+	if m != nil {
+		return m.TxFrames_1024_1518
+	}
+	return 0
+}
+
+func (m *PortStatistics) GetTxFrames_1519_2047() uint64 {
+	if m != nil {
+		return m.TxFrames_1519_2047
+	}
+	return 0
+}
+
+func (m *PortStatistics) GetTxFrames_2048_4095() uint64 {
+	if m != nil {
+		return m.TxFrames_2048_4095
+	}
+	return 0
+}
+
+func (m *PortStatistics) GetTxFrames_4096_9216() uint64 {
+	if m != nil {
+		return m.TxFrames_4096_9216
+	}
+	return 0
+}
+
+func (m *PortStatistics) GetTxFrames_9217_16383() uint64 {
+	if m != nil {
+		return m.TxFrames_9217_16383
+	}
+	return 0
+}
+
+func (m *PortStatistics) GetBipErrors() uint64 {
+	if m != nil {
+		return m.BipErrors
+	}
+	return 0
+}
+
+func (m *PortStatistics) GetTimestamp() uint32 {
+	if m != nil {
+		return m.Timestamp
+	}
+	return 0
+}
+
+type OnuStatistics struct {
+	IntfId                    uint32   `protobuf:"fixed32,1,opt,name=intf_id,json=intfId,proto3" json:"intf_id,omitempty"`
+	OnuId                     uint32   `protobuf:"fixed32,2,opt,name=onu_id,json=onuId,proto3" json:"onu_id,omitempty"`
+	PositiveDrift             uint64   `protobuf:"fixed64,3,opt,name=positive_drift,json=positiveDrift,proto3" json:"positive_drift,omitempty"`
+	NegativeDrift             uint64   `protobuf:"fixed64,4,opt,name=negative_drift,json=negativeDrift,proto3" json:"negative_drift,omitempty"`
+	DelimiterMissDetection    uint64   `protobuf:"fixed64,5,opt,name=delimiter_miss_detection,json=delimiterMissDetection,proto3" json:"delimiter_miss_detection,omitempty"`
+	BipErrors                 uint64   `protobuf:"fixed64,6,opt,name=bip_errors,json=bipErrors,proto3" json:"bip_errors,omitempty"`
+	BipUnits                  uint64   `protobuf:"fixed64,7,opt,name=bip_units,json=bipUnits,proto3" json:"bip_units,omitempty"`
+	FecCorrectedSymbols       uint64   `protobuf:"fixed64,8,opt,name=fec_corrected_symbols,json=fecCorrectedSymbols,proto3" json:"fec_corrected_symbols,omitempty"`
+	FecCodewordsCorrected     uint64   `protobuf:"fixed64,9,opt,name=fec_codewords_corrected,json=fecCodewordsCorrected,proto3" json:"fec_codewords_corrected,omitempty"`
+	FecCodewordsUncorrectable uint64   `protobuf:"fixed64,10,opt,name=fec_codewords_uncorrectable,json=fecCodewordsUncorrectable,proto3" json:"fec_codewords_uncorrectable,omitempty"`
+	FecCodewords              uint64   `protobuf:"fixed64,11,opt,name=fec_codewords,json=fecCodewords,proto3" json:"fec_codewords,omitempty"`
+	FecCorrectedUnits         uint64   `protobuf:"fixed64,12,opt,name=fec_corrected_units,json=fecCorrectedUnits,proto3" json:"fec_corrected_units,omitempty"`
+	XgemKeyErrors             uint64   `protobuf:"fixed64,13,opt,name=xgem_key_errors,json=xgemKeyErrors,proto3" json:"xgem_key_errors,omitempty"`
+	XgemLoss                  uint64   `protobuf:"fixed64,14,opt,name=xgem_loss,json=xgemLoss,proto3" json:"xgem_loss,omitempty"`
+	RxPloamsError             uint64   `protobuf:"fixed64,15,opt,name=rx_ploams_error,json=rxPloamsError,proto3" json:"rx_ploams_error,omitempty"`
+	RxPloamsNonIdle           uint64   `protobuf:"fixed64,16,opt,name=rx_ploams_non_idle,json=rxPloamsNonIdle,proto3" json:"rx_ploams_non_idle,omitempty"`
+	RxOmci                    uint64   `protobuf:"fixed64,17,opt,name=rx_omci,json=rxOmci,proto3" json:"rx_omci,omitempty"`
+	RxOmciPacketsCrcError     uint64   `protobuf:"fixed64,18,opt,name=rx_omci_packets_crc_error,json=rxOmciPacketsCrcError,proto3" json:"rx_omci_packets_crc_error,omitempty"`
+	RxBytes                   uint64   `protobuf:"fixed64,19,opt,name=rx_bytes,json=rxBytes,proto3" json:"rx_bytes,omitempty"`
+	RxPackets                 uint64   `protobuf:"fixed64,20,opt,name=rx_packets,json=rxPackets,proto3" json:"rx_packets,omitempty"`
+	TxBytes                   uint64   `protobuf:"fixed64,21,opt,name=tx_bytes,json=txBytes,proto3" json:"tx_bytes,omitempty"`
+	TxPackets                 uint64   `protobuf:"fixed64,22,opt,name=tx_packets,json=txPackets,proto3" json:"tx_packets,omitempty"`
+	BerReported               uint64   `protobuf:"fixed64,23,opt,name=ber_reported,json=berReported,proto3" json:"ber_reported,omitempty"`
+	LcdgErrors                uint64   `protobuf:"fixed64,24,opt,name=lcdg_errors,json=lcdgErrors,proto3" json:"lcdg_errors,omitempty"`
+	RdiErrors                 uint64   `protobuf:"fixed64,25,opt,name=rdi_errors,json=rdiErrors,proto3" json:"rdi_errors,omitempty"`
+	Timestamp                 uint32   `protobuf:"fixed32,26,opt,name=timestamp,proto3" json:"timestamp,omitempty"`
+	XXX_NoUnkeyedLiteral      struct{} `json:"-"`
+	XXX_unrecognized          []byte   `json:"-"`
+	XXX_sizecache             int32    `json:"-"`
+}
+
+func (m *OnuStatistics) Reset()         { *m = OnuStatistics{} }
+func (m *OnuStatistics) String() string { return proto.CompactTextString(m) }
+func (*OnuStatistics) ProtoMessage()    {}
+func (*OnuStatistics) Descriptor() ([]byte, []int) {
+	return fileDescriptor_c072e7aa0dfd74d5, []int{23}
+}
+
+func (m *OnuStatistics) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_OnuStatistics.Unmarshal(m, b)
+}
+func (m *OnuStatistics) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_OnuStatistics.Marshal(b, m, deterministic)
+}
+func (m *OnuStatistics) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_OnuStatistics.Merge(m, src)
+}
+func (m *OnuStatistics) XXX_Size() int {
+	return xxx_messageInfo_OnuStatistics.Size(m)
+}
+func (m *OnuStatistics) XXX_DiscardUnknown() {
+	xxx_messageInfo_OnuStatistics.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_OnuStatistics proto.InternalMessageInfo
+
+func (m *OnuStatistics) GetIntfId() uint32 {
+	if m != nil {
+		return m.IntfId
+	}
+	return 0
+}
+
+func (m *OnuStatistics) GetOnuId() uint32 {
+	if m != nil {
+		return m.OnuId
+	}
+	return 0
+}
+
+func (m *OnuStatistics) GetPositiveDrift() uint64 {
+	if m != nil {
+		return m.PositiveDrift
+	}
+	return 0
+}
+
+func (m *OnuStatistics) GetNegativeDrift() uint64 {
+	if m != nil {
+		return m.NegativeDrift
+	}
+	return 0
+}
+
+func (m *OnuStatistics) GetDelimiterMissDetection() uint64 {
+	if m != nil {
+		return m.DelimiterMissDetection
+	}
+	return 0
+}
+
+func (m *OnuStatistics) GetBipErrors() uint64 {
+	if m != nil {
+		return m.BipErrors
+	}
+	return 0
+}
+
+func (m *OnuStatistics) GetBipUnits() uint64 {
+	if m != nil {
+		return m.BipUnits
+	}
+	return 0
+}
+
+func (m *OnuStatistics) GetFecCorrectedSymbols() uint64 {
+	if m != nil {
+		return m.FecCorrectedSymbols
+	}
+	return 0
+}
+
+func (m *OnuStatistics) GetFecCodewordsCorrected() uint64 {
+	if m != nil {
+		return m.FecCodewordsCorrected
+	}
+	return 0
+}
+
+func (m *OnuStatistics) GetFecCodewordsUncorrectable() uint64 {
+	if m != nil {
+		return m.FecCodewordsUncorrectable
+	}
+	return 0
+}
+
+func (m *OnuStatistics) GetFecCodewords() uint64 {
+	if m != nil {
+		return m.FecCodewords
+	}
+	return 0
+}
+
+func (m *OnuStatistics) GetFecCorrectedUnits() uint64 {
+	if m != nil {
+		return m.FecCorrectedUnits
+	}
+	return 0
+}
+
+func (m *OnuStatistics) GetXgemKeyErrors() uint64 {
+	if m != nil {
+		return m.XgemKeyErrors
+	}
+	return 0
+}
+
+func (m *OnuStatistics) GetXgemLoss() uint64 {
+	if m != nil {
+		return m.XgemLoss
+	}
+	return 0
+}
+
+func (m *OnuStatistics) GetRxPloamsError() uint64 {
+	if m != nil {
+		return m.RxPloamsError
+	}
+	return 0
+}
+
+func (m *OnuStatistics) GetRxPloamsNonIdle() uint64 {
+	if m != nil {
+		return m.RxPloamsNonIdle
+	}
+	return 0
+}
+
+func (m *OnuStatistics) GetRxOmci() uint64 {
+	if m != nil {
+		return m.RxOmci
+	}
+	return 0
+}
+
+func (m *OnuStatistics) GetRxOmciPacketsCrcError() uint64 {
+	if m != nil {
+		return m.RxOmciPacketsCrcError
+	}
+	return 0
+}
+
+func (m *OnuStatistics) GetRxBytes() uint64 {
+	if m != nil {
+		return m.RxBytes
+	}
+	return 0
+}
+
+func (m *OnuStatistics) GetRxPackets() uint64 {
+	if m != nil {
+		return m.RxPackets
+	}
+	return 0
+}
+
+func (m *OnuStatistics) GetTxBytes() uint64 {
+	if m != nil {
+		return m.TxBytes
+	}
+	return 0
+}
+
+func (m *OnuStatistics) GetTxPackets() uint64 {
+	if m != nil {
+		return m.TxPackets
+	}
+	return 0
+}
+
+func (m *OnuStatistics) GetBerReported() uint64 {
+	if m != nil {
+		return m.BerReported
+	}
+	return 0
+}
+
+func (m *OnuStatistics) GetLcdgErrors() uint64 {
+	if m != nil {
+		return m.LcdgErrors
+	}
+	return 0
+}
+
+func (m *OnuStatistics) GetRdiErrors() uint64 {
+	if m != nil {
+		return m.RdiErrors
+	}
+	return 0
+}
+
+func (m *OnuStatistics) GetTimestamp() uint32 {
+	if m != nil {
+		return m.Timestamp
+	}
+	return 0
+}
+
+type GemPortStatistics struct {
+	IntfId               uint32   `protobuf:"fixed32,1,opt,name=intf_id,json=intfId,proto3" json:"intf_id,omitempty"`
+	GemportId            uint32   `protobuf:"fixed32,2,opt,name=gemport_id,json=gemportId,proto3" json:"gemport_id,omitempty"`
+	RxPackets            uint64   `protobuf:"fixed64,3,opt,name=rx_packets,json=rxPackets,proto3" json:"rx_packets,omitempty"`
+	RxBytes              uint64   `protobuf:"fixed64,4,opt,name=rx_bytes,json=rxBytes,proto3" json:"rx_bytes,omitempty"`
+	TxPackets            uint64   `protobuf:"fixed64,5,opt,name=tx_packets,json=txPackets,proto3" json:"tx_packets,omitempty"`
+	TxBytes              uint64   `protobuf:"fixed64,6,opt,name=tx_bytes,json=txBytes,proto3" json:"tx_bytes,omitempty"`
+	Timestamp            uint32   `protobuf:"fixed32,26,opt,name=timestamp,proto3" json:"timestamp,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *GemPortStatistics) Reset()         { *m = GemPortStatistics{} }
+func (m *GemPortStatistics) String() string { return proto.CompactTextString(m) }
+func (*GemPortStatistics) ProtoMessage()    {}
+func (*GemPortStatistics) Descriptor() ([]byte, []int) {
+	return fileDescriptor_c072e7aa0dfd74d5, []int{24}
+}
+
+func (m *GemPortStatistics) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_GemPortStatistics.Unmarshal(m, b)
+}
+func (m *GemPortStatistics) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_GemPortStatistics.Marshal(b, m, deterministic)
+}
+func (m *GemPortStatistics) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_GemPortStatistics.Merge(m, src)
+}
+func (m *GemPortStatistics) XXX_Size() int {
+	return xxx_messageInfo_GemPortStatistics.Size(m)
+}
+func (m *GemPortStatistics) XXX_DiscardUnknown() {
+	xxx_messageInfo_GemPortStatistics.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_GemPortStatistics proto.InternalMessageInfo
+
+func (m *GemPortStatistics) GetIntfId() uint32 {
+	if m != nil {
+		return m.IntfId
+	}
+	return 0
+}
+
+func (m *GemPortStatistics) GetGemportId() uint32 {
+	if m != nil {
+		return m.GemportId
+	}
+	return 0
+}
+
+func (m *GemPortStatistics) GetRxPackets() uint64 {
+	if m != nil {
+		return m.RxPackets
+	}
+	return 0
+}
+
+func (m *GemPortStatistics) GetRxBytes() uint64 {
+	if m != nil {
+		return m.RxBytes
+	}
+	return 0
+}
+
+func (m *GemPortStatistics) GetTxPackets() uint64 {
+	if m != nil {
+		return m.TxPackets
+	}
+	return 0
+}
+
+func (m *GemPortStatistics) GetTxBytes() uint64 {
+	if m != nil {
+		return m.TxBytes
+	}
+	return 0
+}
+
+func (m *GemPortStatistics) GetTimestamp() uint32 {
+	if m != nil {
+		return m.Timestamp
+	}
+	return 0
+}
+
+type FlowStatistics struct {
+	FlowId               uint32   `protobuf:"fixed32,1,opt,name=flow_id,json=flowId,proto3" json:"flow_id,omitempty"`
+	RxBytes              uint64   `protobuf:"fixed64,2,opt,name=rx_bytes,json=rxBytes,proto3" json:"rx_bytes,omitempty"`
+	RxPackets            uint64   `protobuf:"fixed64,3,opt,name=rx_packets,json=rxPackets,proto3" json:"rx_packets,omitempty"`
+	TxBytes              uint64   `protobuf:"fixed64,8,opt,name=tx_bytes,json=txBytes,proto3" json:"tx_bytes,omitempty"`
+	TxPackets            uint64   `protobuf:"fixed64,9,opt,name=tx_packets,json=txPackets,proto3" json:"tx_packets,omitempty"`
+	Timestamp            uint32   `protobuf:"fixed32,16,opt,name=timestamp,proto3" json:"timestamp,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *FlowStatistics) Reset()         { *m = FlowStatistics{} }
+func (m *FlowStatistics) String() string { return proto.CompactTextString(m) }
+func (*FlowStatistics) ProtoMessage()    {}
+func (*FlowStatistics) Descriptor() ([]byte, []int) {
+	return fileDescriptor_c072e7aa0dfd74d5, []int{25}
+}
+
+func (m *FlowStatistics) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_FlowStatistics.Unmarshal(m, b)
+}
+func (m *FlowStatistics) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_FlowStatistics.Marshal(b, m, deterministic)
+}
+func (m *FlowStatistics) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_FlowStatistics.Merge(m, src)
+}
+func (m *FlowStatistics) XXX_Size() int {
+	return xxx_messageInfo_FlowStatistics.Size(m)
+}
+func (m *FlowStatistics) XXX_DiscardUnknown() {
+	xxx_messageInfo_FlowStatistics.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_FlowStatistics proto.InternalMessageInfo
+
+func (m *FlowStatistics) GetFlowId() uint32 {
+	if m != nil {
+		return m.FlowId
+	}
+	return 0
+}
+
+func (m *FlowStatistics) GetRxBytes() uint64 {
+	if m != nil {
+		return m.RxBytes
+	}
+	return 0
+}
+
+func (m *FlowStatistics) GetRxPackets() uint64 {
+	if m != nil {
+		return m.RxPackets
+	}
+	return 0
+}
+
+func (m *FlowStatistics) GetTxBytes() uint64 {
+	if m != nil {
+		return m.TxBytes
+	}
+	return 0
+}
+
+func (m *FlowStatistics) GetTxPackets() uint64 {
+	if m != nil {
+		return m.TxPackets
+	}
+	return 0
+}
+
+func (m *FlowStatistics) GetTimestamp() uint32 {
+	if m != nil {
+		return m.Timestamp
+	}
+	return 0
+}
+
+type LosIndication struct {
+	IntfId               uint32   `protobuf:"fixed32,1,opt,name=intf_id,json=intfId,proto3" json:"intf_id,omitempty"`
+	Status               string   `protobuf:"bytes,2,opt,name=status,proto3" json:"status,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *LosIndication) Reset()         { *m = LosIndication{} }
+func (m *LosIndication) String() string { return proto.CompactTextString(m) }
+func (*LosIndication) ProtoMessage()    {}
+func (*LosIndication) Descriptor() ([]byte, []int) {
+	return fileDescriptor_c072e7aa0dfd74d5, []int{26}
+}
+
+func (m *LosIndication) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_LosIndication.Unmarshal(m, b)
+}
+func (m *LosIndication) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_LosIndication.Marshal(b, m, deterministic)
+}
+func (m *LosIndication) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_LosIndication.Merge(m, src)
+}
+func (m *LosIndication) XXX_Size() int {
+	return xxx_messageInfo_LosIndication.Size(m)
+}
+func (m *LosIndication) XXX_DiscardUnknown() {
+	xxx_messageInfo_LosIndication.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_LosIndication proto.InternalMessageInfo
+
+func (m *LosIndication) GetIntfId() uint32 {
+	if m != nil {
+		return m.IntfId
+	}
+	return 0
+}
+
+func (m *LosIndication) GetStatus() string {
+	if m != nil {
+		return m.Status
+	}
+	return ""
+}
+
+type DyingGaspIndication struct {
+	IntfId               uint32   `protobuf:"fixed32,1,opt,name=intf_id,json=intfId,proto3" json:"intf_id,omitempty"`
+	OnuId                uint32   `protobuf:"fixed32,2,opt,name=onu_id,json=onuId,proto3" json:"onu_id,omitempty"`
+	Status               string   `protobuf:"bytes,3,opt,name=status,proto3" json:"status,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *DyingGaspIndication) Reset()         { *m = DyingGaspIndication{} }
+func (m *DyingGaspIndication) String() string { return proto.CompactTextString(m) }
+func (*DyingGaspIndication) ProtoMessage()    {}
+func (*DyingGaspIndication) Descriptor() ([]byte, []int) {
+	return fileDescriptor_c072e7aa0dfd74d5, []int{27}
+}
+
+func (m *DyingGaspIndication) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_DyingGaspIndication.Unmarshal(m, b)
+}
+func (m *DyingGaspIndication) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_DyingGaspIndication.Marshal(b, m, deterministic)
+}
+func (m *DyingGaspIndication) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_DyingGaspIndication.Merge(m, src)
+}
+func (m *DyingGaspIndication) XXX_Size() int {
+	return xxx_messageInfo_DyingGaspIndication.Size(m)
+}
+func (m *DyingGaspIndication) XXX_DiscardUnknown() {
+	xxx_messageInfo_DyingGaspIndication.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_DyingGaspIndication proto.InternalMessageInfo
+
+func (m *DyingGaspIndication) GetIntfId() uint32 {
+	if m != nil {
+		return m.IntfId
+	}
+	return 0
+}
+
+func (m *DyingGaspIndication) GetOnuId() uint32 {
+	if m != nil {
+		return m.OnuId
+	}
+	return 0
+}
+
+func (m *DyingGaspIndication) GetStatus() string {
+	if m != nil {
+		return m.Status
+	}
+	return ""
+}
+
+type OnuAlarmIndication struct {
+	IntfId               uint32   `protobuf:"fixed32,1,opt,name=intf_id,json=intfId,proto3" json:"intf_id,omitempty"`
+	OnuId                uint32   `protobuf:"fixed32,2,opt,name=onu_id,json=onuId,proto3" json:"onu_id,omitempty"`
+	LosStatus            string   `protobuf:"bytes,3,opt,name=los_status,json=losStatus,proto3" json:"los_status,omitempty"`
+	LobStatus            string   `protobuf:"bytes,4,opt,name=lob_status,json=lobStatus,proto3" json:"lob_status,omitempty"`
+	LopcMissStatus       string   `protobuf:"bytes,5,opt,name=lopc_miss_status,json=lopcMissStatus,proto3" json:"lopc_miss_status,omitempty"`
+	LopcMicErrorStatus   string   `protobuf:"bytes,6,opt,name=lopc_mic_error_status,json=lopcMicErrorStatus,proto3" json:"lopc_mic_error_status,omitempty"`
+	LofiStatus           string   `protobuf:"bytes,7,opt,name=lofi_status,json=lofiStatus,proto3" json:"lofi_status,omitempty"`
+	LoamiStatus          string   `protobuf:"bytes,8,opt,name=loami_status,json=loamiStatus,proto3" json:"loami_status,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *OnuAlarmIndication) Reset()         { *m = OnuAlarmIndication{} }
+func (m *OnuAlarmIndication) String() string { return proto.CompactTextString(m) }
+func (*OnuAlarmIndication) ProtoMessage()    {}
+func (*OnuAlarmIndication) Descriptor() ([]byte, []int) {
+	return fileDescriptor_c072e7aa0dfd74d5, []int{28}
+}
+
+func (m *OnuAlarmIndication) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_OnuAlarmIndication.Unmarshal(m, b)
+}
+func (m *OnuAlarmIndication) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_OnuAlarmIndication.Marshal(b, m, deterministic)
+}
+func (m *OnuAlarmIndication) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_OnuAlarmIndication.Merge(m, src)
+}
+func (m *OnuAlarmIndication) XXX_Size() int {
+	return xxx_messageInfo_OnuAlarmIndication.Size(m)
+}
+func (m *OnuAlarmIndication) XXX_DiscardUnknown() {
+	xxx_messageInfo_OnuAlarmIndication.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_OnuAlarmIndication proto.InternalMessageInfo
+
+func (m *OnuAlarmIndication) GetIntfId() uint32 {
+	if m != nil {
+		return m.IntfId
+	}
+	return 0
+}
+
+func (m *OnuAlarmIndication) GetOnuId() uint32 {
+	if m != nil {
+		return m.OnuId
+	}
+	return 0
+}
+
+func (m *OnuAlarmIndication) GetLosStatus() string {
+	if m != nil {
+		return m.LosStatus
+	}
+	return ""
+}
+
+func (m *OnuAlarmIndication) GetLobStatus() string {
+	if m != nil {
+		return m.LobStatus
+	}
+	return ""
+}
+
+func (m *OnuAlarmIndication) GetLopcMissStatus() string {
+	if m != nil {
+		return m.LopcMissStatus
+	}
+	return ""
+}
+
+func (m *OnuAlarmIndication) GetLopcMicErrorStatus() string {
+	if m != nil {
+		return m.LopcMicErrorStatus
+	}
+	return ""
+}
+
+func (m *OnuAlarmIndication) GetLofiStatus() string {
+	if m != nil {
+		return m.LofiStatus
+	}
+	return ""
+}
+
+func (m *OnuAlarmIndication) GetLoamiStatus() string {
+	if m != nil {
+		return m.LoamiStatus
+	}
+	return ""
+}
+
+type OnuStartupFailureIndication struct {
+	IntfId               uint32   `protobuf:"fixed32,1,opt,name=intf_id,json=intfId,proto3" json:"intf_id,omitempty"`
+	OnuId                uint32   `protobuf:"fixed32,2,opt,name=onu_id,json=onuId,proto3" json:"onu_id,omitempty"`
+	Status               string   `protobuf:"bytes,3,opt,name=status,proto3" json:"status,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *OnuStartupFailureIndication) Reset()         { *m = OnuStartupFailureIndication{} }
+func (m *OnuStartupFailureIndication) String() string { return proto.CompactTextString(m) }
+func (*OnuStartupFailureIndication) ProtoMessage()    {}
+func (*OnuStartupFailureIndication) Descriptor() ([]byte, []int) {
+	return fileDescriptor_c072e7aa0dfd74d5, []int{29}
+}
+
+func (m *OnuStartupFailureIndication) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_OnuStartupFailureIndication.Unmarshal(m, b)
+}
+func (m *OnuStartupFailureIndication) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_OnuStartupFailureIndication.Marshal(b, m, deterministic)
+}
+func (m *OnuStartupFailureIndication) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_OnuStartupFailureIndication.Merge(m, src)
+}
+func (m *OnuStartupFailureIndication) XXX_Size() int {
+	return xxx_messageInfo_OnuStartupFailureIndication.Size(m)
+}
+func (m *OnuStartupFailureIndication) XXX_DiscardUnknown() {
+	xxx_messageInfo_OnuStartupFailureIndication.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_OnuStartupFailureIndication proto.InternalMessageInfo
+
+func (m *OnuStartupFailureIndication) GetIntfId() uint32 {
+	if m != nil {
+		return m.IntfId
+	}
+	return 0
+}
+
+func (m *OnuStartupFailureIndication) GetOnuId() uint32 {
+	if m != nil {
+		return m.OnuId
+	}
+	return 0
+}
+
+func (m *OnuStartupFailureIndication) GetStatus() string {
+	if m != nil {
+		return m.Status
+	}
+	return ""
+}
+
+type OnuSignalDegradeIndication struct {
+	IntfId               uint32   `protobuf:"fixed32,1,opt,name=intf_id,json=intfId,proto3" json:"intf_id,omitempty"`
+	OnuId                uint32   `protobuf:"fixed32,2,opt,name=onu_id,json=onuId,proto3" json:"onu_id,omitempty"`
+	Status               string   `protobuf:"bytes,3,opt,name=status,proto3" json:"status,omitempty"`
+	InverseBitErrorRate  uint32   `protobuf:"fixed32,4,opt,name=inverse_bit_error_rate,json=inverseBitErrorRate,proto3" json:"inverse_bit_error_rate,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *OnuSignalDegradeIndication) Reset()         { *m = OnuSignalDegradeIndication{} }
+func (m *OnuSignalDegradeIndication) String() string { return proto.CompactTextString(m) }
+func (*OnuSignalDegradeIndication) ProtoMessage()    {}
+func (*OnuSignalDegradeIndication) Descriptor() ([]byte, []int) {
+	return fileDescriptor_c072e7aa0dfd74d5, []int{30}
+}
+
+func (m *OnuSignalDegradeIndication) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_OnuSignalDegradeIndication.Unmarshal(m, b)
+}
+func (m *OnuSignalDegradeIndication) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_OnuSignalDegradeIndication.Marshal(b, m, deterministic)
+}
+func (m *OnuSignalDegradeIndication) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_OnuSignalDegradeIndication.Merge(m, src)
+}
+func (m *OnuSignalDegradeIndication) XXX_Size() int {
+	return xxx_messageInfo_OnuSignalDegradeIndication.Size(m)
+}
+func (m *OnuSignalDegradeIndication) XXX_DiscardUnknown() {
+	xxx_messageInfo_OnuSignalDegradeIndication.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_OnuSignalDegradeIndication proto.InternalMessageInfo
+
+func (m *OnuSignalDegradeIndication) GetIntfId() uint32 {
+	if m != nil {
+		return m.IntfId
+	}
+	return 0
+}
+
+func (m *OnuSignalDegradeIndication) GetOnuId() uint32 {
+	if m != nil {
+		return m.OnuId
+	}
+	return 0
+}
+
+func (m *OnuSignalDegradeIndication) GetStatus() string {
+	if m != nil {
+		return m.Status
+	}
+	return ""
+}
+
+func (m *OnuSignalDegradeIndication) GetInverseBitErrorRate() uint32 {
+	if m != nil {
+		return m.InverseBitErrorRate
+	}
+	return 0
+}
+
+type OnuDriftOfWindowIndication struct {
+	IntfId               uint32   `protobuf:"fixed32,1,opt,name=intf_id,json=intfId,proto3" json:"intf_id,omitempty"`
+	OnuId                uint32   `protobuf:"fixed32,2,opt,name=onu_id,json=onuId,proto3" json:"onu_id,omitempty"`
+	Status               string   `protobuf:"bytes,3,opt,name=status,proto3" json:"status,omitempty"`
+	Drift                uint32   `protobuf:"fixed32,4,opt,name=drift,proto3" json:"drift,omitempty"`
+	NewEqd               uint32   `protobuf:"fixed32,5,opt,name=new_eqd,json=newEqd,proto3" json:"new_eqd,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *OnuDriftOfWindowIndication) Reset()         { *m = OnuDriftOfWindowIndication{} }
+func (m *OnuDriftOfWindowIndication) String() string { return proto.CompactTextString(m) }
+func (*OnuDriftOfWindowIndication) ProtoMessage()    {}
+func (*OnuDriftOfWindowIndication) Descriptor() ([]byte, []int) {
+	return fileDescriptor_c072e7aa0dfd74d5, []int{31}
+}
+
+func (m *OnuDriftOfWindowIndication) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_OnuDriftOfWindowIndication.Unmarshal(m, b)
+}
+func (m *OnuDriftOfWindowIndication) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_OnuDriftOfWindowIndication.Marshal(b, m, deterministic)
+}
+func (m *OnuDriftOfWindowIndication) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_OnuDriftOfWindowIndication.Merge(m, src)
+}
+func (m *OnuDriftOfWindowIndication) XXX_Size() int {
+	return xxx_messageInfo_OnuDriftOfWindowIndication.Size(m)
+}
+func (m *OnuDriftOfWindowIndication) XXX_DiscardUnknown() {
+	xxx_messageInfo_OnuDriftOfWindowIndication.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_OnuDriftOfWindowIndication proto.InternalMessageInfo
+
+func (m *OnuDriftOfWindowIndication) GetIntfId() uint32 {
+	if m != nil {
+		return m.IntfId
+	}
+	return 0
+}
+
+func (m *OnuDriftOfWindowIndication) GetOnuId() uint32 {
+	if m != nil {
+		return m.OnuId
+	}
+	return 0
+}
+
+func (m *OnuDriftOfWindowIndication) GetStatus() string {
+	if m != nil {
+		return m.Status
+	}
+	return ""
+}
+
+func (m *OnuDriftOfWindowIndication) GetDrift() uint32 {
+	if m != nil {
+		return m.Drift
+	}
+	return 0
+}
+
+func (m *OnuDriftOfWindowIndication) GetNewEqd() uint32 {
+	if m != nil {
+		return m.NewEqd
+	}
+	return 0
+}
+
+type OnuLossOfOmciChannelIndication struct {
+	IntfId               uint32   `protobuf:"fixed32,1,opt,name=intf_id,json=intfId,proto3" json:"intf_id,omitempty"`
+	OnuId                uint32   `protobuf:"fixed32,2,opt,name=onu_id,json=onuId,proto3" json:"onu_id,omitempty"`
+	Status               string   `protobuf:"bytes,3,opt,name=status,proto3" json:"status,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *OnuLossOfOmciChannelIndication) Reset()         { *m = OnuLossOfOmciChannelIndication{} }
+func (m *OnuLossOfOmciChannelIndication) String() string { return proto.CompactTextString(m) }
+func (*OnuLossOfOmciChannelIndication) ProtoMessage()    {}
+func (*OnuLossOfOmciChannelIndication) Descriptor() ([]byte, []int) {
+	return fileDescriptor_c072e7aa0dfd74d5, []int{32}
+}
+
+func (m *OnuLossOfOmciChannelIndication) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_OnuLossOfOmciChannelIndication.Unmarshal(m, b)
+}
+func (m *OnuLossOfOmciChannelIndication) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_OnuLossOfOmciChannelIndication.Marshal(b, m, deterministic)
+}
+func (m *OnuLossOfOmciChannelIndication) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_OnuLossOfOmciChannelIndication.Merge(m, src)
+}
+func (m *OnuLossOfOmciChannelIndication) XXX_Size() int {
+	return xxx_messageInfo_OnuLossOfOmciChannelIndication.Size(m)
+}
+func (m *OnuLossOfOmciChannelIndication) XXX_DiscardUnknown() {
+	xxx_messageInfo_OnuLossOfOmciChannelIndication.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_OnuLossOfOmciChannelIndication proto.InternalMessageInfo
+
+func (m *OnuLossOfOmciChannelIndication) GetIntfId() uint32 {
+	if m != nil {
+		return m.IntfId
+	}
+	return 0
+}
+
+func (m *OnuLossOfOmciChannelIndication) GetOnuId() uint32 {
+	if m != nil {
+		return m.OnuId
+	}
+	return 0
+}
+
+func (m *OnuLossOfOmciChannelIndication) GetStatus() string {
+	if m != nil {
+		return m.Status
+	}
+	return ""
+}
+
+type OnuSignalsFailureIndication struct {
+	IntfId               uint32   `protobuf:"fixed32,1,opt,name=intf_id,json=intfId,proto3" json:"intf_id,omitempty"`
+	OnuId                uint32   `protobuf:"fixed32,2,opt,name=onu_id,json=onuId,proto3" json:"onu_id,omitempty"`
+	Status               string   `protobuf:"bytes,3,opt,name=status,proto3" json:"status,omitempty"`
+	InverseBitErrorRate  uint32   `protobuf:"fixed32,4,opt,name=inverse_bit_error_rate,json=inverseBitErrorRate,proto3" json:"inverse_bit_error_rate,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *OnuSignalsFailureIndication) Reset()         { *m = OnuSignalsFailureIndication{} }
+func (m *OnuSignalsFailureIndication) String() string { return proto.CompactTextString(m) }
+func (*OnuSignalsFailureIndication) ProtoMessage()    {}
+func (*OnuSignalsFailureIndication) Descriptor() ([]byte, []int) {
+	return fileDescriptor_c072e7aa0dfd74d5, []int{33}
+}
+
+func (m *OnuSignalsFailureIndication) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_OnuSignalsFailureIndication.Unmarshal(m, b)
+}
+func (m *OnuSignalsFailureIndication) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_OnuSignalsFailureIndication.Marshal(b, m, deterministic)
+}
+func (m *OnuSignalsFailureIndication) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_OnuSignalsFailureIndication.Merge(m, src)
+}
+func (m *OnuSignalsFailureIndication) XXX_Size() int {
+	return xxx_messageInfo_OnuSignalsFailureIndication.Size(m)
+}
+func (m *OnuSignalsFailureIndication) XXX_DiscardUnknown() {
+	xxx_messageInfo_OnuSignalsFailureIndication.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_OnuSignalsFailureIndication proto.InternalMessageInfo
+
+func (m *OnuSignalsFailureIndication) GetIntfId() uint32 {
+	if m != nil {
+		return m.IntfId
+	}
+	return 0
+}
+
+func (m *OnuSignalsFailureIndication) GetOnuId() uint32 {
+	if m != nil {
+		return m.OnuId
+	}
+	return 0
+}
+
+func (m *OnuSignalsFailureIndication) GetStatus() string {
+	if m != nil {
+		return m.Status
+	}
+	return ""
+}
+
+func (m *OnuSignalsFailureIndication) GetInverseBitErrorRate() uint32 {
+	if m != nil {
+		return m.InverseBitErrorRate
+	}
+	return 0
+}
+
+type OnuTransmissionInterferenceWarning struct {
+	IntfId               uint32   `protobuf:"fixed32,1,opt,name=intf_id,json=intfId,proto3" json:"intf_id,omitempty"`
+	OnuId                uint32   `protobuf:"fixed32,2,opt,name=onu_id,json=onuId,proto3" json:"onu_id,omitempty"`
+	Status               string   `protobuf:"bytes,3,opt,name=status,proto3" json:"status,omitempty"`
+	Drift                uint32   `protobuf:"fixed32,4,opt,name=drift,proto3" json:"drift,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *OnuTransmissionInterferenceWarning) Reset()         { *m = OnuTransmissionInterferenceWarning{} }
+func (m *OnuTransmissionInterferenceWarning) String() string { return proto.CompactTextString(m) }
+func (*OnuTransmissionInterferenceWarning) ProtoMessage()    {}
+func (*OnuTransmissionInterferenceWarning) Descriptor() ([]byte, []int) {
+	return fileDescriptor_c072e7aa0dfd74d5, []int{34}
+}
+
+func (m *OnuTransmissionInterferenceWarning) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_OnuTransmissionInterferenceWarning.Unmarshal(m, b)
+}
+func (m *OnuTransmissionInterferenceWarning) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_OnuTransmissionInterferenceWarning.Marshal(b, m, deterministic)
+}
+func (m *OnuTransmissionInterferenceWarning) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_OnuTransmissionInterferenceWarning.Merge(m, src)
+}
+func (m *OnuTransmissionInterferenceWarning) XXX_Size() int {
+	return xxx_messageInfo_OnuTransmissionInterferenceWarning.Size(m)
+}
+func (m *OnuTransmissionInterferenceWarning) XXX_DiscardUnknown() {
+	xxx_messageInfo_OnuTransmissionInterferenceWarning.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_OnuTransmissionInterferenceWarning proto.InternalMessageInfo
+
+func (m *OnuTransmissionInterferenceWarning) GetIntfId() uint32 {
+	if m != nil {
+		return m.IntfId
+	}
+	return 0
+}
+
+func (m *OnuTransmissionInterferenceWarning) GetOnuId() uint32 {
+	if m != nil {
+		return m.OnuId
+	}
+	return 0
+}
+
+func (m *OnuTransmissionInterferenceWarning) GetStatus() string {
+	if m != nil {
+		return m.Status
+	}
+	return ""
+}
+
+func (m *OnuTransmissionInterferenceWarning) GetDrift() uint32 {
+	if m != nil {
+		return m.Drift
+	}
+	return 0
+}
+
+type OnuActivationFailureIndication struct {
+	IntfId               uint32   `protobuf:"fixed32,1,opt,name=intf_id,json=intfId,proto3" json:"intf_id,omitempty"`
+	OnuId                uint32   `protobuf:"fixed32,2,opt,name=onu_id,json=onuId,proto3" json:"onu_id,omitempty"`
+	FailReason           uint32   `protobuf:"fixed32,3,opt,name=fail_reason,json=failReason,proto3" json:"fail_reason,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *OnuActivationFailureIndication) Reset()         { *m = OnuActivationFailureIndication{} }
+func (m *OnuActivationFailureIndication) String() string { return proto.CompactTextString(m) }
+func (*OnuActivationFailureIndication) ProtoMessage()    {}
+func (*OnuActivationFailureIndication) Descriptor() ([]byte, []int) {
+	return fileDescriptor_c072e7aa0dfd74d5, []int{35}
+}
+
+func (m *OnuActivationFailureIndication) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_OnuActivationFailureIndication.Unmarshal(m, b)
+}
+func (m *OnuActivationFailureIndication) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_OnuActivationFailureIndication.Marshal(b, m, deterministic)
+}
+func (m *OnuActivationFailureIndication) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_OnuActivationFailureIndication.Merge(m, src)
+}
+func (m *OnuActivationFailureIndication) XXX_Size() int {
+	return xxx_messageInfo_OnuActivationFailureIndication.Size(m)
+}
+func (m *OnuActivationFailureIndication) XXX_DiscardUnknown() {
+	xxx_messageInfo_OnuActivationFailureIndication.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_OnuActivationFailureIndication proto.InternalMessageInfo
+
+func (m *OnuActivationFailureIndication) GetIntfId() uint32 {
+	if m != nil {
+		return m.IntfId
+	}
+	return 0
+}
+
+func (m *OnuActivationFailureIndication) GetOnuId() uint32 {
+	if m != nil {
+		return m.OnuId
+	}
+	return 0
+}
+
+func (m *OnuActivationFailureIndication) GetFailReason() uint32 {
+	if m != nil {
+		return m.FailReason
+	}
+	return 0
+}
+
+type OnuLossOfKeySyncFailureIndication struct {
+	IntfId               uint32   `protobuf:"fixed32,1,opt,name=intf_id,json=intfId,proto3" json:"intf_id,omitempty"`
+	OnuId                uint32   `protobuf:"fixed32,2,opt,name=onu_id,json=onuId,proto3" json:"onu_id,omitempty"`
+	Status               string   `protobuf:"bytes,3,opt,name=status,proto3" json:"status,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *OnuLossOfKeySyncFailureIndication) Reset()         { *m = OnuLossOfKeySyncFailureIndication{} }
+func (m *OnuLossOfKeySyncFailureIndication) String() string { return proto.CompactTextString(m) }
+func (*OnuLossOfKeySyncFailureIndication) ProtoMessage()    {}
+func (*OnuLossOfKeySyncFailureIndication) Descriptor() ([]byte, []int) {
+	return fileDescriptor_c072e7aa0dfd74d5, []int{36}
+}
+
+func (m *OnuLossOfKeySyncFailureIndication) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_OnuLossOfKeySyncFailureIndication.Unmarshal(m, b)
+}
+func (m *OnuLossOfKeySyncFailureIndication) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_OnuLossOfKeySyncFailureIndication.Marshal(b, m, deterministic)
+}
+func (m *OnuLossOfKeySyncFailureIndication) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_OnuLossOfKeySyncFailureIndication.Merge(m, src)
+}
+func (m *OnuLossOfKeySyncFailureIndication) XXX_Size() int {
+	return xxx_messageInfo_OnuLossOfKeySyncFailureIndication.Size(m)
+}
+func (m *OnuLossOfKeySyncFailureIndication) XXX_DiscardUnknown() {
+	xxx_messageInfo_OnuLossOfKeySyncFailureIndication.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_OnuLossOfKeySyncFailureIndication proto.InternalMessageInfo
+
+func (m *OnuLossOfKeySyncFailureIndication) GetIntfId() uint32 {
+	if m != nil {
+		return m.IntfId
+	}
+	return 0
+}
+
+func (m *OnuLossOfKeySyncFailureIndication) GetOnuId() uint32 {
+	if m != nil {
+		return m.OnuId
+	}
+	return 0
+}
+
+func (m *OnuLossOfKeySyncFailureIndication) GetStatus() string {
+	if m != nil {
+		return m.Status
+	}
+	return ""
+}
+
+type RdiErrorIndication struct {
+	RdiErrorCount        uint64   `protobuf:"fixed64,1,opt,name=rdi_error_count,json=rdiErrorCount,proto3" json:"rdi_error_count,omitempty"`
+	Status               string   `protobuf:"bytes,2,opt,name=status,proto3" json:"status,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *RdiErrorIndication) Reset()         { *m = RdiErrorIndication{} }
+func (m *RdiErrorIndication) String() string { return proto.CompactTextString(m) }
+func (*RdiErrorIndication) ProtoMessage()    {}
+func (*RdiErrorIndication) Descriptor() ([]byte, []int) {
+	return fileDescriptor_c072e7aa0dfd74d5, []int{37}
+}
+
+func (m *RdiErrorIndication) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_RdiErrorIndication.Unmarshal(m, b)
+}
+func (m *RdiErrorIndication) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_RdiErrorIndication.Marshal(b, m, deterministic)
+}
+func (m *RdiErrorIndication) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_RdiErrorIndication.Merge(m, src)
+}
+func (m *RdiErrorIndication) XXX_Size() int {
+	return xxx_messageInfo_RdiErrorIndication.Size(m)
+}
+func (m *RdiErrorIndication) XXX_DiscardUnknown() {
+	xxx_messageInfo_RdiErrorIndication.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_RdiErrorIndication proto.InternalMessageInfo
+
+func (m *RdiErrorIndication) GetRdiErrorCount() uint64 {
+	if m != nil {
+		return m.RdiErrorCount
+	}
+	return 0
+}
+
+func (m *RdiErrorIndication) GetStatus() string {
+	if m != nil {
+		return m.Status
+	}
+	return ""
+}
+
+type OnuItuPonStatsIndication struct {
+	IntfId uint32 `protobuf:"fixed32,1,opt,name=intf_id,json=intfId,proto3" json:"intf_id,omitempty"`
+	OnuId  uint32 `protobuf:"fixed32,2,opt,name=onu_id,json=onuId,proto3" json:"onu_id,omitempty"`
+	// Types that are valid to be assigned to Stats:
+	//	*OnuItuPonStatsIndication_RdiErrorInd
+	Stats                isOnuItuPonStatsIndication_Stats `protobuf_oneof:"stats"`
+	XXX_NoUnkeyedLiteral struct{}                         `json:"-"`
+	XXX_unrecognized     []byte                           `json:"-"`
+	XXX_sizecache        int32                            `json:"-"`
+}
+
+func (m *OnuItuPonStatsIndication) Reset()         { *m = OnuItuPonStatsIndication{} }
+func (m *OnuItuPonStatsIndication) String() string { return proto.CompactTextString(m) }
+func (*OnuItuPonStatsIndication) ProtoMessage()    {}
+func (*OnuItuPonStatsIndication) Descriptor() ([]byte, []int) {
+	return fileDescriptor_c072e7aa0dfd74d5, []int{38}
+}
+
+func (m *OnuItuPonStatsIndication) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_OnuItuPonStatsIndication.Unmarshal(m, b)
+}
+func (m *OnuItuPonStatsIndication) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_OnuItuPonStatsIndication.Marshal(b, m, deterministic)
+}
+func (m *OnuItuPonStatsIndication) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_OnuItuPonStatsIndication.Merge(m, src)
+}
+func (m *OnuItuPonStatsIndication) XXX_Size() int {
+	return xxx_messageInfo_OnuItuPonStatsIndication.Size(m)
+}
+func (m *OnuItuPonStatsIndication) XXX_DiscardUnknown() {
+	xxx_messageInfo_OnuItuPonStatsIndication.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_OnuItuPonStatsIndication proto.InternalMessageInfo
+
+func (m *OnuItuPonStatsIndication) GetIntfId() uint32 {
+	if m != nil {
+		return m.IntfId
+	}
+	return 0
+}
+
+func (m *OnuItuPonStatsIndication) GetOnuId() uint32 {
+	if m != nil {
+		return m.OnuId
+	}
+	return 0
+}
+
+type isOnuItuPonStatsIndication_Stats interface {
+	isOnuItuPonStatsIndication_Stats()
+}
+
+type OnuItuPonStatsIndication_RdiErrorInd struct {
+	RdiErrorInd *RdiErrorIndication `protobuf:"bytes,3,opt,name=rdi_error_ind,json=rdiErrorInd,proto3,oneof"`
+}
+
+func (*OnuItuPonStatsIndication_RdiErrorInd) isOnuItuPonStatsIndication_Stats() {}
+
+func (m *OnuItuPonStatsIndication) GetStats() isOnuItuPonStatsIndication_Stats {
+	if m != nil {
+		return m.Stats
+	}
+	return nil
+}
+
+func (m *OnuItuPonStatsIndication) GetRdiErrorInd() *RdiErrorIndication {
+	if x, ok := m.GetStats().(*OnuItuPonStatsIndication_RdiErrorInd); ok {
+		return x.RdiErrorInd
+	}
+	return nil
+}
+
+// XXX_OneofWrappers is for the internal use of the proto package.
+func (*OnuItuPonStatsIndication) XXX_OneofWrappers() []interface{} {
+	return []interface{}{
+		(*OnuItuPonStatsIndication_RdiErrorInd)(nil),
+	}
+}
+
+type OnuProcessingErrorIndication struct {
+	IntfId               uint32   `protobuf:"fixed32,1,opt,name=intf_id,json=intfId,proto3" json:"intf_id,omitempty"`
+	OnuId                uint32   `protobuf:"fixed32,2,opt,name=onu_id,json=onuId,proto3" json:"onu_id,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *OnuProcessingErrorIndication) Reset()         { *m = OnuProcessingErrorIndication{} }
+func (m *OnuProcessingErrorIndication) String() string { return proto.CompactTextString(m) }
+func (*OnuProcessingErrorIndication) ProtoMessage()    {}
+func (*OnuProcessingErrorIndication) Descriptor() ([]byte, []int) {
+	return fileDescriptor_c072e7aa0dfd74d5, []int{39}
+}
+
+func (m *OnuProcessingErrorIndication) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_OnuProcessingErrorIndication.Unmarshal(m, b)
+}
+func (m *OnuProcessingErrorIndication) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_OnuProcessingErrorIndication.Marshal(b, m, deterministic)
+}
+func (m *OnuProcessingErrorIndication) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_OnuProcessingErrorIndication.Merge(m, src)
+}
+func (m *OnuProcessingErrorIndication) XXX_Size() int {
+	return xxx_messageInfo_OnuProcessingErrorIndication.Size(m)
+}
+func (m *OnuProcessingErrorIndication) XXX_DiscardUnknown() {
+	xxx_messageInfo_OnuProcessingErrorIndication.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_OnuProcessingErrorIndication proto.InternalMessageInfo
+
+func (m *OnuProcessingErrorIndication) GetIntfId() uint32 {
+	if m != nil {
+		return m.IntfId
+	}
+	return 0
+}
+
+func (m *OnuProcessingErrorIndication) GetOnuId() uint32 {
+	if m != nil {
+		return m.OnuId
+	}
+	return 0
+}
+
+type OnuDeactivationFailureIndication struct {
+	IntfId               uint32   `protobuf:"fixed32,1,opt,name=intf_id,json=intfId,proto3" json:"intf_id,omitempty"`
+	OnuId                uint32   `protobuf:"fixed32,2,opt,name=onu_id,json=onuId,proto3" json:"onu_id,omitempty"`
+	Status               string   `protobuf:"bytes,3,opt,name=status,proto3" json:"status,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *OnuDeactivationFailureIndication) Reset()         { *m = OnuDeactivationFailureIndication{} }
+func (m *OnuDeactivationFailureIndication) String() string { return proto.CompactTextString(m) }
+func (*OnuDeactivationFailureIndication) ProtoMessage()    {}
+func (*OnuDeactivationFailureIndication) Descriptor() ([]byte, []int) {
+	return fileDescriptor_c072e7aa0dfd74d5, []int{40}
+}
+
+func (m *OnuDeactivationFailureIndication) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_OnuDeactivationFailureIndication.Unmarshal(m, b)
+}
+func (m *OnuDeactivationFailureIndication) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_OnuDeactivationFailureIndication.Marshal(b, m, deterministic)
+}
+func (m *OnuDeactivationFailureIndication) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_OnuDeactivationFailureIndication.Merge(m, src)
+}
+func (m *OnuDeactivationFailureIndication) XXX_Size() int {
+	return xxx_messageInfo_OnuDeactivationFailureIndication.Size(m)
+}
+func (m *OnuDeactivationFailureIndication) XXX_DiscardUnknown() {
+	xxx_messageInfo_OnuDeactivationFailureIndication.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_OnuDeactivationFailureIndication proto.InternalMessageInfo
+
+func (m *OnuDeactivationFailureIndication) GetIntfId() uint32 {
+	if m != nil {
+		return m.IntfId
+	}
+	return 0
+}
+
+func (m *OnuDeactivationFailureIndication) GetOnuId() uint32 {
+	if m != nil {
+		return m.OnuId
+	}
+	return 0
+}
+
+func (m *OnuDeactivationFailureIndication) GetStatus() string {
+	if m != nil {
+		return m.Status
+	}
+	return ""
+}
+
+type OnuRemoteDefectIndication struct {
+	IntfId               uint32   `protobuf:"fixed32,1,opt,name=intf_id,json=intfId,proto3" json:"intf_id,omitempty"`
+	OnuId                uint32   `protobuf:"fixed32,2,opt,name=onu_id,json=onuId,proto3" json:"onu_id,omitempty"`
+	RdiErrors            uint64   `protobuf:"fixed64,3,opt,name=rdi_errors,json=rdiErrors,proto3" json:"rdi_errors,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *OnuRemoteDefectIndication) Reset()         { *m = OnuRemoteDefectIndication{} }
+func (m *OnuRemoteDefectIndication) String() string { return proto.CompactTextString(m) }
+func (*OnuRemoteDefectIndication) ProtoMessage()    {}
+func (*OnuRemoteDefectIndication) Descriptor() ([]byte, []int) {
+	return fileDescriptor_c072e7aa0dfd74d5, []int{41}
+}
+
+func (m *OnuRemoteDefectIndication) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_OnuRemoteDefectIndication.Unmarshal(m, b)
+}
+func (m *OnuRemoteDefectIndication) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_OnuRemoteDefectIndication.Marshal(b, m, deterministic)
+}
+func (m *OnuRemoteDefectIndication) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_OnuRemoteDefectIndication.Merge(m, src)
+}
+func (m *OnuRemoteDefectIndication) XXX_Size() int {
+	return xxx_messageInfo_OnuRemoteDefectIndication.Size(m)
+}
+func (m *OnuRemoteDefectIndication) XXX_DiscardUnknown() {
+	xxx_messageInfo_OnuRemoteDefectIndication.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_OnuRemoteDefectIndication proto.InternalMessageInfo
+
+func (m *OnuRemoteDefectIndication) GetIntfId() uint32 {
+	if m != nil {
+		return m.IntfId
+	}
+	return 0
+}
+
+func (m *OnuRemoteDefectIndication) GetOnuId() uint32 {
+	if m != nil {
+		return m.OnuId
+	}
+	return 0
+}
+
+func (m *OnuRemoteDefectIndication) GetRdiErrors() uint64 {
+	if m != nil {
+		return m.RdiErrors
+	}
+	return 0
+}
+
+type OnuLossOfGEMChannelDelineationIndication struct {
+	IntfId               uint32   `protobuf:"fixed32,1,opt,name=intf_id,json=intfId,proto3" json:"intf_id,omitempty"`
+	OnuId                uint32   `protobuf:"fixed32,2,opt,name=onu_id,json=onuId,proto3" json:"onu_id,omitempty"`
+	Status               string   `protobuf:"bytes,3,opt,name=status,proto3" json:"status,omitempty"`
+	DelineationErrors    uint32   `protobuf:"fixed32,4,opt,name=delineation_errors,json=delineationErrors,proto3" json:"delineation_errors,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *OnuLossOfGEMChannelDelineationIndication) Reset() {
+	*m = OnuLossOfGEMChannelDelineationIndication{}
+}
+func (m *OnuLossOfGEMChannelDelineationIndication) String() string { return proto.CompactTextString(m) }
+func (*OnuLossOfGEMChannelDelineationIndication) ProtoMessage()    {}
+func (*OnuLossOfGEMChannelDelineationIndication) Descriptor() ([]byte, []int) {
+	return fileDescriptor_c072e7aa0dfd74d5, []int{42}
+}
+
+func (m *OnuLossOfGEMChannelDelineationIndication) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_OnuLossOfGEMChannelDelineationIndication.Unmarshal(m, b)
+}
+func (m *OnuLossOfGEMChannelDelineationIndication) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_OnuLossOfGEMChannelDelineationIndication.Marshal(b, m, deterministic)
+}
+func (m *OnuLossOfGEMChannelDelineationIndication) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_OnuLossOfGEMChannelDelineationIndication.Merge(m, src)
+}
+func (m *OnuLossOfGEMChannelDelineationIndication) XXX_Size() int {
+	return xxx_messageInfo_OnuLossOfGEMChannelDelineationIndication.Size(m)
+}
+func (m *OnuLossOfGEMChannelDelineationIndication) XXX_DiscardUnknown() {
+	xxx_messageInfo_OnuLossOfGEMChannelDelineationIndication.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_OnuLossOfGEMChannelDelineationIndication proto.InternalMessageInfo
+
+func (m *OnuLossOfGEMChannelDelineationIndication) GetIntfId() uint32 {
+	if m != nil {
+		return m.IntfId
+	}
+	return 0
+}
+
+func (m *OnuLossOfGEMChannelDelineationIndication) GetOnuId() uint32 {
+	if m != nil {
+		return m.OnuId
+	}
+	return 0
+}
+
+func (m *OnuLossOfGEMChannelDelineationIndication) GetStatus() string {
+	if m != nil {
+		return m.Status
+	}
+	return ""
+}
+
+func (m *OnuLossOfGEMChannelDelineationIndication) GetDelineationErrors() uint32 {
+	if m != nil {
+		return m.DelineationErrors
+	}
+	return 0
+}
+
+type OnuPhysicalEquipmentErrorIndication struct {
+	IntfId               uint32   `protobuf:"fixed32,1,opt,name=intf_id,json=intfId,proto3" json:"intf_id,omitempty"`
+	OnuId                uint32   `protobuf:"fixed32,2,opt,name=onu_id,json=onuId,proto3" json:"onu_id,omitempty"`
+	Status               string   `protobuf:"bytes,3,opt,name=status,proto3" json:"status,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *OnuPhysicalEquipmentErrorIndication) Reset()         { *m = OnuPhysicalEquipmentErrorIndication{} }
+func (m *OnuPhysicalEquipmentErrorIndication) String() string { return proto.CompactTextString(m) }
+func (*OnuPhysicalEquipmentErrorIndication) ProtoMessage()    {}
+func (*OnuPhysicalEquipmentErrorIndication) Descriptor() ([]byte, []int) {
+	return fileDescriptor_c072e7aa0dfd74d5, []int{43}
+}
+
+func (m *OnuPhysicalEquipmentErrorIndication) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_OnuPhysicalEquipmentErrorIndication.Unmarshal(m, b)
+}
+func (m *OnuPhysicalEquipmentErrorIndication) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_OnuPhysicalEquipmentErrorIndication.Marshal(b, m, deterministic)
+}
+func (m *OnuPhysicalEquipmentErrorIndication) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_OnuPhysicalEquipmentErrorIndication.Merge(m, src)
+}
+func (m *OnuPhysicalEquipmentErrorIndication) XXX_Size() int {
+	return xxx_messageInfo_OnuPhysicalEquipmentErrorIndication.Size(m)
+}
+func (m *OnuPhysicalEquipmentErrorIndication) XXX_DiscardUnknown() {
+	xxx_messageInfo_OnuPhysicalEquipmentErrorIndication.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_OnuPhysicalEquipmentErrorIndication proto.InternalMessageInfo
+
+func (m *OnuPhysicalEquipmentErrorIndication) GetIntfId() uint32 {
+	if m != nil {
+		return m.IntfId
+	}
+	return 0
+}
+
+func (m *OnuPhysicalEquipmentErrorIndication) GetOnuId() uint32 {
+	if m != nil {
+		return m.OnuId
+	}
+	return 0
+}
+
+func (m *OnuPhysicalEquipmentErrorIndication) GetStatus() string {
+	if m != nil {
+		return m.Status
+	}
+	return ""
+}
+
+type OnuLossOfAcknowledgementIndication struct {
+	IntfId               uint32   `protobuf:"fixed32,1,opt,name=intf_id,json=intfId,proto3" json:"intf_id,omitempty"`
+	OnuId                uint32   `protobuf:"fixed32,2,opt,name=onu_id,json=onuId,proto3" json:"onu_id,omitempty"`
+	Status               string   `protobuf:"bytes,3,opt,name=status,proto3" json:"status,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *OnuLossOfAcknowledgementIndication) Reset()         { *m = OnuLossOfAcknowledgementIndication{} }
+func (m *OnuLossOfAcknowledgementIndication) String() string { return proto.CompactTextString(m) }
+func (*OnuLossOfAcknowledgementIndication) ProtoMessage()    {}
+func (*OnuLossOfAcknowledgementIndication) Descriptor() ([]byte, []int) {
+	return fileDescriptor_c072e7aa0dfd74d5, []int{44}
+}
+
+func (m *OnuLossOfAcknowledgementIndication) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_OnuLossOfAcknowledgementIndication.Unmarshal(m, b)
+}
+func (m *OnuLossOfAcknowledgementIndication) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_OnuLossOfAcknowledgementIndication.Marshal(b, m, deterministic)
+}
+func (m *OnuLossOfAcknowledgementIndication) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_OnuLossOfAcknowledgementIndication.Merge(m, src)
+}
+func (m *OnuLossOfAcknowledgementIndication) XXX_Size() int {
+	return xxx_messageInfo_OnuLossOfAcknowledgementIndication.Size(m)
+}
+func (m *OnuLossOfAcknowledgementIndication) XXX_DiscardUnknown() {
+	xxx_messageInfo_OnuLossOfAcknowledgementIndication.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_OnuLossOfAcknowledgementIndication proto.InternalMessageInfo
+
+func (m *OnuLossOfAcknowledgementIndication) GetIntfId() uint32 {
+	if m != nil {
+		return m.IntfId
+	}
+	return 0
+}
+
+func (m *OnuLossOfAcknowledgementIndication) GetOnuId() uint32 {
+	if m != nil {
+		return m.OnuId
+	}
+	return 0
+}
+
+func (m *OnuLossOfAcknowledgementIndication) GetStatus() string {
+	if m != nil {
+		return m.Status
+	}
+	return ""
+}
+
+type OnuDifferentialReachExceededIndication struct {
+	IntfId               uint32   `protobuf:"fixed32,1,opt,name=intf_id,json=intfId,proto3" json:"intf_id,omitempty"`
+	OnuId                uint32   `protobuf:"fixed32,2,opt,name=onu_id,json=onuId,proto3" json:"onu_id,omitempty"`
+	Status               string   `protobuf:"bytes,3,opt,name=status,proto3" json:"status,omitempty"`
+	Distance             uint32   `protobuf:"fixed32,4,opt,name=distance,proto3" json:"distance,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *OnuDifferentialReachExceededIndication) Reset() {
+	*m = OnuDifferentialReachExceededIndication{}
+}
+func (m *OnuDifferentialReachExceededIndication) String() string { return proto.CompactTextString(m) }
+func (*OnuDifferentialReachExceededIndication) ProtoMessage()    {}
+func (*OnuDifferentialReachExceededIndication) Descriptor() ([]byte, []int) {
+	return fileDescriptor_c072e7aa0dfd74d5, []int{45}
+}
+
+func (m *OnuDifferentialReachExceededIndication) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_OnuDifferentialReachExceededIndication.Unmarshal(m, b)
+}
+func (m *OnuDifferentialReachExceededIndication) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_OnuDifferentialReachExceededIndication.Marshal(b, m, deterministic)
+}
+func (m *OnuDifferentialReachExceededIndication) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_OnuDifferentialReachExceededIndication.Merge(m, src)
+}
+func (m *OnuDifferentialReachExceededIndication) XXX_Size() int {
+	return xxx_messageInfo_OnuDifferentialReachExceededIndication.Size(m)
+}
+func (m *OnuDifferentialReachExceededIndication) XXX_DiscardUnknown() {
+	xxx_messageInfo_OnuDifferentialReachExceededIndication.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_OnuDifferentialReachExceededIndication proto.InternalMessageInfo
+
+func (m *OnuDifferentialReachExceededIndication) GetIntfId() uint32 {
+	if m != nil {
+		return m.IntfId
+	}
+	return 0
+}
+
+func (m *OnuDifferentialReachExceededIndication) GetOnuId() uint32 {
+	if m != nil {
+		return m.OnuId
+	}
+	return 0
+}
+
+func (m *OnuDifferentialReachExceededIndication) GetStatus() string {
+	if m != nil {
+		return m.Status
+	}
+	return ""
+}
+
+func (m *OnuDifferentialReachExceededIndication) GetDistance() uint32 {
+	if m != nil {
+		return m.Distance
+	}
+	return 0
+}
+
+type GroupMember struct {
+	InterfaceId          uint32                    `protobuf:"varint,1,opt,name=interface_id,json=interfaceId,proto3" json:"interface_id,omitempty"`
+	InterfaceType        GroupMember_InterfaceType `protobuf:"varint,2,opt,name=interface_type,json=interfaceType,proto3,enum=openolt.GroupMember_InterfaceType" json:"interface_type,omitempty"`
+	GemPortId            uint32                    `protobuf:"varint,3,opt,name=gem_port_id,json=gemPortId,proto3" json:"gem_port_id,omitempty"`
+	Priority             uint32                    `protobuf:"varint,4,opt,name=priority,proto3" json:"priority,omitempty"`
+	XXX_NoUnkeyedLiteral struct{}                  `json:"-"`
+	XXX_unrecognized     []byte                    `json:"-"`
+	XXX_sizecache        int32                     `json:"-"`
+}
+
+func (m *GroupMember) Reset()         { *m = GroupMember{} }
+func (m *GroupMember) String() string { return proto.CompactTextString(m) }
+func (*GroupMember) ProtoMessage()    {}
+func (*GroupMember) Descriptor() ([]byte, []int) {
+	return fileDescriptor_c072e7aa0dfd74d5, []int{46}
+}
+
+func (m *GroupMember) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_GroupMember.Unmarshal(m, b)
+}
+func (m *GroupMember) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_GroupMember.Marshal(b, m, deterministic)
+}
+func (m *GroupMember) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_GroupMember.Merge(m, src)
+}
+func (m *GroupMember) XXX_Size() int {
+	return xxx_messageInfo_GroupMember.Size(m)
+}
+func (m *GroupMember) XXX_DiscardUnknown() {
+	xxx_messageInfo_GroupMember.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_GroupMember proto.InternalMessageInfo
+
+func (m *GroupMember) GetInterfaceId() uint32 {
+	if m != nil {
+		return m.InterfaceId
+	}
+	return 0
+}
+
+func (m *GroupMember) GetInterfaceType() GroupMember_InterfaceType {
+	if m != nil {
+		return m.InterfaceType
+	}
+	return GroupMember_PON
+}
+
+func (m *GroupMember) GetGemPortId() uint32 {
+	if m != nil {
+		return m.GemPortId
+	}
+	return 0
+}
+
+func (m *GroupMember) GetPriority() uint32 {
+	if m != nil {
+		return m.Priority
+	}
+	return 0
+}
+
+type Group struct {
+	GroupId              uint32                    `protobuf:"varint,1,opt,name=group_id,json=groupId,proto3" json:"group_id,omitempty"`
+	Command              Group_GroupMembersCommand `protobuf:"varint,2,opt,name=command,proto3,enum=openolt.Group_GroupMembersCommand" json:"command,omitempty"`
+	Members              []*GroupMember            `protobuf:"bytes,3,rep,name=members,proto3" json:"members,omitempty"`
+	Action               *Action                   `protobuf:"bytes,4,opt,name=action,proto3" json:"action,omitempty"`
+	XXX_NoUnkeyedLiteral struct{}                  `json:"-"`
+	XXX_unrecognized     []byte                    `json:"-"`
+	XXX_sizecache        int32                     `json:"-"`
+}
+
+func (m *Group) Reset()         { *m = Group{} }
+func (m *Group) String() string { return proto.CompactTextString(m) }
+func (*Group) ProtoMessage()    {}
+func (*Group) Descriptor() ([]byte, []int) {
+	return fileDescriptor_c072e7aa0dfd74d5, []int{47}
+}
+
+func (m *Group) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_Group.Unmarshal(m, b)
+}
+func (m *Group) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_Group.Marshal(b, m, deterministic)
+}
+func (m *Group) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_Group.Merge(m, src)
+}
+func (m *Group) XXX_Size() int {
+	return xxx_messageInfo_Group.Size(m)
+}
+func (m *Group) XXX_DiscardUnknown() {
+	xxx_messageInfo_Group.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Group proto.InternalMessageInfo
+
+func (m *Group) GetGroupId() uint32 {
+	if m != nil {
+		return m.GroupId
+	}
+	return 0
+}
+
+func (m *Group) GetCommand() Group_GroupMembersCommand {
+	if m != nil {
+		return m.Command
+	}
+	return Group_ADD_MEMBERS
+}
+
+func (m *Group) GetMembers() []*GroupMember {
+	if m != nil {
+		return m.Members
+	}
+	return nil
+}
+
+func (m *Group) GetAction() *Action {
+	if m != nil {
+		return m.Action
+	}
+	return nil
+}
+
+type ValueParam struct {
+	Onu                  *Onu                     `protobuf:"bytes,1,opt,name=onu,proto3" json:"onu,omitempty"`
+	Value                extension.ValueType_Type `protobuf:"varint,2,opt,name=value,proto3,enum=extension.ValueType_Type" json:"value,omitempty"`
+	XXX_NoUnkeyedLiteral struct{}                 `json:"-"`
+	XXX_unrecognized     []byte                   `json:"-"`
+	XXX_sizecache        int32                    `json:"-"`
+}
+
+func (m *ValueParam) Reset()         { *m = ValueParam{} }
+func (m *ValueParam) String() string { return proto.CompactTextString(m) }
+func (*ValueParam) ProtoMessage()    {}
+func (*ValueParam) Descriptor() ([]byte, []int) {
+	return fileDescriptor_c072e7aa0dfd74d5, []int{48}
+}
+
+func (m *ValueParam) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_ValueParam.Unmarshal(m, b)
+}
+func (m *ValueParam) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_ValueParam.Marshal(b, m, deterministic)
+}
+func (m *ValueParam) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_ValueParam.Merge(m, src)
+}
+func (m *ValueParam) XXX_Size() int {
+	return xxx_messageInfo_ValueParam.Size(m)
+}
+func (m *ValueParam) XXX_DiscardUnknown() {
+	xxx_messageInfo_ValueParam.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_ValueParam proto.InternalMessageInfo
+
+func (m *ValueParam) GetOnu() *Onu {
+	if m != nil {
+		return m.Onu
+	}
+	return nil
+}
+
+func (m *ValueParam) GetValue() extension.ValueType_Type {
+	if m != nil {
+		return m.Value
+	}
+	return extension.ValueType_EMPTY
+}
+
+type PonRxPowerData struct {
+	IntfId               uint32                                   `protobuf:"fixed32,1,opt,name=intf_id,json=intfId,proto3" json:"intf_id,omitempty"`
+	OnuId                uint32                                   `protobuf:"fixed32,2,opt,name=onu_id,json=onuId,proto3" json:"onu_id,omitempty"`
+	Status               string                                   `protobuf:"bytes,3,opt,name=status,proto3" json:"status,omitempty"`
+	FailReason           PonRxPowerData_RssiMeasurementFailReason `protobuf:"varint,4,opt,name=fail_reason,json=failReason,proto3,enum=openolt.PonRxPowerData_RssiMeasurementFailReason" json:"fail_reason,omitempty"`
+	RxPowerMeanDbm       float64                                  `protobuf:"fixed64,5,opt,name=rx_power_mean_dbm,json=rxPowerMeanDbm,proto3" json:"rx_power_mean_dbm,omitempty"`
+	XXX_NoUnkeyedLiteral struct{}                                 `json:"-"`
+	XXX_unrecognized     []byte                                   `json:"-"`
+	XXX_sizecache        int32                                    `json:"-"`
+}
+
+func (m *PonRxPowerData) Reset()         { *m = PonRxPowerData{} }
+func (m *PonRxPowerData) String() string { return proto.CompactTextString(m) }
+func (*PonRxPowerData) ProtoMessage()    {}
+func (*PonRxPowerData) Descriptor() ([]byte, []int) {
+	return fileDescriptor_c072e7aa0dfd74d5, []int{49}
+}
+
+func (m *PonRxPowerData) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_PonRxPowerData.Unmarshal(m, b)
+}
+func (m *PonRxPowerData) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_PonRxPowerData.Marshal(b, m, deterministic)
+}
+func (m *PonRxPowerData) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_PonRxPowerData.Merge(m, src)
+}
+func (m *PonRxPowerData) XXX_Size() int {
+	return xxx_messageInfo_PonRxPowerData.Size(m)
+}
+func (m *PonRxPowerData) XXX_DiscardUnknown() {
+	xxx_messageInfo_PonRxPowerData.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_PonRxPowerData proto.InternalMessageInfo
+
+func (m *PonRxPowerData) GetIntfId() uint32 {
+	if m != nil {
+		return m.IntfId
+	}
+	return 0
+}
+
+func (m *PonRxPowerData) GetOnuId() uint32 {
+	if m != nil {
+		return m.OnuId
+	}
+	return 0
+}
+
+func (m *PonRxPowerData) GetStatus() string {
+	if m != nil {
+		return m.Status
+	}
+	return ""
+}
+
+func (m *PonRxPowerData) GetFailReason() PonRxPowerData_RssiMeasurementFailReason {
+	if m != nil {
+		return m.FailReason
+	}
+	return PonRxPowerData_FAIL_REASON_NONE
+}
+
+func (m *PonRxPowerData) GetRxPowerMeanDbm() float64 {
+	if m != nil {
+		return m.RxPowerMeanDbm
+	}
+	return 0
+}
+
+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_c072e7aa0dfd74d5, []int{50}
+}
+
+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.RegisterEnum("openolt.OnuIndication_ActivationFailReason", OnuIndication_ActivationFailReason_name, OnuIndication_ActivationFailReason_value)
+	proto.RegisterEnum("openolt.DeviceInfo_DeviceResourceRanges_Pool_PoolType", DeviceInfo_DeviceResourceRanges_Pool_PoolType_name, DeviceInfo_DeviceResourceRanges_Pool_PoolType_value)
+	proto.RegisterEnum("openolt.DeviceInfo_DeviceResourceRanges_Pool_SharingType", DeviceInfo_DeviceResourceRanges_Pool_SharingType_name, DeviceInfo_DeviceResourceRanges_Pool_SharingType_value)
+	proto.RegisterEnum("openolt.GroupMember_InterfaceType", GroupMember_InterfaceType_name, GroupMember_InterfaceType_value)
+	proto.RegisterEnum("openolt.Group_GroupMembersCommand", Group_GroupMembersCommand_name, Group_GroupMembersCommand_value)
+	proto.RegisterEnum("openolt.PonRxPowerData_RssiMeasurementFailReason", PonRxPowerData_RssiMeasurementFailReason_name, PonRxPowerData_RssiMeasurementFailReason_value)
+	proto.RegisterType((*Indication)(nil), "openolt.Indication")
+	proto.RegisterType((*AlarmIndication)(nil), "openolt.AlarmIndication")
+	proto.RegisterType((*OltIndication)(nil), "openolt.OltIndication")
+	proto.RegisterType((*IntfIndication)(nil), "openolt.IntfIndication")
+	proto.RegisterType((*OnuDiscIndication)(nil), "openolt.OnuDiscIndication")
+	proto.RegisterType((*OnuIndication)(nil), "openolt.OnuIndication")
+	proto.RegisterType((*IntfOperIndication)(nil), "openolt.IntfOperIndication")
+	proto.RegisterType((*OmciIndication)(nil), "openolt.OmciIndication")
+	proto.RegisterType((*PacketIndication)(nil), "openolt.PacketIndication")
+	proto.RegisterType((*Interface)(nil), "openolt.Interface")
+	proto.RegisterType((*Heartbeat)(nil), "openolt.Heartbeat")
+	proto.RegisterType((*Onu)(nil), "openolt.Onu")
+	proto.RegisterType((*OnuLogicalDistance)(nil), "openolt.OnuLogicalDistance")
+	proto.RegisterType((*OmciMsg)(nil), "openolt.OmciMsg")
+	proto.RegisterType((*OnuPacket)(nil), "openolt.OnuPacket")
+	proto.RegisterType((*UplinkPacket)(nil), "openolt.UplinkPacket")
+	proto.RegisterType((*DeviceInfo)(nil), "openolt.DeviceInfo")
+	proto.RegisterType((*DeviceInfo_DeviceResourceRanges)(nil), "openolt.DeviceInfo.DeviceResourceRanges")
+	proto.RegisterType((*DeviceInfo_DeviceResourceRanges_Pool)(nil), "openolt.DeviceInfo.DeviceResourceRanges.Pool")
+	proto.RegisterType((*Classifier)(nil), "openolt.Classifier")
+	proto.RegisterType((*ActionCmd)(nil), "openolt.ActionCmd")
+	proto.RegisterType((*Action)(nil), "openolt.Action")
+	proto.RegisterType((*Flow)(nil), "openolt.Flow")
+	proto.RegisterMapType((map[uint32]bool)(nil), "openolt.Flow.GemportToAesEntry")
+	proto.RegisterMapType((map[uint32]uint32)(nil), "openolt.Flow.PbitToGemportEntry")
+	proto.RegisterType((*SerialNumber)(nil), "openolt.SerialNumber")
+	proto.RegisterType((*PortStatistics)(nil), "openolt.PortStatistics")
+	proto.RegisterType((*OnuStatistics)(nil), "openolt.OnuStatistics")
+	proto.RegisterType((*GemPortStatistics)(nil), "openolt.GemPortStatistics")
+	proto.RegisterType((*FlowStatistics)(nil), "openolt.FlowStatistics")
+	proto.RegisterType((*LosIndication)(nil), "openolt.LosIndication")
+	proto.RegisterType((*DyingGaspIndication)(nil), "openolt.DyingGaspIndication")
+	proto.RegisterType((*OnuAlarmIndication)(nil), "openolt.OnuAlarmIndication")
+	proto.RegisterType((*OnuStartupFailureIndication)(nil), "openolt.OnuStartupFailureIndication")
+	proto.RegisterType((*OnuSignalDegradeIndication)(nil), "openolt.OnuSignalDegradeIndication")
+	proto.RegisterType((*OnuDriftOfWindowIndication)(nil), "openolt.OnuDriftOfWindowIndication")
+	proto.RegisterType((*OnuLossOfOmciChannelIndication)(nil), "openolt.OnuLossOfOmciChannelIndication")
+	proto.RegisterType((*OnuSignalsFailureIndication)(nil), "openolt.OnuSignalsFailureIndication")
+	proto.RegisterType((*OnuTransmissionInterferenceWarning)(nil), "openolt.OnuTransmissionInterferenceWarning")
+	proto.RegisterType((*OnuActivationFailureIndication)(nil), "openolt.OnuActivationFailureIndication")
+	proto.RegisterType((*OnuLossOfKeySyncFailureIndication)(nil), "openolt.OnuLossOfKeySyncFailureIndication")
+	proto.RegisterType((*RdiErrorIndication)(nil), "openolt.RdiErrorIndication")
+	proto.RegisterType((*OnuItuPonStatsIndication)(nil), "openolt.OnuItuPonStatsIndication")
+	proto.RegisterType((*OnuProcessingErrorIndication)(nil), "openolt.OnuProcessingErrorIndication")
+	proto.RegisterType((*OnuDeactivationFailureIndication)(nil), "openolt.OnuDeactivationFailureIndication")
+	proto.RegisterType((*OnuRemoteDefectIndication)(nil), "openolt.OnuRemoteDefectIndication")
+	proto.RegisterType((*OnuLossOfGEMChannelDelineationIndication)(nil), "openolt.OnuLossOfGEMChannelDelineationIndication")
+	proto.RegisterType((*OnuPhysicalEquipmentErrorIndication)(nil), "openolt.OnuPhysicalEquipmentErrorIndication")
+	proto.RegisterType((*OnuLossOfAcknowledgementIndication)(nil), "openolt.OnuLossOfAcknowledgementIndication")
+	proto.RegisterType((*OnuDifferentialReachExceededIndication)(nil), "openolt.OnuDifferentialReachExceededIndication")
+	proto.RegisterType((*GroupMember)(nil), "openolt.GroupMember")
+	proto.RegisterType((*Group)(nil), "openolt.Group")
+	proto.RegisterType((*ValueParam)(nil), "openolt.ValueParam")
+	proto.RegisterType((*PonRxPowerData)(nil), "openolt.PonRxPowerData")
+	proto.RegisterType((*Empty)(nil), "openolt.Empty")
+}
+
+func init() { proto.RegisterFile("voltha_protos/openolt.proto", fileDescriptor_c072e7aa0dfd74d5) }
+
+var fileDescriptor_c072e7aa0dfd74d5 = []byte{
+	// 5260 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x5c, 0x4d, 0x70, 0x23, 0x49,
+	0x56, 0x6e, 0xd9, 0xb2, 0x24, 0x3f, 0x59, 0xb2, 0x9c, 0xfe, 0xb7, 0xfb, 0xc7, 0x5d, 0xf3, 0xd7,
+	0x3b, 0xbb, 0x63, 0xb7, 0x3d, 0xed, 0x9e, 0xee, 0x61, 0xd9, 0x1d, 0xb7, 0xad, 0xb6, 0x35, 0x63,
+	0x5b, 0xa6, 0xac, 0xee, 0x66, 0x77, 0x63, 0xa2, 0x28, 0x57, 0xa5, 0xe4, 0x5a, 0x97, 0x2a, 0x6b,
+	0xaa, 0x52, 0xfe, 0xe1, 0xb8, 0xc1, 0xc2, 0x85, 0xdb, 0x06, 0x44, 0x00, 0x07, 0x82, 0xe0, 0xca,
+	0x85, 0x1b, 0x11, 0x1c, 0x39, 0x70, 0xe1, 0xc6, 0x99, 0x1b, 0xc1, 0x85, 0x13, 0x17, 0x4e, 0x04,
+	0x41, 0xe4, 0xcb, 0xac, 0x3f, 0x49, 0x76, 0x77, 0x0f, 0x26, 0xb8, 0x74, 0x38, 0xdf, 0xfb, 0xde,
+	0xf7, 0xf2, 0xe7, 0xe5, 0xcb, 0x57, 0x55, 0xa9, 0x86, 0xe5, 0x73, 0xe6, 0xf2, 0x53, 0xd3, 0xf0,
+	0x03, 0xc6, 0x59, 0xb8, 0xc6, 0x7c, 0xea, 0x31, 0x97, 0xaf, 0x62, 0x93, 0x14, 0x55, 0x73, 0xe9,
+	0x6e, 0x87, 0xb1, 0x8e, 0x4b, 0xd7, 0x4c, 0xdf, 0x59, 0x33, 0x3d, 0x8f, 0x71, 0x93, 0x3b, 0xcc,
+	0x0b, 0x25, 0x6c, 0x69, 0x25, 0xcb, 0xc1, 0xa9, 0x75, 0x2a, 0xfe, 0x6e, 0x3b, 0x2e, 0x55, 0x88,
+	0xfb, 0x59, 0x04, 0xbd, 0xe4, 0x86, 0xc5, 0xbc, 0xb6, 0xd3, 0xb9, 0x56, 0x4f, 0xbd, 0x30, 0xf1,
+	0xa0, 0xfd, 0x53, 0x1e, 0xa0, 0xe1, 0xd9, 0x8e, 0x85, 0x7e, 0xc9, 0x3a, 0x14, 0x99, 0xcb, 0x0d,
+	0xc7, 0xb3, 0x17, 0x72, 0x2b, 0xb9, 0x47, 0xe5, 0x8d, 0xb9, 0xd5, 0xa8, 0xe3, 0x4d, 0x97, 0x27,
+	0xc0, 0xbd, 0x3b, 0x7a, 0x81, 0xa1, 0x80, 0x3c, 0x81, 0x92, 0xe3, 0xf1, 0x36, 0xda, 0x8c, 0xa0,
+	0xcd, 0x7c, 0x6c, 0xd3, 0xf0, 0x78, 0x3b, 0x63, 0x54, 0x74, 0xa4, 0x84, 0x6c, 0x41, 0x05, 0xad,
+	0x98, 0x4f, 0x03, 0x34, 0x1d, 0x45, 0xd3, 0xe5, 0x8c, 0x69, 0xd3, 0xa7, 0x41, 0xc6, 0xbc, 0xec,
+	0x24, 0x52, 0xf2, 0x13, 0x98, 0x60, 0x5e, 0xcf, 0xb0, 0x9d, 0xd0, 0x42, 0x86, 0x3c, 0x32, 0x2c,
+	0x25, 0x1d, 0xf6, 0x7a, 0x3b, 0x4e, 0x68, 0x65, 0x08, 0x80, 0xc5, 0x42, 0x1c, 0xab, 0xd7, 0x43,
+	0xd3, 0xb1, 0xfe, 0xb1, 0x7a, 0xbd, 0xbe, 0xb1, 0xa2, 0x40, 0x8c, 0x95, 0x75, 0x2d, 0x07, 0x6d,
+	0x0a, 0x7d, 0x63, 0x6d, 0x76, 0x2d, 0x27, 0x3b, 0x56, 0x26, 0x25, 0xe4, 0x09, 0x14, 0xfd, 0x33,
+	0x39, 0xa9, 0x45, 0x34, 0x5a, 0x8c, 0x8d, 0x8e, 0x4c, 0xeb, 0x8c, 0xf6, 0xcd, 0xab, 0x7f, 0x86,
+	0xf3, 0xfa, 0x0c, 0xc0, 0x67, 0x01, 0x37, 0x42, 0x6e, 0xf2, 0x70, 0xa1, 0xd4, 0xe7, 0xed, 0x88,
+	0x05, 0xfc, 0x58, 0x04, 0x4b, 0xc8, 0x1d, 0x2b, 0xdc, 0xbb, 0xa3, 0x8f, 0xfb, 0x4a, 0x12, 0x0a,
+	0xcb, 0xb6, 0xcb, 0x2e, 0x94, 0xe5, 0x78, 0x9f, 0xe5, 0x4b, 0x97, 0x5d, 0x64, 0x2d, 0xdb, 0x4a,
+	0x12, 0x92, 0x2f, 0x60, 0xdc, 0x74, 0xcd, 0xa0, 0x8b, 0x7d, 0x05, 0x34, 0x5c, 0x88, 0x0d, 0xb7,
+	0x84, 0x26, 0xd3, 0xd5, 0x92, 0xa9, 0x44, 0x2f, 0x0a, 0x90, 0xb7, 0x4d, 0x6e, 0x6a, 0xff, 0x5e,
+	0x81, 0xc9, 0x3e, 0x9c, 0x98, 0x67, 0x97, 0x85, 0x43, 0x63, 0x6a, 0x9f, 0x85, 0xd9, 0xb1, 0xbb,
+	0x28, 0x20, 0x3b, 0x50, 0xb5, 0xaf, 0x1c, 0xaf, 0x63, 0x74, 0xcc, 0xd0, 0x4f, 0x45, 0xd6, 0xdd,
+	0xd8, 0x72, 0x47, 0xa8, 0x77, 0xcd, 0xd0, 0xcf, 0xd8, 0x4f, 0xd8, 0x29, 0xb1, 0x88, 0x31, 0xb1,
+	0xc0, 0xc9, 0x88, 0xfa, 0x63, 0xac, 0xe9, 0xf5, 0x06, 0x07, 0x55, 0x66, 0x89, 0x94, 0xbc, 0x81,
+	0x19, 0x41, 0x11, 0x72, 0x33, 0xe0, 0x3d, 0xdf, 0x68, 0x9b, 0x8e, 0x9b, 0x8a, 0xb5, 0x0f, 0xd3,
+	0x4c, 0xc7, 0x12, 0xf3, 0xd2, 0x74, 0xdc, 0x5e, 0x40, 0x33, 0x94, 0x53, 0x2c, 0xa3, 0x16, 0xc4,
+	0x3f, 0x87, 0x39, 0x24, 0x76, 0x3a, 0x9e, 0xe9, 0x1a, 0x36, 0xed, 0x04, 0xa6, 0x4d, 0x53, 0xb1,
+	0xf8, 0x41, 0x86, 0x1a, 0x51, 0x3b, 0x12, 0x94, 0x61, 0x9e, 0x66, 0x83, 0x5a, 0xf2, 0x0b, 0x98,
+	0xc7, 0x8d, 0x11, 0x38, 0x6d, 0x6e, 0xb0, 0xb6, 0x71, 0xe1, 0x78, 0x36, 0xbb, 0x48, 0x05, 0x6d,
+	0x86, 0x7c, 0x47, 0xc0, 0x9a, 0xed, 0x37, 0x08, 0x1a, 0x20, 0xef, 0xd7, 0x92, 0x16, 0x88, 0xd1,
+	0x18, 0x2e, 0x0b, 0x43, 0x23, 0xde, 0x0b, 0x32, 0xac, 0x3f, 0x49, 0xd3, 0xee, 0xb3, 0x30, 0x6c,
+	0xb6, 0xc5, 0xa6, 0xd8, 0x3e, 0x35, 0x3d, 0x8f, 0xba, 0x19, 0xea, 0x2a, 0x53, 0x08, 0xb5, 0x45,
+	0xa2, 0x79, 0xc6, 0xa1, 0x84, 0xc9, 0x3c, 0x97, 0x86, 0xcc, 0xb3, 0xc4, 0x5c, 0x3b, 0xcf, 0x89,
+	0x5a, 0x10, 0x37, 0x65, 0x92, 0xe0, 0xce, 0x85, 0xec, 0xa9, 0xdc, 0x0d, 0x3f, 0x4c, 0x13, 0xb6,
+	0x02, 0xd3, 0x0b, 0xbb, 0x4e, 0x28, 0xd2, 0x62, 0xc3, 0xe3, 0x34, 0x68, 0xd3, 0x80, 0x7a, 0x16,
+	0x7d, 0x63, 0x06, 0x9e, 0xe3, 0x75, 0x54, 0xd6, 0x68, 0x39, 0x17, 0xd8, 0xd3, 0xdf, 0x93, 0x93,
+	0x6b, 0x5a, 0xdc, 0x39, 0x47, 0xbf, 0x49, 0x67, 0x61, 0x70, 0x16, 0xb6, 0x62, 0xd8, 0xb0, 0xfe,
+	0x8a, 0x31, 0x67, 0x11, 0xd2, 0xc3, 0x82, 0xf0, 0xe0, 0x07, 0xcc, 0xa2, 0x61, 0x28, 0x76, 0x01,
+	0x0d, 0x02, 0x26, 0xb3, 0x64, 0x19, 0x5d, 0x7c, 0x94, 0x76, 0x71, 0x14, 0xe3, 0xea, 0x02, 0x96,
+	0x71, 0x30, 0xcb, 0x86, 0xe9, 0x09, 0x85, 0xc5, 0x64, 0x0d, 0xdb, 0x46, 0x78, 0xe5, 0x59, 0xc9,
+	0x28, 0x26, 0xd0, 0xc5, 0xa7, 0x83, 0x6b, 0xf9, 0x0d, 0xbd, 0x3a, 0xbe, 0xf2, 0xac, 0xeb, 0x06,
+	0x22, 0x41, 0x11, 0x42, 0xb8, 0x79, 0x05, 0xb3, 0x98, 0x60, 0x79, 0xcf, 0xf0, 0x99, 0x27, 0xd3,
+	0x11, 0xba, 0xa8, 0xa0, 0x8b, 0x87, 0x99, 0x74, 0xcb, 0x7b, 0x47, 0xcc, 0xc3, 0x2c, 0x34, 0xb0,
+	0xa4, 0x59, 0x1d, 0x71, 0xe1, 0x2e, 0x86, 0x37, 0xed, 0x5b, 0x83, 0x5e, 0x20, 0x37, 0x50, 0x15,
+	0xd9, 0x7f, 0x90, 0x89, 0xf1, 0x14, 0x76, 0x58, 0xff, 0xc5, 0x74, 0x0c, 0xc7, 0x90, 0x37, 0x72,
+	0x10, 0x01, 0xed, 0x32, 0x4e, 0x0d, 0x9b, 0xb6, 0xa9, 0x25, 0x53, 0xf9, 0x24, 0xba, 0xd1, 0xd2,
+	0x6e, 0x74, 0x04, 0xed, 0x20, 0x26, 0xc3, 0x4f, 0xd8, 0x80, 0x92, 0x84, 0x72, 0x18, 0xb8, 0x08,
+	0x1d, 0xda, 0x35, 0x6c, 0xea, 0x3a, 0x1e, 0x95, 0xc3, 0x11, 0xfc, 0x35, 0xe4, 0x5f, 0x1f, 0x5c,
+	0x87, 0xdd, 0xfa, 0x81, 0xda, 0x52, 0x3b, 0x89, 0x49, 0xc6, 0xdd, 0x82, 0x5a, 0x8e, 0x5d, 0xda,
+	0xcd, 0x42, 0xc8, 0x39, 0xac, 0x60, 0x6c, 0x9d, 0x5e, 0x85, 0x8e, 0x65, 0xba, 0x06, 0xfd, 0xae,
+	0xe7, 0xf8, 0x5d, 0xea, 0xf1, 0x54, 0x8c, 0x4d, 0xa1, 0xe3, 0x1f, 0x65, 0x62, 0x4c, 0xe1, 0xeb,
+	0x11, 0x7c, 0x30, 0xd4, 0xc4, 0x60, 0xae, 0x85, 0x91, 0x5f, 0xc0, 0x74, 0x3a, 0xe2, 0x4c, 0xeb,
+	0x0c, 0x5d, 0x91, 0xc1, 0xdd, 0x28, 0xc7, 0xb8, 0x65, 0x9d, 0x79, 0xec, 0xc2, 0xa5, 0x76, 0x87,
+	0x0a, 0x9e, 0x8c, 0xa7, 0x49, 0x96, 0x42, 0x09, 0x72, 0x06, 0xcb, 0xb2, 0x10, 0x68, 0xb7, 0x8d,
+	0x80, 0x9a, 0xd6, 0xa9, 0x41, 0x2f, 0x2d, 0x4a, 0x6d, 0x6a, 0xa3, 0x93, 0x69, 0x74, 0xb2, 0x96,
+	0xad, 0x0b, 0xda, 0xb8, 0xc9, 0xb9, 0x63, 0xba, 0xba, 0xb0, 0xa8, 0x2b, 0x83, 0x8c, 0xa3, 0x79,
+	0x26, 0x91, 0xfd, 0x88, 0xf8, 0xb4, 0x5b, 0x85, 0x4a, 0xa6, 0x2a, 0x22, 0xf7, 0x00, 0xb0, 0xa0,
+	0x11, 0xa1, 0x4e, 0xf1, 0xb4, 0x1b, 0xd7, 0xc7, 0x85, 0x44, 0x04, 0x2f, 0xd5, 0xf6, 0xa0, 0x9a,
+	0xad, 0x88, 0xc8, 0x3c, 0x14, 0x65, 0xf1, 0x24, 0xcf, 0xc6, 0xa2, 0x5e, 0xc0, 0x02, 0xc9, 0xee,
+	0x63, 0x1a, 0xe9, 0x67, 0x3a, 0x85, 0xa9, 0x81, 0xf2, 0xe6, 0x7a, 0xb2, 0x2f, 0xa1, 0x12, 0xd2,
+	0xc0, 0x31, 0x5d, 0xc3, 0xeb, 0x75, 0x4f, 0x68, 0xa0, 0x4e, 0xd3, 0xd9, 0x78, 0x4a, 0x8e, 0x51,
+	0x7b, 0x88, 0x4a, 0x7d, 0x22, 0x4c, 0xb5, 0xb4, 0xdf, 0xe4, 0xa1, 0x92, 0x29, 0x87, 0xae, 0x77,
+	0x33, 0x0b, 0x05, 0xdc, 0xef, 0xf2, 0xb4, 0x2e, 0xea, 0x63, 0x62, 0xef, 0xf6, 0x0f, 0x65, 0xb4,
+	0x6f, 0x28, 0xe4, 0x01, 0x94, 0x4d, 0xbb, 0xeb, 0x78, 0x4a, 0x3f, 0x86, 0x7a, 0x40, 0x91, 0x04,
+	0x0c, 0xf4, 0x3e, 0xff, 0xce, 0xbd, 0x27, 0xfb, 0x50, 0xc6, 0xc4, 0x16, 0x50, 0x33, 0x64, 0x1e,
+	0x1e, 0x7f, 0xd5, 0x6c, 0xbc, 0x25, 0x03, 0x5b, 0xcd, 0xa6, 0x62, 0x1d, 0x4d, 0x74, 0x68, 0xc7,
+	0x7f, 0x6b, 0x7f, 0x34, 0x02, 0x33, 0xc3, 0x40, 0xe4, 0x03, 0x78, 0xd0, 0x3c, 0x7c, 0x65, 0x6c,
+	0x6d, 0xb7, 0x1a, 0xaf, 0xb7, 0x5a, 0x8d, 0xe6, 0xa1, 0xf1, 0x72, 0xab, 0xb1, 0x6f, 0xe8, 0xf5,
+	0xad, 0xe3, 0xe6, 0xa1, 0x71, 0xd8, 0x3c, 0xac, 0xd7, 0xee, 0x90, 0x8f, 0x41, 0xbb, 0x01, 0xa4,
+	0x6f, 0x1d, 0xee, 0x36, 0x0e, 0x77, 0x6b, 0x39, 0xf2, 0x14, 0x36, 0x6e, 0xc0, 0x1d, 0x6d, 0x1d,
+	0x1f, 0xbf, 0x69, 0xea, 0x3b, 0xc6, 0xd6, 0xab, 0xd6, 0x5e, 0xfd, 0xb0, 0xd5, 0xd8, 0x46, 0x4c,
+	0x6d, 0x84, 0x68, 0x70, 0xff, 0x06, 0xbb, 0xfd, 0xe6, 0x71, 0x6d, 0x94, 0x3c, 0x84, 0x7b, 0xc3,
+	0x30, 0x28, 0xdb, 0xdf, 0xd2, 0x0f, 0x6a, 0xf9, 0xeb, 0xc6, 0x72, 0xfc, 0xa6, 0xd1, 0xda, 0xde,
+	0x33, 0x9a, 0xaf, 0xeb, 0x7a, 0x6d, 0x4c, 0x3b, 0x07, 0x32, 0x58, 0xa0, 0x13, 0x02, 0x79, 0x7e,
+	0xe5, 0x47, 0x81, 0x8f, 0x7f, 0xa7, 0xa3, 0x65, 0xe4, 0x86, 0x08, 0x1f, 0x08, 0x8b, 0x19, 0x18,
+	0x0b, 0x7d, 0x4a, 0x65, 0xa9, 0x55, 0xd4, 0x65, 0x43, 0xd3, 0xa1, 0x9a, 0xad, 0xb3, 0xdf, 0x3b,
+	0x1a, 0x6b, 0x30, 0xea, 0x9f, 0x71, 0xf4, 0x37, 0xa1, 0x8b, 0x3f, 0xb5, 0xff, 0xc8, 0x41, 0xad,
+	0xbf, 0x0e, 0x27, 0xcb, 0x30, 0x8e, 0xb4, 0x38, 0x1e, 0x19, 0x93, 0xf8, 0x98, 0xd3, 0xea, 0x1b,
+	0xd3, 0x75, 0x3e, 0x4b, 0x69, 0x9f, 0xb3, 0x50, 0xe8, 0x79, 0x8e, 0x10, 0x8f, 0x4b, 0x71, 0xcf,
+	0x73, 0xe4, 0x0c, 0x74, 0x68, 0x17, 0x8b, 0xfc, 0xb8, 0x97, 0xe3, 0x4a, 0xd2, 0xb0, 0x85, 0x17,
+	0x2c, 0xe3, 0x1d, 0x59, 0xb8, 0x16, 0xf5, 0x82, 0x68, 0x4a, 0x05, 0x1a, 0x79, 0x0c, 0x03, 0xba,
+	0xa8, 0x17, 0x44, 0xf3, 0x90, 0x91, 0x39, 0x28, 0x58, 0x8c, 0x9d, 0x39, 0x14, 0x0b, 0xb2, 0x82,
+	0xae, 0x5a, 0xd1, 0x98, 0xf3, 0xc9, 0x98, 0x3f, 0x84, 0x71, 0x59, 0xea, 0x98, 0xd6, 0xf5, 0xc3,
+	0xd1, 0x7e, 0x0c, 0xe3, 0x7b, 0xd4, 0x0c, 0xf8, 0x09, 0x35, 0x39, 0x59, 0x83, 0xe9, 0xd3, 0xa8,
+	0x21, 0x0b, 0x35, 0xde, 0x0b, 0xa8, 0xb2, 0x20, 0xb1, 0xea, 0x38, 0xd2, 0x68, 0x7f, 0x93, 0x83,
+	0xd1, 0xa6, 0xd7, 0x7b, 0xef, 0x15, 0x1a, 0xd8, 0xef, 0xa3, 0xef, 0xbe, 0xdf, 0xc5, 0x48, 0x9d,
+	0x40, 0xc5, 0x8c, 0xf8, 0x93, 0x7c, 0x02, 0x93, 0xac, 0x6b, 0x59, 0x06, 0xf5, 0xac, 0xe0, 0xca,
+	0x17, 0x6b, 0x8b, 0xcb, 0x59, 0xd2, 0xab, 0x42, 0x5c, 0x8f, 0xa5, 0xda, 0xdf, 0xe6, 0x80, 0xe0,
+	0xf9, 0xd3, 0x11, 0x47, 0xd8, 0x8e, 0x13, 0x72, 0xd3, 0xb3, 0xe8, 0x7b, 0xf7, 0xfe, 0x39, 0x2c,
+	0xba, 0x92, 0xc2, 0x50, 0x4f, 0xa7, 0xc8, 0x63, 0xfc, 0x3e, 0x0d, 0x98, 0x5a, 0xc7, 0x39, 0x05,
+	0x90, 0x19, 0x1c, 0xd5, 0x3f, 0xa7, 0x01, 0x23, 0x8f, 0x61, 0x66, 0x98, 0xa9, 0x1a, 0x0d, 0x19,
+	0xb4, 0xd2, 0xbe, 0x81, 0xa2, 0xd8, 0x0e, 0x07, 0x61, 0xe7, 0x16, 0xf6, 0xc1, 0xaf, 0x73, 0x30,
+	0x2e, 0xce, 0x7a, 0xdc, 0x0a, 0xef, 0xcd, 0x97, 0x0a, 0xca, 0x7c, 0x26, 0x28, 0xb3, 0x51, 0x3e,
+	0xd6, 0x1f, 0xe5, 0x83, 0xfd, 0x78, 0x0e, 0x13, 0xaf, 0x7c, 0xd7, 0xf1, 0xce, 0xde, 0xd6, 0x13,
+	0x65, 0x3a, 0x92, 0x98, 0xfe, 0x45, 0x11, 0x60, 0x87, 0x9e, 0x3b, 0x16, 0x6d, 0x78, 0x6d, 0xdc,
+	0x0f, 0xe7, 0xd4, 0xb3, 0x59, 0xa0, 0x32, 0x92, 0x6a, 0x89, 0xdc, 0xd2, 0x65, 0x36, 0x75, 0xd5,
+	0xb9, 0x2a, 0x1b, 0xe4, 0x07, 0x50, 0x3b, 0x35, 0x03, 0xfb, 0xc2, 0x0c, 0xa8, 0x71, 0x4e, 0x03,
+	0xf1, 0x38, 0xa0, 0xd2, 0xd2, 0x64, 0x24, 0x7f, 0x2d, 0xc5, 0x02, 0xda, 0x76, 0x82, 0x6e, 0x06,
+	0x9a, 0x97, 0xd0, 0x48, 0x1e, 0x41, 0x97, 0x61, 0xdc, 0xc6, 0x1e, 0x89, 0xfe, 0xd7, 0x64, 0x22,
+	0x91, 0x82, 0x86, 0x2d, 0x56, 0x5c, 0x29, 0xb3, 0x11, 0x3f, 0x85, 0x38, 0x22, 0x75, 0xe9, 0x70,
+	0x27, 0xeb, 0x30, 0xe3, 0x07, 0xf4, 0xdc, 0x61, 0xbd, 0xd0, 0xbd, 0x32, 0x2c, 0xe6, 0x79, 0xd4,
+	0xe2, 0x54, 0x16, 0x39, 0x25, 0x7d, 0x3a, 0xd1, 0x6d, 0x47, 0x2a, 0xd1, 0x03, 0x51, 0x7e, 0x8b,
+	0xf9, 0x0e, 0xb1, 0xba, 0x2f, 0xea, 0x25, 0x9f, 0x79, 0x47, 0xa2, 0x4d, 0xbe, 0x82, 0x42, 0x60,
+	0x7a, 0x1d, 0x1a, 0x2e, 0x4c, 0xae, 0x8c, 0x3e, 0x2a, 0x6f, 0x3c, 0x4a, 0x9e, 0xb0, 0xe3, 0x79,
+	0x54, 0x7f, 0xea, 0x34, 0x64, 0xbd, 0xc0, 0xa2, 0x3a, 0xe2, 0x75, 0x65, 0xb7, 0xf4, 0x27, 0x79,
+	0x98, 0x19, 0x06, 0x20, 0x8b, 0xd1, 0x8b, 0x21, 0x3b, 0x5c, 0xc8, 0xad, 0x8c, 0x3e, 0x2a, 0xaa,
+	0xb7, 0x3f, 0x76, 0x48, 0xee, 0x03, 0x70, 0x6a, 0x9d, 0x7a, 0xcc, 0x65, 0x9d, 0x2b, 0xb5, 0x0a,
+	0x29, 0x09, 0xd9, 0x86, 0x31, 0x9f, 0x31, 0x37, 0x5c, 0x18, 0xc5, 0x4e, 0x7d, 0xf6, 0xae, 0x9d,
+	0x5a, 0x3d, 0x62, 0xcc, 0xd5, 0xa5, 0xed, 0xd2, 0x7f, 0x8d, 0x40, 0x5e, 0xb4, 0xc9, 0xd7, 0xa9,
+	0x63, 0xa9, 0xba, 0xf1, 0xf4, 0xbd, 0xc8, 0xf0, 0x1f, 0x91, 0xf4, 0xd5, 0x71, 0x76, 0x0c, 0xc5,
+	0xf0, 0xd4, 0x0c, 0x1c, 0xaf, 0x83, 0xdd, 0xae, 0x6e, 0x3c, 0x7f, 0x3f, 0xba, 0x63, 0x69, 0x8c,
+	0x8c, 0x11, 0x13, 0x9e, 0x75, 0xdc, 0x0c, 0xb8, 0xca, 0x0f, 0xb2, 0x21, 0xc2, 0x9b, 0x7a, 0xd1,
+	0xf9, 0x27, 0xfe, 0xd4, 0xb6, 0xa0, 0x14, 0x75, 0x87, 0x00, 0x14, 0xc4, 0x31, 0xdd, 0xd8, 0xa9,
+	0xdd, 0x21, 0x13, 0x50, 0xda, 0xda, 0xdf, 0x6f, 0x6e, 0x8b, 0x56, 0x8e, 0x54, 0x01, 0x76, 0xeb,
+	0x07, 0x47, 0x4d, 0xbd, 0x25, 0xda, 0x23, 0xa4, 0x0c, 0xc5, 0x97, 0xfb, 0xcd, 0x37, 0xa2, 0x31,
+	0xaa, 0x9d, 0x42, 0x39, 0xd5, 0x05, 0x32, 0x07, 0x64, 0xa7, 0xbe, 0x23, 0x6a, 0x88, 0xfa, 0x8e,
+	0x71, 0x54, 0xd7, 0x8d, 0xc6, 0x61, 0xeb, 0x65, 0xed, 0x0e, 0x79, 0x00, 0xcb, 0xc7, 0x7b, 0x5b,
+	0x7a, 0x7d, 0xc7, 0x78, 0xf1, 0x33, 0x63, 0x6b, 0x7f, 0x1f, 0xe5, 0xf8, 0x47, 0xab, 0xbe, 0xbd,
+	0x57, 0xcb, 0x91, 0x15, 0xb8, 0x3b, 0x04, 0x70, 0xbc, 0x75, 0x50, 0x97, 0x88, 0x91, 0xaf, 0xf3,
+	0xa5, 0xb1, 0xda, 0xc4, 0xd7, 0xf9, 0x52, 0xa5, 0x56, 0xfd, 0x3a, 0x5f, 0xaa, 0xd6, 0x26, 0xb5,
+	0x3f, 0x18, 0x05, 0xd8, 0x76, 0xcd, 0x30, 0x74, 0xda, 0x0e, 0x0d, 0x30, 0x91, 0x18, 0xdc, 0x8f,
+	0xb7, 0xf5, 0x18, 0x6b, 0xf9, 0x8e, 0x4d, 0xa6, 0x61, 0x8c, 0x19, 0xe7, 0x71, 0x7a, 0xc9, 0xb3,
+	0xd7, 0x0e, 0x26, 0x1d, 0x47, 0x62, 0xd5, 0x14, 0x39, 0x11, 0xd6, 0x41, 0xac, 0x9c, 0xa4, 0xbc,
+	0x23, 0xb0, 0xf3, 0x50, 0x64, 0x86, 0x7f, 0xe2, 0xf0, 0x50, 0x65, 0x9b, 0x02, 0x3b, 0x12, 0x2d,
+	0x4c, 0x24, 0x4a, 0xa1, 0xce, 0x4d, 0x47, 0x2a, 0x16, 0xa1, 0x44, 0xf9, 0xa9, 0x3c, 0xeb, 0x8b,
+	0xa8, 0x29, 0x52, 0x7e, 0x1a, 0x1d, 0xf5, 0x76, 0xc8, 0x8d, 0xae, 0x69, 0xe1, 0x91, 0x3e, 0xa1,
+	0x17, 0xec, 0x90, 0x1f, 0x98, 0x96, 0x50, 0x84, 0x81, 0x85, 0x8a, 0x71, 0xa9, 0x08, 0x03, 0x4b,
+	0x28, 0x44, 0xd8, 0xfb, 0xf2, 0x7d, 0x2b, 0xbe, 0x11, 0x10, 0x61, 0xef, 0x1f, 0xe1, 0x5b, 0xdf,
+	0x59, 0x10, 0xd6, 0x86, 0xe3, 0xe3, 0x73, 0x7c, 0x51, 0x1f, 0xb3, 0x43, 0xde, 0xf0, 0x85, 0x58,
+	0x50, 0x39, 0xbe, 0xda, 0x9d, 0x63, 0x61, 0x60, 0x35, 0x7c, 0x41, 0x24, 0xc4, 0x62, 0xdf, 0xe2,
+	0x13, 0x73, 0x51, 0x17, 0x1e, 0xc5, 0xb6, 0x15, 0x2a, 0x41, 0x84, 0xaa, 0xaa, 0x54, 0xd9, 0x21,
+	0x47, 0xd5, 0x0a, 0x4c, 0xf8, 0x67, 0xdc, 0xe0, 0x66, 0x47, 0x8e, 0x67, 0x52, 0x6e, 0x2e, 0xff,
+	0x8c, 0xb7, 0x4c, 0x5c, 0x73, 0xed, 0xd7, 0xa3, 0x30, 0x2e, 0xaa, 0x58, 0xe6, 0x6d, 0x77, 0x6d,
+	0xa2, 0x41, 0xc5, 0xb4, 0x6d, 0x83, 0xf5, 0x38, 0x0d, 0x84, 0x15, 0x2e, 0x46, 0x49, 0x2f, 0x9b,
+	0xb6, 0xdd, 0x14, 0xb2, 0x96, 0xd9, 0x21, 0x8f, 0xa0, 0x26, 0x9e, 0x7f, 0xcf, 0x69, 0x0a, 0x36,
+	0x22, 0x0f, 0x51, 0x29, 0x8f, 0x91, 0x2b, 0x30, 0xc1, 0x03, 0xd3, 0x37, 0x38, 0x33, 0x4e, 0x59,
+	0x28, 0x03, 0xba, 0xa4, 0x83, 0x90, 0xb5, 0xd8, 0x1e, 0x0b, 0x39, 0xf9, 0x11, 0x90, 0x80, 0x76,
+	0xcd, 0xe0, 0x4c, 0x71, 0xc9, 0xf5, 0xc8, 0x23, 0xae, 0x26, 0x35, 0xc8, 0x26, 0x57, 0x26, 0x41,
+	0x3b, 0x9e, 0x17, 0xa3, 0xc7, 0xd2, 0xe8, 0x86, 0x50, 0x48, 0xb4, 0x1a, 0x8b, 0x84, 0x8a, 0x4e,
+	0x16, 0xe2, 0xb1, 0x20, 0x2a, 0x3b, 0x96, 0x04, 0x56, 0x4c, 0x8f, 0x25, 0x46, 0xae, 0xc2, 0x34,
+	0x0f, 0x4c, 0x2f, 0x74, 0x4d, 0x9e, 0x06, 0x97, 0x10, 0x3c, 0x15, 0xab, 0x86, 0xe3, 0x93, 0x89,
+	0x1a, 0xef, 0xc3, 0x47, 0x73, 0xa5, 0xfd, 0x5d, 0x0e, 0x0a, 0x72, 0x1d, 0xc8, 0x87, 0x30, 0x6a,
+	0x75, 0xa3, 0xd7, 0xa3, 0x24, 0x79, 0xe3, 0x1a, 0xad, 0x92, 0x2e, 0xd4, 0xc3, 0x77, 0x46, 0x2a,
+	0xda, 0x47, 0x33, 0xd1, 0x9e, 0x6c, 0xaf, 0x7c, 0xdf, 0xf6, 0x92, 0x5b, 0x66, 0x2c, 0xbb, 0x65,
+	0x86, 0xef, 0x8c, 0x64, 0xdf, 0x15, 0x53, 0xfb, 0x4e, 0xfb, 0xc7, 0x02, 0xe4, 0x5f, 0xba, 0xec,
+	0x82, 0x7c, 0x08, 0x55, 0xd3, 0xb2, 0x68, 0x18, 0x1a, 0xe9, 0x23, 0x7a, 0x52, 0x9f, 0x90, 0xd2,
+	0xc6, 0xb0, 0x92, 0x61, 0x72, 0xb0, 0x2c, 0x2e, 0x4b, 0xb1, 0x2c, 0x8b, 0xfb, 0xea, 0xde, 0x42,
+	0x5c, 0xf7, 0x7e, 0x0a, 0x53, 0xe1, 0x55, 0xb7, 0x4b, 0x79, 0xe0, 0x58, 0x46, 0x04, 0x21, 0x08,
+	0x99, 0x8c, 0x15, 0x2f, 0x25, 0x76, 0x19, 0xf0, 0xb5, 0xb6, 0xdc, 0x03, 0xf2, 0x68, 0x2e, 0x09,
+	0x01, 0x6e, 0xea, 0x45, 0x28, 0x99, 0xae, 0xcb, 0x2c, 0x61, 0x0f, 0xe8, 0xba, 0x88, 0xed, 0x86,
+	0x4d, 0x3e, 0x86, 0x49, 0x8f, 0xf2, 0x0b, 0x86, 0x11, 0x27, 0x47, 0x34, 0x86, 0x88, 0x8a, 0x12,
+	0x37, 0xe2, 0xa7, 0x97, 0x54, 0x55, 0x53, 0x40, 0x48, 0xaa, 0xaa, 0xf9, 0x1c, 0xc0, 0x8a, 0x33,
+	0x9d, 0x7a, 0x3d, 0x3a, 0x1d, 0xaf, 0x6b, 0x92, 0x04, 0xf5, 0x14, 0x8c, 0x7c, 0x02, 0x05, 0x13,
+	0x57, 0x5c, 0xbd, 0xf6, 0x9c, 0xec, 0x0b, 0x04, 0x5d, 0xa9, 0xc9, 0x12, 0x94, 0xfc, 0xc0, 0x61,
+	0x81, 0xc3, 0xaf, 0x30, 0xbc, 0x26, 0xf5, 0xb8, 0x9d, 0x7a, 0x06, 0x98, 0xc8, 0x3c, 0x03, 0xa4,
+	0xea, 0xb3, 0x4a, 0xa6, 0x3e, 0x5b, 0x84, 0x52, 0x27, 0x60, 0x3d, 0x5f, 0x8c, 0x43, 0xe5, 0x12,
+	0x6c, 0xcb, 0xc9, 0x48, 0x7f, 0x72, 0x12, 0x88, 0x49, 0x44, 0x54, 0x84, 0xf8, 0x48, 0x4a, 0x1b,
+	0x36, 0xf9, 0x08, 0xaa, 0x01, 0xf5, 0x5d, 0xf1, 0xec, 0x44, 0x71, 0x61, 0xb0, 0xd0, 0x29, 0xe9,
+	0x95, 0x58, 0x8a, 0xc1, 0xb2, 0x07, 0x93, 0x22, 0xc6, 0x44, 0x72, 0x50, 0x33, 0xb5, 0x30, 0x85,
+	0xe7, 0xfb, 0x4a, 0xe6, 0xe3, 0xc4, 0xaa, 0x08, 0xbd, 0x16, 0xdb, 0x95, 0x90, 0xba, 0xc7, 0x83,
+	0x2b, 0xbd, 0xe2, 0xa7, 0x65, 0xa4, 0x0e, 0xd5, 0x68, 0xf6, 0x39, 0x33, 0x4c, 0x1a, 0x2e, 0x4c,
+	0x23, 0xd1, 0x83, 0x2c, 0x91, 0x82, 0xb7, 0xd8, 0x16, 0x0d, 0x25, 0xcf, 0x44, 0x27, 0x25, 0x5a,
+	0xfa, 0x0a, 0xc8, 0xa0, 0x2f, 0x71, 0xee, 0x9e, 0xd1, 0x2b, 0x75, 0x28, 0x89, 0x3f, 0xc5, 0xf9,
+	0x7c, 0x6e, 0xba, 0x3d, 0x1a, 0x55, 0xbc, 0xd8, 0xf8, 0x72, 0xe4, 0x59, 0x6e, 0xe9, 0xa7, 0x30,
+	0x35, 0xe0, 0xe4, 0x6d, 0x04, 0xa5, 0x14, 0x81, 0xd6, 0x82, 0x89, 0x4c, 0x7d, 0xb7, 0x0c, 0xe3,
+	0xb2, 0x48, 0x8d, 0xf6, 0xd2, 0x84, 0x5e, 0x92, 0x82, 0x86, 0x2d, 0x9e, 0x65, 0x94, 0x32, 0xf4,
+	0xa9, 0xe5, 0xb4, 0x1d, 0x4b, 0x15, 0xbf, 0x55, 0x29, 0x3e, 0x56, 0x52, 0xed, 0xbf, 0xcb, 0x50,
+	0xcd, 0x7e, 0x21, 0xba, 0xbe, 0x8a, 0x5e, 0x84, 0x52, 0x70, 0x69, 0x9c, 0x5c, 0x71, 0x1a, 0x22,
+	0x5b, 0x41, 0x2f, 0x06, 0x97, 0x2f, 0x44, 0x53, 0x04, 0x79, 0x70, 0x69, 0xf8, 0x58, 0x86, 0x87,
+	0x6a, 0x33, 0x8e, 0x07, 0x97, 0xb2, 0x2e, 0x0f, 0x31, 0x95, 0x5e, 0x1a, 0x3d, 0xcb, 0x14, 0x47,
+	0x91, 0x02, 0xe5, 0x11, 0x54, 0x0d, 0x2e, 0x5f, 0x09, 0x71, 0x16, 0xd9, 0xcd, 0x20, 0xc7, 0x22,
+	0xe4, 0xc1, 0x20, 0xf2, 0x24, 0x83, 0x2c, 0x44, 0xc8, 0x17, 0x83, 0x48, 0xf9, 0xda, 0x32, 0x42,
+	0x16, 0x23, 0x24, 0xbe, 0x78, 0x8c, 0x90, 0xcb, 0x30, 0x1e, 0x5c, 0x1a, 0xed, 0xc0, 0xec, 0xd2,
+	0x10, 0x4b, 0xeb, 0x82, 0x5e, 0x0a, 0x2e, 0x5f, 0x62, 0x5b, 0x9c, 0x58, 0xb1, 0xd2, 0x78, 0xfa,
+	0x44, 0xe5, 0x13, 0x88, 0xf4, 0x4f, 0x9f, 0x90, 0x4f, 0xd0, 0x51, 0x84, 0xd8, 0x34, 0xd6, 0x37,
+	0xbe, 0xc0, 0x72, 0xbb, 0xa0, 0x57, 0x62, 0xd4, 0xe6, 0xfa, 0xc6, 0x17, 0xe4, 0x07, 0x30, 0x95,
+	0x00, 0xd7, 0x37, 0x9e, 0x19, 0x1b, 0x9b, 0x9b, 0x0b, 0x33, 0x51, 0x97, 0x24, 0x72, 0x7d, 0xe3,
+	0xd9, 0xc6, 0xe6, 0x66, 0x16, 0xba, 0xb1, 0xf9, 0xd4, 0xd8, 0x5c, 0x5f, 0x5f, 0x98, 0xcd, 0x42,
+	0x37, 0x36, 0x9f, 0x6e, 0xae, 0xaf, 0x93, 0x1f, 0x02, 0x49, 0xa0, 0x9b, 0xeb, 0x1b, 0xc6, 0xfa,
+	0xe3, 0x8d, 0xcf, 0x17, 0xe6, 0x64, 0xda, 0x8b, 0xb0, 0x9b, 0xeb, 0x1b, 0x42, 0x4c, 0x3e, 0x83,
+	0xe9, 0x54, 0x17, 0x1e, 0x6f, 0x3c, 0x31, 0xd6, 0x37, 0xd7, 0x9f, 0x2d, 0xcc, 0x23, 0xba, 0x16,
+	0x77, 0xe2, 0xf1, 0xc6, 0x13, 0x21, 0xef, 0x83, 0x6f, 0xae, 0x3f, 0x37, 0x36, 0x1e, 0x3f, 0xf9,
+	0x62, 0x61, 0xa1, 0x0f, 0xbe, 0xb9, 0xfe, 0x5c, 0xc8, 0xb3, 0xf0, 0x8d, 0xc7, 0x4f, 0x9e, 0x19,
+	0x4f, 0x1e, 0x3f, 0xdf, 0x5c, 0x58, 0xcc, 0xc2, 0x85, 0x42, 0xc8, 0xb3, 0xf0, 0x27, 0x8f, 0x9f,
+	0x3f, 0x35, 0x9e, 0x6f, 0xac, 0x3f, 0x5d, 0x58, 0xca, 0xc2, 0x85, 0x42, 0xc8, 0xc9, 0x1a, 0xcc,
+	0x24, 0xf0, 0xe7, 0x1b, 0xeb, 0x5f, 0x18, 0xeb, 0x4f, 0x3f, 0x7f, 0xf6, 0xf9, 0xc2, 0x32, 0xe2,
+	0xa7, 0x22, 0xbc, 0xd0, 0xa0, 0x42, 0x1c, 0xf7, 0xc1, 0xa5, 0x61, 0x05, 0x96, 0x8c, 0x82, 0x10,
+	0xd3, 0x57, 0x41, 0x2f, 0x07, 0x97, 0xdb, 0x81, 0x85, 0x11, 0x80, 0xa5, 0x1d, 0x8f, 0xa2, 0xbb,
+	0x24, 0xa3, 0x9b, 0x27, 0xd1, 0xcd, 0x93, 0xe8, 0x1e, 0x97, 0xd1, 0xcd, 0xd3, 0xd1, 0xcd, 0xfb,
+	0xa3, 0x1b, 0xe4, 0x0a, 0xf1, 0x81, 0xe8, 0xe6, 0xfd, 0xd1, 0x5d, 0x8e, 0x90, 0x07, 0x83, 0xc8,
+	0x6c, 0x74, 0x4f, 0x44, 0xc8, 0x17, 0x83, 0xc8, 0x6c, 0x74, 0x57, 0x22, 0x64, 0x7f, 0x74, 0xf3,
+	0x38, 0xba, 0xef, 0xca, 0xe8, 0xe6, 0xa9, 0xe8, 0xe6, 0xe9, 0xe8, 0xbe, 0x27, 0xa3, 0x9b, 0x67,
+	0xa2, 0x9b, 0xf7, 0x47, 0xf7, 0x7d, 0x19, 0xdd, 0xbc, 0x3f, 0xba, 0xf9, 0x40, 0x74, 0x3f, 0x88,
+	0xba, 0xd4, 0x1f, 0xdd, 0x7c, 0x20, 0xba, 0x57, 0xb2, 0xd0, 0x24, 0xba, 0xf9, 0x60, 0x74, 0x3f,
+	0x94, 0xd1, 0xcd, 0x07, 0xa3, 0x9b, 0x0f, 0x89, 0x6e, 0x4d, 0x06, 0x14, 0x1f, 0x12, 0xdd, 0x7c,
+	0x48, 0x74, 0x7f, 0xd0, 0x07, 0x4f, 0x45, 0x37, 0x1f, 0x12, 0xdd, 0x1f, 0x66, 0xe1, 0xe9, 0xe8,
+	0xe6, 0x43, 0xa2, 0xfb, 0xa3, 0x2c, 0x3c, 0x1d, 0xdd, 0x7c, 0x58, 0x74, 0x7f, 0x2c, 0xa3, 0x9b,
+	0x0f, 0x44, 0xf7, 0x3d, 0x80, 0x13, 0xc7, 0x8f, 0x42, 0x7b, 0x52, 0x86, 0xe7, 0x89, 0xe3, 0xab,
+	0xc0, 0xbe, 0x0b, 0xe3, 0xdc, 0xe9, 0xd2, 0x90, 0x9b, 0x5d, 0x1f, 0x8f, 0xdb, 0xa2, 0x9e, 0x08,
+	0xb4, 0x7f, 0x2b, 0xe2, 0x5b, 0xfb, 0x77, 0xc9, 0xff, 0xd7, 0xbc, 0xcf, 0xf9, 0x08, 0xaa, 0x3e,
+	0x0b, 0x1d, 0xee, 0x9c, 0x53, 0xf9, 0x25, 0x59, 0xe5, 0xff, 0x4a, 0x24, 0xc5, 0x2f, 0xc3, 0x02,
+	0xe6, 0xd1, 0x8e, 0x99, 0x82, 0xc9, 0x13, 0xa0, 0x12, 0x49, 0x25, 0xec, 0x19, 0x2c, 0xd8, 0xd4,
+	0x75, 0xba, 0x8e, 0xa8, 0x8a, 0xbb, 0x4e, 0x18, 0x1a, 0x36, 0xe5, 0xd4, 0x8a, 0x5f, 0xc7, 0x15,
+	0xf4, 0xb9, 0x58, 0x7f, 0xe0, 0x84, 0xe1, 0x4e, 0xa4, 0xed, 0x9b, 0x86, 0x42, 0xff, 0x34, 0x2c,
+	0x83, 0x68, 0x18, 0x3d, 0xcf, 0x89, 0xd3, 0x7f, 0xe9, 0xc4, 0xf1, 0x5f, 0x89, 0x36, 0xd9, 0x80,
+	0xd9, 0x36, 0xb5, 0x0c, 0x8b, 0x05, 0x01, 0xbe, 0x0a, 0x31, 0xc2, 0xab, 0xee, 0x09, 0x73, 0xa3,
+	0x4c, 0x30, 0xdd, 0xa6, 0xd6, 0x76, 0xa4, 0x3b, 0x96, 0x2a, 0xf2, 0x14, 0xe6, 0xa5, 0x8d, 0x4d,
+	0x2f, 0x58, 0x60, 0x87, 0x89, 0xb5, 0x4a, 0x11, 0xb3, 0x68, 0xa5, 0xb4, 0xb1, 0x39, 0xf9, 0x09,
+	0x2c, 0x67, 0xed, 0x7a, 0x9e, 0xb2, 0x34, 0x4f, 0x5c, 0xaa, 0x32, 0xc7, 0x62, 0xda, 0xf6, 0x55,
+	0x1a, 0x40, 0x3e, 0x80, 0x4a, 0xc6, 0x5e, 0x65, 0x90, 0x89, 0xb4, 0x85, 0x78, 0xc4, 0xc8, 0x0e,
+	0x48, 0x8e, 0x5b, 0xa6, 0x90, 0xa9, 0xf4, 0x70, 0xe4, 0x04, 0x7c, 0x0c, 0x93, 0x97, 0x1d, 0xda,
+	0x35, 0xce, 0xe8, 0x55, 0x34, 0x83, 0x32, 0x89, 0x54, 0x84, 0xf8, 0x1b, 0x7a, 0x95, 0xcc, 0x22,
+	0xe2, 0x5c, 0x16, 0x46, 0x59, 0xb4, 0x24, 0x04, 0xfb, 0x2c, 0x44, 0x12, 0x51, 0x05, 0xb8, 0xcc,
+	0xec, 0x86, 0x92, 0x45, 0x45, 0x63, 0x25, 0xb8, 0x3c, 0x42, 0x29, 0xb2, 0xa8, 0x83, 0x4a, 0xe1,
+	0x3c, 0xe6, 0x19, 0x8e, 0xed, 0x52, 0x0c, 0x4d, 0x3c, 0xa8, 0x24, 0xf4, 0x90, 0x79, 0x0d, 0xdb,
+	0xc5, 0x72, 0x34, 0xb8, 0xc4, 0x0b, 0x04, 0xea, 0x44, 0x2e, 0x04, 0x97, 0xcd, 0xae, 0xe5, 0x90,
+	0x67, 0xb0, 0xa8, 0x14, 0x51, 0xde, 0x4b, 0x32, 0xbc, 0x3a, 0x9c, 0x67, 0x25, 0x54, 0x25, 0xc0,
+	0x28, 0xd7, 0x67, 0x0a, 0x99, 0xe9, 0x9b, 0x0a, 0x99, 0x99, 0xfe, 0x42, 0x26, 0x7d, 0x48, 0xcc,
+	0xde, 0x74, 0x48, 0xcc, 0xf5, 0x1f, 0x12, 0x0f, 0x61, 0xe2, 0x84, 0x06, 0x46, 0x40, 0x45, 0x09,
+	0x48, 0x6d, 0x75, 0xd0, 0x96, 0x4f, 0x68, 0xa0, 0x2b, 0x11, 0x79, 0x00, 0x65, 0xd7, 0xb2, 0x3b,
+	0xd1, 0xfc, 0xcb, 0xb3, 0x15, 0x84, 0x48, 0x4d, 0xbe, 0xe8, 0x9c, 0xed, 0x44, 0xfa, 0x45, 0xd5,
+	0x39, 0xdb, 0x19, 0xb6, 0xd1, 0x97, 0xfa, 0x37, 0xfa, 0xbf, 0xe4, 0xb0, 0x02, 0x7d, 0xd7, 0x62,
+	0xef, 0x2d, 0x9f, 0x1c, 0xde, 0x52, 0xf0, 0xa5, 0x67, 0x38, 0x3f, 0x30, 0xc3, 0xa9, 0x79, 0x1a,
+	0xeb, 0x9f, 0xa7, 0xf4, 0x0c, 0x17, 0xb2, 0x33, 0x7c, 0xf3, 0xf8, 0xfe, 0x3e, 0x07, 0xd5, 0xec,
+	0x8d, 0xa5, 0xf4, 0xf3, 0x61, 0x2e, 0xf3, 0x5d, 0xe4, 0xfb, 0x57, 0xb2, 0xdf, 0xbf, 0x4a, 0xb8,
+	0x39, 0x0d, 0x7f, 0x05, 0x95, 0xcc, 0x15, 0xa7, 0xeb, 0x17, 0x66, 0x0e, 0x0a, 0x21, 0x37, 0x79,
+	0x2f, 0x54, 0x6f, 0x43, 0x55, 0x4b, 0xfb, 0x16, 0xa6, 0x87, 0x5c, 0x75, 0x7a, 0xef, 0x6c, 0x9e,
+	0xd0, 0x8f, 0x66, 0xe8, 0xff, 0x7a, 0x04, 0x3f, 0x7a, 0xf4, 0x5f, 0xd9, 0xfa, 0x1e, 0x9f, 0x78,
+	0x5d, 0x16, 0x1a, 0x19, 0x17, 0xe3, 0x2e, 0x0b, 0x8f, 0x51, 0x20, 0xd5, 0x27, 0x91, 0x3a, 0x1f,
+	0xa9, 0x4f, 0x94, 0xfa, 0x11, 0xd4, 0x5c, 0xe6, 0x5b, 0xf2, 0x5c, 0x50, 0x20, 0xf9, 0xc9, 0xad,
+	0x2a, 0xe4, 0xe2, 0x3c, 0x50, 0xc8, 0x75, 0x98, 0x55, 0x48, 0x95, 0x11, 0x22, 0x78, 0x41, 0xbe,
+	0x30, 0x97, 0x70, 0x99, 0x0f, 0x94, 0x89, 0xd8, 0x7e, 0xac, 0xed, 0x44, 0xc0, 0xa2, 0x7c, 0x1d,
+	0x26, 0x44, 0x0a, 0xf0, 0x10, 0x26, 0x44, 0x66, 0x8a, 0x11, 0x25, 0x44, 0x94, 0x51, 0x26, 0x21,
+	0x1a, 0x85, 0xe5, 0x1b, 0x2e, 0x78, 0xdd, 0xda, 0x62, 0xfc, 0x59, 0x0e, 0x96, 0xae, 0xbf, 0xed,
+	0x75, 0x5b, 0x6e, 0xc8, 0xe7, 0x30, 0xe7, 0x78, 0xe7, 0x34, 0x08, 0xa9, 0x21, 0x9e, 0xc6, 0xe5,
+	0x3c, 0x06, 0x26, 0x8f, 0x3e, 0x34, 0x4d, 0x2b, 0xed, 0x0b, 0x47, 0xde, 0xdf, 0xd0, 0x4d, 0x4e,
+	0xb5, 0xdf, 0xc8, 0xbe, 0x5d, 0x73, 0x59, 0xec, 0xd6, 0xfa, 0x36, 0x03, 0x63, 0x49, 0x15, 0x51,
+	0xd4, 0x65, 0x43, 0xb0, 0x7b, 0xf4, 0xc2, 0xa0, 0xdf, 0x45, 0x6f, 0xad, 0x0a, 0x1e, 0xbd, 0xa8,
+	0x7f, 0x67, 0x6b, 0xa7, 0x70, 0xff, 0xe6, 0xab, 0x66, 0xb7, 0xb6, 0x36, 0x7f, 0x9e, 0x93, 0x31,
+	0x70, 0xcd, 0xe5, 0xb3, 0xff, 0xdf, 0xc5, 0xf9, 0x55, 0x0e, 0xb4, 0xb7, 0x5f, 0x64, 0xfb, 0xbf,
+	0x5d, 0x24, 0xed, 0x3b, 0x5c, 0x8b, 0x1b, 0x2e, 0xbc, 0xbd, 0xb7, 0xff, 0x07, 0xd9, 0xcb, 0x1b,
+	0xf2, 0xf5, 0x66, 0xfa, 0x3e, 0xc6, 0x19, 0x3c, 0x7c, 0xeb, 0xed, 0xb4, 0x5b, 0x8b, 0x80, 0x16,
+	0x10, 0x5d, 0x1d, 0xca, 0x29, 0x76, 0x51, 0x1c, 0x45, 0x87, 0xb7, 0x61, 0xb1, 0x9e, 0xc7, 0xd1,
+	0x8b, 0x28, 0x8e, 0x14, 0x78, 0x5b, 0x08, 0xaf, 0xcd, 0xef, 0x7f, 0x9a, 0x83, 0x85, 0xeb, 0xae,
+	0xbf, 0xbd, 0x77, 0xd7, 0xb7, 0xa0, 0x92, 0x74, 0x66, 0xd8, 0x85, 0xd7, 0xc1, 0x01, 0xec, 0xdd,
+	0xd1, 0xcb, 0x41, 0x22, 0x7d, 0x51, 0xc4, 0x4f, 0x51, 0x3c, 0xd4, 0x0e, 0xe1, 0xee, 0x4d, 0x97,
+	0x0b, 0xdf, 0xb7, 0x6f, 0xda, 0x2f, 0x61, 0xe5, 0x6d, 0x17, 0xf1, 0x6e, 0x6d, 0xa9, 0x7e, 0x09,
+	0x8b, 0xd7, 0xde, 0xc6, 0xfb, 0x3e, 0x67, 0x5b, 0xaa, 0x3c, 0x1b, 0xed, 0x2b, 0xcf, 0xb4, 0xbf,
+	0xca, 0xc1, 0xa3, 0x77, 0xbd, 0x9a, 0x77, 0x6b, 0x3b, 0xf0, 0x33, 0x20, 0xe9, 0xeb, 0x82, 0xaa,
+	0x6f, 0x72, 0x3b, 0x4e, 0xa5, 0x34, 0xaa, 0x8f, 0x5d, 0xf8, 0xe0, 0x1d, 0x2e, 0xf1, 0xdd, 0xda,
+	0xf4, 0xbb, 0x98, 0x8d, 0xde, 0x72, 0x91, 0xef, 0xd6, 0xbc, 0xfd, 0x71, 0x0e, 0x3e, 0x7e, 0xb7,
+	0x2b, 0x7d, 0xb7, 0x36, 0xfd, 0x4b, 0x50, 0xea, 0xbb, 0x9c, 0x11, 0xb7, 0xb5, 0xff, 0xcc, 0x41,
+	0x79, 0x37, 0x60, 0x3d, 0xff, 0x80, 0xe2, 0x0b, 0xdd, 0x87, 0x30, 0xe1, 0x44, 0x37, 0x6d, 0x22,
+	0xc7, 0x15, 0xfc, 0x21, 0x83, 0x94, 0x35, 0x6c, 0xd2, 0x80, 0x6a, 0x02, 0xc1, 0x0f, 0x16, 0xf2,
+	0xd3, 0x72, 0x72, 0xb7, 0x34, 0x45, 0xb8, 0x1a, 0xdf, 0xdb, 0xc1, 0x6f, 0xc8, 0x15, 0x27, 0xdd,
+	0x24, 0xf7, 0xa1, 0x2c, 0x9e, 0xe3, 0xa2, 0x02, 0x7f, 0x14, 0x9d, 0x89, 0x02, 0xff, 0x48, 0x16,
+	0xf8, 0xe9, 0x2f, 0x07, 0x79, 0x54, 0xc6, 0x6d, 0xed, 0xb7, 0xa1, 0x92, 0xe1, 0x26, 0x45, 0x18,
+	0x3d, 0x6a, 0x1e, 0xd6, 0xee, 0x90, 0x1a, 0x4c, 0xd4, 0x8f, 0x9a, 0x87, 0xc6, 0xfa, 0xae, 0x71,
+	0xb4, 0xd5, 0xda, 0xab, 0xe5, 0xc8, 0x14, 0x54, 0xa4, 0xe4, 0xb1, 0x12, 0x8d, 0x68, 0x7f, 0x38,
+	0x02, 0x63, 0xd8, 0xcf, 0xcc, 0x17, 0x05, 0x39, 0xdc, 0xf8, 0x8b, 0xc2, 0x8f, 0xa1, 0x68, 0xb1,
+	0x6e, 0xd7, 0x54, 0x37, 0xfa, 0x07, 0xc6, 0x98, 0x1e, 0x69, 0xb8, 0x2d, 0x91, 0x7a, 0x64, 0x42,
+	0x56, 0xa1, 0xd8, 0x95, 0x2a, 0x75, 0x31, 0x60, 0x66, 0xd8, 0x0c, 0xe9, 0x11, 0x28, 0xf5, 0x41,
+	0x25, 0x7f, 0xe3, 0x07, 0x15, 0xed, 0x1b, 0x98, 0x1e, 0xe2, 0x98, 0x4c, 0x42, 0x79, 0x6b, 0x67,
+	0xc7, 0x38, 0xa8, 0x1f, 0xbc, 0xa8, 0xeb, 0xc7, 0xb5, 0x3b, 0x84, 0x40, 0x55, 0xaf, 0x1f, 0x34,
+	0x5f, 0xd7, 0x63, 0x59, 0x4e, 0x80, 0x8e, 0xeb, 0xad, 0x58, 0x30, 0xa2, 0x7d, 0x0b, 0xf0, 0xda,
+	0x74, 0x7b, 0xf4, 0xc8, 0x0c, 0xcc, 0x2e, 0xb9, 0x0f, 0xa3, 0xcc, 0xeb, 0xa9, 0x4f, 0x7b, 0x13,
+	0x99, 0xdb, 0xc2, 0x42, 0x41, 0xd6, 0xd2, 0x9f, 0x06, 0xaa, 0x1b, 0x8b, 0xab, 0xf1, 0x4f, 0x74,
+	0x56, 0x91, 0x45, 0xac, 0xc4, 0x2a, 0x2e, 0xb5, 0xc4, 0x69, 0xff, 0x30, 0x02, 0xd5, 0x23, 0xe6,
+	0xe9, 0x97, 0x47, 0xec, 0x82, 0x06, 0x3b, 0x26, 0x37, 0x6f, 0x2d, 0xae, 0xf5, 0xec, 0x81, 0x9b,
+	0xc7, 0x1e, 0xad, 0xa7, 0x7e, 0x73, 0x92, 0xf6, 0xba, 0xaa, 0x87, 0xa1, 0x73, 0x40, 0xcd, 0xb0,
+	0x17, 0xe0, 0xd6, 0x1e, 0x7e, 0x67, 0x52, 0xbd, 0xe9, 0xf6, 0x85, 0x95, 0xd1, 0xa5, 0xa6, 0x67,
+	0xd8, 0x27, 0x5d, 0xac, 0xe2, 0x72, 0x7a, 0x35, 0x90, 0x6c, 0x07, 0xd4, 0xf4, 0x76, 0x4e, 0xba,
+	0x22, 0x6d, 0x5f, 0xcb, 0x49, 0x66, 0xa0, 0x36, 0xe4, 0x4e, 0xe5, 0x5d, 0x58, 0xc8, 0x4a, 0x8d,
+	0x9d, 0xfa, 0x7e, 0xe3, 0xa0, 0xd1, 0xaa, 0xeb, 0xb5, 0x1c, 0x59, 0x84, 0xd9, 0x3e, 0xed, 0xd6,
+	0xf6, 0x76, 0xfd, 0x58, 0x2c, 0x52, 0x11, 0xc6, 0xea, 0x5d, 0x9f, 0x5f, 0x6d, 0xfc, 0xe5, 0x0c,
+	0x14, 0x9b, 0x72, 0x80, 0x64, 0x07, 0x60, 0xc7, 0x09, 0xcd, 0x13, 0x97, 0x36, 0x5d, 0x4e, 0xaa,
+	0xf1, 0xc0, 0x11, 0xb9, 0xd4, 0xd7, 0xd6, 0xe6, 0x7e, 0xf5, 0xcf, 0xff, 0xfa, 0x9b, 0x91, 0x9a,
+	0x56, 0x5e, 0x3b, 0x5f, 0x5f, 0x53, 0x76, 0x5f, 0xe6, 0x3e, 0x25, 0x2f, 0xa1, 0xac, 0x53, 0xea,
+	0xbd, 0x2b, 0xcd, 0x3c, 0xd2, 0x4c, 0x69, 0x13, 0x82, 0x26, 0x32, 0x14, 0x3c, 0x75, 0x28, 0xab,
+	0x6a, 0x8a, 0x36, 0xbd, 0x1e, 0xc9, 0xc4, 0xce, 0x00, 0xcb, 0x02, 0xb2, 0x10, 0xad, 0x22, 0x58,
+	0xea, 0xd2, 0xb9, 0xd7, 0x13, 0x34, 0x7b, 0x50, 0x89, 0x4f, 0xdd, 0x77, 0x20, 0x5a, 0x44, 0xa2,
+	0x69, 0xad, 0x9a, 0x1a, 0x95, 0x62, 0xda, 0x86, 0xf1, 0x1d, 0xea, 0xd2, 0xf7, 0xee, 0x4e, 0x6c,
+	0x24, 0x48, 0x1a, 0x00, 0xea, 0xca, 0x5a, 0xb3, 0xc7, 0x49, 0x2d, 0xf3, 0xf3, 0xa9, 0x83, 0xb0,
+	0x73, 0x73, 0x7f, 0x12, 0x4b, 0x41, 0xd5, 0x84, 0x89, 0xf8, 0xbe, 0x9a, 0x20, 0x23, 0x99, 0x2b,
+	0xeb, 0x28, 0x1e, 0xa0, 0x5b, 0x46, 0xba, 0x59, 0xad, 0x86, 0x74, 0x29, 0x6b, 0x41, 0xf8, 0xbb,
+	0x30, 0x99, 0xbe, 0x79, 0x26, 0x38, 0x93, 0x5b, 0x87, 0x69, 0xcd, 0x00, 0xed, 0x7d, 0xa4, 0x5d,
+	0xd0, 0xa6, 0x05, 0x6d, 0x1f, 0x87, 0x60, 0xfe, 0x0a, 0x8a, 0x2f, 0x5d, 0x76, 0xb1, 0x65, 0xdb,
+	0xa4, 0x92, 0xf9, 0x46, 0x79, 0x73, 0x54, 0x29, 0x1b, 0x19, 0x55, 0x20, 0x5a, 0x3a, 0xde, 0x51,
+	0x78, 0x1b, 0x49, 0x66, 0xd2, 0x12, 0x33, 0xc1, 0x73, 0x0c, 0xd5, 0xf8, 0x4e, 0xe7, 0xf6, 0x29,
+	0xb5, 0xce, 0x06, 0x02, 0x34, 0x99, 0xc6, 0x18, 0xa8, 0xdd, 0x43, 0xc2, 0x79, 0x8d, 0x08, 0xc2,
+	0xac, 0xbd, 0x20, 0x3d, 0x80, 0xb2, 0x8c, 0xb9, 0x23, 0xe6, 0x35, 0xda, 0xa9, 0x85, 0x88, 0x0f,
+	0x94, 0x81, 0x2e, 0x2e, 0x21, 0xe3, 0x8c, 0x36, 0x99, 0x04, 0x2c, 0x1a, 0xab, 0x85, 0x55, 0x91,
+	0xf7, 0xee, 0x7c, 0x99, 0x85, 0x4d, 0x5b, 0x0b, 0x42, 0x1d, 0x2a, 0xbb, 0x94, 0xa7, 0x6e, 0x06,
+	0xf6, 0x8f, 0x79, 0x7a, 0xc8, 0x2d, 0x2e, 0xed, 0x2e, 0x52, 0xce, 0x69, 0x53, 0x82, 0x32, 0x63,
+	0x2f, 0x38, 0x7f, 0x0a, 0x05, 0x9d, 0x9e, 0x30, 0xf6, 0xf6, 0x1d, 0x3e, 0x8b, 0x3c, 0x93, 0x1a,
+	0xc8, 0x1d, 0x2e, 0x6c, 0x04, 0xc1, 0x2b, 0x98, 0xda, 0x66, 0xae, 0x4b, 0xad, 0xf4, 0x9b, 0xbb,
+	0xb7, 0x71, 0xad, 0x20, 0xd7, 0x92, 0x36, 0x2b, 0xb8, 0x06, 0xcc, 0x05, 0xed, 0xcf, 0xa0, 0xb6,
+	0x4b, 0x79, 0xf6, 0xe5, 0x7f, 0x76, 0xb3, 0xce, 0xf5, 0xfd, 0x6c, 0x4d, 0xa1, 0xb4, 0x07, 0xc8,
+	0xbd, 0xa8, 0xcd, 0xa8, 0xf1, 0x66, 0xb4, 0x82, 0xfa, 0x0c, 0x66, 0x76, 0x29, 0x1f, 0x7c, 0xdd,
+	0x38, 0x6c, 0xe3, 0x25, 0xbf, 0xc3, 0x1c, 0xc0, 0x6b, 0x1f, 0xa0, 0xa3, 0x7b, 0xda, 0x82, 0x72,
+	0x34, 0x80, 0x10, 0xce, 0x02, 0x98, 0xdf, 0x0e, 0xa8, 0xc9, 0x69, 0x2b, 0x30, 0xdb, 0x6d, 0xc7,
+	0x3a, 0xb6, 0x4e, 0xa9, 0xdd, 0x73, 0xc5, 0xb9, 0xfe, 0x60, 0x35, 0xf3, 0x4b, 0xd8, 0x01, 0xc0,
+	0xc0, 0xac, 0x7d, 0x8c, 0x0e, 0x57, 0xb4, 0x65, 0x9c, 0xb5, 0xe1, 0xac, 0xca, 0xa7, 0xdc, 0x29,
+	0xb7, 0xed, 0xf3, 0x1a, 0x56, 0xe1, 0xb3, 0x0d, 0xd3, 0x99, 0x1e, 0xfd, 0x4e, 0x8f, 0xf6, 0x68,
+	0x48, 0x96, 0x87, 0xfa, 0x93, 0xca, 0x01, 0x5f, 0x1a, 0xfa, 0xba, 0xab, 0xcd, 0x0f, 0x8c, 0x4f,
+	0x1a, 0x28, 0x3f, 0x99, 0x5e, 0xfc, 0xaf, 0xfd, 0x0c, 0x61, 0x13, 0x7e, 0x7e, 0x0b, 0x6a, 0x72,
+	0x3b, 0xa7, 0x0a, 0xef, 0xeb, 0xb7, 0x5b, 0x02, 0xd2, 0xee, 0x3c, 0xce, 0x91, 0x6f, 0x61, 0xf6,
+	0x88, 0x06, 0x6d, 0x16, 0x74, 0xb1, 0x1e, 0x6b, 0xfa, 0x34, 0xe8, 0x67, 0x40, 0xc5, 0x40, 0xcf,
+	0x3e, 0xc4, 0x9e, 0xdd, 0xd7, 0x16, 0x45, 0xcf, 0x86, 0x52, 0xc8, 0xc3, 0xa7, 0x2c, 0x0f, 0x23,
+	0x59, 0xa8, 0xbe, 0x8d, 0x34, 0x93, 0xa3, 0x52, 0x86, 0x82, 0xea, 0x0d, 0x94, 0x77, 0x29, 0xaf,
+	0x5f, 0x72, 0xac, 0xd2, 0x48, 0x32, 0xa2, 0xa4, 0xf6, 0x5b, 0x9a, 0x4f, 0x15, 0x73, 0x3a, 0xe5,
+	0xbd, 0xc0, 0x43, 0x65, 0x98, 0x25, 0x4e, 0xd1, 0x08, 0xe2, 0x6f, 0xf1, 0xa7, 0x3d, 0xf2, 0x85,
+	0x00, 0xbe, 0x97, 0x3d, 0xa6, 0x9c, 0xcc, 0xad, 0xaa, 0x5f, 0x75, 0x67, 0x55, 0x37, 0xa7, 0x87,
+	0x01, 0x1a, 0x41, 0xef, 0xc3, 0xe2, 0x2e, 0xe5, 0xfb, 0xc3, 0x6f, 0xa0, 0x67, 0xf3, 0xc4, 0x72,
+	0xf6, 0x77, 0x59, 0x99, 0x7b, 0xf1, 0xda, 0x23, 0xf4, 0xa4, 0x69, 0xf7, 0xd4, 0x10, 0x86, 0x33,
+	0x0a, 0x8f, 0xa7, 0x30, 0x3b, 0x54, 0xff, 0x3e, 0xde, 0x32, 0xcb, 0x3b, 0x94, 0x4d, 0x78, 0x6a,
+	0x61, 0x9a, 0x4f, 0xca, 0xd4, 0x3e, 0x0f, 0xf3, 0xd7, 0x54, 0xb2, 0x03, 0x89, 0x3e, 0x51, 0x7f,
+	0x99, 0xfb, 0xf4, 0xc5, 0xb7, 0xb0, 0xcc, 0x82, 0x0e, 0xda, 0x5a, 0x2c, 0xb0, 0x57, 0xe5, 0x2f,
+	0xea, 0x23, 0xae, 0x17, 0x95, 0xd7, 0xd8, 0x16, 0x35, 0x64, 0x73, 0xbf, 0xf5, 0xf3, 0xb5, 0x8e,
+	0xc3, 0x4f, 0x7b, 0x27, 0xab, 0x16, 0xeb, 0xae, 0x45, 0x26, 0x6b, 0xd2, 0xe4, 0x33, 0xf5, 0x23,
+	0xfc, 0xf3, 0xcd, 0xb5, 0x0e, 0x8b, 0xfe, 0x43, 0x80, 0x93, 0x02, 0x4a, 0x3f, 0xff, 0x9f, 0x00,
+	0x00, 0x00, 0xff, 0xff, 0x79, 0x04, 0xa4, 0x52, 0x30, 0x40, 0x00, 0x00,
+}
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ context.Context
+var _ grpc.ClientConn
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the grpc package it is being compiled against.
+const _ = grpc.SupportPackageIsVersion4
+
+// OpenoltClient is the client API for Openolt service.
+//
+// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
+type OpenoltClient interface {
+	DisableOlt(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*Empty, error)
+	ReenableOlt(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*Empty, error)
+	ActivateOnu(ctx context.Context, in *Onu, opts ...grpc.CallOption) (*Empty, error)
+	DeactivateOnu(ctx context.Context, in *Onu, opts ...grpc.CallOption) (*Empty, error)
+	DeleteOnu(ctx context.Context, in *Onu, opts ...grpc.CallOption) (*Empty, error)
+	OmciMsgOut(ctx context.Context, in *OmciMsg, opts ...grpc.CallOption) (*Empty, error)
+	OnuPacketOut(ctx context.Context, in *OnuPacket, opts ...grpc.CallOption) (*Empty, error)
+	UplinkPacketOut(ctx context.Context, in *UplinkPacket, opts ...grpc.CallOption) (*Empty, error)
+	FlowAdd(ctx context.Context, in *Flow, opts ...grpc.CallOption) (*Empty, error)
+	FlowRemove(ctx context.Context, in *Flow, opts ...grpc.CallOption) (*Empty, error)
+	HeartbeatCheck(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*Heartbeat, error)
+	EnablePonIf(ctx context.Context, in *Interface, opts ...grpc.CallOption) (*Empty, error)
+	DisablePonIf(ctx context.Context, in *Interface, opts ...grpc.CallOption) (*Empty, error)
+	GetDeviceInfo(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*DeviceInfo, error)
+	Reboot(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*Empty, error)
+	CollectStatistics(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*Empty, error)
+	GetOnuStatistics(ctx context.Context, in *Onu, opts ...grpc.CallOption) (*OnuStatistics, error)
+	GetGemPortStatistics(ctx context.Context, in *OnuPacket, opts ...grpc.CallOption) (*GemPortStatistics, error)
+	CreateTrafficSchedulers(ctx context.Context, in *tech_profile.TrafficSchedulers, opts ...grpc.CallOption) (*Empty, error)
+	RemoveTrafficSchedulers(ctx context.Context, in *tech_profile.TrafficSchedulers, opts ...grpc.CallOption) (*Empty, error)
+	CreateTrafficQueues(ctx context.Context, in *tech_profile.TrafficQueues, opts ...grpc.CallOption) (*Empty, error)
+	RemoveTrafficQueues(ctx context.Context, in *tech_profile.TrafficQueues, opts ...grpc.CallOption) (*Empty, error)
+	EnableIndication(ctx context.Context, in *Empty, opts ...grpc.CallOption) (Openolt_EnableIndicationClient, error)
+	PerformGroupOperation(ctx context.Context, in *Group, opts ...grpc.CallOption) (*Empty, error)
+	DeleteGroup(ctx context.Context, in *Group, opts ...grpc.CallOption) (*Empty, error)
+	GetExtValue(ctx context.Context, in *ValueParam, opts ...grpc.CallOption) (*extension.ReturnValues, error)
+	OnuItuPonAlarmSet(ctx context.Context, in *config.OnuItuPonAlarm, opts ...grpc.CallOption) (*Empty, error)
+	GetLogicalOnuDistanceZero(ctx context.Context, in *Onu, opts ...grpc.CallOption) (*OnuLogicalDistance, error)
+	GetLogicalOnuDistance(ctx context.Context, in *Onu, opts ...grpc.CallOption) (*OnuLogicalDistance, error)
+	GetPonRxPower(ctx context.Context, in *Onu, opts ...grpc.CallOption) (*PonRxPowerData, error)
+}
+
+type openoltClient struct {
+	cc *grpc.ClientConn
+}
+
+func NewOpenoltClient(cc *grpc.ClientConn) OpenoltClient {
+	return &openoltClient{cc}
+}
+
+func (c *openoltClient) DisableOlt(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*Empty, error) {
+	out := new(Empty)
+	err := c.cc.Invoke(ctx, "/openolt.Openolt/DisableOlt", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *openoltClient) ReenableOlt(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*Empty, error) {
+	out := new(Empty)
+	err := c.cc.Invoke(ctx, "/openolt.Openolt/ReenableOlt", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *openoltClient) ActivateOnu(ctx context.Context, in *Onu, opts ...grpc.CallOption) (*Empty, error) {
+	out := new(Empty)
+	err := c.cc.Invoke(ctx, "/openolt.Openolt/ActivateOnu", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *openoltClient) DeactivateOnu(ctx context.Context, in *Onu, opts ...grpc.CallOption) (*Empty, error) {
+	out := new(Empty)
+	err := c.cc.Invoke(ctx, "/openolt.Openolt/DeactivateOnu", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *openoltClient) DeleteOnu(ctx context.Context, in *Onu, opts ...grpc.CallOption) (*Empty, error) {
+	out := new(Empty)
+	err := c.cc.Invoke(ctx, "/openolt.Openolt/DeleteOnu", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *openoltClient) OmciMsgOut(ctx context.Context, in *OmciMsg, opts ...grpc.CallOption) (*Empty, error) {
+	out := new(Empty)
+	err := c.cc.Invoke(ctx, "/openolt.Openolt/OmciMsgOut", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *openoltClient) OnuPacketOut(ctx context.Context, in *OnuPacket, opts ...grpc.CallOption) (*Empty, error) {
+	out := new(Empty)
+	err := c.cc.Invoke(ctx, "/openolt.Openolt/OnuPacketOut", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *openoltClient) UplinkPacketOut(ctx context.Context, in *UplinkPacket, opts ...grpc.CallOption) (*Empty, error) {
+	out := new(Empty)
+	err := c.cc.Invoke(ctx, "/openolt.Openolt/UplinkPacketOut", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *openoltClient) FlowAdd(ctx context.Context, in *Flow, opts ...grpc.CallOption) (*Empty, error) {
+	out := new(Empty)
+	err := c.cc.Invoke(ctx, "/openolt.Openolt/FlowAdd", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *openoltClient) FlowRemove(ctx context.Context, in *Flow, opts ...grpc.CallOption) (*Empty, error) {
+	out := new(Empty)
+	err := c.cc.Invoke(ctx, "/openolt.Openolt/FlowRemove", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *openoltClient) HeartbeatCheck(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*Heartbeat, error) {
+	out := new(Heartbeat)
+	err := c.cc.Invoke(ctx, "/openolt.Openolt/HeartbeatCheck", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *openoltClient) EnablePonIf(ctx context.Context, in *Interface, opts ...grpc.CallOption) (*Empty, error) {
+	out := new(Empty)
+	err := c.cc.Invoke(ctx, "/openolt.Openolt/EnablePonIf", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *openoltClient) DisablePonIf(ctx context.Context, in *Interface, opts ...grpc.CallOption) (*Empty, error) {
+	out := new(Empty)
+	err := c.cc.Invoke(ctx, "/openolt.Openolt/DisablePonIf", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *openoltClient) GetDeviceInfo(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*DeviceInfo, error) {
+	out := new(DeviceInfo)
+	err := c.cc.Invoke(ctx, "/openolt.Openolt/GetDeviceInfo", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *openoltClient) Reboot(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*Empty, error) {
+	out := new(Empty)
+	err := c.cc.Invoke(ctx, "/openolt.Openolt/Reboot", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *openoltClient) CollectStatistics(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*Empty, error) {
+	out := new(Empty)
+	err := c.cc.Invoke(ctx, "/openolt.Openolt/CollectStatistics", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *openoltClient) GetOnuStatistics(ctx context.Context, in *Onu, opts ...grpc.CallOption) (*OnuStatistics, error) {
+	out := new(OnuStatistics)
+	err := c.cc.Invoke(ctx, "/openolt.Openolt/GetOnuStatistics", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *openoltClient) GetGemPortStatistics(ctx context.Context, in *OnuPacket, opts ...grpc.CallOption) (*GemPortStatistics, error) {
+	out := new(GemPortStatistics)
+	err := c.cc.Invoke(ctx, "/openolt.Openolt/GetGemPortStatistics", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *openoltClient) CreateTrafficSchedulers(ctx context.Context, in *tech_profile.TrafficSchedulers, opts ...grpc.CallOption) (*Empty, error) {
+	out := new(Empty)
+	err := c.cc.Invoke(ctx, "/openolt.Openolt/CreateTrafficSchedulers", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *openoltClient) RemoveTrafficSchedulers(ctx context.Context, in *tech_profile.TrafficSchedulers, opts ...grpc.CallOption) (*Empty, error) {
+	out := new(Empty)
+	err := c.cc.Invoke(ctx, "/openolt.Openolt/RemoveTrafficSchedulers", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *openoltClient) CreateTrafficQueues(ctx context.Context, in *tech_profile.TrafficQueues, opts ...grpc.CallOption) (*Empty, error) {
+	out := new(Empty)
+	err := c.cc.Invoke(ctx, "/openolt.Openolt/CreateTrafficQueues", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *openoltClient) RemoveTrafficQueues(ctx context.Context, in *tech_profile.TrafficQueues, opts ...grpc.CallOption) (*Empty, error) {
+	out := new(Empty)
+	err := c.cc.Invoke(ctx, "/openolt.Openolt/RemoveTrafficQueues", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *openoltClient) EnableIndication(ctx context.Context, in *Empty, opts ...grpc.CallOption) (Openolt_EnableIndicationClient, error) {
+	stream, err := c.cc.NewStream(ctx, &_Openolt_serviceDesc.Streams[0], "/openolt.Openolt/EnableIndication", opts...)
+	if err != nil {
+		return nil, err
+	}
+	x := &openoltEnableIndicationClient{stream}
+	if err := x.ClientStream.SendMsg(in); err != nil {
+		return nil, err
+	}
+	if err := x.ClientStream.CloseSend(); err != nil {
+		return nil, err
+	}
+	return x, nil
+}
+
+type Openolt_EnableIndicationClient interface {
+	Recv() (*Indication, error)
+	grpc.ClientStream
+}
+
+type openoltEnableIndicationClient struct {
+	grpc.ClientStream
+}
+
+func (x *openoltEnableIndicationClient) Recv() (*Indication, error) {
+	m := new(Indication)
+	if err := x.ClientStream.RecvMsg(m); err != nil {
+		return nil, err
+	}
+	return m, nil
+}
+
+func (c *openoltClient) PerformGroupOperation(ctx context.Context, in *Group, opts ...grpc.CallOption) (*Empty, error) {
+	out := new(Empty)
+	err := c.cc.Invoke(ctx, "/openolt.Openolt/PerformGroupOperation", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *openoltClient) DeleteGroup(ctx context.Context, in *Group, opts ...grpc.CallOption) (*Empty, error) {
+	out := new(Empty)
+	err := c.cc.Invoke(ctx, "/openolt.Openolt/DeleteGroup", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *openoltClient) GetExtValue(ctx context.Context, in *ValueParam, opts ...grpc.CallOption) (*extension.ReturnValues, error) {
+	out := new(extension.ReturnValues)
+	err := c.cc.Invoke(ctx, "/openolt.Openolt/GetExtValue", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *openoltClient) OnuItuPonAlarmSet(ctx context.Context, in *config.OnuItuPonAlarm, opts ...grpc.CallOption) (*Empty, error) {
+	out := new(Empty)
+	err := c.cc.Invoke(ctx, "/openolt.Openolt/OnuItuPonAlarmSet", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *openoltClient) GetLogicalOnuDistanceZero(ctx context.Context, in *Onu, opts ...grpc.CallOption) (*OnuLogicalDistance, error) {
+	out := new(OnuLogicalDistance)
+	err := c.cc.Invoke(ctx, "/openolt.Openolt/GetLogicalOnuDistanceZero", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *openoltClient) GetLogicalOnuDistance(ctx context.Context, in *Onu, opts ...grpc.CallOption) (*OnuLogicalDistance, error) {
+	out := new(OnuLogicalDistance)
+	err := c.cc.Invoke(ctx, "/openolt.Openolt/GetLogicalOnuDistance", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *openoltClient) GetPonRxPower(ctx context.Context, in *Onu, opts ...grpc.CallOption) (*PonRxPowerData, error) {
+	out := new(PonRxPowerData)
+	err := c.cc.Invoke(ctx, "/openolt.Openolt/GetPonRxPower", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+// OpenoltServer is the server API for Openolt service.
+type OpenoltServer interface {
+	DisableOlt(context.Context, *Empty) (*Empty, error)
+	ReenableOlt(context.Context, *Empty) (*Empty, error)
+	ActivateOnu(context.Context, *Onu) (*Empty, error)
+	DeactivateOnu(context.Context, *Onu) (*Empty, error)
+	DeleteOnu(context.Context, *Onu) (*Empty, error)
+	OmciMsgOut(context.Context, *OmciMsg) (*Empty, error)
+	OnuPacketOut(context.Context, *OnuPacket) (*Empty, error)
+	UplinkPacketOut(context.Context, *UplinkPacket) (*Empty, error)
+	FlowAdd(context.Context, *Flow) (*Empty, error)
+	FlowRemove(context.Context, *Flow) (*Empty, error)
+	HeartbeatCheck(context.Context, *Empty) (*Heartbeat, error)
+	EnablePonIf(context.Context, *Interface) (*Empty, error)
+	DisablePonIf(context.Context, *Interface) (*Empty, error)
+	GetDeviceInfo(context.Context, *Empty) (*DeviceInfo, error)
+	Reboot(context.Context, *Empty) (*Empty, error)
+	CollectStatistics(context.Context, *Empty) (*Empty, error)
+	GetOnuStatistics(context.Context, *Onu) (*OnuStatistics, error)
+	GetGemPortStatistics(context.Context, *OnuPacket) (*GemPortStatistics, error)
+	CreateTrafficSchedulers(context.Context, *tech_profile.TrafficSchedulers) (*Empty, error)
+	RemoveTrafficSchedulers(context.Context, *tech_profile.TrafficSchedulers) (*Empty, error)
+	CreateTrafficQueues(context.Context, *tech_profile.TrafficQueues) (*Empty, error)
+	RemoveTrafficQueues(context.Context, *tech_profile.TrafficQueues) (*Empty, error)
+	EnableIndication(*Empty, Openolt_EnableIndicationServer) error
+	PerformGroupOperation(context.Context, *Group) (*Empty, error)
+	DeleteGroup(context.Context, *Group) (*Empty, error)
+	GetExtValue(context.Context, *ValueParam) (*extension.ReturnValues, error)
+	OnuItuPonAlarmSet(context.Context, *config.OnuItuPonAlarm) (*Empty, error)
+	GetLogicalOnuDistanceZero(context.Context, *Onu) (*OnuLogicalDistance, error)
+	GetLogicalOnuDistance(context.Context, *Onu) (*OnuLogicalDistance, error)
+	GetPonRxPower(context.Context, *Onu) (*PonRxPowerData, error)
+}
+
+// UnimplementedOpenoltServer can be embedded to have forward compatible implementations.
+type UnimplementedOpenoltServer struct {
+}
+
+func (*UnimplementedOpenoltServer) DisableOlt(ctx context.Context, req *Empty) (*Empty, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method DisableOlt not implemented")
+}
+func (*UnimplementedOpenoltServer) ReenableOlt(ctx context.Context, req *Empty) (*Empty, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method ReenableOlt not implemented")
+}
+func (*UnimplementedOpenoltServer) ActivateOnu(ctx context.Context, req *Onu) (*Empty, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method ActivateOnu not implemented")
+}
+func (*UnimplementedOpenoltServer) DeactivateOnu(ctx context.Context, req *Onu) (*Empty, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method DeactivateOnu not implemented")
+}
+func (*UnimplementedOpenoltServer) DeleteOnu(ctx context.Context, req *Onu) (*Empty, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method DeleteOnu not implemented")
+}
+func (*UnimplementedOpenoltServer) OmciMsgOut(ctx context.Context, req *OmciMsg) (*Empty, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method OmciMsgOut not implemented")
+}
+func (*UnimplementedOpenoltServer) OnuPacketOut(ctx context.Context, req *OnuPacket) (*Empty, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method OnuPacketOut not implemented")
+}
+func (*UnimplementedOpenoltServer) UplinkPacketOut(ctx context.Context, req *UplinkPacket) (*Empty, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method UplinkPacketOut not implemented")
+}
+func (*UnimplementedOpenoltServer) FlowAdd(ctx context.Context, req *Flow) (*Empty, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method FlowAdd not implemented")
+}
+func (*UnimplementedOpenoltServer) FlowRemove(ctx context.Context, req *Flow) (*Empty, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method FlowRemove not implemented")
+}
+func (*UnimplementedOpenoltServer) HeartbeatCheck(ctx context.Context, req *Empty) (*Heartbeat, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method HeartbeatCheck not implemented")
+}
+func (*UnimplementedOpenoltServer) EnablePonIf(ctx context.Context, req *Interface) (*Empty, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method EnablePonIf not implemented")
+}
+func (*UnimplementedOpenoltServer) DisablePonIf(ctx context.Context, req *Interface) (*Empty, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method DisablePonIf not implemented")
+}
+func (*UnimplementedOpenoltServer) GetDeviceInfo(ctx context.Context, req *Empty) (*DeviceInfo, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method GetDeviceInfo not implemented")
+}
+func (*UnimplementedOpenoltServer) Reboot(ctx context.Context, req *Empty) (*Empty, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method Reboot not implemented")
+}
+func (*UnimplementedOpenoltServer) CollectStatistics(ctx context.Context, req *Empty) (*Empty, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method CollectStatistics not implemented")
+}
+func (*UnimplementedOpenoltServer) GetOnuStatistics(ctx context.Context, req *Onu) (*OnuStatistics, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method GetOnuStatistics not implemented")
+}
+func (*UnimplementedOpenoltServer) GetGemPortStatistics(ctx context.Context, req *OnuPacket) (*GemPortStatistics, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method GetGemPortStatistics not implemented")
+}
+func (*UnimplementedOpenoltServer) CreateTrafficSchedulers(ctx context.Context, req *tech_profile.TrafficSchedulers) (*Empty, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method CreateTrafficSchedulers not implemented")
+}
+func (*UnimplementedOpenoltServer) RemoveTrafficSchedulers(ctx context.Context, req *tech_profile.TrafficSchedulers) (*Empty, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method RemoveTrafficSchedulers not implemented")
+}
+func (*UnimplementedOpenoltServer) CreateTrafficQueues(ctx context.Context, req *tech_profile.TrafficQueues) (*Empty, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method CreateTrafficQueues not implemented")
+}
+func (*UnimplementedOpenoltServer) RemoveTrafficQueues(ctx context.Context, req *tech_profile.TrafficQueues) (*Empty, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method RemoveTrafficQueues not implemented")
+}
+func (*UnimplementedOpenoltServer) EnableIndication(req *Empty, srv Openolt_EnableIndicationServer) error {
+	return status.Errorf(codes.Unimplemented, "method EnableIndication not implemented")
+}
+func (*UnimplementedOpenoltServer) PerformGroupOperation(ctx context.Context, req *Group) (*Empty, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method PerformGroupOperation not implemented")
+}
+func (*UnimplementedOpenoltServer) DeleteGroup(ctx context.Context, req *Group) (*Empty, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method DeleteGroup not implemented")
+}
+func (*UnimplementedOpenoltServer) GetExtValue(ctx context.Context, req *ValueParam) (*extension.ReturnValues, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method GetExtValue not implemented")
+}
+func (*UnimplementedOpenoltServer) OnuItuPonAlarmSet(ctx context.Context, req *config.OnuItuPonAlarm) (*Empty, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method OnuItuPonAlarmSet not implemented")
+}
+func (*UnimplementedOpenoltServer) GetLogicalOnuDistanceZero(ctx context.Context, req *Onu) (*OnuLogicalDistance, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method GetLogicalOnuDistanceZero not implemented")
+}
+func (*UnimplementedOpenoltServer) GetLogicalOnuDistance(ctx context.Context, req *Onu) (*OnuLogicalDistance, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method GetLogicalOnuDistance not implemented")
+}
+func (*UnimplementedOpenoltServer) GetPonRxPower(ctx context.Context, req *Onu) (*PonRxPowerData, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method GetPonRxPower not implemented")
+}
+
+func RegisterOpenoltServer(s *grpc.Server, srv OpenoltServer) {
+	s.RegisterService(&_Openolt_serviceDesc, srv)
+}
+
+func _Openolt_DisableOlt_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(Empty)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(OpenoltServer).DisableOlt(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/openolt.Openolt/DisableOlt",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(OpenoltServer).DisableOlt(ctx, req.(*Empty))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Openolt_ReenableOlt_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(Empty)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(OpenoltServer).ReenableOlt(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/openolt.Openolt/ReenableOlt",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(OpenoltServer).ReenableOlt(ctx, req.(*Empty))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Openolt_ActivateOnu_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(Onu)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(OpenoltServer).ActivateOnu(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/openolt.Openolt/ActivateOnu",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(OpenoltServer).ActivateOnu(ctx, req.(*Onu))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Openolt_DeactivateOnu_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(Onu)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(OpenoltServer).DeactivateOnu(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/openolt.Openolt/DeactivateOnu",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(OpenoltServer).DeactivateOnu(ctx, req.(*Onu))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Openolt_DeleteOnu_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(Onu)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(OpenoltServer).DeleteOnu(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/openolt.Openolt/DeleteOnu",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(OpenoltServer).DeleteOnu(ctx, req.(*Onu))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Openolt_OmciMsgOut_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(OmciMsg)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(OpenoltServer).OmciMsgOut(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/openolt.Openolt/OmciMsgOut",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(OpenoltServer).OmciMsgOut(ctx, req.(*OmciMsg))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Openolt_OnuPacketOut_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(OnuPacket)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(OpenoltServer).OnuPacketOut(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/openolt.Openolt/OnuPacketOut",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(OpenoltServer).OnuPacketOut(ctx, req.(*OnuPacket))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Openolt_UplinkPacketOut_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(UplinkPacket)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(OpenoltServer).UplinkPacketOut(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/openolt.Openolt/UplinkPacketOut",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(OpenoltServer).UplinkPacketOut(ctx, req.(*UplinkPacket))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Openolt_FlowAdd_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(Flow)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(OpenoltServer).FlowAdd(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/openolt.Openolt/FlowAdd",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(OpenoltServer).FlowAdd(ctx, req.(*Flow))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Openolt_FlowRemove_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(Flow)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(OpenoltServer).FlowRemove(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/openolt.Openolt/FlowRemove",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(OpenoltServer).FlowRemove(ctx, req.(*Flow))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Openolt_HeartbeatCheck_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(Empty)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(OpenoltServer).HeartbeatCheck(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/openolt.Openolt/HeartbeatCheck",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(OpenoltServer).HeartbeatCheck(ctx, req.(*Empty))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Openolt_EnablePonIf_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(Interface)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(OpenoltServer).EnablePonIf(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/openolt.Openolt/EnablePonIf",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(OpenoltServer).EnablePonIf(ctx, req.(*Interface))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Openolt_DisablePonIf_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(Interface)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(OpenoltServer).DisablePonIf(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/openolt.Openolt/DisablePonIf",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(OpenoltServer).DisablePonIf(ctx, req.(*Interface))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Openolt_GetDeviceInfo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(Empty)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(OpenoltServer).GetDeviceInfo(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/openolt.Openolt/GetDeviceInfo",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(OpenoltServer).GetDeviceInfo(ctx, req.(*Empty))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Openolt_Reboot_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(Empty)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(OpenoltServer).Reboot(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/openolt.Openolt/Reboot",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(OpenoltServer).Reboot(ctx, req.(*Empty))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Openolt_CollectStatistics_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(Empty)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(OpenoltServer).CollectStatistics(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/openolt.Openolt/CollectStatistics",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(OpenoltServer).CollectStatistics(ctx, req.(*Empty))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Openolt_GetOnuStatistics_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(Onu)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(OpenoltServer).GetOnuStatistics(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/openolt.Openolt/GetOnuStatistics",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(OpenoltServer).GetOnuStatistics(ctx, req.(*Onu))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Openolt_GetGemPortStatistics_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(OnuPacket)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(OpenoltServer).GetGemPortStatistics(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/openolt.Openolt/GetGemPortStatistics",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(OpenoltServer).GetGemPortStatistics(ctx, req.(*OnuPacket))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Openolt_CreateTrafficSchedulers_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(tech_profile.TrafficSchedulers)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(OpenoltServer).CreateTrafficSchedulers(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/openolt.Openolt/CreateTrafficSchedulers",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(OpenoltServer).CreateTrafficSchedulers(ctx, req.(*tech_profile.TrafficSchedulers))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Openolt_RemoveTrafficSchedulers_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(tech_profile.TrafficSchedulers)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(OpenoltServer).RemoveTrafficSchedulers(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/openolt.Openolt/RemoveTrafficSchedulers",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(OpenoltServer).RemoveTrafficSchedulers(ctx, req.(*tech_profile.TrafficSchedulers))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Openolt_CreateTrafficQueues_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(tech_profile.TrafficQueues)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(OpenoltServer).CreateTrafficQueues(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/openolt.Openolt/CreateTrafficQueues",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(OpenoltServer).CreateTrafficQueues(ctx, req.(*tech_profile.TrafficQueues))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Openolt_RemoveTrafficQueues_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(tech_profile.TrafficQueues)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(OpenoltServer).RemoveTrafficQueues(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/openolt.Openolt/RemoveTrafficQueues",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(OpenoltServer).RemoveTrafficQueues(ctx, req.(*tech_profile.TrafficQueues))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Openolt_EnableIndication_Handler(srv interface{}, stream grpc.ServerStream) error {
+	m := new(Empty)
+	if err := stream.RecvMsg(m); err != nil {
+		return err
+	}
+	return srv.(OpenoltServer).EnableIndication(m, &openoltEnableIndicationServer{stream})
+}
+
+type Openolt_EnableIndicationServer interface {
+	Send(*Indication) error
+	grpc.ServerStream
+}
+
+type openoltEnableIndicationServer struct {
+	grpc.ServerStream
+}
+
+func (x *openoltEnableIndicationServer) Send(m *Indication) error {
+	return x.ServerStream.SendMsg(m)
+}
+
+func _Openolt_PerformGroupOperation_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(Group)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(OpenoltServer).PerformGroupOperation(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/openolt.Openolt/PerformGroupOperation",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(OpenoltServer).PerformGroupOperation(ctx, req.(*Group))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Openolt_DeleteGroup_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(Group)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(OpenoltServer).DeleteGroup(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/openolt.Openolt/DeleteGroup",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(OpenoltServer).DeleteGroup(ctx, req.(*Group))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Openolt_GetExtValue_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(ValueParam)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(OpenoltServer).GetExtValue(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/openolt.Openolt/GetExtValue",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(OpenoltServer).GetExtValue(ctx, req.(*ValueParam))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Openolt_OnuItuPonAlarmSet_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(config.OnuItuPonAlarm)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(OpenoltServer).OnuItuPonAlarmSet(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/openolt.Openolt/OnuItuPonAlarmSet",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(OpenoltServer).OnuItuPonAlarmSet(ctx, req.(*config.OnuItuPonAlarm))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Openolt_GetLogicalOnuDistanceZero_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(Onu)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(OpenoltServer).GetLogicalOnuDistanceZero(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/openolt.Openolt/GetLogicalOnuDistanceZero",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(OpenoltServer).GetLogicalOnuDistanceZero(ctx, req.(*Onu))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Openolt_GetLogicalOnuDistance_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(Onu)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(OpenoltServer).GetLogicalOnuDistance(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/openolt.Openolt/GetLogicalOnuDistance",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(OpenoltServer).GetLogicalOnuDistance(ctx, req.(*Onu))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Openolt_GetPonRxPower_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(Onu)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(OpenoltServer).GetPonRxPower(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/openolt.Openolt/GetPonRxPower",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(OpenoltServer).GetPonRxPower(ctx, req.(*Onu))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+var _Openolt_serviceDesc = grpc.ServiceDesc{
+	ServiceName: "openolt.Openolt",
+	HandlerType: (*OpenoltServer)(nil),
+	Methods: []grpc.MethodDesc{
+		{
+			MethodName: "DisableOlt",
+			Handler:    _Openolt_DisableOlt_Handler,
+		},
+		{
+			MethodName: "ReenableOlt",
+			Handler:    _Openolt_ReenableOlt_Handler,
+		},
+		{
+			MethodName: "ActivateOnu",
+			Handler:    _Openolt_ActivateOnu_Handler,
+		},
+		{
+			MethodName: "DeactivateOnu",
+			Handler:    _Openolt_DeactivateOnu_Handler,
+		},
+		{
+			MethodName: "DeleteOnu",
+			Handler:    _Openolt_DeleteOnu_Handler,
+		},
+		{
+			MethodName: "OmciMsgOut",
+			Handler:    _Openolt_OmciMsgOut_Handler,
+		},
+		{
+			MethodName: "OnuPacketOut",
+			Handler:    _Openolt_OnuPacketOut_Handler,
+		},
+		{
+			MethodName: "UplinkPacketOut",
+			Handler:    _Openolt_UplinkPacketOut_Handler,
+		},
+		{
+			MethodName: "FlowAdd",
+			Handler:    _Openolt_FlowAdd_Handler,
+		},
+		{
+			MethodName: "FlowRemove",
+			Handler:    _Openolt_FlowRemove_Handler,
+		},
+		{
+			MethodName: "HeartbeatCheck",
+			Handler:    _Openolt_HeartbeatCheck_Handler,
+		},
+		{
+			MethodName: "EnablePonIf",
+			Handler:    _Openolt_EnablePonIf_Handler,
+		},
+		{
+			MethodName: "DisablePonIf",
+			Handler:    _Openolt_DisablePonIf_Handler,
+		},
+		{
+			MethodName: "GetDeviceInfo",
+			Handler:    _Openolt_GetDeviceInfo_Handler,
+		},
+		{
+			MethodName: "Reboot",
+			Handler:    _Openolt_Reboot_Handler,
+		},
+		{
+			MethodName: "CollectStatistics",
+			Handler:    _Openolt_CollectStatistics_Handler,
+		},
+		{
+			MethodName: "GetOnuStatistics",
+			Handler:    _Openolt_GetOnuStatistics_Handler,
+		},
+		{
+			MethodName: "GetGemPortStatistics",
+			Handler:    _Openolt_GetGemPortStatistics_Handler,
+		},
+		{
+			MethodName: "CreateTrafficSchedulers",
+			Handler:    _Openolt_CreateTrafficSchedulers_Handler,
+		},
+		{
+			MethodName: "RemoveTrafficSchedulers",
+			Handler:    _Openolt_RemoveTrafficSchedulers_Handler,
+		},
+		{
+			MethodName: "CreateTrafficQueues",
+			Handler:    _Openolt_CreateTrafficQueues_Handler,
+		},
+		{
+			MethodName: "RemoveTrafficQueues",
+			Handler:    _Openolt_RemoveTrafficQueues_Handler,
+		},
+		{
+			MethodName: "PerformGroupOperation",
+			Handler:    _Openolt_PerformGroupOperation_Handler,
+		},
+		{
+			MethodName: "DeleteGroup",
+			Handler:    _Openolt_DeleteGroup_Handler,
+		},
+		{
+			MethodName: "GetExtValue",
+			Handler:    _Openolt_GetExtValue_Handler,
+		},
+		{
+			MethodName: "OnuItuPonAlarmSet",
+			Handler:    _Openolt_OnuItuPonAlarmSet_Handler,
+		},
+		{
+			MethodName: "GetLogicalOnuDistanceZero",
+			Handler:    _Openolt_GetLogicalOnuDistanceZero_Handler,
+		},
+		{
+			MethodName: "GetLogicalOnuDistance",
+			Handler:    _Openolt_GetLogicalOnuDistance_Handler,
+		},
+		{
+			MethodName: "GetPonRxPower",
+			Handler:    _Openolt_GetPonRxPower_Handler,
+		},
+	},
+	Streams: []grpc.StreamDesc{
+		{
+			StreamName:    "EnableIndication",
+			Handler:       _Openolt_EnableIndication_Handler,
+			ServerStreams: true,
+		},
+	},
+	Metadata: "voltha_protos/openolt.proto",
+}
diff --git a/vendor/github.com/opencord/voltha-protos/v5/go/tech_profile/tech_profile.pb.go b/vendor/github.com/opencord/voltha-protos/v5/go/tech_profile/tech_profile.pb.go
new file mode 100644
index 0000000..85f717a
--- /dev/null
+++ b/vendor/github.com/opencord/voltha-protos/v5/go/tech_profile/tech_profile.pb.go
@@ -0,0 +1,2089 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// source: voltha_protos/tech_profile.proto
+
+package tech_profile
+
+import (
+	fmt "fmt"
+	proto "github.com/golang/protobuf/proto"
+	_ "google.golang.org/genproto/googleapis/api/annotations"
+	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
+
+type Direction int32
+
+const (
+	Direction_UPSTREAM      Direction = 0
+	Direction_DOWNSTREAM    Direction = 1
+	Direction_BIDIRECTIONAL Direction = 2
+)
+
+var Direction_name = map[int32]string{
+	0: "UPSTREAM",
+	1: "DOWNSTREAM",
+	2: "BIDIRECTIONAL",
+}
+
+var Direction_value = map[string]int32{
+	"UPSTREAM":      0,
+	"DOWNSTREAM":    1,
+	"BIDIRECTIONAL": 2,
+}
+
+func (x Direction) String() string {
+	return proto.EnumName(Direction_name, int32(x))
+}
+
+func (Direction) EnumDescriptor() ([]byte, []int) {
+	return fileDescriptor_d019a68bffe14cae, []int{0}
+}
+
+type SchedulingPolicy int32
+
+const (
+	SchedulingPolicy_WRR            SchedulingPolicy = 0
+	SchedulingPolicy_StrictPriority SchedulingPolicy = 1
+	SchedulingPolicy_Hybrid         SchedulingPolicy = 2
+)
+
+var SchedulingPolicy_name = map[int32]string{
+	0: "WRR",
+	1: "StrictPriority",
+	2: "Hybrid",
+}
+
+var SchedulingPolicy_value = map[string]int32{
+	"WRR":            0,
+	"StrictPriority": 1,
+	"Hybrid":         2,
+}
+
+func (x SchedulingPolicy) String() string {
+	return proto.EnumName(SchedulingPolicy_name, int32(x))
+}
+
+func (SchedulingPolicy) EnumDescriptor() ([]byte, []int) {
+	return fileDescriptor_d019a68bffe14cae, []int{1}
+}
+
+type AdditionalBW int32
+
+const (
+	AdditionalBW_AdditionalBW_None       AdditionalBW = 0
+	AdditionalBW_AdditionalBW_NA         AdditionalBW = 1
+	AdditionalBW_AdditionalBW_BestEffort AdditionalBW = 2
+	AdditionalBW_AdditionalBW_Auto       AdditionalBW = 3
+)
+
+var AdditionalBW_name = map[int32]string{
+	0: "AdditionalBW_None",
+	1: "AdditionalBW_NA",
+	2: "AdditionalBW_BestEffort",
+	3: "AdditionalBW_Auto",
+}
+
+var AdditionalBW_value = map[string]int32{
+	"AdditionalBW_None":       0,
+	"AdditionalBW_NA":         1,
+	"AdditionalBW_BestEffort": 2,
+	"AdditionalBW_Auto":       3,
+}
+
+func (x AdditionalBW) String() string {
+	return proto.EnumName(AdditionalBW_name, int32(x))
+}
+
+func (AdditionalBW) EnumDescriptor() ([]byte, []int) {
+	return fileDescriptor_d019a68bffe14cae, []int{2}
+}
+
+type DiscardPolicy int32
+
+const (
+	DiscardPolicy_TailDrop  DiscardPolicy = 0
+	DiscardPolicy_WTailDrop DiscardPolicy = 1
+	DiscardPolicy_Red       DiscardPolicy = 2
+	DiscardPolicy_WRed      DiscardPolicy = 3
+)
+
+var DiscardPolicy_name = map[int32]string{
+	0: "TailDrop",
+	1: "WTailDrop",
+	2: "Red",
+	3: "WRed",
+}
+
+var DiscardPolicy_value = map[string]int32{
+	"TailDrop":  0,
+	"WTailDrop": 1,
+	"Red":       2,
+	"WRed":      3,
+}
+
+func (x DiscardPolicy) String() string {
+	return proto.EnumName(DiscardPolicy_name, int32(x))
+}
+
+func (DiscardPolicy) EnumDescriptor() ([]byte, []int) {
+	return fileDescriptor_d019a68bffe14cae, []int{3}
+}
+
+type InferredAdditionBWIndication int32
+
+const (
+	InferredAdditionBWIndication_InferredAdditionBWIndication_None       InferredAdditionBWIndication = 0
+	InferredAdditionBWIndication_InferredAdditionBWIndication_Assured    InferredAdditionBWIndication = 1
+	InferredAdditionBWIndication_InferredAdditionBWIndication_BestEffort InferredAdditionBWIndication = 2
+)
+
+var InferredAdditionBWIndication_name = map[int32]string{
+	0: "InferredAdditionBWIndication_None",
+	1: "InferredAdditionBWIndication_Assured",
+	2: "InferredAdditionBWIndication_BestEffort",
+}
+
+var InferredAdditionBWIndication_value = map[string]int32{
+	"InferredAdditionBWIndication_None":       0,
+	"InferredAdditionBWIndication_Assured":    1,
+	"InferredAdditionBWIndication_BestEffort": 2,
+}
+
+func (x InferredAdditionBWIndication) String() string {
+	return proto.EnumName(InferredAdditionBWIndication_name, int32(x))
+}
+
+func (InferredAdditionBWIndication) EnumDescriptor() ([]byte, []int) {
+	return fileDescriptor_d019a68bffe14cae, []int{4}
+}
+
+type SchedulerConfig struct {
+	Direction            Direction        `protobuf:"varint,1,opt,name=direction,proto3,enum=tech_profile.Direction" json:"direction,omitempty"`
+	AdditionalBw         AdditionalBW     `protobuf:"varint,2,opt,name=additional_bw,json=additionalBw,proto3,enum=tech_profile.AdditionalBW" json:"additional_bw,omitempty"`
+	Priority             uint32           `protobuf:"fixed32,3,opt,name=priority,proto3" json:"priority,omitempty"`
+	Weight               uint32           `protobuf:"fixed32,4,opt,name=weight,proto3" json:"weight,omitempty"`
+	SchedPolicy          SchedulingPolicy `protobuf:"varint,5,opt,name=sched_policy,json=schedPolicy,proto3,enum=tech_profile.SchedulingPolicy" json:"sched_policy,omitempty"`
+	XXX_NoUnkeyedLiteral struct{}         `json:"-"`
+	XXX_unrecognized     []byte           `json:"-"`
+	XXX_sizecache        int32            `json:"-"`
+}
+
+func (m *SchedulerConfig) Reset()         { *m = SchedulerConfig{} }
+func (m *SchedulerConfig) String() string { return proto.CompactTextString(m) }
+func (*SchedulerConfig) ProtoMessage()    {}
+func (*SchedulerConfig) Descriptor() ([]byte, []int) {
+	return fileDescriptor_d019a68bffe14cae, []int{0}
+}
+
+func (m *SchedulerConfig) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_SchedulerConfig.Unmarshal(m, b)
+}
+func (m *SchedulerConfig) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_SchedulerConfig.Marshal(b, m, deterministic)
+}
+func (m *SchedulerConfig) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_SchedulerConfig.Merge(m, src)
+}
+func (m *SchedulerConfig) XXX_Size() int {
+	return xxx_messageInfo_SchedulerConfig.Size(m)
+}
+func (m *SchedulerConfig) XXX_DiscardUnknown() {
+	xxx_messageInfo_SchedulerConfig.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_SchedulerConfig proto.InternalMessageInfo
+
+func (m *SchedulerConfig) GetDirection() Direction {
+	if m != nil {
+		return m.Direction
+	}
+	return Direction_UPSTREAM
+}
+
+func (m *SchedulerConfig) GetAdditionalBw() AdditionalBW {
+	if m != nil {
+		return m.AdditionalBw
+	}
+	return AdditionalBW_AdditionalBW_None
+}
+
+func (m *SchedulerConfig) GetPriority() uint32 {
+	if m != nil {
+		return m.Priority
+	}
+	return 0
+}
+
+func (m *SchedulerConfig) GetWeight() uint32 {
+	if m != nil {
+		return m.Weight
+	}
+	return 0
+}
+
+func (m *SchedulerConfig) GetSchedPolicy() SchedulingPolicy {
+	if m != nil {
+		return m.SchedPolicy
+	}
+	return SchedulingPolicy_WRR
+}
+
+type TrafficShapingInfo struct {
+	Cir                  uint32                       `protobuf:"fixed32,1,opt,name=cir,proto3" json:"cir,omitempty"`
+	Cbs                  uint32                       `protobuf:"fixed32,2,opt,name=cbs,proto3" json:"cbs,omitempty"`
+	Pir                  uint32                       `protobuf:"fixed32,3,opt,name=pir,proto3" json:"pir,omitempty"`
+	Pbs                  uint32                       `protobuf:"fixed32,4,opt,name=pbs,proto3" json:"pbs,omitempty"`
+	Gir                  uint32                       `protobuf:"fixed32,5,opt,name=gir,proto3" json:"gir,omitempty"`
+	AddBwInd             InferredAdditionBWIndication `protobuf:"varint,6,opt,name=add_bw_ind,json=addBwInd,proto3,enum=tech_profile.InferredAdditionBWIndication" json:"add_bw_ind,omitempty"`
+	XXX_NoUnkeyedLiteral struct{}                     `json:"-"`
+	XXX_unrecognized     []byte                       `json:"-"`
+	XXX_sizecache        int32                        `json:"-"`
+}
+
+func (m *TrafficShapingInfo) Reset()         { *m = TrafficShapingInfo{} }
+func (m *TrafficShapingInfo) String() string { return proto.CompactTextString(m) }
+func (*TrafficShapingInfo) ProtoMessage()    {}
+func (*TrafficShapingInfo) Descriptor() ([]byte, []int) {
+	return fileDescriptor_d019a68bffe14cae, []int{1}
+}
+
+func (m *TrafficShapingInfo) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_TrafficShapingInfo.Unmarshal(m, b)
+}
+func (m *TrafficShapingInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_TrafficShapingInfo.Marshal(b, m, deterministic)
+}
+func (m *TrafficShapingInfo) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_TrafficShapingInfo.Merge(m, src)
+}
+func (m *TrafficShapingInfo) XXX_Size() int {
+	return xxx_messageInfo_TrafficShapingInfo.Size(m)
+}
+func (m *TrafficShapingInfo) XXX_DiscardUnknown() {
+	xxx_messageInfo_TrafficShapingInfo.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_TrafficShapingInfo proto.InternalMessageInfo
+
+func (m *TrafficShapingInfo) GetCir() uint32 {
+	if m != nil {
+		return m.Cir
+	}
+	return 0
+}
+
+func (m *TrafficShapingInfo) GetCbs() uint32 {
+	if m != nil {
+		return m.Cbs
+	}
+	return 0
+}
+
+func (m *TrafficShapingInfo) GetPir() uint32 {
+	if m != nil {
+		return m.Pir
+	}
+	return 0
+}
+
+func (m *TrafficShapingInfo) GetPbs() uint32 {
+	if m != nil {
+		return m.Pbs
+	}
+	return 0
+}
+
+func (m *TrafficShapingInfo) GetGir() uint32 {
+	if m != nil {
+		return m.Gir
+	}
+	return 0
+}
+
+func (m *TrafficShapingInfo) GetAddBwInd() InferredAdditionBWIndication {
+	if m != nil {
+		return m.AddBwInd
+	}
+	return InferredAdditionBWIndication_InferredAdditionBWIndication_None
+}
+
+type TrafficScheduler struct {
+	Direction            Direction           `protobuf:"varint,1,opt,name=direction,proto3,enum=tech_profile.Direction" json:"direction,omitempty"`
+	AllocId              uint32              `protobuf:"fixed32,2,opt,name=alloc_id,json=allocId,proto3" json:"alloc_id,omitempty"`
+	Scheduler            *SchedulerConfig    `protobuf:"bytes,3,opt,name=scheduler,proto3" json:"scheduler,omitempty"`
+	TrafficShapingInfo   *TrafficShapingInfo `protobuf:"bytes,4,opt,name=traffic_shaping_info,json=trafficShapingInfo,proto3" json:"traffic_shaping_info,omitempty"`
+	TechProfileId        uint32              `protobuf:"fixed32,5,opt,name=tech_profile_id,json=techProfileId,proto3" json:"tech_profile_id,omitempty"`
+	XXX_NoUnkeyedLiteral struct{}            `json:"-"`
+	XXX_unrecognized     []byte              `json:"-"`
+	XXX_sizecache        int32               `json:"-"`
+}
+
+func (m *TrafficScheduler) Reset()         { *m = TrafficScheduler{} }
+func (m *TrafficScheduler) String() string { return proto.CompactTextString(m) }
+func (*TrafficScheduler) ProtoMessage()    {}
+func (*TrafficScheduler) Descriptor() ([]byte, []int) {
+	return fileDescriptor_d019a68bffe14cae, []int{2}
+}
+
+func (m *TrafficScheduler) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_TrafficScheduler.Unmarshal(m, b)
+}
+func (m *TrafficScheduler) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_TrafficScheduler.Marshal(b, m, deterministic)
+}
+func (m *TrafficScheduler) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_TrafficScheduler.Merge(m, src)
+}
+func (m *TrafficScheduler) XXX_Size() int {
+	return xxx_messageInfo_TrafficScheduler.Size(m)
+}
+func (m *TrafficScheduler) XXX_DiscardUnknown() {
+	xxx_messageInfo_TrafficScheduler.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_TrafficScheduler proto.InternalMessageInfo
+
+func (m *TrafficScheduler) GetDirection() Direction {
+	if m != nil {
+		return m.Direction
+	}
+	return Direction_UPSTREAM
+}
+
+func (m *TrafficScheduler) GetAllocId() uint32 {
+	if m != nil {
+		return m.AllocId
+	}
+	return 0
+}
+
+func (m *TrafficScheduler) GetScheduler() *SchedulerConfig {
+	if m != nil {
+		return m.Scheduler
+	}
+	return nil
+}
+
+func (m *TrafficScheduler) GetTrafficShapingInfo() *TrafficShapingInfo {
+	if m != nil {
+		return m.TrafficShapingInfo
+	}
+	return nil
+}
+
+func (m *TrafficScheduler) GetTechProfileId() uint32 {
+	if m != nil {
+		return m.TechProfileId
+	}
+	return 0
+}
+
+type TrafficSchedulers struct {
+	IntfId               uint32              `protobuf:"fixed32,1,opt,name=intf_id,json=intfId,proto3" json:"intf_id,omitempty"`
+	OnuId                uint32              `protobuf:"fixed32,2,opt,name=onu_id,json=onuId,proto3" json:"onu_id,omitempty"`
+	UniId                uint32              `protobuf:"fixed32,4,opt,name=uni_id,json=uniId,proto3" json:"uni_id,omitempty"`
+	PortNo               uint32              `protobuf:"fixed32,5,opt,name=port_no,json=portNo,proto3" json:"port_no,omitempty"`
+	TrafficScheds        []*TrafficScheduler `protobuf:"bytes,3,rep,name=traffic_scheds,json=trafficScheds,proto3" json:"traffic_scheds,omitempty"`
+	XXX_NoUnkeyedLiteral struct{}            `json:"-"`
+	XXX_unrecognized     []byte              `json:"-"`
+	XXX_sizecache        int32               `json:"-"`
+}
+
+func (m *TrafficSchedulers) Reset()         { *m = TrafficSchedulers{} }
+func (m *TrafficSchedulers) String() string { return proto.CompactTextString(m) }
+func (*TrafficSchedulers) ProtoMessage()    {}
+func (*TrafficSchedulers) Descriptor() ([]byte, []int) {
+	return fileDescriptor_d019a68bffe14cae, []int{3}
+}
+
+func (m *TrafficSchedulers) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_TrafficSchedulers.Unmarshal(m, b)
+}
+func (m *TrafficSchedulers) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_TrafficSchedulers.Marshal(b, m, deterministic)
+}
+func (m *TrafficSchedulers) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_TrafficSchedulers.Merge(m, src)
+}
+func (m *TrafficSchedulers) XXX_Size() int {
+	return xxx_messageInfo_TrafficSchedulers.Size(m)
+}
+func (m *TrafficSchedulers) XXX_DiscardUnknown() {
+	xxx_messageInfo_TrafficSchedulers.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_TrafficSchedulers proto.InternalMessageInfo
+
+func (m *TrafficSchedulers) GetIntfId() uint32 {
+	if m != nil {
+		return m.IntfId
+	}
+	return 0
+}
+
+func (m *TrafficSchedulers) GetOnuId() uint32 {
+	if m != nil {
+		return m.OnuId
+	}
+	return 0
+}
+
+func (m *TrafficSchedulers) GetUniId() uint32 {
+	if m != nil {
+		return m.UniId
+	}
+	return 0
+}
+
+func (m *TrafficSchedulers) GetPortNo() uint32 {
+	if m != nil {
+		return m.PortNo
+	}
+	return 0
+}
+
+func (m *TrafficSchedulers) GetTrafficScheds() []*TrafficScheduler {
+	if m != nil {
+		return m.TrafficScheds
+	}
+	return nil
+}
+
+type TailDropDiscardConfig struct {
+	QueueSize            uint32   `protobuf:"fixed32,1,opt,name=queue_size,json=queueSize,proto3" json:"queue_size,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *TailDropDiscardConfig) Reset()         { *m = TailDropDiscardConfig{} }
+func (m *TailDropDiscardConfig) String() string { return proto.CompactTextString(m) }
+func (*TailDropDiscardConfig) ProtoMessage()    {}
+func (*TailDropDiscardConfig) Descriptor() ([]byte, []int) {
+	return fileDescriptor_d019a68bffe14cae, []int{4}
+}
+
+func (m *TailDropDiscardConfig) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_TailDropDiscardConfig.Unmarshal(m, b)
+}
+func (m *TailDropDiscardConfig) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_TailDropDiscardConfig.Marshal(b, m, deterministic)
+}
+func (m *TailDropDiscardConfig) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_TailDropDiscardConfig.Merge(m, src)
+}
+func (m *TailDropDiscardConfig) XXX_Size() int {
+	return xxx_messageInfo_TailDropDiscardConfig.Size(m)
+}
+func (m *TailDropDiscardConfig) XXX_DiscardUnknown() {
+	xxx_messageInfo_TailDropDiscardConfig.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_TailDropDiscardConfig proto.InternalMessageInfo
+
+func (m *TailDropDiscardConfig) GetQueueSize() uint32 {
+	if m != nil {
+		return m.QueueSize
+	}
+	return 0
+}
+
+type RedDiscardConfig struct {
+	MinThreshold         uint32   `protobuf:"fixed32,1,opt,name=min_threshold,json=minThreshold,proto3" json:"min_threshold,omitempty"`
+	MaxThreshold         uint32   `protobuf:"fixed32,2,opt,name=max_threshold,json=maxThreshold,proto3" json:"max_threshold,omitempty"`
+	MaxProbability       uint32   `protobuf:"fixed32,3,opt,name=max_probability,json=maxProbability,proto3" json:"max_probability,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *RedDiscardConfig) Reset()         { *m = RedDiscardConfig{} }
+func (m *RedDiscardConfig) String() string { return proto.CompactTextString(m) }
+func (*RedDiscardConfig) ProtoMessage()    {}
+func (*RedDiscardConfig) Descriptor() ([]byte, []int) {
+	return fileDescriptor_d019a68bffe14cae, []int{5}
+}
+
+func (m *RedDiscardConfig) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_RedDiscardConfig.Unmarshal(m, b)
+}
+func (m *RedDiscardConfig) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_RedDiscardConfig.Marshal(b, m, deterministic)
+}
+func (m *RedDiscardConfig) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_RedDiscardConfig.Merge(m, src)
+}
+func (m *RedDiscardConfig) XXX_Size() int {
+	return xxx_messageInfo_RedDiscardConfig.Size(m)
+}
+func (m *RedDiscardConfig) XXX_DiscardUnknown() {
+	xxx_messageInfo_RedDiscardConfig.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_RedDiscardConfig proto.InternalMessageInfo
+
+func (m *RedDiscardConfig) GetMinThreshold() uint32 {
+	if m != nil {
+		return m.MinThreshold
+	}
+	return 0
+}
+
+func (m *RedDiscardConfig) GetMaxThreshold() uint32 {
+	if m != nil {
+		return m.MaxThreshold
+	}
+	return 0
+}
+
+func (m *RedDiscardConfig) GetMaxProbability() uint32 {
+	if m != nil {
+		return m.MaxProbability
+	}
+	return 0
+}
+
+type WRedDiscardConfig struct {
+	Green                *RedDiscardConfig `protobuf:"bytes,1,opt,name=green,proto3" json:"green,omitempty"`
+	Yellow               *RedDiscardConfig `protobuf:"bytes,2,opt,name=yellow,proto3" json:"yellow,omitempty"`
+	Red                  *RedDiscardConfig `protobuf:"bytes,3,opt,name=red,proto3" json:"red,omitempty"`
+	XXX_NoUnkeyedLiteral struct{}          `json:"-"`
+	XXX_unrecognized     []byte            `json:"-"`
+	XXX_sizecache        int32             `json:"-"`
+}
+
+func (m *WRedDiscardConfig) Reset()         { *m = WRedDiscardConfig{} }
+func (m *WRedDiscardConfig) String() string { return proto.CompactTextString(m) }
+func (*WRedDiscardConfig) ProtoMessage()    {}
+func (*WRedDiscardConfig) Descriptor() ([]byte, []int) {
+	return fileDescriptor_d019a68bffe14cae, []int{6}
+}
+
+func (m *WRedDiscardConfig) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_WRedDiscardConfig.Unmarshal(m, b)
+}
+func (m *WRedDiscardConfig) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_WRedDiscardConfig.Marshal(b, m, deterministic)
+}
+func (m *WRedDiscardConfig) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_WRedDiscardConfig.Merge(m, src)
+}
+func (m *WRedDiscardConfig) XXX_Size() int {
+	return xxx_messageInfo_WRedDiscardConfig.Size(m)
+}
+func (m *WRedDiscardConfig) XXX_DiscardUnknown() {
+	xxx_messageInfo_WRedDiscardConfig.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_WRedDiscardConfig proto.InternalMessageInfo
+
+func (m *WRedDiscardConfig) GetGreen() *RedDiscardConfig {
+	if m != nil {
+		return m.Green
+	}
+	return nil
+}
+
+func (m *WRedDiscardConfig) GetYellow() *RedDiscardConfig {
+	if m != nil {
+		return m.Yellow
+	}
+	return nil
+}
+
+func (m *WRedDiscardConfig) GetRed() *RedDiscardConfig {
+	if m != nil {
+		return m.Red
+	}
+	return nil
+}
+
+type DiscardConfig struct {
+	DiscardPolicy DiscardPolicy `protobuf:"varint,1,opt,name=discard_policy,json=discardPolicy,proto3,enum=tech_profile.DiscardPolicy" json:"discard_policy,omitempty"`
+	// Types that are valid to be assigned to DiscardConfig:
+	//	*DiscardConfig_TailDropDiscardConfig
+	//	*DiscardConfig_RedDiscardConfig
+	//	*DiscardConfig_WredDiscardConfig
+	DiscardConfig        isDiscardConfig_DiscardConfig `protobuf_oneof:"discard_config"`
+	XXX_NoUnkeyedLiteral struct{}                      `json:"-"`
+	XXX_unrecognized     []byte                        `json:"-"`
+	XXX_sizecache        int32                         `json:"-"`
+}
+
+func (m *DiscardConfig) Reset()         { *m = DiscardConfig{} }
+func (m *DiscardConfig) String() string { return proto.CompactTextString(m) }
+func (*DiscardConfig) ProtoMessage()    {}
+func (*DiscardConfig) Descriptor() ([]byte, []int) {
+	return fileDescriptor_d019a68bffe14cae, []int{7}
+}
+
+func (m *DiscardConfig) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_DiscardConfig.Unmarshal(m, b)
+}
+func (m *DiscardConfig) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_DiscardConfig.Marshal(b, m, deterministic)
+}
+func (m *DiscardConfig) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_DiscardConfig.Merge(m, src)
+}
+func (m *DiscardConfig) XXX_Size() int {
+	return xxx_messageInfo_DiscardConfig.Size(m)
+}
+func (m *DiscardConfig) XXX_DiscardUnknown() {
+	xxx_messageInfo_DiscardConfig.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_DiscardConfig proto.InternalMessageInfo
+
+func (m *DiscardConfig) GetDiscardPolicy() DiscardPolicy {
+	if m != nil {
+		return m.DiscardPolicy
+	}
+	return DiscardPolicy_TailDrop
+}
+
+type isDiscardConfig_DiscardConfig interface {
+	isDiscardConfig_DiscardConfig()
+}
+
+type DiscardConfig_TailDropDiscardConfig struct {
+	TailDropDiscardConfig *TailDropDiscardConfig `protobuf:"bytes,2,opt,name=tail_drop_discard_config,json=tailDropDiscardConfig,proto3,oneof"`
+}
+
+type DiscardConfig_RedDiscardConfig struct {
+	RedDiscardConfig *RedDiscardConfig `protobuf:"bytes,3,opt,name=red_discard_config,json=redDiscardConfig,proto3,oneof"`
+}
+
+type DiscardConfig_WredDiscardConfig struct {
+	WredDiscardConfig *WRedDiscardConfig `protobuf:"bytes,4,opt,name=wred_discard_config,json=wredDiscardConfig,proto3,oneof"`
+}
+
+func (*DiscardConfig_TailDropDiscardConfig) isDiscardConfig_DiscardConfig() {}
+
+func (*DiscardConfig_RedDiscardConfig) isDiscardConfig_DiscardConfig() {}
+
+func (*DiscardConfig_WredDiscardConfig) isDiscardConfig_DiscardConfig() {}
+
+func (m *DiscardConfig) GetDiscardConfig() isDiscardConfig_DiscardConfig {
+	if m != nil {
+		return m.DiscardConfig
+	}
+	return nil
+}
+
+func (m *DiscardConfig) GetTailDropDiscardConfig() *TailDropDiscardConfig {
+	if x, ok := m.GetDiscardConfig().(*DiscardConfig_TailDropDiscardConfig); ok {
+		return x.TailDropDiscardConfig
+	}
+	return nil
+}
+
+func (m *DiscardConfig) GetRedDiscardConfig() *RedDiscardConfig {
+	if x, ok := m.GetDiscardConfig().(*DiscardConfig_RedDiscardConfig); ok {
+		return x.RedDiscardConfig
+	}
+	return nil
+}
+
+func (m *DiscardConfig) GetWredDiscardConfig() *WRedDiscardConfig {
+	if x, ok := m.GetDiscardConfig().(*DiscardConfig_WredDiscardConfig); ok {
+		return x.WredDiscardConfig
+	}
+	return nil
+}
+
+// XXX_OneofWrappers is for the internal use of the proto package.
+func (*DiscardConfig) XXX_OneofWrappers() []interface{} {
+	return []interface{}{
+		(*DiscardConfig_TailDropDiscardConfig)(nil),
+		(*DiscardConfig_RedDiscardConfig)(nil),
+		(*DiscardConfig_WredDiscardConfig)(nil),
+	}
+}
+
+type TrafficQueue struct {
+	Direction            Direction        `protobuf:"varint,1,opt,name=direction,proto3,enum=tech_profile.Direction" json:"direction,omitempty"`
+	GemportId            uint32           `protobuf:"fixed32,2,opt,name=gemport_id,json=gemportId,proto3" json:"gemport_id,omitempty"`
+	PbitMap              string           `protobuf:"bytes,3,opt,name=pbit_map,json=pbitMap,proto3" json:"pbit_map,omitempty"`
+	AesEncryption        bool             `protobuf:"varint,4,opt,name=aes_encryption,json=aesEncryption,proto3" json:"aes_encryption,omitempty"`
+	SchedPolicy          SchedulingPolicy `protobuf:"varint,5,opt,name=sched_policy,json=schedPolicy,proto3,enum=tech_profile.SchedulingPolicy" json:"sched_policy,omitempty"`
+	Priority             uint32           `protobuf:"fixed32,6,opt,name=priority,proto3" json:"priority,omitempty"`
+	Weight               uint32           `protobuf:"fixed32,7,opt,name=weight,proto3" json:"weight,omitempty"`
+	DiscardPolicy        DiscardPolicy    `protobuf:"varint,8,opt,name=discard_policy,json=discardPolicy,proto3,enum=tech_profile.DiscardPolicy" json:"discard_policy,omitempty"`
+	DiscardConfig        *DiscardConfig   `protobuf:"bytes,9,opt,name=discard_config,json=discardConfig,proto3" json:"discard_config,omitempty"`
+	XXX_NoUnkeyedLiteral struct{}         `json:"-"`
+	XXX_unrecognized     []byte           `json:"-"`
+	XXX_sizecache        int32            `json:"-"`
+}
+
+func (m *TrafficQueue) Reset()         { *m = TrafficQueue{} }
+func (m *TrafficQueue) String() string { return proto.CompactTextString(m) }
+func (*TrafficQueue) ProtoMessage()    {}
+func (*TrafficQueue) Descriptor() ([]byte, []int) {
+	return fileDescriptor_d019a68bffe14cae, []int{8}
+}
+
+func (m *TrafficQueue) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_TrafficQueue.Unmarshal(m, b)
+}
+func (m *TrafficQueue) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_TrafficQueue.Marshal(b, m, deterministic)
+}
+func (m *TrafficQueue) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_TrafficQueue.Merge(m, src)
+}
+func (m *TrafficQueue) XXX_Size() int {
+	return xxx_messageInfo_TrafficQueue.Size(m)
+}
+func (m *TrafficQueue) XXX_DiscardUnknown() {
+	xxx_messageInfo_TrafficQueue.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_TrafficQueue proto.InternalMessageInfo
+
+func (m *TrafficQueue) GetDirection() Direction {
+	if m != nil {
+		return m.Direction
+	}
+	return Direction_UPSTREAM
+}
+
+func (m *TrafficQueue) GetGemportId() uint32 {
+	if m != nil {
+		return m.GemportId
+	}
+	return 0
+}
+
+func (m *TrafficQueue) GetPbitMap() string {
+	if m != nil {
+		return m.PbitMap
+	}
+	return ""
+}
+
+func (m *TrafficQueue) GetAesEncryption() bool {
+	if m != nil {
+		return m.AesEncryption
+	}
+	return false
+}
+
+func (m *TrafficQueue) GetSchedPolicy() SchedulingPolicy {
+	if m != nil {
+		return m.SchedPolicy
+	}
+	return SchedulingPolicy_WRR
+}
+
+func (m *TrafficQueue) GetPriority() uint32 {
+	if m != nil {
+		return m.Priority
+	}
+	return 0
+}
+
+func (m *TrafficQueue) GetWeight() uint32 {
+	if m != nil {
+		return m.Weight
+	}
+	return 0
+}
+
+func (m *TrafficQueue) GetDiscardPolicy() DiscardPolicy {
+	if m != nil {
+		return m.DiscardPolicy
+	}
+	return DiscardPolicy_TailDrop
+}
+
+func (m *TrafficQueue) GetDiscardConfig() *DiscardConfig {
+	if m != nil {
+		return m.DiscardConfig
+	}
+	return nil
+}
+
+type TrafficQueues struct {
+	IntfId               uint32          `protobuf:"fixed32,1,opt,name=intf_id,json=intfId,proto3" json:"intf_id,omitempty"`
+	OnuId                uint32          `protobuf:"fixed32,2,opt,name=onu_id,json=onuId,proto3" json:"onu_id,omitempty"`
+	UniId                uint32          `protobuf:"fixed32,4,opt,name=uni_id,json=uniId,proto3" json:"uni_id,omitempty"`
+	PortNo               uint32          `protobuf:"fixed32,5,opt,name=port_no,json=portNo,proto3" json:"port_no,omitempty"`
+	TrafficQueues        []*TrafficQueue `protobuf:"bytes,6,rep,name=traffic_queues,json=trafficQueues,proto3" json:"traffic_queues,omitempty"`
+	TechProfileId        uint32          `protobuf:"fixed32,7,opt,name=tech_profile_id,json=techProfileId,proto3" json:"tech_profile_id,omitempty"`
+	XXX_NoUnkeyedLiteral struct{}        `json:"-"`
+	XXX_unrecognized     []byte          `json:"-"`
+	XXX_sizecache        int32           `json:"-"`
+}
+
+func (m *TrafficQueues) Reset()         { *m = TrafficQueues{} }
+func (m *TrafficQueues) String() string { return proto.CompactTextString(m) }
+func (*TrafficQueues) ProtoMessage()    {}
+func (*TrafficQueues) Descriptor() ([]byte, []int) {
+	return fileDescriptor_d019a68bffe14cae, []int{9}
+}
+
+func (m *TrafficQueues) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_TrafficQueues.Unmarshal(m, b)
+}
+func (m *TrafficQueues) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_TrafficQueues.Marshal(b, m, deterministic)
+}
+func (m *TrafficQueues) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_TrafficQueues.Merge(m, src)
+}
+func (m *TrafficQueues) XXX_Size() int {
+	return xxx_messageInfo_TrafficQueues.Size(m)
+}
+func (m *TrafficQueues) XXX_DiscardUnknown() {
+	xxx_messageInfo_TrafficQueues.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_TrafficQueues proto.InternalMessageInfo
+
+func (m *TrafficQueues) GetIntfId() uint32 {
+	if m != nil {
+		return m.IntfId
+	}
+	return 0
+}
+
+func (m *TrafficQueues) GetOnuId() uint32 {
+	if m != nil {
+		return m.OnuId
+	}
+	return 0
+}
+
+func (m *TrafficQueues) GetUniId() uint32 {
+	if m != nil {
+		return m.UniId
+	}
+	return 0
+}
+
+func (m *TrafficQueues) GetPortNo() uint32 {
+	if m != nil {
+		return m.PortNo
+	}
+	return 0
+}
+
+func (m *TrafficQueues) GetTrafficQueues() []*TrafficQueue {
+	if m != nil {
+		return m.TrafficQueues
+	}
+	return nil
+}
+
+func (m *TrafficQueues) GetTechProfileId() uint32 {
+	if m != nil {
+		return m.TechProfileId
+	}
+	return 0
+}
+
+type InstanceControl struct {
+	Onu                  string   `protobuf:"bytes,1,opt,name=onu,proto3" json:"onu,omitempty"`
+	Uni                  string   `protobuf:"bytes,2,opt,name=uni,proto3" json:"uni,omitempty"`
+	MaxGemPayloadSize    string   `protobuf:"bytes,3,opt,name=max_gem_payload_size,json=maxGemPayloadSize,proto3" json:"max_gem_payload_size,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *InstanceControl) Reset()         { *m = InstanceControl{} }
+func (m *InstanceControl) String() string { return proto.CompactTextString(m) }
+func (*InstanceControl) ProtoMessage()    {}
+func (*InstanceControl) Descriptor() ([]byte, []int) {
+	return fileDescriptor_d019a68bffe14cae, []int{10}
+}
+
+func (m *InstanceControl) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_InstanceControl.Unmarshal(m, b)
+}
+func (m *InstanceControl) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_InstanceControl.Marshal(b, m, deterministic)
+}
+func (m *InstanceControl) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_InstanceControl.Merge(m, src)
+}
+func (m *InstanceControl) XXX_Size() int {
+	return xxx_messageInfo_InstanceControl.Size(m)
+}
+func (m *InstanceControl) XXX_DiscardUnknown() {
+	xxx_messageInfo_InstanceControl.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_InstanceControl proto.InternalMessageInfo
+
+func (m *InstanceControl) GetOnu() string {
+	if m != nil {
+		return m.Onu
+	}
+	return ""
+}
+
+func (m *InstanceControl) GetUni() string {
+	if m != nil {
+		return m.Uni
+	}
+	return ""
+}
+
+func (m *InstanceControl) GetMaxGemPayloadSize() string {
+	if m != nil {
+		return m.MaxGemPayloadSize
+	}
+	return ""
+}
+
+type QThresholds struct {
+	QThreshold1          uint32   `protobuf:"varint,1,opt,name=q_threshold1,json=qThreshold1,proto3" json:"q_threshold1,omitempty"`
+	QThreshold2          uint32   `protobuf:"varint,2,opt,name=q_threshold2,json=qThreshold2,proto3" json:"q_threshold2,omitempty"`
+	QThreshold3          uint32   `protobuf:"varint,3,opt,name=q_threshold3,json=qThreshold3,proto3" json:"q_threshold3,omitempty"`
+	QThreshold4          uint32   `protobuf:"varint,4,opt,name=q_threshold4,json=qThreshold4,proto3" json:"q_threshold4,omitempty"`
+	QThreshold5          uint32   `protobuf:"varint,5,opt,name=q_threshold5,json=qThreshold5,proto3" json:"q_threshold5,omitempty"`
+	QThreshold6          uint32   `protobuf:"varint,6,opt,name=q_threshold6,json=qThreshold6,proto3" json:"q_threshold6,omitempty"`
+	QThreshold7          uint32   `protobuf:"varint,7,opt,name=q_threshold7,json=qThreshold7,proto3" json:"q_threshold7,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *QThresholds) Reset()         { *m = QThresholds{} }
+func (m *QThresholds) String() string { return proto.CompactTextString(m) }
+func (*QThresholds) ProtoMessage()    {}
+func (*QThresholds) Descriptor() ([]byte, []int) {
+	return fileDescriptor_d019a68bffe14cae, []int{11}
+}
+
+func (m *QThresholds) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_QThresholds.Unmarshal(m, b)
+}
+func (m *QThresholds) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_QThresholds.Marshal(b, m, deterministic)
+}
+func (m *QThresholds) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_QThresholds.Merge(m, src)
+}
+func (m *QThresholds) XXX_Size() int {
+	return xxx_messageInfo_QThresholds.Size(m)
+}
+func (m *QThresholds) XXX_DiscardUnknown() {
+	xxx_messageInfo_QThresholds.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_QThresholds proto.InternalMessageInfo
+
+func (m *QThresholds) GetQThreshold1() uint32 {
+	if m != nil {
+		return m.QThreshold1
+	}
+	return 0
+}
+
+func (m *QThresholds) GetQThreshold2() uint32 {
+	if m != nil {
+		return m.QThreshold2
+	}
+	return 0
+}
+
+func (m *QThresholds) GetQThreshold3() uint32 {
+	if m != nil {
+		return m.QThreshold3
+	}
+	return 0
+}
+
+func (m *QThresholds) GetQThreshold4() uint32 {
+	if m != nil {
+		return m.QThreshold4
+	}
+	return 0
+}
+
+func (m *QThresholds) GetQThreshold5() uint32 {
+	if m != nil {
+		return m.QThreshold5
+	}
+	return 0
+}
+
+func (m *QThresholds) GetQThreshold6() uint32 {
+	if m != nil {
+		return m.QThreshold6
+	}
+	return 0
+}
+
+func (m *QThresholds) GetQThreshold7() uint32 {
+	if m != nil {
+		return m.QThreshold7
+	}
+	return 0
+}
+
+type GemPortAttributes struct {
+	GemportId                uint32            `protobuf:"fixed32,1,opt,name=gemport_id,json=gemportId,proto3" json:"gemport_id,omitempty"`
+	MaxQSize                 string            `protobuf:"bytes,2,opt,name=max_q_size,json=maxQSize,proto3" json:"max_q_size,omitempty"`
+	PbitMap                  string            `protobuf:"bytes,3,opt,name=pbit_map,json=pbitMap,proto3" json:"pbit_map,omitempty"`
+	AesEncryption            string            `protobuf:"bytes,4,opt,name=aes_encryption,json=aesEncryption,proto3" json:"aes_encryption,omitempty"`
+	SchedulingPolicy         SchedulingPolicy  `protobuf:"varint,5,opt,name=scheduling_policy,json=schedulingPolicy,proto3,enum=tech_profile.SchedulingPolicy" json:"scheduling_policy,omitempty"`
+	PriorityQ                uint32            `protobuf:"fixed32,6,opt,name=priority_q,json=priorityQ,proto3" json:"priority_q,omitempty"`
+	Weight                   uint32            `protobuf:"fixed32,7,opt,name=weight,proto3" json:"weight,omitempty"`
+	DiscardPolicy            DiscardPolicy     `protobuf:"varint,8,opt,name=discard_policy,json=discardPolicy,proto3,enum=tech_profile.DiscardPolicy" json:"discard_policy,omitempty"`
+	DiscardConfig            *RedDiscardConfig `protobuf:"bytes,9,opt,name=discard_config,json=discardConfig,proto3" json:"discard_config,omitempty"`
+	DiscardConfigV2          *DiscardConfig    `protobuf:"bytes,14,opt,name=discard_config_v2,json=discardConfigV2,proto3" json:"discard_config_v2,omitempty"`
+	IsMulticast              string            `protobuf:"bytes,10,opt,name=is_multicast,json=isMulticast,proto3" json:"is_multicast,omitempty"`
+	MulticastGemId           uint32            `protobuf:"fixed32,11,opt,name=multicast_gem_id,json=multicastGemId,proto3" json:"multicast_gem_id,omitempty"`
+	DynamicAccessControlList string            `protobuf:"bytes,12,opt,name=dynamic_access_control_list,json=dynamicAccessControlList,proto3" json:"dynamic_access_control_list,omitempty"`
+	StaticAccessControlList  string            `protobuf:"bytes,13,opt,name=static_access_control_list,json=staticAccessControlList,proto3" json:"static_access_control_list,omitempty"`
+	XXX_NoUnkeyedLiteral     struct{}          `json:"-"`
+	XXX_unrecognized         []byte            `json:"-"`
+	XXX_sizecache            int32             `json:"-"`
+}
+
+func (m *GemPortAttributes) Reset()         { *m = GemPortAttributes{} }
+func (m *GemPortAttributes) String() string { return proto.CompactTextString(m) }
+func (*GemPortAttributes) ProtoMessage()    {}
+func (*GemPortAttributes) Descriptor() ([]byte, []int) {
+	return fileDescriptor_d019a68bffe14cae, []int{12}
+}
+
+func (m *GemPortAttributes) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_GemPortAttributes.Unmarshal(m, b)
+}
+func (m *GemPortAttributes) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_GemPortAttributes.Marshal(b, m, deterministic)
+}
+func (m *GemPortAttributes) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_GemPortAttributes.Merge(m, src)
+}
+func (m *GemPortAttributes) XXX_Size() int {
+	return xxx_messageInfo_GemPortAttributes.Size(m)
+}
+func (m *GemPortAttributes) XXX_DiscardUnknown() {
+	xxx_messageInfo_GemPortAttributes.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_GemPortAttributes proto.InternalMessageInfo
+
+func (m *GemPortAttributes) GetGemportId() uint32 {
+	if m != nil {
+		return m.GemportId
+	}
+	return 0
+}
+
+func (m *GemPortAttributes) GetMaxQSize() string {
+	if m != nil {
+		return m.MaxQSize
+	}
+	return ""
+}
+
+func (m *GemPortAttributes) GetPbitMap() string {
+	if m != nil {
+		return m.PbitMap
+	}
+	return ""
+}
+
+func (m *GemPortAttributes) GetAesEncryption() string {
+	if m != nil {
+		return m.AesEncryption
+	}
+	return ""
+}
+
+func (m *GemPortAttributes) GetSchedulingPolicy() SchedulingPolicy {
+	if m != nil {
+		return m.SchedulingPolicy
+	}
+	return SchedulingPolicy_WRR
+}
+
+func (m *GemPortAttributes) GetPriorityQ() uint32 {
+	if m != nil {
+		return m.PriorityQ
+	}
+	return 0
+}
+
+func (m *GemPortAttributes) GetWeight() uint32 {
+	if m != nil {
+		return m.Weight
+	}
+	return 0
+}
+
+func (m *GemPortAttributes) GetDiscardPolicy() DiscardPolicy {
+	if m != nil {
+		return m.DiscardPolicy
+	}
+	return DiscardPolicy_TailDrop
+}
+
+func (m *GemPortAttributes) GetDiscardConfig() *RedDiscardConfig {
+	if m != nil {
+		return m.DiscardConfig
+	}
+	return nil
+}
+
+func (m *GemPortAttributes) GetDiscardConfigV2() *DiscardConfig {
+	if m != nil {
+		return m.DiscardConfigV2
+	}
+	return nil
+}
+
+func (m *GemPortAttributes) GetIsMulticast() string {
+	if m != nil {
+		return m.IsMulticast
+	}
+	return ""
+}
+
+func (m *GemPortAttributes) GetMulticastGemId() uint32 {
+	if m != nil {
+		return m.MulticastGemId
+	}
+	return 0
+}
+
+func (m *GemPortAttributes) GetDynamicAccessControlList() string {
+	if m != nil {
+		return m.DynamicAccessControlList
+	}
+	return ""
+}
+
+func (m *GemPortAttributes) GetStaticAccessControlList() string {
+	if m != nil {
+		return m.StaticAccessControlList
+	}
+	return ""
+}
+
+type SchedulerAttributes struct {
+	Direction            Direction        `protobuf:"varint,1,opt,name=direction,proto3,enum=tech_profile.Direction" json:"direction,omitempty"`
+	AllocId              uint32           `protobuf:"varint,2,opt,name=alloc_id,json=allocId,proto3" json:"alloc_id,omitempty"`
+	AdditionalBw         AdditionalBW     `protobuf:"varint,3,opt,name=additional_bw,json=additionalBw,proto3,enum=tech_profile.AdditionalBW" json:"additional_bw,omitempty"`
+	Priority             uint32           `protobuf:"fixed32,4,opt,name=priority,proto3" json:"priority,omitempty"`
+	Weight               uint32           `protobuf:"fixed32,5,opt,name=weight,proto3" json:"weight,omitempty"`
+	QSchedPolicy         SchedulingPolicy `protobuf:"varint,6,opt,name=q_sched_policy,json=qSchedPolicy,proto3,enum=tech_profile.SchedulingPolicy" json:"q_sched_policy,omitempty"`
+	XXX_NoUnkeyedLiteral struct{}         `json:"-"`
+	XXX_unrecognized     []byte           `json:"-"`
+	XXX_sizecache        int32            `json:"-"`
+}
+
+func (m *SchedulerAttributes) Reset()         { *m = SchedulerAttributes{} }
+func (m *SchedulerAttributes) String() string { return proto.CompactTextString(m) }
+func (*SchedulerAttributes) ProtoMessage()    {}
+func (*SchedulerAttributes) Descriptor() ([]byte, []int) {
+	return fileDescriptor_d019a68bffe14cae, []int{13}
+}
+
+func (m *SchedulerAttributes) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_SchedulerAttributes.Unmarshal(m, b)
+}
+func (m *SchedulerAttributes) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_SchedulerAttributes.Marshal(b, m, deterministic)
+}
+func (m *SchedulerAttributes) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_SchedulerAttributes.Merge(m, src)
+}
+func (m *SchedulerAttributes) XXX_Size() int {
+	return xxx_messageInfo_SchedulerAttributes.Size(m)
+}
+func (m *SchedulerAttributes) XXX_DiscardUnknown() {
+	xxx_messageInfo_SchedulerAttributes.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_SchedulerAttributes proto.InternalMessageInfo
+
+func (m *SchedulerAttributes) GetDirection() Direction {
+	if m != nil {
+		return m.Direction
+	}
+	return Direction_UPSTREAM
+}
+
+func (m *SchedulerAttributes) GetAllocId() uint32 {
+	if m != nil {
+		return m.AllocId
+	}
+	return 0
+}
+
+func (m *SchedulerAttributes) GetAdditionalBw() AdditionalBW {
+	if m != nil {
+		return m.AdditionalBw
+	}
+	return AdditionalBW_AdditionalBW_None
+}
+
+func (m *SchedulerAttributes) GetPriority() uint32 {
+	if m != nil {
+		return m.Priority
+	}
+	return 0
+}
+
+func (m *SchedulerAttributes) GetWeight() uint32 {
+	if m != nil {
+		return m.Weight
+	}
+	return 0
+}
+
+func (m *SchedulerAttributes) GetQSchedPolicy() SchedulingPolicy {
+	if m != nil {
+		return m.QSchedPolicy
+	}
+	return SchedulingPolicy_WRR
+}
+
+type EPONQueueAttributes struct {
+	MaxQSize                  string            `protobuf:"bytes,1,opt,name=max_q_size,json=maxQSize,proto3" json:"max_q_size,omitempty"`
+	PbitMap                   string            `protobuf:"bytes,2,opt,name=pbit_map,json=pbitMap,proto3" json:"pbit_map,omitempty"`
+	GemportId                 uint32            `protobuf:"varint,3,opt,name=gemport_id,json=gemportId,proto3" json:"gemport_id,omitempty"`
+	AesEncryption             string            `protobuf:"bytes,4,opt,name=aes_encryption,json=aesEncryption,proto3" json:"aes_encryption,omitempty"`
+	TrafficType               string            `protobuf:"bytes,5,opt,name=traffic_type,json=trafficType,proto3" json:"traffic_type,omitempty"`
+	UnsolicitedGrantSize      uint32            `protobuf:"varint,6,opt,name=unsolicited_grant_size,json=unsolicitedGrantSize,proto3" json:"unsolicited_grant_size,omitempty"`
+	NominalInterval           uint32            `protobuf:"varint,7,opt,name=nominal_interval,json=nominalInterval,proto3" json:"nominal_interval,omitempty"`
+	ToleratedPollJitter       uint32            `protobuf:"varint,8,opt,name=tolerated_poll_jitter,json=toleratedPollJitter,proto3" json:"tolerated_poll_jitter,omitempty"`
+	RequestTransmissionPolicy uint32            `protobuf:"varint,9,opt,name=request_transmission_policy,json=requestTransmissionPolicy,proto3" json:"request_transmission_policy,omitempty"`
+	NumQSets                  uint32            `protobuf:"varint,10,opt,name=num_q_sets,json=numQSets,proto3" json:"num_q_sets,omitempty"`
+	QThresholds               *QThresholds      `protobuf:"bytes,11,opt,name=q_thresholds,json=qThresholds,proto3" json:"q_thresholds,omitempty"`
+	SchedulingPolicy          SchedulingPolicy  `protobuf:"varint,12,opt,name=scheduling_policy,json=schedulingPolicy,proto3,enum=tech_profile.SchedulingPolicy" json:"scheduling_policy,omitempty"`
+	PriorityQ                 uint32            `protobuf:"varint,13,opt,name=priority_q,json=priorityQ,proto3" json:"priority_q,omitempty"`
+	Weight                    uint32            `protobuf:"varint,14,opt,name=weight,proto3" json:"weight,omitempty"`
+	DiscardPolicy             DiscardPolicy     `protobuf:"varint,15,opt,name=discard_policy,json=discardPolicy,proto3,enum=tech_profile.DiscardPolicy" json:"discard_policy,omitempty"`
+	DiscardConfig             *RedDiscardConfig `protobuf:"bytes,16,opt,name=discard_config,json=discardConfig,proto3" json:"discard_config,omitempty"`
+	DiscardConfigV2           *DiscardConfig    `protobuf:"bytes,17,opt,name=discard_config_v2,json=discardConfigV2,proto3" json:"discard_config_v2,omitempty"`
+	XXX_NoUnkeyedLiteral      struct{}          `json:"-"`
+	XXX_unrecognized          []byte            `json:"-"`
+	XXX_sizecache             int32             `json:"-"`
+}
+
+func (m *EPONQueueAttributes) Reset()         { *m = EPONQueueAttributes{} }
+func (m *EPONQueueAttributes) String() string { return proto.CompactTextString(m) }
+func (*EPONQueueAttributes) ProtoMessage()    {}
+func (*EPONQueueAttributes) Descriptor() ([]byte, []int) {
+	return fileDescriptor_d019a68bffe14cae, []int{14}
+}
+
+func (m *EPONQueueAttributes) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_EPONQueueAttributes.Unmarshal(m, b)
+}
+func (m *EPONQueueAttributes) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_EPONQueueAttributes.Marshal(b, m, deterministic)
+}
+func (m *EPONQueueAttributes) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_EPONQueueAttributes.Merge(m, src)
+}
+func (m *EPONQueueAttributes) XXX_Size() int {
+	return xxx_messageInfo_EPONQueueAttributes.Size(m)
+}
+func (m *EPONQueueAttributes) XXX_DiscardUnknown() {
+	xxx_messageInfo_EPONQueueAttributes.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_EPONQueueAttributes proto.InternalMessageInfo
+
+func (m *EPONQueueAttributes) GetMaxQSize() string {
+	if m != nil {
+		return m.MaxQSize
+	}
+	return ""
+}
+
+func (m *EPONQueueAttributes) GetPbitMap() string {
+	if m != nil {
+		return m.PbitMap
+	}
+	return ""
+}
+
+func (m *EPONQueueAttributes) GetGemportId() uint32 {
+	if m != nil {
+		return m.GemportId
+	}
+	return 0
+}
+
+func (m *EPONQueueAttributes) GetAesEncryption() string {
+	if m != nil {
+		return m.AesEncryption
+	}
+	return ""
+}
+
+func (m *EPONQueueAttributes) GetTrafficType() string {
+	if m != nil {
+		return m.TrafficType
+	}
+	return ""
+}
+
+func (m *EPONQueueAttributes) GetUnsolicitedGrantSize() uint32 {
+	if m != nil {
+		return m.UnsolicitedGrantSize
+	}
+	return 0
+}
+
+func (m *EPONQueueAttributes) GetNominalInterval() uint32 {
+	if m != nil {
+		return m.NominalInterval
+	}
+	return 0
+}
+
+func (m *EPONQueueAttributes) GetToleratedPollJitter() uint32 {
+	if m != nil {
+		return m.ToleratedPollJitter
+	}
+	return 0
+}
+
+func (m *EPONQueueAttributes) GetRequestTransmissionPolicy() uint32 {
+	if m != nil {
+		return m.RequestTransmissionPolicy
+	}
+	return 0
+}
+
+func (m *EPONQueueAttributes) GetNumQSets() uint32 {
+	if m != nil {
+		return m.NumQSets
+	}
+	return 0
+}
+
+func (m *EPONQueueAttributes) GetQThresholds() *QThresholds {
+	if m != nil {
+		return m.QThresholds
+	}
+	return nil
+}
+
+func (m *EPONQueueAttributes) GetSchedulingPolicy() SchedulingPolicy {
+	if m != nil {
+		return m.SchedulingPolicy
+	}
+	return SchedulingPolicy_WRR
+}
+
+func (m *EPONQueueAttributes) GetPriorityQ() uint32 {
+	if m != nil {
+		return m.PriorityQ
+	}
+	return 0
+}
+
+func (m *EPONQueueAttributes) GetWeight() uint32 {
+	if m != nil {
+		return m.Weight
+	}
+	return 0
+}
+
+func (m *EPONQueueAttributes) GetDiscardPolicy() DiscardPolicy {
+	if m != nil {
+		return m.DiscardPolicy
+	}
+	return DiscardPolicy_TailDrop
+}
+
+func (m *EPONQueueAttributes) GetDiscardConfig() *RedDiscardConfig {
+	if m != nil {
+		return m.DiscardConfig
+	}
+	return nil
+}
+
+func (m *EPONQueueAttributes) GetDiscardConfigV2() *DiscardConfig {
+	if m != nil {
+		return m.DiscardConfigV2
+	}
+	return nil
+}
+
+// TechProfile definition (relevant for GPON, XGPON and XGS-PON technologies)
+type TechProfile struct {
+	Name                           string               `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
+	Version                        uint32               `protobuf:"varint,2,opt,name=version,proto3" json:"version,omitempty"`
+	ProfileType                    string               `protobuf:"bytes,3,opt,name=profile_type,json=profileType,proto3" json:"profile_type,omitempty"`
+	NumGemPorts                    uint32               `protobuf:"varint,4,opt,name=num_gem_ports,json=numGemPorts,proto3" json:"num_gem_ports,omitempty"`
+	InstanceControl                *InstanceControl     `protobuf:"bytes,5,opt,name=instance_control,json=instanceControl,proto3" json:"instance_control,omitempty"`
+	UsScheduler                    *SchedulerAttributes `protobuf:"bytes,6,opt,name=us_scheduler,json=usScheduler,proto3" json:"us_scheduler,omitempty"`
+	DsScheduler                    *SchedulerAttributes `protobuf:"bytes,7,opt,name=ds_scheduler,json=dsScheduler,proto3" json:"ds_scheduler,omitempty"`
+	UpstreamGemPortAttributeList   []*GemPortAttributes `protobuf:"bytes,8,rep,name=upstream_gem_port_attribute_list,json=upstreamGemPortAttributeList,proto3" json:"upstream_gem_port_attribute_list,omitempty"`
+	DownstreamGemPortAttributeList []*GemPortAttributes `protobuf:"bytes,9,rep,name=downstream_gem_port_attribute_list,json=downstreamGemPortAttributeList,proto3" json:"downstream_gem_port_attribute_list,omitempty"`
+	XXX_NoUnkeyedLiteral           struct{}             `json:"-"`
+	XXX_unrecognized               []byte               `json:"-"`
+	XXX_sizecache                  int32                `json:"-"`
+}
+
+func (m *TechProfile) Reset()         { *m = TechProfile{} }
+func (m *TechProfile) String() string { return proto.CompactTextString(m) }
+func (*TechProfile) ProtoMessage()    {}
+func (*TechProfile) Descriptor() ([]byte, []int) {
+	return fileDescriptor_d019a68bffe14cae, []int{15}
+}
+
+func (m *TechProfile) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_TechProfile.Unmarshal(m, b)
+}
+func (m *TechProfile) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_TechProfile.Marshal(b, m, deterministic)
+}
+func (m *TechProfile) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_TechProfile.Merge(m, src)
+}
+func (m *TechProfile) XXX_Size() int {
+	return xxx_messageInfo_TechProfile.Size(m)
+}
+func (m *TechProfile) XXX_DiscardUnknown() {
+	xxx_messageInfo_TechProfile.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_TechProfile proto.InternalMessageInfo
+
+func (m *TechProfile) GetName() string {
+	if m != nil {
+		return m.Name
+	}
+	return ""
+}
+
+func (m *TechProfile) GetVersion() uint32 {
+	if m != nil {
+		return m.Version
+	}
+	return 0
+}
+
+func (m *TechProfile) GetProfileType() string {
+	if m != nil {
+		return m.ProfileType
+	}
+	return ""
+}
+
+func (m *TechProfile) GetNumGemPorts() uint32 {
+	if m != nil {
+		return m.NumGemPorts
+	}
+	return 0
+}
+
+func (m *TechProfile) GetInstanceControl() *InstanceControl {
+	if m != nil {
+		return m.InstanceControl
+	}
+	return nil
+}
+
+func (m *TechProfile) GetUsScheduler() *SchedulerAttributes {
+	if m != nil {
+		return m.UsScheduler
+	}
+	return nil
+}
+
+func (m *TechProfile) GetDsScheduler() *SchedulerAttributes {
+	if m != nil {
+		return m.DsScheduler
+	}
+	return nil
+}
+
+func (m *TechProfile) GetUpstreamGemPortAttributeList() []*GemPortAttributes {
+	if m != nil {
+		return m.UpstreamGemPortAttributeList
+	}
+	return nil
+}
+
+func (m *TechProfile) GetDownstreamGemPortAttributeList() []*GemPortAttributes {
+	if m != nil {
+		return m.DownstreamGemPortAttributeList
+	}
+	return nil
+}
+
+// EPON TechProfile definition
+type EponTechProfile struct {
+	Name                         string                 `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
+	Version                      uint32                 `protobuf:"varint,2,opt,name=version,proto3" json:"version,omitempty"`
+	ProfileType                  string                 `protobuf:"bytes,3,opt,name=profile_type,json=profileType,proto3" json:"profile_type,omitempty"`
+	NumGemPorts                  uint32                 `protobuf:"varint,4,opt,name=num_gem_ports,json=numGemPorts,proto3" json:"num_gem_ports,omitempty"`
+	InstanceControl              *InstanceControl       `protobuf:"bytes,5,opt,name=instance_control,json=instanceControl,proto3" json:"instance_control,omitempty"`
+	PackageType                  string                 `protobuf:"bytes,6,opt,name=package_type,json=packageType,proto3" json:"package_type,omitempty"`
+	UpstreamQueueAttributeList   []*EPONQueueAttributes `protobuf:"bytes,7,rep,name=upstream_queue_attribute_list,json=upstreamQueueAttributeList,proto3" json:"upstream_queue_attribute_list,omitempty"`
+	DownstreamQueueAttributeList []*EPONQueueAttributes `protobuf:"bytes,8,rep,name=downstream_queue_attribute_list,json=downstreamQueueAttributeList,proto3" json:"downstream_queue_attribute_list,omitempty"`
+	XXX_NoUnkeyedLiteral         struct{}               `json:"-"`
+	XXX_unrecognized             []byte                 `json:"-"`
+	XXX_sizecache                int32                  `json:"-"`
+}
+
+func (m *EponTechProfile) Reset()         { *m = EponTechProfile{} }
+func (m *EponTechProfile) String() string { return proto.CompactTextString(m) }
+func (*EponTechProfile) ProtoMessage()    {}
+func (*EponTechProfile) Descriptor() ([]byte, []int) {
+	return fileDescriptor_d019a68bffe14cae, []int{16}
+}
+
+func (m *EponTechProfile) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_EponTechProfile.Unmarshal(m, b)
+}
+func (m *EponTechProfile) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_EponTechProfile.Marshal(b, m, deterministic)
+}
+func (m *EponTechProfile) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_EponTechProfile.Merge(m, src)
+}
+func (m *EponTechProfile) XXX_Size() int {
+	return xxx_messageInfo_EponTechProfile.Size(m)
+}
+func (m *EponTechProfile) XXX_DiscardUnknown() {
+	xxx_messageInfo_EponTechProfile.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_EponTechProfile proto.InternalMessageInfo
+
+func (m *EponTechProfile) GetName() string {
+	if m != nil {
+		return m.Name
+	}
+	return ""
+}
+
+func (m *EponTechProfile) GetVersion() uint32 {
+	if m != nil {
+		return m.Version
+	}
+	return 0
+}
+
+func (m *EponTechProfile) GetProfileType() string {
+	if m != nil {
+		return m.ProfileType
+	}
+	return ""
+}
+
+func (m *EponTechProfile) GetNumGemPorts() uint32 {
+	if m != nil {
+		return m.NumGemPorts
+	}
+	return 0
+}
+
+func (m *EponTechProfile) GetInstanceControl() *InstanceControl {
+	if m != nil {
+		return m.InstanceControl
+	}
+	return nil
+}
+
+func (m *EponTechProfile) GetPackageType() string {
+	if m != nil {
+		return m.PackageType
+	}
+	return ""
+}
+
+func (m *EponTechProfile) GetUpstreamQueueAttributeList() []*EPONQueueAttributes {
+	if m != nil {
+		return m.UpstreamQueueAttributeList
+	}
+	return nil
+}
+
+func (m *EponTechProfile) GetDownstreamQueueAttributeList() []*EPONQueueAttributes {
+	if m != nil {
+		return m.DownstreamQueueAttributeList
+	}
+	return nil
+}
+
+// TechProfile Instance definition (relevant for GPON, XGPON and XGS-PON technologies)
+type TechProfileInstance struct {
+	Name                           string               `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
+	Version                        uint32               `protobuf:"varint,2,opt,name=version,proto3" json:"version,omitempty"`
+	SubscriberIdentifier           string               `protobuf:"bytes,3,opt,name=subscriber_identifier,json=subscriberIdentifier,proto3" json:"subscriber_identifier,omitempty"`
+	ProfileType                    string               `protobuf:"bytes,4,opt,name=profile_type,json=profileType,proto3" json:"profile_type,omitempty"`
+	NumGemPorts                    uint32               `protobuf:"varint,5,opt,name=num_gem_ports,json=numGemPorts,proto3" json:"num_gem_ports,omitempty"`
+	InstanceControl                *InstanceControl     `protobuf:"bytes,6,opt,name=instance_control,json=instanceControl,proto3" json:"instance_control,omitempty"`
+	UsScheduler                    *SchedulerAttributes `protobuf:"bytes,7,opt,name=us_scheduler,json=usScheduler,proto3" json:"us_scheduler,omitempty"`
+	DsScheduler                    *SchedulerAttributes `protobuf:"bytes,8,opt,name=ds_scheduler,json=dsScheduler,proto3" json:"ds_scheduler,omitempty"`
+	UpstreamGemPortAttributeList   []*GemPortAttributes `protobuf:"bytes,9,rep,name=upstream_gem_port_attribute_list,json=upstreamGemPortAttributeList,proto3" json:"upstream_gem_port_attribute_list,omitempty"`
+	DownstreamGemPortAttributeList []*GemPortAttributes `protobuf:"bytes,10,rep,name=downstream_gem_port_attribute_list,json=downstreamGemPortAttributeList,proto3" json:"downstream_gem_port_attribute_list,omitempty"`
+	XXX_NoUnkeyedLiteral           struct{}             `json:"-"`
+	XXX_unrecognized               []byte               `json:"-"`
+	XXX_sizecache                  int32                `json:"-"`
+}
+
+func (m *TechProfileInstance) Reset()         { *m = TechProfileInstance{} }
+func (m *TechProfileInstance) String() string { return proto.CompactTextString(m) }
+func (*TechProfileInstance) ProtoMessage()    {}
+func (*TechProfileInstance) Descriptor() ([]byte, []int) {
+	return fileDescriptor_d019a68bffe14cae, []int{17}
+}
+
+func (m *TechProfileInstance) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_TechProfileInstance.Unmarshal(m, b)
+}
+func (m *TechProfileInstance) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_TechProfileInstance.Marshal(b, m, deterministic)
+}
+func (m *TechProfileInstance) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_TechProfileInstance.Merge(m, src)
+}
+func (m *TechProfileInstance) XXX_Size() int {
+	return xxx_messageInfo_TechProfileInstance.Size(m)
+}
+func (m *TechProfileInstance) XXX_DiscardUnknown() {
+	xxx_messageInfo_TechProfileInstance.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_TechProfileInstance proto.InternalMessageInfo
+
+func (m *TechProfileInstance) GetName() string {
+	if m != nil {
+		return m.Name
+	}
+	return ""
+}
+
+func (m *TechProfileInstance) GetVersion() uint32 {
+	if m != nil {
+		return m.Version
+	}
+	return 0
+}
+
+func (m *TechProfileInstance) GetSubscriberIdentifier() string {
+	if m != nil {
+		return m.SubscriberIdentifier
+	}
+	return ""
+}
+
+func (m *TechProfileInstance) GetProfileType() string {
+	if m != nil {
+		return m.ProfileType
+	}
+	return ""
+}
+
+func (m *TechProfileInstance) GetNumGemPorts() uint32 {
+	if m != nil {
+		return m.NumGemPorts
+	}
+	return 0
+}
+
+func (m *TechProfileInstance) GetInstanceControl() *InstanceControl {
+	if m != nil {
+		return m.InstanceControl
+	}
+	return nil
+}
+
+func (m *TechProfileInstance) GetUsScheduler() *SchedulerAttributes {
+	if m != nil {
+		return m.UsScheduler
+	}
+	return nil
+}
+
+func (m *TechProfileInstance) GetDsScheduler() *SchedulerAttributes {
+	if m != nil {
+		return m.DsScheduler
+	}
+	return nil
+}
+
+func (m *TechProfileInstance) GetUpstreamGemPortAttributeList() []*GemPortAttributes {
+	if m != nil {
+		return m.UpstreamGemPortAttributeList
+	}
+	return nil
+}
+
+func (m *TechProfileInstance) GetDownstreamGemPortAttributeList() []*GemPortAttributes {
+	if m != nil {
+		return m.DownstreamGemPortAttributeList
+	}
+	return nil
+}
+
+// EPON TechProfile Instance definition.
+type EponTechProfileInstance struct {
+	Name                         string                 `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
+	Version                      uint32                 `protobuf:"varint,2,opt,name=version,proto3" json:"version,omitempty"`
+	SubscriberIdentifier         string                 `protobuf:"bytes,3,opt,name=subscriber_identifier,json=subscriberIdentifier,proto3" json:"subscriber_identifier,omitempty"`
+	ProfileType                  string                 `protobuf:"bytes,4,opt,name=profile_type,json=profileType,proto3" json:"profile_type,omitempty"`
+	NumGemPorts                  uint32                 `protobuf:"varint,5,opt,name=num_gem_ports,json=numGemPorts,proto3" json:"num_gem_ports,omitempty"`
+	AllocId                      uint32                 `protobuf:"varint,6,opt,name=alloc_id,json=allocId,proto3" json:"alloc_id,omitempty"`
+	InstanceControl              *InstanceControl       `protobuf:"bytes,7,opt,name=instance_control,json=instanceControl,proto3" json:"instance_control,omitempty"`
+	PackageType                  string                 `protobuf:"bytes,8,opt,name=package_type,json=packageType,proto3" json:"package_type,omitempty"`
+	UpstreamQueueAttributeList   []*EPONQueueAttributes `protobuf:"bytes,9,rep,name=upstream_queue_attribute_list,json=upstreamQueueAttributeList,proto3" json:"upstream_queue_attribute_list,omitempty"`
+	DownstreamQueueAttributeList []*EPONQueueAttributes `protobuf:"bytes,10,rep,name=downstream_queue_attribute_list,json=downstreamQueueAttributeList,proto3" json:"downstream_queue_attribute_list,omitempty"`
+	XXX_NoUnkeyedLiteral         struct{}               `json:"-"`
+	XXX_unrecognized             []byte                 `json:"-"`
+	XXX_sizecache                int32                  `json:"-"`
+}
+
+func (m *EponTechProfileInstance) Reset()         { *m = EponTechProfileInstance{} }
+func (m *EponTechProfileInstance) String() string { return proto.CompactTextString(m) }
+func (*EponTechProfileInstance) ProtoMessage()    {}
+func (*EponTechProfileInstance) Descriptor() ([]byte, []int) {
+	return fileDescriptor_d019a68bffe14cae, []int{18}
+}
+
+func (m *EponTechProfileInstance) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_EponTechProfileInstance.Unmarshal(m, b)
+}
+func (m *EponTechProfileInstance) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_EponTechProfileInstance.Marshal(b, m, deterministic)
+}
+func (m *EponTechProfileInstance) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_EponTechProfileInstance.Merge(m, src)
+}
+func (m *EponTechProfileInstance) XXX_Size() int {
+	return xxx_messageInfo_EponTechProfileInstance.Size(m)
+}
+func (m *EponTechProfileInstance) XXX_DiscardUnknown() {
+	xxx_messageInfo_EponTechProfileInstance.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_EponTechProfileInstance proto.InternalMessageInfo
+
+func (m *EponTechProfileInstance) GetName() string {
+	if m != nil {
+		return m.Name
+	}
+	return ""
+}
+
+func (m *EponTechProfileInstance) GetVersion() uint32 {
+	if m != nil {
+		return m.Version
+	}
+	return 0
+}
+
+func (m *EponTechProfileInstance) GetSubscriberIdentifier() string {
+	if m != nil {
+		return m.SubscriberIdentifier
+	}
+	return ""
+}
+
+func (m *EponTechProfileInstance) GetProfileType() string {
+	if m != nil {
+		return m.ProfileType
+	}
+	return ""
+}
+
+func (m *EponTechProfileInstance) GetNumGemPorts() uint32 {
+	if m != nil {
+		return m.NumGemPorts
+	}
+	return 0
+}
+
+func (m *EponTechProfileInstance) GetAllocId() uint32 {
+	if m != nil {
+		return m.AllocId
+	}
+	return 0
+}
+
+func (m *EponTechProfileInstance) GetInstanceControl() *InstanceControl {
+	if m != nil {
+		return m.InstanceControl
+	}
+	return nil
+}
+
+func (m *EponTechProfileInstance) GetPackageType() string {
+	if m != nil {
+		return m.PackageType
+	}
+	return ""
+}
+
+func (m *EponTechProfileInstance) GetUpstreamQueueAttributeList() []*EPONQueueAttributes {
+	if m != nil {
+		return m.UpstreamQueueAttributeList
+	}
+	return nil
+}
+
+func (m *EponTechProfileInstance) GetDownstreamQueueAttributeList() []*EPONQueueAttributes {
+	if m != nil {
+		return m.DownstreamQueueAttributeList
+	}
+	return nil
+}
+
+// Resource Instance definition
+type ResourceInstance struct {
+	TpId                 uint32   `protobuf:"varint,1,opt,name=tp_id,json=tpId,proto3" json:"tp_id,omitempty"`
+	ProfileType          string   `protobuf:"bytes,2,opt,name=profile_type,json=profileType,proto3" json:"profile_type,omitempty"`
+	SubscriberIdentifier string   `protobuf:"bytes,3,opt,name=subscriber_identifier,json=subscriberIdentifier,proto3" json:"subscriber_identifier,omitempty"`
+	AllocId              uint32   `protobuf:"varint,4,opt,name=alloc_id,json=allocId,proto3" json:"alloc_id,omitempty"`
+	GemportIds           []uint32 `protobuf:"varint,5,rep,packed,name=gemport_ids,json=gemportIds,proto3" json:"gemport_ids,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *ResourceInstance) Reset()         { *m = ResourceInstance{} }
+func (m *ResourceInstance) String() string { return proto.CompactTextString(m) }
+func (*ResourceInstance) ProtoMessage()    {}
+func (*ResourceInstance) Descriptor() ([]byte, []int) {
+	return fileDescriptor_d019a68bffe14cae, []int{19}
+}
+
+func (m *ResourceInstance) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_ResourceInstance.Unmarshal(m, b)
+}
+func (m *ResourceInstance) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_ResourceInstance.Marshal(b, m, deterministic)
+}
+func (m *ResourceInstance) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_ResourceInstance.Merge(m, src)
+}
+func (m *ResourceInstance) XXX_Size() int {
+	return xxx_messageInfo_ResourceInstance.Size(m)
+}
+func (m *ResourceInstance) XXX_DiscardUnknown() {
+	xxx_messageInfo_ResourceInstance.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_ResourceInstance proto.InternalMessageInfo
+
+func (m *ResourceInstance) GetTpId() uint32 {
+	if m != nil {
+		return m.TpId
+	}
+	return 0
+}
+
+func (m *ResourceInstance) GetProfileType() string {
+	if m != nil {
+		return m.ProfileType
+	}
+	return ""
+}
+
+func (m *ResourceInstance) GetSubscriberIdentifier() string {
+	if m != nil {
+		return m.SubscriberIdentifier
+	}
+	return ""
+}
+
+func (m *ResourceInstance) GetAllocId() uint32 {
+	if m != nil {
+		return m.AllocId
+	}
+	return 0
+}
+
+func (m *ResourceInstance) GetGemportIds() []uint32 {
+	if m != nil {
+		return m.GemportIds
+	}
+	return nil
+}
+
+func init() {
+	proto.RegisterEnum("tech_profile.Direction", Direction_name, Direction_value)
+	proto.RegisterEnum("tech_profile.SchedulingPolicy", SchedulingPolicy_name, SchedulingPolicy_value)
+	proto.RegisterEnum("tech_profile.AdditionalBW", AdditionalBW_name, AdditionalBW_value)
+	proto.RegisterEnum("tech_profile.DiscardPolicy", DiscardPolicy_name, DiscardPolicy_value)
+	proto.RegisterEnum("tech_profile.InferredAdditionBWIndication", InferredAdditionBWIndication_name, InferredAdditionBWIndication_value)
+	proto.RegisterType((*SchedulerConfig)(nil), "tech_profile.SchedulerConfig")
+	proto.RegisterType((*TrafficShapingInfo)(nil), "tech_profile.TrafficShapingInfo")
+	proto.RegisterType((*TrafficScheduler)(nil), "tech_profile.TrafficScheduler")
+	proto.RegisterType((*TrafficSchedulers)(nil), "tech_profile.TrafficSchedulers")
+	proto.RegisterType((*TailDropDiscardConfig)(nil), "tech_profile.TailDropDiscardConfig")
+	proto.RegisterType((*RedDiscardConfig)(nil), "tech_profile.RedDiscardConfig")
+	proto.RegisterType((*WRedDiscardConfig)(nil), "tech_profile.WRedDiscardConfig")
+	proto.RegisterType((*DiscardConfig)(nil), "tech_profile.DiscardConfig")
+	proto.RegisterType((*TrafficQueue)(nil), "tech_profile.TrafficQueue")
+	proto.RegisterType((*TrafficQueues)(nil), "tech_profile.TrafficQueues")
+	proto.RegisterType((*InstanceControl)(nil), "tech_profile.InstanceControl")
+	proto.RegisterType((*QThresholds)(nil), "tech_profile.QThresholds")
+	proto.RegisterType((*GemPortAttributes)(nil), "tech_profile.GemPortAttributes")
+	proto.RegisterType((*SchedulerAttributes)(nil), "tech_profile.SchedulerAttributes")
+	proto.RegisterType((*EPONQueueAttributes)(nil), "tech_profile.EPONQueueAttributes")
+	proto.RegisterType((*TechProfile)(nil), "tech_profile.TechProfile")
+	proto.RegisterType((*EponTechProfile)(nil), "tech_profile.EponTechProfile")
+	proto.RegisterType((*TechProfileInstance)(nil), "tech_profile.TechProfileInstance")
+	proto.RegisterType((*EponTechProfileInstance)(nil), "tech_profile.EponTechProfileInstance")
+	proto.RegisterType((*ResourceInstance)(nil), "tech_profile.ResourceInstance")
+}
+
+func init() { proto.RegisterFile("voltha_protos/tech_profile.proto", fileDescriptor_d019a68bffe14cae) }
+
+var fileDescriptor_d019a68bffe14cae = []byte{
+	// 2138 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x59, 0x4d, 0x73, 0x1c, 0x39,
+	0xf9, 0xf7, 0xcc, 0xd8, 0xf3, 0xf2, 0xcc, 0x8c, 0xdd, 0x96, 0xe3, 0xcd, 0xc4, 0x71, 0x36, 0xce,
+	0xec, 0x7f, 0xff, 0x6b, 0x4c, 0x11, 0xb3, 0xce, 0xcb, 0x1e, 0xb2, 0xb0, 0x65, 0xc7, 0xae, 0x64,
+	0x60, 0xe3, 0xd8, 0x6d, 0x83, 0x29, 0x0e, 0x74, 0xf5, 0xb4, 0x34, 0x63, 0xb1, 0x3d, 0x52, 0x5b,
+	0x52, 0xc7, 0xf1, 0x9e, 0x28, 0xaa, 0xf8, 0x14, 0xc0, 0x85, 0x2a, 0xae, 0x5c, 0xf6, 0x42, 0xc1,
+	0x85, 0x2a, 0xbe, 0x05, 0x9f, 0x80, 0x2a, 0xbe, 0x04, 0x25, 0x75, 0xf7, 0xf4, 0xcb, 0x4c, 0x12,
+	0x27, 0x38, 0x5b, 0x05, 0x37, 0xe9, 0xd1, 0x4f, 0x8f, 0x1e, 0x3d, 0x2f, 0x3f, 0x49, 0xdd, 0xb0,
+	0xf6, 0x82, 0xfb, 0xea, 0xd4, 0x75, 0x02, 0xc1, 0x15, 0x97, 0x9b, 0x8a, 0x78, 0xa7, 0xba, 0x3d,
+	0xa0, 0x3e, 0xb9, 0x6b, 0x64, 0xa8, 0x95, 0x95, 0xad, 0xac, 0x0e, 0x39, 0x1f, 0xfa, 0x64, 0xd3,
+	0x0d, 0xe8, 0xa6, 0xcb, 0x18, 0x57, 0xae, 0xa2, 0x9c, 0xc9, 0x08, 0xdb, 0xfd, 0x55, 0x19, 0x16,
+	0x8e, 0xbc, 0x53, 0x82, 0x43, 0x9f, 0x88, 0xc7, 0x9c, 0x0d, 0xe8, 0x10, 0x3d, 0x80, 0x06, 0xa6,
+	0x82, 0x78, 0x1a, 0xd7, 0x29, 0xad, 0x95, 0xd6, 0xe7, 0xb7, 0xae, 0xdf, 0xcd, 0xad, 0xb3, 0x9b,
+	0x0c, 0xdb, 0x29, 0x12, 0x7d, 0x01, 0x6d, 0x17, 0x63, 0xaa, 0xdb, 0xae, 0xef, 0xf4, 0xcf, 0x3b,
+	0x65, 0x33, 0x75, 0x25, 0x3f, 0x75, 0x7b, 0x0c, 0xd9, 0x39, 0xb1, 0x5b, 0xe9, 0x84, 0x9d, 0x73,
+	0xb4, 0x02, 0xf5, 0x40, 0x50, 0x2e, 0xa8, 0xba, 0xe8, 0x54, 0xd6, 0x4a, 0xeb, 0x35, 0x7b, 0xdc,
+	0x47, 0x1f, 0x40, 0xf5, 0x9c, 0xd0, 0xe1, 0xa9, 0xea, 0xcc, 0x9a, 0x91, 0xb8, 0x87, 0xb6, 0xa1,
+	0x25, 0xb5, 0xf9, 0x4e, 0xc0, 0x7d, 0xea, 0x5d, 0x74, 0xe6, 0xcc, 0x9a, 0x1f, 0xe6, 0xd7, 0x8c,
+	0x37, 0x48, 0xd9, 0xf0, 0xc0, 0xa0, 0xec, 0xa6, 0x99, 0x13, 0x75, 0xba, 0x7f, 0x2e, 0x01, 0x3a,
+	0x16, 0xee, 0x60, 0x40, 0xbd, 0xa3, 0x53, 0x37, 0xa0, 0x6c, 0xd8, 0x63, 0x03, 0x8e, 0x2c, 0xa8,
+	0x78, 0x54, 0x98, 0xfd, 0xd7, 0x6c, 0xdd, 0x34, 0x92, 0xbe, 0x34, 0xdb, 0xd2, 0x92, 0xbe, 0xd4,
+	0x92, 0x80, 0x8a, 0xd8, 0x58, 0xdd, 0x34, 0x92, 0xbe, 0x8c, 0x8d, 0xd4, 0x4d, 0x2d, 0x19, 0x52,
+	0x61, 0x0c, 0xab, 0xd9, 0xba, 0x89, 0x9e, 0x02, 0xb8, 0x18, 0x3b, 0xfd, 0x73, 0x87, 0x32, 0xdc,
+	0xa9, 0x1a, 0x8b, 0x37, 0xf2, 0x16, 0xf7, 0xd8, 0x80, 0x08, 0x41, 0x70, 0xe2, 0xad, 0x9d, 0x93,
+	0x1e, 0xc3, 0xd4, 0x33, 0xa1, 0xb3, 0xeb, 0x2e, 0xc6, 0x3b, 0xe7, 0x3d, 0x86, 0xbb, 0xbf, 0x2f,
+	0x83, 0x95, 0x98, 0x9e, 0x04, 0xf1, 0x5d, 0xc3, 0x77, 0x03, 0xea, 0xae, 0xef, 0x73, 0xcf, 0xa1,
+	0x38, 0xde, 0x62, 0xcd, 0xf4, 0x7b, 0x18, 0x3d, 0x82, 0x86, 0x4c, 0xd4, 0x9b, 0xcd, 0x36, 0xb7,
+	0x6e, 0x4d, 0xf5, 0x70, 0x92, 0x42, 0x76, 0x8a, 0x47, 0x36, 0x5c, 0x53, 0x91, 0x89, 0x8e, 0x8c,
+	0xdc, 0xeb, 0x50, 0x36, 0xe0, 0xc6, 0x45, 0xcd, 0xad, 0xb5, 0xbc, 0x9e, 0xc9, 0x38, 0xd8, 0x48,
+	0x4d, 0xc6, 0xe6, 0xff, 0x61, 0x21, 0x3b, 0x4d, 0x9b, 0x1c, 0xf9, 0xb7, 0xad, 0xc5, 0x07, 0x91,
+	0xb4, 0x87, 0xbb, 0x7f, 0x29, 0xc1, 0x62, 0xd1, 0x3f, 0x12, 0x5d, 0x87, 0x1a, 0x65, 0x6a, 0xa0,
+	0x67, 0x45, 0xd1, 0xad, 0xea, 0x6e, 0x0f, 0xa3, 0x65, 0xa8, 0x72, 0x16, 0xa6, 0x0e, 0x98, 0xe3,
+	0x2c, 0x8c, 0xc4, 0x21, 0xa3, 0x5a, 0x1c, 0x85, 0x75, 0x2e, 0x64, 0xb4, 0x87, 0xb5, 0x9a, 0x80,
+	0x0b, 0xe5, 0x30, 0x1e, 0x2f, 0x5e, 0xd5, 0xdd, 0x7d, 0x8e, 0xf6, 0x60, 0x7e, 0xbc, 0x63, 0xbd,
+	0xaa, 0xec, 0x54, 0xd6, 0x2a, 0xeb, 0xcd, 0x62, 0x56, 0x16, 0x0d, 0xb3, 0xdb, 0x2a, 0x23, 0x91,
+	0xdd, 0x87, 0xb0, 0x7c, 0xec, 0x52, 0x7f, 0x57, 0xf0, 0x60, 0x97, 0x4a, 0xcf, 0x15, 0x38, 0xae,
+	0xcf, 0x5b, 0x00, 0x67, 0x21, 0x09, 0x89, 0x23, 0xe9, 0xd7, 0x24, 0xde, 0x42, 0xc3, 0x48, 0x8e,
+	0xe8, 0xd7, 0xa4, 0xfb, 0x9b, 0x12, 0x58, 0x36, 0xc1, 0xf9, 0x39, 0x1f, 0x41, 0x7b, 0x44, 0x99,
+	0xa3, 0x4e, 0x05, 0x91, 0xa7, 0xdc, 0x4f, 0x76, 0xde, 0x1a, 0x51, 0x76, 0x9c, 0xc8, 0x0c, 0xc8,
+	0x7d, 0x99, 0x01, 0x95, 0x63, 0x90, 0xfb, 0x32, 0x05, 0x7d, 0x02, 0x0b, 0x1a, 0x14, 0x08, 0xde,
+	0x77, 0xfb, 0xd4, 0x4f, 0x8b, 0x75, 0x7e, 0xe4, 0xbe, 0x3c, 0x48, 0xa5, 0xdd, 0x6f, 0x4a, 0xb0,
+	0x78, 0x32, 0x61, 0xc8, 0x7d, 0x98, 0x1b, 0x0a, 0x42, 0xa2, 0xcc, 0x9c, 0xf0, 0x49, 0x11, 0x6e,
+	0x47, 0x60, 0xf4, 0x10, 0xaa, 0x17, 0xc4, 0xf7, 0x79, 0x44, 0x2a, 0x6f, 0x9e, 0x16, 0xa3, 0xd1,
+	0xf7, 0xa1, 0x22, 0x08, 0x8e, 0x73, 0xf6, 0x4d, 0x93, 0x34, 0xb4, 0xfb, 0xcf, 0x32, 0xb4, 0xf3,
+	0x16, 0xef, 0xc0, 0x3c, 0x8e, 0x04, 0x09, 0xc9, 0x44, 0x45, 0x75, 0xb3, 0x58, 0x54, 0x06, 0x13,
+	0x33, 0x4c, 0x1b, 0x67, 0xbb, 0xe8, 0x17, 0xd0, 0x51, 0x2e, 0xf5, 0x1d, 0x2c, 0x78, 0xe0, 0x24,
+	0xda, 0x3c, 0xa3, 0x3f, 0xde, 0xd1, 0x47, 0x85, 0xe4, 0x98, 0x16, 0xf9, 0xa7, 0x33, 0xf6, 0xb2,
+	0x9a, 0x9a, 0x12, 0xfb, 0x80, 0x04, 0xc1, 0x45, 0xcd, 0x97, 0xda, 0xf6, 0xd3, 0x19, 0xdb, 0x12,
+	0xc5, 0x28, 0x1d, 0xc2, 0xd2, 0xf9, 0x14, 0x85, 0x51, 0xcd, 0xde, 0xce, 0x2b, 0x3c, 0x99, 0xa2,
+	0x71, 0xf1, 0xbc, 0xa8, 0x72, 0xc7, 0x4a, 0xdd, 0x18, 0x69, 0xeb, 0xfe, 0xb1, 0x02, 0xad, 0xb8,
+	0x08, 0x0e, 0x75, 0xf6, 0xbe, 0x2b, 0x73, 0xdd, 0x02, 0x18, 0x92, 0x91, 0xa9, 0xc5, 0x71, 0xe9,
+	0x36, 0x62, 0x49, 0x0f, 0x6b, 0x62, 0x0b, 0xfa, 0x54, 0x39, 0x23, 0x37, 0x30, 0x1e, 0x69, 0xd8,
+	0x35, 0xdd, 0x7f, 0xe6, 0x06, 0xe8, 0x63, 0x98, 0x77, 0x89, 0x74, 0x08, 0xf3, 0xc4, 0x45, 0x60,
+	0x56, 0xd5, 0x3b, 0xac, 0xdb, 0x6d, 0x97, 0xc8, 0xbd, 0xb1, 0xf0, 0x0a, 0x0e, 0x99, 0xdc, 0xd9,
+	0x56, 0x7d, 0xe5, 0xd9, 0x56, 0xcb, 0x9d, 0x6d, 0x93, 0x89, 0x57, 0x7f, 0xeb, 0xc4, 0xdb, 0x29,
+	0x7a, 0xbd, 0xd3, 0x30, 0x31, 0x9c, 0xae, 0x23, 0x2e, 0x84, 0x44, 0x47, 0xd4, 0xed, 0xfe, 0xa3,
+	0x04, 0xed, 0x6c, 0x9c, 0xde, 0x3f, 0x83, 0x6e, 0xa7, 0x0c, 0x6a, 0x78, 0x4d, 0x76, 0xaa, 0x86,
+	0x41, 0x57, 0xa6, 0x32, 0xa8, 0x31, 0x6a, 0xcc, 0x9e, 0xb1, 0x89, 0x53, 0x8e, 0x88, 0xda, 0xb4,
+	0x23, 0x62, 0x00, 0x0b, 0x3d, 0x26, 0x95, 0xcb, 0x3c, 0xf2, 0x98, 0x33, 0x25, 0xb8, 0xaf, 0x4f,
+	0x6c, 0xce, 0x42, 0xb3, 0xb3, 0x86, 0xad, 0x9b, 0x5a, 0x12, 0x32, 0x6a, 0xf6, 0xd4, 0xb0, 0x75,
+	0x13, 0x6d, 0xc2, 0x35, 0xcd, 0x82, 0x43, 0x32, 0x72, 0x02, 0xf7, 0xc2, 0xe7, 0x2e, 0x8e, 0xd8,
+	0x38, 0x4a, 0xb0, 0xc5, 0x91, 0xfb, 0xf2, 0x09, 0x19, 0x1d, 0x44, 0x23, 0x86, 0x95, 0x7f, 0x5d,
+	0x86, 0xe6, 0xe1, 0x98, 0x45, 0x25, 0xba, 0x03, 0xad, 0xb3, 0x94, 0x69, 0x3f, 0x35, 0xab, 0xb5,
+	0xed, 0xe6, 0xd9, 0x18, 0xf2, 0x69, 0x01, 0xb2, 0x65, 0x96, 0xcf, 0x41, 0xb6, 0x0a, 0x90, 0x7b,
+	0x66, 0xf9, 0x1c, 0xe4, 0x5e, 0x01, 0x72, 0xdf, 0x44, 0x20, 0x07, 0xb9, 0x5f, 0x80, 0x3c, 0x30,
+	0xc1, 0xc8, 0x41, 0x1e, 0x14, 0x20, 0x0f, 0x4d, 0x0e, 0xe7, 0x20, 0x0f, 0x0b, 0x90, 0xcf, 0x8c,
+	0xbb, 0x73, 0x90, 0xcf, 0xba, 0xdf, 0xcc, 0xc1, 0xa2, 0xf6, 0x0b, 0x17, 0x6a, 0x5b, 0x29, 0x41,
+	0xfb, 0xa1, 0x22, 0xb2, 0x50, 0xbf, 0xa5, 0x62, 0xfd, 0xae, 0x02, 0x68, 0x57, 0x9f, 0x45, 0x0e,
+	0x8e, 0x62, 0x50, 0x1f, 0xb9, 0x2f, 0x0f, 0xb5, 0x5f, 0xdf, 0xbe, 0xba, 0x1b, 0xc5, 0xea, 0xfe,
+	0x31, 0x2c, 0xca, 0x71, 0xed, 0xbe, 0x5d, 0x89, 0x5b, 0xb2, 0x20, 0xd1, 0x7b, 0x49, 0xea, 0xda,
+	0x39, 0x8b, 0x2b, 0xbd, 0x91, 0x48, 0x0e, 0xdf, 0x6b, 0xa9, 0xef, 0xbd, 0xa2, 0xd4, 0xdf, 0x74,
+	0xec, 0xe5, 0xab, 0x1d, 0x3d, 0x81, 0xc5, 0xbc, 0x1a, 0xe7, 0xc5, 0x56, 0x67, 0xfe, 0xcd, 0xa4,
+	0xb1, 0x90, 0x53, 0xf3, 0x53, 0x93, 0x9b, 0x54, 0x3a, 0xa3, 0xd0, 0x57, 0xd4, 0x73, 0xa5, 0xea,
+	0x80, 0x71, 0x7e, 0x93, 0xca, 0x67, 0x89, 0x08, 0xad, 0x83, 0x35, 0x1e, 0x37, 0xb5, 0x44, 0x71,
+	0xa7, 0x19, 0x5f, 0x26, 0x12, 0xf9, 0x13, 0x32, 0xea, 0x61, 0xf4, 0x03, 0xb8, 0x89, 0x2f, 0x98,
+	0x3b, 0xa2, 0x9e, 0xe3, 0x7a, 0x1e, 0x91, 0x52, 0x1b, 0xa7, 0xab, 0xd5, 0xf1, 0xa9, 0x54, 0x9d,
+	0x96, 0xd1, 0xdd, 0x89, 0x21, 0xdb, 0x06, 0x11, 0x97, 0xf3, 0x97, 0x54, 0x2a, 0xf4, 0x08, 0x56,
+	0xa4, 0x7e, 0xf8, 0x4c, 0x9f, 0xdd, 0x36, 0xb3, 0xaf, 0x47, 0x88, 0x89, 0xc9, 0xdd, 0x3f, 0x94,
+	0x61, 0x69, 0x7c, 0x4b, 0xcb, 0xe4, 0xed, 0x15, 0x5d, 0xb4, 0xdb, 0xe9, 0x45, 0x7b, 0xe2, 0x09,
+	0x55, 0xf9, 0x0f, 0x9e, 0x50, 0xb3, 0xaf, 0x3c, 0x66, 0xe6, 0x72, 0xb9, 0xb7, 0x0b, 0xf3, 0x67,
+	0x4e, 0xee, 0x7c, 0xab, 0x5e, 0x2a, 0xf9, 0x5b, 0x67, 0x47, 0x99, 0x57, 0xd4, 0xdf, 0xaa, 0xb0,
+	0xb4, 0x77, 0xf0, 0x7c, 0xdf, 0xd0, 0x6f, 0xc6, 0x49, 0xf9, 0xea, 0x2d, 0xbd, 0xa6, 0x7a, 0xcb,
+	0xf9, 0xea, 0xcd, 0xb3, 0x42, 0x44, 0x6c, 0x19, 0x56, 0xb8, 0x64, 0x71, 0xdf, 0x81, 0x56, 0x72,
+	0x92, 0xa8, 0x8b, 0x80, 0x98, 0xad, 0x37, 0xec, 0x66, 0x2c, 0x3b, 0xbe, 0x08, 0x08, 0xba, 0x0f,
+	0x1f, 0x84, 0x4c, 0xea, 0x5d, 0x50, 0x45, 0xb0, 0x33, 0x14, 0x2e, 0x53, 0x91, 0xb5, 0x11, 0xc9,
+	0x5d, 0xcb, 0x8c, 0x3e, 0xd1, 0x83, 0xc6, 0xf2, 0xef, 0x80, 0xc5, 0xf8, 0x88, 0xea, 0x38, 0x51,
+	0xa6, 0x88, 0x78, 0xe1, 0xfa, 0x31, 0xe3, 0x2d, 0xc4, 0xf2, 0x5e, 0x2c, 0x46, 0x5b, 0xb0, 0xac,
+	0xb8, 0x4f, 0x84, 0xab, 0x22, 0x17, 0xfb, 0xce, 0x2f, 0xa9, 0x52, 0x44, 0x98, 0x1a, 0x6f, 0xdb,
+	0x4b, 0xe3, 0xc1, 0x03, 0xee, 0xfb, 0x3f, 0x32, 0x43, 0xe8, 0x87, 0x70, 0x53, 0x90, 0xb3, 0x90,
+	0x48, 0xe5, 0x28, 0xe1, 0x32, 0x39, 0xa2, 0x52, 0x52, 0xce, 0x92, 0x08, 0x35, 0xcc, 0xcc, 0x1b,
+	0x31, 0xe4, 0x38, 0x83, 0x88, 0xc9, 0x60, 0x15, 0x80, 0x85, 0x23, 0xed, 0x76, 0xa2, 0xa4, 0x29,
+	0xbd, 0xb6, 0x5d, 0x67, 0xe1, 0xe8, 0xf0, 0x88, 0x28, 0x89, 0x3e, 0xcf, 0x51, 0xb5, 0x34, 0x35,
+	0xd7, 0xdc, 0xba, 0x91, 0x0f, 0x78, 0xe6, 0xb4, 0xca, 0xb2, 0xb8, 0x9c, 0x4e, 0x98, 0xad, 0x2b,
+	0x21, 0xcc, 0x76, 0x14, 0xe6, 0x69, 0x84, 0x39, 0x6f, 0x86, 0x5e, 0x4d, 0x98, 0x0b, 0x57, 0x40,
+	0x98, 0xd6, 0x95, 0x11, 0xe6, 0xe2, 0xdb, 0x13, 0x66, 0xf7, 0x4f, 0xb3, 0xd0, 0x3c, 0x4e, 0x2f,
+	0x27, 0x08, 0xc1, 0x2c, 0x73, 0x47, 0x49, 0xd1, 0x98, 0x36, 0xea, 0x40, 0xed, 0x05, 0x11, 0x3a,
+	0xd0, 0x09, 0x77, 0xc4, 0x5d, 0x9d, 0xe9, 0xc9, 0x5d, 0xc7, 0x64, 0x7a, 0x74, 0x18, 0x36, 0x63,
+	0x99, 0xc9, 0xf4, 0x2e, 0xb4, 0x75, 0x52, 0x98, 0x4b, 0x0b, 0x17, 0x4a, 0x26, 0x77, 0x01, 0x16,
+	0x8e, 0xe2, 0x53, 0x59, 0xa2, 0xa7, 0x60, 0xd1, 0xf8, 0x3e, 0x94, 0x90, 0xa4, 0x29, 0x9a, 0x89,
+	0x27, 0x7f, 0xe1, 0xd6, 0x64, 0x2f, 0xd0, 0xc2, 0x35, 0x6a, 0x17, 0x5a, 0xa1, 0x74, 0xd2, 0x0f,
+	0x07, 0x55, 0xa3, 0xe5, 0xce, 0x2b, 0x3e, 0x1c, 0xa4, 0x94, 0x61, 0x37, 0x43, 0x99, 0x7e, 0xcd,
+	0xd8, 0x85, 0x16, 0xce, 0x6a, 0xa9, 0x5d, 0x5a, 0x0b, 0xce, 0x68, 0x19, 0xc2, 0x5a, 0x18, 0x48,
+	0x25, 0x88, 0x9b, 0x6e, 0xdf, 0x71, 0x13, 0x70, 0x74, 0x0a, 0xd4, 0xcd, 0x15, 0xb3, 0xf0, 0xb8,
+	0x99, 0xb8, 0xad, 0xd8, 0xab, 0x89, 0xa2, 0xe2, 0x90, 0x39, 0x68, 0xbe, 0x82, 0x2e, 0xe6, 0xe7,
+	0xec, 0x0d, 0x4b, 0x35, 0x2e, 0xb7, 0xd4, 0x87, 0xa9, 0xaa, 0x69, 0x8b, 0x75, 0xff, 0x5e, 0x81,
+	0x85, 0xbd, 0x80, 0xb3, 0xff, 0xa1, 0xa4, 0xd1, 0x06, 0xb9, 0xde, 0x57, 0xee, 0x30, 0x36, 0xa8,
+	0x1a, 0x1b, 0x14, 0xc9, 0x8c, 0x41, 0x18, 0x6e, 0x8d, 0x63, 0x19, 0x7d, 0x07, 0x29, 0x78, 0xb7,
+	0x66, 0xbc, 0x5b, 0x48, 0x91, 0x29, 0x67, 0x93, 0xbd, 0x92, 0xe8, 0xc9, 0x0f, 0x98, 0x40, 0x9e,
+	0xc2, 0xed, 0x4c, 0x20, 0xa7, 0xae, 0x53, 0xbf, 0xec, 0x3a, 0xab, 0xa9, 0xa6, 0xc9, 0x95, 0xba,
+	0xff, 0x9a, 0x85, 0xa5, 0x4c, 0x04, 0x13, 0x17, 0xbd, 0x65, 0x24, 0xef, 0xc1, 0xb2, 0x0c, 0xfb,
+	0xd2, 0x13, 0xb4, 0x4f, 0x84, 0x43, 0x31, 0x61, 0x8a, 0x0e, 0x68, 0xfc, 0xbd, 0xae, 0x61, 0x5f,
+	0x4b, 0x07, 0x7b, 0xe3, 0xb1, 0x89, 0xf0, 0xcf, 0x5e, 0x22, 0xfc, 0x73, 0x97, 0x0b, 0x7f, 0xf5,
+	0x4a, 0x38, 0xa3, 0x76, 0x25, 0x9c, 0x51, 0x7f, 0x6f, 0x9c, 0xd1, 0xf8, 0xf6, 0x38, 0x03, 0xae,
+	0x86, 0x33, 0x7e, 0x3b, 0x0b, 0xd7, 0x0b, 0x9c, 0xf1, 0x5f, 0x98, 0x71, 0xd9, 0x3b, 0x74, 0x35,
+	0x7f, 0x87, 0x9e, 0x96, 0x8c, 0xb5, 0x2b, 0xe1, 0xa2, 0xfa, 0x3b, 0x70, 0x51, 0xe3, 0x5b, 0xe2,
+	0x22, 0xb8, 0x1a, 0x2e, 0xfa, 0xab, 0xf9, 0x76, 0x2c, 0x79, 0x28, 0xbc, 0x34, 0x2d, 0x96, 0x60,
+	0x4e, 0x05, 0xc9, 0xd3, 0xbc, 0x6d, 0xcf, 0xaa, 0xa0, 0x87, 0x27, 0x02, 0x59, 0x9e, 0x0c, 0xe4,
+	0x3b, 0x25, 0x48, 0x36, 0xb2, 0xb3, 0xf9, 0xc8, 0xde, 0x86, 0x66, 0xfa, 0x22, 0xd0, 0x69, 0x51,
+	0x59, 0x6f, 0xdb, 0x30, 0x7e, 0x12, 0xc8, 0x8d, 0xcf, 0xa1, 0x31, 0x7e, 0x71, 0xa1, 0x16, 0xd4,
+	0x7f, 0x72, 0x70, 0x74, 0x6c, 0xef, 0x6d, 0x3f, 0xb3, 0x66, 0xd0, 0x3c, 0xc0, 0xee, 0xf3, 0x93,
+	0xfd, 0xb8, 0x5f, 0x42, 0x8b, 0xd0, 0xde, 0xe9, 0xed, 0xf6, 0xec, 0xbd, 0xc7, 0xc7, 0xbd, 0xe7,
+	0xfb, 0xdb, 0x5f, 0x5a, 0xe5, 0x8d, 0x47, 0x60, 0x15, 0xef, 0xab, 0xa8, 0x06, 0x95, 0x13, 0xdb,
+	0xb6, 0x66, 0x10, 0x82, 0xf9, 0x23, 0x25, 0xa8, 0xa7, 0x0e, 0xe2, 0xab, 0xa9, 0x55, 0x42, 0x00,
+	0xd5, 0xa7, 0x17, 0x7d, 0x41, 0xb1, 0x55, 0xde, 0x60, 0xd0, 0xca, 0x3e, 0xcb, 0xd0, 0x32, 0x2c,
+	0x66, 0xfb, 0xce, 0x3e, 0x67, 0xc4, 0x9a, 0x41, 0x4b, 0xb0, 0x90, 0x17, 0x6f, 0x5b, 0x25, 0x74,
+	0x13, 0xae, 0xe7, 0x84, 0x3b, 0x44, 0xaa, 0xbd, 0xc1, 0x80, 0x0b, 0x65, 0x95, 0x27, 0x14, 0x6d,
+	0x87, 0x8a, 0x5b, 0x95, 0x8d, 0x2f, 0xc6, 0x5f, 0xa9, 0x63, 0x4b, 0x5b, 0x50, 0x4f, 0xbe, 0x19,
+	0x5b, 0x33, 0xa8, 0x0d, 0x8d, 0x93, 0x71, 0xb7, 0xa4, 0xb7, 0x61, 0x13, 0x6c, 0x95, 0x51, 0x1d,
+	0x66, 0x4f, 0x74, 0xab, 0xb2, 0xf1, 0xbb, 0x12, 0xac, 0xbe, 0xee, 0x2f, 0x13, 0xfa, 0x18, 0xee,
+	0xbc, 0x6e, 0x3c, 0xd9, 0xd1, 0x3a, 0xfc, 0xdf, 0x6b, 0x61, 0xdb, 0x52, 0x86, 0x82, 0x60, 0xab,
+	0x84, 0xbe, 0x0b, 0x9f, 0xbc, 0x16, 0x99, 0xdd, 0xf6, 0xce, 0xcf, 0x60, 0x8d, 0x8b, 0xe1, 0x5d,
+	0x1e, 0x10, 0xe6, 0x71, 0x81, 0xef, 0x46, 0x3f, 0x3d, 0x73, 0xe9, 0xfd, 0xf3, 0xfb, 0x43, 0xaa,
+	0x4e, 0xc3, 0xfe, 0x5d, 0x8f, 0x8f, 0x36, 0x13, 0xe0, 0x66, 0x04, 0xfc, 0x5e, 0xfc, 0x77, 0xf4,
+	0xc5, 0x83, 0xcd, 0x21, 0xcf, 0xfd, 0x23, 0xed, 0x57, 0xcd, 0xd0, 0xbd, 0x7f, 0x07, 0x00, 0x00,
+	0xff, 0xff, 0xc9, 0xfb, 0x08, 0x8b, 0x48, 0x1d, 0x00, 0x00,
+}
diff --git a/vendor/golang.org/x/net/context/context.go b/vendor/golang.org/x/net/context/context.go
new file mode 100644
index 0000000..a3c021d
--- /dev/null
+++ b/vendor/golang.org/x/net/context/context.go
@@ -0,0 +1,56 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package context defines the Context type, which carries deadlines,
+// cancelation signals, and other request-scoped values across API boundaries
+// and between processes.
+// As of Go 1.7 this package is available in the standard library under the
+// name context.  https://golang.org/pkg/context.
+//
+// Incoming requests to a server should create a Context, and outgoing calls to
+// servers should accept a Context. The chain of function calls between must
+// propagate the Context, optionally replacing it with a modified copy created
+// using WithDeadline, WithTimeout, WithCancel, or WithValue.
+//
+// Programs that use Contexts should follow these rules to keep interfaces
+// consistent across packages and enable static analysis tools to check context
+// propagation:
+//
+// Do not store Contexts inside a struct type; instead, pass a Context
+// explicitly to each function that needs it. The Context should be the first
+// parameter, typically named ctx:
+//
+// 	func DoSomething(ctx context.Context, arg Arg) error {
+// 		// ... use ctx ...
+// 	}
+//
+// Do not pass a nil Context, even if a function permits it. Pass context.TODO
+// if you are unsure about which Context to use.
+//
+// Use context Values only for request-scoped data that transits processes and
+// APIs, not for passing optional parameters to functions.
+//
+// The same Context may be passed to functions running in different goroutines;
+// Contexts are safe for simultaneous use by multiple goroutines.
+//
+// See http://blog.golang.org/context for example code for a server that uses
+// Contexts.
+package context // import "golang.org/x/net/context"
+
+// Background returns a non-nil, empty Context. It is never canceled, has no
+// values, and has no deadline. It is typically used by the main function,
+// initialization, and tests, and as the top-level Context for incoming
+// requests.
+func Background() Context {
+	return background
+}
+
+// TODO returns a non-nil, empty Context. Code should use context.TODO when
+// it's unclear which Context to use or it is not yet available (because the
+// surrounding function has not yet been extended to accept a Context
+// parameter).  TODO is recognized by static analysis tools that determine
+// whether Contexts are propagated correctly in a program.
+func TODO() Context {
+	return todo
+}
diff --git a/vendor/golang.org/x/net/context/go17.go b/vendor/golang.org/x/net/context/go17.go
new file mode 100644
index 0000000..344bd14
--- /dev/null
+++ b/vendor/golang.org/x/net/context/go17.go
@@ -0,0 +1,73 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build go1.7
+// +build go1.7
+
+package context
+
+import (
+	"context" // standard library's context, as of Go 1.7
+	"time"
+)
+
+var (
+	todo       = context.TODO()
+	background = context.Background()
+)
+
+// Canceled is the error returned by Context.Err when the context is canceled.
+var Canceled = context.Canceled
+
+// DeadlineExceeded is the error returned by Context.Err when the context's
+// deadline passes.
+var DeadlineExceeded = context.DeadlineExceeded
+
+// WithCancel returns a copy of parent with a new Done channel. The returned
+// context's Done channel is closed when the returned cancel function is called
+// or when the parent context's Done channel is closed, whichever happens first.
+//
+// Canceling this context releases resources associated with it, so code should
+// call cancel as soon as the operations running in this Context complete.
+func WithCancel(parent Context) (ctx Context, cancel CancelFunc) {
+	ctx, f := context.WithCancel(parent)
+	return ctx, CancelFunc(f)
+}
+
+// WithDeadline returns a copy of the parent context with the deadline adjusted
+// to be no later than d. If the parent's deadline is already earlier than d,
+// WithDeadline(parent, d) is semantically equivalent to parent. The returned
+// context's Done channel is closed when the deadline expires, when the returned
+// cancel function is called, or when the parent context's Done channel is
+// closed, whichever happens first.
+//
+// Canceling this context releases resources associated with it, so code should
+// call cancel as soon as the operations running in this Context complete.
+func WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc) {
+	ctx, f := context.WithDeadline(parent, deadline)
+	return ctx, CancelFunc(f)
+}
+
+// WithTimeout returns WithDeadline(parent, time.Now().Add(timeout)).
+//
+// Canceling this context releases resources associated with it, so code should
+// call cancel as soon as the operations running in this Context complete:
+//
+// 	func slowOperationWithTimeout(ctx context.Context) (Result, error) {
+// 		ctx, cancel := context.WithTimeout(ctx, 100*time.Millisecond)
+// 		defer cancel()  // releases resources if slowOperation completes before timeout elapses
+// 		return slowOperation(ctx)
+// 	}
+func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc) {
+	return WithDeadline(parent, time.Now().Add(timeout))
+}
+
+// WithValue returns a copy of parent in which the value associated with key is
+// val.
+//
+// Use context Values only for request-scoped data that transits processes and
+// APIs, not for passing optional parameters to functions.
+func WithValue(parent Context, key interface{}, val interface{}) Context {
+	return context.WithValue(parent, key, val)
+}
diff --git a/vendor/golang.org/x/net/context/go19.go b/vendor/golang.org/x/net/context/go19.go
new file mode 100644
index 0000000..64d31ec
--- /dev/null
+++ b/vendor/golang.org/x/net/context/go19.go
@@ -0,0 +1,21 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build go1.9
+// +build go1.9
+
+package context
+
+import "context" // standard library's context, as of Go 1.7
+
+// A Context carries a deadline, a cancelation signal, and other values across
+// API boundaries.
+//
+// Context's methods may be called by multiple goroutines simultaneously.
+type Context = context.Context
+
+// A CancelFunc tells an operation to abandon its work.
+// A CancelFunc does not wait for the work to stop.
+// After the first call, subsequent calls to a CancelFunc do nothing.
+type CancelFunc = context.CancelFunc
diff --git a/vendor/golang.org/x/net/context/pre_go17.go b/vendor/golang.org/x/net/context/pre_go17.go
new file mode 100644
index 0000000..5270db5
--- /dev/null
+++ b/vendor/golang.org/x/net/context/pre_go17.go
@@ -0,0 +1,301 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !go1.7
+// +build !go1.7
+
+package context
+
+import (
+	"errors"
+	"fmt"
+	"sync"
+	"time"
+)
+
+// An emptyCtx is never canceled, has no values, and has no deadline. It is not
+// struct{}, since vars of this type must have distinct addresses.
+type emptyCtx int
+
+func (*emptyCtx) Deadline() (deadline time.Time, ok bool) {
+	return
+}
+
+func (*emptyCtx) Done() <-chan struct{} {
+	return nil
+}
+
+func (*emptyCtx) Err() error {
+	return nil
+}
+
+func (*emptyCtx) Value(key interface{}) interface{} {
+	return nil
+}
+
+func (e *emptyCtx) String() string {
+	switch e {
+	case background:
+		return "context.Background"
+	case todo:
+		return "context.TODO"
+	}
+	return "unknown empty Context"
+}
+
+var (
+	background = new(emptyCtx)
+	todo       = new(emptyCtx)
+)
+
+// Canceled is the error returned by Context.Err when the context is canceled.
+var Canceled = errors.New("context canceled")
+
+// DeadlineExceeded is the error returned by Context.Err when the context's
+// deadline passes.
+var DeadlineExceeded = errors.New("context deadline exceeded")
+
+// WithCancel returns a copy of parent with a new Done channel. The returned
+// context's Done channel is closed when the returned cancel function is called
+// or when the parent context's Done channel is closed, whichever happens first.
+//
+// Canceling this context releases resources associated with it, so code should
+// call cancel as soon as the operations running in this Context complete.
+func WithCancel(parent Context) (ctx Context, cancel CancelFunc) {
+	c := newCancelCtx(parent)
+	propagateCancel(parent, c)
+	return c, func() { c.cancel(true, Canceled) }
+}
+
+// newCancelCtx returns an initialized cancelCtx.
+func newCancelCtx(parent Context) *cancelCtx {
+	return &cancelCtx{
+		Context: parent,
+		done:    make(chan struct{}),
+	}
+}
+
+// propagateCancel arranges for child to be canceled when parent is.
+func propagateCancel(parent Context, child canceler) {
+	if parent.Done() == nil {
+		return // parent is never canceled
+	}
+	if p, ok := parentCancelCtx(parent); ok {
+		p.mu.Lock()
+		if p.err != nil {
+			// parent has already been canceled
+			child.cancel(false, p.err)
+		} else {
+			if p.children == nil {
+				p.children = make(map[canceler]bool)
+			}
+			p.children[child] = true
+		}
+		p.mu.Unlock()
+	} else {
+		go func() {
+			select {
+			case <-parent.Done():
+				child.cancel(false, parent.Err())
+			case <-child.Done():
+			}
+		}()
+	}
+}
+
+// parentCancelCtx follows a chain of parent references until it finds a
+// *cancelCtx. This function understands how each of the concrete types in this
+// package represents its parent.
+func parentCancelCtx(parent Context) (*cancelCtx, bool) {
+	for {
+		switch c := parent.(type) {
+		case *cancelCtx:
+			return c, true
+		case *timerCtx:
+			return c.cancelCtx, true
+		case *valueCtx:
+			parent = c.Context
+		default:
+			return nil, false
+		}
+	}
+}
+
+// removeChild removes a context from its parent.
+func removeChild(parent Context, child canceler) {
+	p, ok := parentCancelCtx(parent)
+	if !ok {
+		return
+	}
+	p.mu.Lock()
+	if p.children != nil {
+		delete(p.children, child)
+	}
+	p.mu.Unlock()
+}
+
+// A canceler is a context type that can be canceled directly. The
+// implementations are *cancelCtx and *timerCtx.
+type canceler interface {
+	cancel(removeFromParent bool, err error)
+	Done() <-chan struct{}
+}
+
+// A cancelCtx can be canceled. When canceled, it also cancels any children
+// that implement canceler.
+type cancelCtx struct {
+	Context
+
+	done chan struct{} // closed by the first cancel call.
+
+	mu       sync.Mutex
+	children map[canceler]bool // set to nil by the first cancel call
+	err      error             // set to non-nil by the first cancel call
+}
+
+func (c *cancelCtx) Done() <-chan struct{} {
+	return c.done
+}
+
+func (c *cancelCtx) Err() error {
+	c.mu.Lock()
+	defer c.mu.Unlock()
+	return c.err
+}
+
+func (c *cancelCtx) String() string {
+	return fmt.Sprintf("%v.WithCancel", c.Context)
+}
+
+// cancel closes c.done, cancels each of c's children, and, if
+// removeFromParent is true, removes c from its parent's children.
+func (c *cancelCtx) cancel(removeFromParent bool, err error) {
+	if err == nil {
+		panic("context: internal error: missing cancel error")
+	}
+	c.mu.Lock()
+	if c.err != nil {
+		c.mu.Unlock()
+		return // already canceled
+	}
+	c.err = err
+	close(c.done)
+	for child := range c.children {
+		// NOTE: acquiring the child's lock while holding parent's lock.
+		child.cancel(false, err)
+	}
+	c.children = nil
+	c.mu.Unlock()
+
+	if removeFromParent {
+		removeChild(c.Context, c)
+	}
+}
+
+// WithDeadline returns a copy of the parent context with the deadline adjusted
+// to be no later than d. If the parent's deadline is already earlier than d,
+// WithDeadline(parent, d) is semantically equivalent to parent. The returned
+// context's Done channel is closed when the deadline expires, when the returned
+// cancel function is called, or when the parent context's Done channel is
+// closed, whichever happens first.
+//
+// Canceling this context releases resources associated with it, so code should
+// call cancel as soon as the operations running in this Context complete.
+func WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc) {
+	if cur, ok := parent.Deadline(); ok && cur.Before(deadline) {
+		// The current deadline is already sooner than the new one.
+		return WithCancel(parent)
+	}
+	c := &timerCtx{
+		cancelCtx: newCancelCtx(parent),
+		deadline:  deadline,
+	}
+	propagateCancel(parent, c)
+	d := deadline.Sub(time.Now())
+	if d <= 0 {
+		c.cancel(true, DeadlineExceeded) // deadline has already passed
+		return c, func() { c.cancel(true, Canceled) }
+	}
+	c.mu.Lock()
+	defer c.mu.Unlock()
+	if c.err == nil {
+		c.timer = time.AfterFunc(d, func() {
+			c.cancel(true, DeadlineExceeded)
+		})
+	}
+	return c, func() { c.cancel(true, Canceled) }
+}
+
+// A timerCtx carries a timer and a deadline. It embeds a cancelCtx to
+// implement Done and Err. It implements cancel by stopping its timer then
+// delegating to cancelCtx.cancel.
+type timerCtx struct {
+	*cancelCtx
+	timer *time.Timer // Under cancelCtx.mu.
+
+	deadline time.Time
+}
+
+func (c *timerCtx) Deadline() (deadline time.Time, ok bool) {
+	return c.deadline, true
+}
+
+func (c *timerCtx) String() string {
+	return fmt.Sprintf("%v.WithDeadline(%s [%s])", c.cancelCtx.Context, c.deadline, c.deadline.Sub(time.Now()))
+}
+
+func (c *timerCtx) cancel(removeFromParent bool, err error) {
+	c.cancelCtx.cancel(false, err)
+	if removeFromParent {
+		// Remove this timerCtx from its parent cancelCtx's children.
+		removeChild(c.cancelCtx.Context, c)
+	}
+	c.mu.Lock()
+	if c.timer != nil {
+		c.timer.Stop()
+		c.timer = nil
+	}
+	c.mu.Unlock()
+}
+
+// WithTimeout returns WithDeadline(parent, time.Now().Add(timeout)).
+//
+// Canceling this context releases resources associated with it, so code should
+// call cancel as soon as the operations running in this Context complete:
+//
+// 	func slowOperationWithTimeout(ctx context.Context) (Result, error) {
+// 		ctx, cancel := context.WithTimeout(ctx, 100*time.Millisecond)
+// 		defer cancel()  // releases resources if slowOperation completes before timeout elapses
+// 		return slowOperation(ctx)
+// 	}
+func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc) {
+	return WithDeadline(parent, time.Now().Add(timeout))
+}
+
+// WithValue returns a copy of parent in which the value associated with key is
+// val.
+//
+// Use context Values only for request-scoped data that transits processes and
+// APIs, not for passing optional parameters to functions.
+func WithValue(parent Context, key interface{}, val interface{}) Context {
+	return &valueCtx{parent, key, val}
+}
+
+// A valueCtx carries a key-value pair. It implements Value for that key and
+// delegates all other calls to the embedded Context.
+type valueCtx struct {
+	Context
+	key, val interface{}
+}
+
+func (c *valueCtx) String() string {
+	return fmt.Sprintf("%v.WithValue(%#v, %#v)", c.Context, c.key, c.val)
+}
+
+func (c *valueCtx) Value(key interface{}) interface{} {
+	if c.key == key {
+		return c.val
+	}
+	return c.Context.Value(key)
+}
diff --git a/vendor/golang.org/x/net/context/pre_go19.go b/vendor/golang.org/x/net/context/pre_go19.go
new file mode 100644
index 0000000..1f97153
--- /dev/null
+++ b/vendor/golang.org/x/net/context/pre_go19.go
@@ -0,0 +1,110 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !go1.9
+// +build !go1.9
+
+package context
+
+import "time"
+
+// A Context carries a deadline, a cancelation signal, and other values across
+// API boundaries.
+//
+// Context's methods may be called by multiple goroutines simultaneously.
+type Context interface {
+	// Deadline returns the time when work done on behalf of this context
+	// should be canceled. Deadline returns ok==false when no deadline is
+	// set. Successive calls to Deadline return the same results.
+	Deadline() (deadline time.Time, ok bool)
+
+	// Done returns a channel that's closed when work done on behalf of this
+	// context should be canceled. Done may return nil if this context can
+	// never be canceled. Successive calls to Done return the same value.
+	//
+	// WithCancel arranges for Done to be closed when cancel is called;
+	// WithDeadline arranges for Done to be closed when the deadline
+	// expires; WithTimeout arranges for Done to be closed when the timeout
+	// elapses.
+	//
+	// Done is provided for use in select statements:
+	//
+	//  // Stream generates values with DoSomething and sends them to out
+	//  // until DoSomething returns an error or ctx.Done is closed.
+	//  func Stream(ctx context.Context, out chan<- Value) error {
+	//  	for {
+	//  		v, err := DoSomething(ctx)
+	//  		if err != nil {
+	//  			return err
+	//  		}
+	//  		select {
+	//  		case <-ctx.Done():
+	//  			return ctx.Err()
+	//  		case out <- v:
+	//  		}
+	//  	}
+	//  }
+	//
+	// See http://blog.golang.org/pipelines for more examples of how to use
+	// a Done channel for cancelation.
+	Done() <-chan struct{}
+
+	// Err returns a non-nil error value after Done is closed. Err returns
+	// Canceled if the context was canceled or DeadlineExceeded if the
+	// context's deadline passed. No other values for Err are defined.
+	// After Done is closed, successive calls to Err return the same value.
+	Err() error
+
+	// Value returns the value associated with this context for key, or nil
+	// if no value is associated with key. Successive calls to Value with
+	// the same key returns the same result.
+	//
+	// Use context values only for request-scoped data that transits
+	// processes and API boundaries, not for passing optional parameters to
+	// functions.
+	//
+	// A key identifies a specific value in a Context. Functions that wish
+	// to store values in Context typically allocate a key in a global
+	// variable then use that key as the argument to context.WithValue and
+	// Context.Value. A key can be any type that supports equality;
+	// packages should define keys as an unexported type to avoid
+	// collisions.
+	//
+	// Packages that define a Context key should provide type-safe accessors
+	// for the values stores using that key:
+	//
+	// 	// Package user defines a User type that's stored in Contexts.
+	// 	package user
+	//
+	// 	import "golang.org/x/net/context"
+	//
+	// 	// User is the type of value stored in the Contexts.
+	// 	type User struct {...}
+	//
+	// 	// key is an unexported type for keys defined in this package.
+	// 	// This prevents collisions with keys defined in other packages.
+	// 	type key int
+	//
+	// 	// userKey is the key for user.User values in Contexts. It is
+	// 	// unexported; clients use user.NewContext and user.FromContext
+	// 	// instead of using this key directly.
+	// 	var userKey key = 0
+	//
+	// 	// NewContext returns a new Context that carries value u.
+	// 	func NewContext(ctx context.Context, u *User) context.Context {
+	// 		return context.WithValue(ctx, userKey, u)
+	// 	}
+	//
+	// 	// FromContext returns the User value stored in ctx, if any.
+	// 	func FromContext(ctx context.Context) (*User, bool) {
+	// 		u, ok := ctx.Value(userKey).(*User)
+	// 		return u, ok
+	// 	}
+	Value(key interface{}) interface{}
+}
+
+// A CancelFunc tells an operation to abandon its work.
+// A CancelFunc does not wait for the work to stop.
+// After the first call, subsequent calls to a CancelFunc do nothing.
+type CancelFunc func()
diff --git a/vendor/google.golang.org/grpc/reflection/README.md b/vendor/google.golang.org/grpc/reflection/README.md
new file mode 100644
index 0000000..04b6371
--- /dev/null
+++ b/vendor/google.golang.org/grpc/reflection/README.md
@@ -0,0 +1,18 @@
+# Reflection
+
+Package reflection implements server reflection service.
+
+The service implemented is defined in: https://github.com/grpc/grpc/blob/master/src/proto/grpc/reflection/v1alpha/reflection.proto.
+
+To register server reflection on a gRPC server:
+```go
+import "google.golang.org/grpc/reflection"
+
+s := grpc.NewServer()
+pb.RegisterYourOwnServer(s, &server{})
+
+// Register reflection service on gRPC server.
+reflection.Register(s)
+
+s.Serve(lis)
+```
diff --git a/vendor/google.golang.org/grpc/reflection/grpc_reflection_v1alpha/reflection.pb.go b/vendor/google.golang.org/grpc/reflection/grpc_reflection_v1alpha/reflection.pb.go
new file mode 100644
index 0000000..0a12ad2
--- /dev/null
+++ b/vendor/google.golang.org/grpc/reflection/grpc_reflection_v1alpha/reflection.pb.go
@@ -0,0 +1,750 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// source: grpc_reflection_v1alpha/reflection.proto
+
+package grpc_reflection_v1alpha
+
+import (
+	context "context"
+	fmt "fmt"
+	proto "github.com/golang/protobuf/proto"
+	grpc "google.golang.org/grpc"
+	codes "google.golang.org/grpc/codes"
+	status "google.golang.org/grpc/status"
+	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
+
+// The message sent by the client when calling ServerReflectionInfo method.
+type ServerReflectionRequest struct {
+	Host string `protobuf:"bytes,1,opt,name=host,proto3" json:"host,omitempty"`
+	// To use reflection service, the client should set one of the following
+	// fields in message_request. The server distinguishes requests by their
+	// defined field and then handles them using corresponding methods.
+	//
+	// Types that are valid to be assigned to MessageRequest:
+	//	*ServerReflectionRequest_FileByFilename
+	//	*ServerReflectionRequest_FileContainingSymbol
+	//	*ServerReflectionRequest_FileContainingExtension
+	//	*ServerReflectionRequest_AllExtensionNumbersOfType
+	//	*ServerReflectionRequest_ListServices
+	MessageRequest       isServerReflectionRequest_MessageRequest `protobuf_oneof:"message_request"`
+	XXX_NoUnkeyedLiteral struct{}                                 `json:"-"`
+	XXX_unrecognized     []byte                                   `json:"-"`
+	XXX_sizecache        int32                                    `json:"-"`
+}
+
+func (m *ServerReflectionRequest) Reset()         { *m = ServerReflectionRequest{} }
+func (m *ServerReflectionRequest) String() string { return proto.CompactTextString(m) }
+func (*ServerReflectionRequest) ProtoMessage()    {}
+func (*ServerReflectionRequest) Descriptor() ([]byte, []int) {
+	return fileDescriptor_42a8ac412db3cb03, []int{0}
+}
+
+func (m *ServerReflectionRequest) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_ServerReflectionRequest.Unmarshal(m, b)
+}
+func (m *ServerReflectionRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_ServerReflectionRequest.Marshal(b, m, deterministic)
+}
+func (m *ServerReflectionRequest) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_ServerReflectionRequest.Merge(m, src)
+}
+func (m *ServerReflectionRequest) XXX_Size() int {
+	return xxx_messageInfo_ServerReflectionRequest.Size(m)
+}
+func (m *ServerReflectionRequest) XXX_DiscardUnknown() {
+	xxx_messageInfo_ServerReflectionRequest.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_ServerReflectionRequest proto.InternalMessageInfo
+
+func (m *ServerReflectionRequest) GetHost() string {
+	if m != nil {
+		return m.Host
+	}
+	return ""
+}
+
+type isServerReflectionRequest_MessageRequest interface {
+	isServerReflectionRequest_MessageRequest()
+}
+
+type ServerReflectionRequest_FileByFilename struct {
+	FileByFilename string `protobuf:"bytes,3,opt,name=file_by_filename,json=fileByFilename,proto3,oneof"`
+}
+
+type ServerReflectionRequest_FileContainingSymbol struct {
+	FileContainingSymbol string `protobuf:"bytes,4,opt,name=file_containing_symbol,json=fileContainingSymbol,proto3,oneof"`
+}
+
+type ServerReflectionRequest_FileContainingExtension struct {
+	FileContainingExtension *ExtensionRequest `protobuf:"bytes,5,opt,name=file_containing_extension,json=fileContainingExtension,proto3,oneof"`
+}
+
+type ServerReflectionRequest_AllExtensionNumbersOfType struct {
+	AllExtensionNumbersOfType string `protobuf:"bytes,6,opt,name=all_extension_numbers_of_type,json=allExtensionNumbersOfType,proto3,oneof"`
+}
+
+type ServerReflectionRequest_ListServices struct {
+	ListServices string `protobuf:"bytes,7,opt,name=list_services,json=listServices,proto3,oneof"`
+}
+
+func (*ServerReflectionRequest_FileByFilename) isServerReflectionRequest_MessageRequest() {}
+
+func (*ServerReflectionRequest_FileContainingSymbol) isServerReflectionRequest_MessageRequest() {}
+
+func (*ServerReflectionRequest_FileContainingExtension) isServerReflectionRequest_MessageRequest() {}
+
+func (*ServerReflectionRequest_AllExtensionNumbersOfType) isServerReflectionRequest_MessageRequest() {}
+
+func (*ServerReflectionRequest_ListServices) isServerReflectionRequest_MessageRequest() {}
+
+func (m *ServerReflectionRequest) GetMessageRequest() isServerReflectionRequest_MessageRequest {
+	if m != nil {
+		return m.MessageRequest
+	}
+	return nil
+}
+
+func (m *ServerReflectionRequest) GetFileByFilename() string {
+	if x, ok := m.GetMessageRequest().(*ServerReflectionRequest_FileByFilename); ok {
+		return x.FileByFilename
+	}
+	return ""
+}
+
+func (m *ServerReflectionRequest) GetFileContainingSymbol() string {
+	if x, ok := m.GetMessageRequest().(*ServerReflectionRequest_FileContainingSymbol); ok {
+		return x.FileContainingSymbol
+	}
+	return ""
+}
+
+func (m *ServerReflectionRequest) GetFileContainingExtension() *ExtensionRequest {
+	if x, ok := m.GetMessageRequest().(*ServerReflectionRequest_FileContainingExtension); ok {
+		return x.FileContainingExtension
+	}
+	return nil
+}
+
+func (m *ServerReflectionRequest) GetAllExtensionNumbersOfType() string {
+	if x, ok := m.GetMessageRequest().(*ServerReflectionRequest_AllExtensionNumbersOfType); ok {
+		return x.AllExtensionNumbersOfType
+	}
+	return ""
+}
+
+func (m *ServerReflectionRequest) GetListServices() string {
+	if x, ok := m.GetMessageRequest().(*ServerReflectionRequest_ListServices); ok {
+		return x.ListServices
+	}
+	return ""
+}
+
+// XXX_OneofWrappers is for the internal use of the proto package.
+func (*ServerReflectionRequest) XXX_OneofWrappers() []interface{} {
+	return []interface{}{
+		(*ServerReflectionRequest_FileByFilename)(nil),
+		(*ServerReflectionRequest_FileContainingSymbol)(nil),
+		(*ServerReflectionRequest_FileContainingExtension)(nil),
+		(*ServerReflectionRequest_AllExtensionNumbersOfType)(nil),
+		(*ServerReflectionRequest_ListServices)(nil),
+	}
+}
+
+// The type name and extension number sent by the client when requesting
+// file_containing_extension.
+type ExtensionRequest struct {
+	// Fully-qualified type name. The format should be <package>.<type>
+	ContainingType       string   `protobuf:"bytes,1,opt,name=containing_type,json=containingType,proto3" json:"containing_type,omitempty"`
+	ExtensionNumber      int32    `protobuf:"varint,2,opt,name=extension_number,json=extensionNumber,proto3" json:"extension_number,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *ExtensionRequest) Reset()         { *m = ExtensionRequest{} }
+func (m *ExtensionRequest) String() string { return proto.CompactTextString(m) }
+func (*ExtensionRequest) ProtoMessage()    {}
+func (*ExtensionRequest) Descriptor() ([]byte, []int) {
+	return fileDescriptor_42a8ac412db3cb03, []int{1}
+}
+
+func (m *ExtensionRequest) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_ExtensionRequest.Unmarshal(m, b)
+}
+func (m *ExtensionRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_ExtensionRequest.Marshal(b, m, deterministic)
+}
+func (m *ExtensionRequest) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_ExtensionRequest.Merge(m, src)
+}
+func (m *ExtensionRequest) XXX_Size() int {
+	return xxx_messageInfo_ExtensionRequest.Size(m)
+}
+func (m *ExtensionRequest) XXX_DiscardUnknown() {
+	xxx_messageInfo_ExtensionRequest.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_ExtensionRequest proto.InternalMessageInfo
+
+func (m *ExtensionRequest) GetContainingType() string {
+	if m != nil {
+		return m.ContainingType
+	}
+	return ""
+}
+
+func (m *ExtensionRequest) GetExtensionNumber() int32 {
+	if m != nil {
+		return m.ExtensionNumber
+	}
+	return 0
+}
+
+// The message sent by the server to answer ServerReflectionInfo method.
+type ServerReflectionResponse struct {
+	ValidHost       string                   `protobuf:"bytes,1,opt,name=valid_host,json=validHost,proto3" json:"valid_host,omitempty"`
+	OriginalRequest *ServerReflectionRequest `protobuf:"bytes,2,opt,name=original_request,json=originalRequest,proto3" json:"original_request,omitempty"`
+	// The server sets one of the following fields according to the
+	// message_request in the request.
+	//
+	// Types that are valid to be assigned to MessageResponse:
+	//	*ServerReflectionResponse_FileDescriptorResponse
+	//	*ServerReflectionResponse_AllExtensionNumbersResponse
+	//	*ServerReflectionResponse_ListServicesResponse
+	//	*ServerReflectionResponse_ErrorResponse
+	MessageResponse      isServerReflectionResponse_MessageResponse `protobuf_oneof:"message_response"`
+	XXX_NoUnkeyedLiteral struct{}                                   `json:"-"`
+	XXX_unrecognized     []byte                                     `json:"-"`
+	XXX_sizecache        int32                                      `json:"-"`
+}
+
+func (m *ServerReflectionResponse) Reset()         { *m = ServerReflectionResponse{} }
+func (m *ServerReflectionResponse) String() string { return proto.CompactTextString(m) }
+func (*ServerReflectionResponse) ProtoMessage()    {}
+func (*ServerReflectionResponse) Descriptor() ([]byte, []int) {
+	return fileDescriptor_42a8ac412db3cb03, []int{2}
+}
+
+func (m *ServerReflectionResponse) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_ServerReflectionResponse.Unmarshal(m, b)
+}
+func (m *ServerReflectionResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_ServerReflectionResponse.Marshal(b, m, deterministic)
+}
+func (m *ServerReflectionResponse) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_ServerReflectionResponse.Merge(m, src)
+}
+func (m *ServerReflectionResponse) XXX_Size() int {
+	return xxx_messageInfo_ServerReflectionResponse.Size(m)
+}
+func (m *ServerReflectionResponse) XXX_DiscardUnknown() {
+	xxx_messageInfo_ServerReflectionResponse.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_ServerReflectionResponse proto.InternalMessageInfo
+
+func (m *ServerReflectionResponse) GetValidHost() string {
+	if m != nil {
+		return m.ValidHost
+	}
+	return ""
+}
+
+func (m *ServerReflectionResponse) GetOriginalRequest() *ServerReflectionRequest {
+	if m != nil {
+		return m.OriginalRequest
+	}
+	return nil
+}
+
+type isServerReflectionResponse_MessageResponse interface {
+	isServerReflectionResponse_MessageResponse()
+}
+
+type ServerReflectionResponse_FileDescriptorResponse struct {
+	FileDescriptorResponse *FileDescriptorResponse `protobuf:"bytes,4,opt,name=file_descriptor_response,json=fileDescriptorResponse,proto3,oneof"`
+}
+
+type ServerReflectionResponse_AllExtensionNumbersResponse struct {
+	AllExtensionNumbersResponse *ExtensionNumberResponse `protobuf:"bytes,5,opt,name=all_extension_numbers_response,json=allExtensionNumbersResponse,proto3,oneof"`
+}
+
+type ServerReflectionResponse_ListServicesResponse struct {
+	ListServicesResponse *ListServiceResponse `protobuf:"bytes,6,opt,name=list_services_response,json=listServicesResponse,proto3,oneof"`
+}
+
+type ServerReflectionResponse_ErrorResponse struct {
+	ErrorResponse *ErrorResponse `protobuf:"bytes,7,opt,name=error_response,json=errorResponse,proto3,oneof"`
+}
+
+func (*ServerReflectionResponse_FileDescriptorResponse) isServerReflectionResponse_MessageResponse() {}
+
+func (*ServerReflectionResponse_AllExtensionNumbersResponse) isServerReflectionResponse_MessageResponse() {
+}
+
+func (*ServerReflectionResponse_ListServicesResponse) isServerReflectionResponse_MessageResponse() {}
+
+func (*ServerReflectionResponse_ErrorResponse) isServerReflectionResponse_MessageResponse() {}
+
+func (m *ServerReflectionResponse) GetMessageResponse() isServerReflectionResponse_MessageResponse {
+	if m != nil {
+		return m.MessageResponse
+	}
+	return nil
+}
+
+func (m *ServerReflectionResponse) GetFileDescriptorResponse() *FileDescriptorResponse {
+	if x, ok := m.GetMessageResponse().(*ServerReflectionResponse_FileDescriptorResponse); ok {
+		return x.FileDescriptorResponse
+	}
+	return nil
+}
+
+func (m *ServerReflectionResponse) GetAllExtensionNumbersResponse() *ExtensionNumberResponse {
+	if x, ok := m.GetMessageResponse().(*ServerReflectionResponse_AllExtensionNumbersResponse); ok {
+		return x.AllExtensionNumbersResponse
+	}
+	return nil
+}
+
+func (m *ServerReflectionResponse) GetListServicesResponse() *ListServiceResponse {
+	if x, ok := m.GetMessageResponse().(*ServerReflectionResponse_ListServicesResponse); ok {
+		return x.ListServicesResponse
+	}
+	return nil
+}
+
+func (m *ServerReflectionResponse) GetErrorResponse() *ErrorResponse {
+	if x, ok := m.GetMessageResponse().(*ServerReflectionResponse_ErrorResponse); ok {
+		return x.ErrorResponse
+	}
+	return nil
+}
+
+// XXX_OneofWrappers is for the internal use of the proto package.
+func (*ServerReflectionResponse) XXX_OneofWrappers() []interface{} {
+	return []interface{}{
+		(*ServerReflectionResponse_FileDescriptorResponse)(nil),
+		(*ServerReflectionResponse_AllExtensionNumbersResponse)(nil),
+		(*ServerReflectionResponse_ListServicesResponse)(nil),
+		(*ServerReflectionResponse_ErrorResponse)(nil),
+	}
+}
+
+// Serialized FileDescriptorProto messages sent by the server answering
+// a file_by_filename, file_containing_symbol, or file_containing_extension
+// request.
+type FileDescriptorResponse struct {
+	// Serialized FileDescriptorProto messages. We avoid taking a dependency on
+	// descriptor.proto, which uses proto2 only features, by making them opaque
+	// bytes instead.
+	FileDescriptorProto  [][]byte `protobuf:"bytes,1,rep,name=file_descriptor_proto,json=fileDescriptorProto,proto3" json:"file_descriptor_proto,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *FileDescriptorResponse) Reset()         { *m = FileDescriptorResponse{} }
+func (m *FileDescriptorResponse) String() string { return proto.CompactTextString(m) }
+func (*FileDescriptorResponse) ProtoMessage()    {}
+func (*FileDescriptorResponse) Descriptor() ([]byte, []int) {
+	return fileDescriptor_42a8ac412db3cb03, []int{3}
+}
+
+func (m *FileDescriptorResponse) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_FileDescriptorResponse.Unmarshal(m, b)
+}
+func (m *FileDescriptorResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_FileDescriptorResponse.Marshal(b, m, deterministic)
+}
+func (m *FileDescriptorResponse) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_FileDescriptorResponse.Merge(m, src)
+}
+func (m *FileDescriptorResponse) XXX_Size() int {
+	return xxx_messageInfo_FileDescriptorResponse.Size(m)
+}
+func (m *FileDescriptorResponse) XXX_DiscardUnknown() {
+	xxx_messageInfo_FileDescriptorResponse.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_FileDescriptorResponse proto.InternalMessageInfo
+
+func (m *FileDescriptorResponse) GetFileDescriptorProto() [][]byte {
+	if m != nil {
+		return m.FileDescriptorProto
+	}
+	return nil
+}
+
+// A list of extension numbers sent by the server answering
+// all_extension_numbers_of_type request.
+type ExtensionNumberResponse struct {
+	// Full name of the base type, including the package name. The format
+	// is <package>.<type>
+	BaseTypeName         string   `protobuf:"bytes,1,opt,name=base_type_name,json=baseTypeName,proto3" json:"base_type_name,omitempty"`
+	ExtensionNumber      []int32  `protobuf:"varint,2,rep,packed,name=extension_number,json=extensionNumber,proto3" json:"extension_number,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *ExtensionNumberResponse) Reset()         { *m = ExtensionNumberResponse{} }
+func (m *ExtensionNumberResponse) String() string { return proto.CompactTextString(m) }
+func (*ExtensionNumberResponse) ProtoMessage()    {}
+func (*ExtensionNumberResponse) Descriptor() ([]byte, []int) {
+	return fileDescriptor_42a8ac412db3cb03, []int{4}
+}
+
+func (m *ExtensionNumberResponse) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_ExtensionNumberResponse.Unmarshal(m, b)
+}
+func (m *ExtensionNumberResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_ExtensionNumberResponse.Marshal(b, m, deterministic)
+}
+func (m *ExtensionNumberResponse) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_ExtensionNumberResponse.Merge(m, src)
+}
+func (m *ExtensionNumberResponse) XXX_Size() int {
+	return xxx_messageInfo_ExtensionNumberResponse.Size(m)
+}
+func (m *ExtensionNumberResponse) XXX_DiscardUnknown() {
+	xxx_messageInfo_ExtensionNumberResponse.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_ExtensionNumberResponse proto.InternalMessageInfo
+
+func (m *ExtensionNumberResponse) GetBaseTypeName() string {
+	if m != nil {
+		return m.BaseTypeName
+	}
+	return ""
+}
+
+func (m *ExtensionNumberResponse) GetExtensionNumber() []int32 {
+	if m != nil {
+		return m.ExtensionNumber
+	}
+	return nil
+}
+
+// A list of ServiceResponse sent by the server answering list_services request.
+type ListServiceResponse struct {
+	// The information of each service may be expanded in the future, so we use
+	// ServiceResponse message to encapsulate it.
+	Service              []*ServiceResponse `protobuf:"bytes,1,rep,name=service,proto3" json:"service,omitempty"`
+	XXX_NoUnkeyedLiteral struct{}           `json:"-"`
+	XXX_unrecognized     []byte             `json:"-"`
+	XXX_sizecache        int32              `json:"-"`
+}
+
+func (m *ListServiceResponse) Reset()         { *m = ListServiceResponse{} }
+func (m *ListServiceResponse) String() string { return proto.CompactTextString(m) }
+func (*ListServiceResponse) ProtoMessage()    {}
+func (*ListServiceResponse) Descriptor() ([]byte, []int) {
+	return fileDescriptor_42a8ac412db3cb03, []int{5}
+}
+
+func (m *ListServiceResponse) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_ListServiceResponse.Unmarshal(m, b)
+}
+func (m *ListServiceResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_ListServiceResponse.Marshal(b, m, deterministic)
+}
+func (m *ListServiceResponse) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_ListServiceResponse.Merge(m, src)
+}
+func (m *ListServiceResponse) XXX_Size() int {
+	return xxx_messageInfo_ListServiceResponse.Size(m)
+}
+func (m *ListServiceResponse) XXX_DiscardUnknown() {
+	xxx_messageInfo_ListServiceResponse.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_ListServiceResponse proto.InternalMessageInfo
+
+func (m *ListServiceResponse) GetService() []*ServiceResponse {
+	if m != nil {
+		return m.Service
+	}
+	return nil
+}
+
+// The information of a single service used by ListServiceResponse to answer
+// list_services request.
+type ServiceResponse struct {
+	// Full name of a registered service, including its package name. The format
+	// is <package>.<service>
+	Name                 string   `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *ServiceResponse) Reset()         { *m = ServiceResponse{} }
+func (m *ServiceResponse) String() string { return proto.CompactTextString(m) }
+func (*ServiceResponse) ProtoMessage()    {}
+func (*ServiceResponse) Descriptor() ([]byte, []int) {
+	return fileDescriptor_42a8ac412db3cb03, []int{6}
+}
+
+func (m *ServiceResponse) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_ServiceResponse.Unmarshal(m, b)
+}
+func (m *ServiceResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_ServiceResponse.Marshal(b, m, deterministic)
+}
+func (m *ServiceResponse) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_ServiceResponse.Merge(m, src)
+}
+func (m *ServiceResponse) XXX_Size() int {
+	return xxx_messageInfo_ServiceResponse.Size(m)
+}
+func (m *ServiceResponse) XXX_DiscardUnknown() {
+	xxx_messageInfo_ServiceResponse.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_ServiceResponse proto.InternalMessageInfo
+
+func (m *ServiceResponse) GetName() string {
+	if m != nil {
+		return m.Name
+	}
+	return ""
+}
+
+// The error code and error message sent by the server when an error occurs.
+type ErrorResponse struct {
+	// This field uses the error codes defined in grpc::StatusCode.
+	ErrorCode            int32    `protobuf:"varint,1,opt,name=error_code,json=errorCode,proto3" json:"error_code,omitempty"`
+	ErrorMessage         string   `protobuf:"bytes,2,opt,name=error_message,json=errorMessage,proto3" json:"error_message,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *ErrorResponse) Reset()         { *m = ErrorResponse{} }
+func (m *ErrorResponse) String() string { return proto.CompactTextString(m) }
+func (*ErrorResponse) ProtoMessage()    {}
+func (*ErrorResponse) Descriptor() ([]byte, []int) {
+	return fileDescriptor_42a8ac412db3cb03, []int{7}
+}
+
+func (m *ErrorResponse) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_ErrorResponse.Unmarshal(m, b)
+}
+func (m *ErrorResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_ErrorResponse.Marshal(b, m, deterministic)
+}
+func (m *ErrorResponse) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_ErrorResponse.Merge(m, src)
+}
+func (m *ErrorResponse) XXX_Size() int {
+	return xxx_messageInfo_ErrorResponse.Size(m)
+}
+func (m *ErrorResponse) XXX_DiscardUnknown() {
+	xxx_messageInfo_ErrorResponse.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_ErrorResponse proto.InternalMessageInfo
+
+func (m *ErrorResponse) GetErrorCode() int32 {
+	if m != nil {
+		return m.ErrorCode
+	}
+	return 0
+}
+
+func (m *ErrorResponse) GetErrorMessage() string {
+	if m != nil {
+		return m.ErrorMessage
+	}
+	return ""
+}
+
+func init() {
+	proto.RegisterType((*ServerReflectionRequest)(nil), "grpc.reflection.v1alpha.ServerReflectionRequest")
+	proto.RegisterType((*ExtensionRequest)(nil), "grpc.reflection.v1alpha.ExtensionRequest")
+	proto.RegisterType((*ServerReflectionResponse)(nil), "grpc.reflection.v1alpha.ServerReflectionResponse")
+	proto.RegisterType((*FileDescriptorResponse)(nil), "grpc.reflection.v1alpha.FileDescriptorResponse")
+	proto.RegisterType((*ExtensionNumberResponse)(nil), "grpc.reflection.v1alpha.ExtensionNumberResponse")
+	proto.RegisterType((*ListServiceResponse)(nil), "grpc.reflection.v1alpha.ListServiceResponse")
+	proto.RegisterType((*ServiceResponse)(nil), "grpc.reflection.v1alpha.ServiceResponse")
+	proto.RegisterType((*ErrorResponse)(nil), "grpc.reflection.v1alpha.ErrorResponse")
+}
+
+func init() {
+	proto.RegisterFile("grpc_reflection_v1alpha/reflection.proto", fileDescriptor_42a8ac412db3cb03)
+}
+
+var fileDescriptor_42a8ac412db3cb03 = []byte{
+	// 656 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x54, 0x51, 0x73, 0xd2, 0x40,
+	0x10, 0x6e, 0x5a, 0x68, 0x87, 0x85, 0x02, 0x5e, 0x2b, 0xa4, 0x3a, 0x75, 0x98, 0x68, 0x35, 0x75,
+	0x1c, 0xda, 0xe2, 0x8c, 0x3f, 0x80, 0xaa, 0x83, 0x33, 0xb5, 0x75, 0x0e, 0x5f, 0x1c, 0x1f, 0x6e,
+	0x02, 0x2c, 0x34, 0x1a, 0x72, 0xf1, 0x2e, 0x45, 0x79, 0xf2, 0x47, 0xf8, 0xa3, 0xfc, 0x4b, 0x3e,
+	0x3a, 0x77, 0x09, 0x21, 0xa4, 0x44, 0xa7, 0x4f, 0x30, 0xdf, 0xee, 0xde, 0xb7, 0xbb, 0xdf, 0xb7,
+	0x01, 0x7b, 0x22, 0x82, 0x21, 0x13, 0x38, 0xf6, 0x70, 0x18, 0xba, 0xdc, 0x67, 0xb3, 0x33, 0xc7,
+	0x0b, 0xae, 0x9d, 0x93, 0x25, 0xd4, 0x0e, 0x04, 0x0f, 0x39, 0x69, 0xaa, 0xcc, 0x76, 0x0a, 0x8e,
+	0x33, 0xad, 0x3f, 0x9b, 0xd0, 0xec, 0xa3, 0x98, 0xa1, 0xa0, 0x49, 0x90, 0xe2, 0xb7, 0x1b, 0x94,
+	0x21, 0x21, 0x50, 0xb8, 0xe6, 0x32, 0x34, 0x8d, 0x96, 0x61, 0x97, 0xa8, 0xfe, 0x4f, 0x9e, 0x43,
+	0x7d, 0xec, 0x7a, 0xc8, 0x06, 0x73, 0xa6, 0x7e, 0x7d, 0x67, 0x8a, 0xe6, 0x96, 0x8a, 0xf7, 0x36,
+	0x68, 0x55, 0x21, 0xdd, 0xf9, 0xdb, 0x18, 0x27, 0xaf, 0xa0, 0xa1, 0x73, 0x87, 0xdc, 0x0f, 0x1d,
+	0xd7, 0x77, 0xfd, 0x09, 0x93, 0xf3, 0xe9, 0x80, 0x7b, 0x66, 0x21, 0xae, 0xd8, 0x57, 0xf1, 0xf3,
+	0x24, 0xdc, 0xd7, 0x51, 0x32, 0x81, 0x83, 0x6c, 0x1d, 0xfe, 0x08, 0xd1, 0x97, 0x2e, 0xf7, 0xcd,
+	0x62, 0xcb, 0xb0, 0xcb, 0x9d, 0xe3, 0x76, 0xce, 0x40, 0xed, 0x37, 0x8b, 0xcc, 0x78, 0x8a, 0xde,
+	0x06, 0x6d, 0xae, 0xb2, 0x24, 0x19, 0xa4, 0x0b, 0x87, 0x8e, 0xe7, 0x2d, 0x1f, 0x67, 0xfe, 0xcd,
+	0x74, 0x80, 0x42, 0x32, 0x3e, 0x66, 0xe1, 0x3c, 0x40, 0x73, 0x3b, 0xee, 0xf3, 0xc0, 0xf1, 0xbc,
+	0xa4, 0xec, 0x32, 0x4a, 0xba, 0x1a, 0x7f, 0x9c, 0x07, 0x48, 0x8e, 0x60, 0xd7, 0x73, 0x65, 0xc8,
+	0x24, 0x8a, 0x99, 0x3b, 0x44, 0x69, 0xee, 0xc4, 0x35, 0x15, 0x05, 0xf7, 0x63, 0xb4, 0x7b, 0x0f,
+	0x6a, 0x53, 0x94, 0xd2, 0x99, 0x20, 0x13, 0x51, 0x63, 0xd6, 0x18, 0xea, 0xd9, 0x66, 0xc9, 0x33,
+	0xa8, 0xa5, 0xa6, 0xd6, 0x3d, 0x44, 0xdb, 0xaf, 0x2e, 0x61, 0x4d, 0x7b, 0x0c, 0xf5, 0x6c, 0xdb,
+	0xe6, 0x66, 0xcb, 0xb0, 0x8b, 0xb4, 0x86, 0xab, 0x8d, 0x5a, 0xbf, 0x0b, 0x60, 0xde, 0x96, 0x58,
+	0x06, 0xdc, 0x97, 0x48, 0x0e, 0x01, 0x66, 0x8e, 0xe7, 0x8e, 0x58, 0x4a, 0xe9, 0x92, 0x46, 0x7a,
+	0x4a, 0xee, 0xcf, 0x50, 0xe7, 0xc2, 0x9d, 0xb8, 0xbe, 0xe3, 0x2d, 0xfa, 0xd6, 0x34, 0xe5, 0xce,
+	0x69, 0xae, 0x02, 0x39, 0x76, 0xa2, 0xb5, 0xc5, 0x4b, 0x8b, 0x61, 0xbf, 0x82, 0xa9, 0x75, 0x1e,
+	0xa1, 0x1c, 0x0a, 0x37, 0x08, 0xb9, 0x60, 0x22, 0xee, 0x4b, 0x3b, 0xa4, 0xdc, 0x39, 0xc9, 0x25,
+	0x51, 0x26, 0x7b, 0x9d, 0xd4, 0x2d, 0xc6, 0xe9, 0x6d, 0x50, 0x6d, 0xb9, 0xdb, 0x11, 0xf2, 0x1d,
+	0x1e, 0xad, 0xd7, 0x3a, 0xa1, 0x2c, 0xfe, 0x67, 0xae, 0x8c, 0x01, 0x52, 0x9c, 0x0f, 0xd7, 0xd8,
+	0x23, 0x21, 0x1e, 0x41, 0x63, 0xc5, 0x20, 0x4b, 0xc2, 0x6d, 0x4d, 0xf8, 0x22, 0x97, 0xf0, 0x62,
+	0x69, 0xa0, 0x14, 0xd9, 0x7e, 0xda, 0x57, 0x09, 0xcb, 0x15, 0x54, 0x51, 0x88, 0xf4, 0x06, 0x77,
+	0xf4, 0xeb, 0x4f, 0xf3, 0xc7, 0x51, 0xe9, 0xa9, 0x77, 0x77, 0x31, 0x0d, 0x74, 0x09, 0xd4, 0x97,
+	0x86, 0x8d, 0x30, 0xeb, 0x02, 0x1a, 0xeb, 0xf7, 0x4e, 0x3a, 0x70, 0x3f, 0x2b, 0xa5, 0xfe, 0xf0,
+	0x98, 0x46, 0x6b, 0xcb, 0xae, 0xd0, 0xbd, 0x55, 0x51, 0x3e, 0xa8, 0x90, 0xf5, 0x05, 0x9a, 0x39,
+	0x2b, 0x25, 0x4f, 0xa0, 0x3a, 0x70, 0x24, 0xea, 0x03, 0x60, 0xfa, 0x1b, 0x13, 0x39, 0xb3, 0xa2,
+	0x50, 0xe5, 0xff, 0x4b, 0xf5, 0x7d, 0x59, 0x7f, 0x03, 0x5b, 0xeb, 0x6e, 0xe0, 0x13, 0xec, 0xad,
+	0xd9, 0x26, 0xe9, 0xc2, 0x4e, 0x2c, 0x8b, 0x6e, 0xb4, 0xdc, 0xb1, 0xff, 0xe9, 0xea, 0x54, 0x29,
+	0x5d, 0x14, 0x5a, 0x47, 0x50, 0xcb, 0x3e, 0x4b, 0xa0, 0x90, 0x6a, 0x5a, 0xff, 0xb7, 0xfa, 0xb0,
+	0xbb, 0xb2, 0x71, 0x75, 0x79, 0x91, 0x62, 0x43, 0x3e, 0x8a, 0x52, 0x8b, 0xb4, 0xa4, 0x91, 0x73,
+	0x3e, 0x42, 0xf2, 0x18, 0x22, 0x41, 0x58, 0xac, 0x82, 0x3e, 0xbb, 0x12, 0xad, 0x68, 0xf0, 0x7d,
+	0x84, 0x75, 0x7e, 0x19, 0x50, 0xcf, 0x9e, 0x1b, 0xf9, 0x09, 0xfb, 0x59, 0xec, 0x9d, 0x3f, 0xe6,
+	0xe4, 0xce, 0x17, 0xfb, 0xe0, 0xec, 0x0e, 0x15, 0xd1, 0x54, 0xb6, 0x71, 0x6a, 0x0c, 0xb6, 0xb5,
+	0xf4, 0x2f, 0xff, 0x06, 0x00, 0x00, 0xff, 0xff, 0x85, 0x02, 0x09, 0x9d, 0x9f, 0x06, 0x00, 0x00,
+}
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ context.Context
+var _ grpc.ClientConn
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the grpc package it is being compiled against.
+const _ = grpc.SupportPackageIsVersion4
+
+// ServerReflectionClient is the client API for ServerReflection service.
+//
+// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
+type ServerReflectionClient interface {
+	// The reflection service is structured as a bidirectional stream, ensuring
+	// all related requests go to a single server.
+	ServerReflectionInfo(ctx context.Context, opts ...grpc.CallOption) (ServerReflection_ServerReflectionInfoClient, error)
+}
+
+type serverReflectionClient struct {
+	cc *grpc.ClientConn
+}
+
+func NewServerReflectionClient(cc *grpc.ClientConn) ServerReflectionClient {
+	return &serverReflectionClient{cc}
+}
+
+func (c *serverReflectionClient) ServerReflectionInfo(ctx context.Context, opts ...grpc.CallOption) (ServerReflection_ServerReflectionInfoClient, error) {
+	stream, err := c.cc.NewStream(ctx, &_ServerReflection_serviceDesc.Streams[0], "/grpc.reflection.v1alpha.ServerReflection/ServerReflectionInfo", opts...)
+	if err != nil {
+		return nil, err
+	}
+	x := &serverReflectionServerReflectionInfoClient{stream}
+	return x, nil
+}
+
+type ServerReflection_ServerReflectionInfoClient interface {
+	Send(*ServerReflectionRequest) error
+	Recv() (*ServerReflectionResponse, error)
+	grpc.ClientStream
+}
+
+type serverReflectionServerReflectionInfoClient struct {
+	grpc.ClientStream
+}
+
+func (x *serverReflectionServerReflectionInfoClient) Send(m *ServerReflectionRequest) error {
+	return x.ClientStream.SendMsg(m)
+}
+
+func (x *serverReflectionServerReflectionInfoClient) Recv() (*ServerReflectionResponse, error) {
+	m := new(ServerReflectionResponse)
+	if err := x.ClientStream.RecvMsg(m); err != nil {
+		return nil, err
+	}
+	return m, nil
+}
+
+// ServerReflectionServer is the server API for ServerReflection service.
+type ServerReflectionServer interface {
+	// The reflection service is structured as a bidirectional stream, ensuring
+	// all related requests go to a single server.
+	ServerReflectionInfo(ServerReflection_ServerReflectionInfoServer) error
+}
+
+// UnimplementedServerReflectionServer can be embedded to have forward compatible implementations.
+type UnimplementedServerReflectionServer struct {
+}
+
+func (*UnimplementedServerReflectionServer) ServerReflectionInfo(srv ServerReflection_ServerReflectionInfoServer) error {
+	return status.Errorf(codes.Unimplemented, "method ServerReflectionInfo not implemented")
+}
+
+func RegisterServerReflectionServer(s *grpc.Server, srv ServerReflectionServer) {
+	s.RegisterService(&_ServerReflection_serviceDesc, srv)
+}
+
+func _ServerReflection_ServerReflectionInfo_Handler(srv interface{}, stream grpc.ServerStream) error {
+	return srv.(ServerReflectionServer).ServerReflectionInfo(&serverReflectionServerReflectionInfoServer{stream})
+}
+
+type ServerReflection_ServerReflectionInfoServer interface {
+	Send(*ServerReflectionResponse) error
+	Recv() (*ServerReflectionRequest, error)
+	grpc.ServerStream
+}
+
+type serverReflectionServerReflectionInfoServer struct {
+	grpc.ServerStream
+}
+
+func (x *serverReflectionServerReflectionInfoServer) Send(m *ServerReflectionResponse) error {
+	return x.ServerStream.SendMsg(m)
+}
+
+func (x *serverReflectionServerReflectionInfoServer) Recv() (*ServerReflectionRequest, error) {
+	m := new(ServerReflectionRequest)
+	if err := x.ServerStream.RecvMsg(m); err != nil {
+		return nil, err
+	}
+	return m, nil
+}
+
+var _ServerReflection_serviceDesc = grpc.ServiceDesc{
+	ServiceName: "grpc.reflection.v1alpha.ServerReflection",
+	HandlerType: (*ServerReflectionServer)(nil),
+	Methods:     []grpc.MethodDesc{},
+	Streams: []grpc.StreamDesc{
+		{
+			StreamName:    "ServerReflectionInfo",
+			Handler:       _ServerReflection_ServerReflectionInfo_Handler,
+			ServerStreams: true,
+			ClientStreams: true,
+		},
+	},
+	Metadata: "grpc_reflection_v1alpha/reflection.proto",
+}
diff --git a/vendor/google.golang.org/grpc/reflection/grpc_reflection_v1alpha/reflection.proto b/vendor/google.golang.org/grpc/reflection/grpc_reflection_v1alpha/reflection.proto
new file mode 100644
index 0000000..99b00df
--- /dev/null
+++ b/vendor/google.golang.org/grpc/reflection/grpc_reflection_v1alpha/reflection.proto
@@ -0,0 +1,136 @@
+// Copyright 2016 gRPC authors.
+//
+// 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.
+
+// Service exported by server reflection
+
+syntax = "proto3";
+
+package grpc.reflection.v1alpha;
+
+service ServerReflection {
+  // The reflection service is structured as a bidirectional stream, ensuring
+  // all related requests go to a single server.
+  rpc ServerReflectionInfo(stream ServerReflectionRequest)
+      returns (stream ServerReflectionResponse);
+}
+
+// The message sent by the client when calling ServerReflectionInfo method.
+message ServerReflectionRequest {
+  string host = 1;
+  // To use reflection service, the client should set one of the following
+  // fields in message_request. The server distinguishes requests by their
+  // defined field and then handles them using corresponding methods.
+  oneof message_request {
+    // Find a proto file by the file name.
+    string file_by_filename = 3;
+
+    // Find the proto file that declares the given fully-qualified symbol name.
+    // This field should be a fully-qualified symbol name
+    // (e.g. <package>.<service>[.<method>] or <package>.<type>).
+    string file_containing_symbol = 4;
+
+    // Find the proto file which defines an extension extending the given
+    // message type with the given field number.
+    ExtensionRequest file_containing_extension = 5;
+
+    // Finds the tag numbers used by all known extensions of extendee_type, and
+    // appends them to ExtensionNumberResponse in an undefined order.
+    // Its corresponding method is best-effort: it's not guaranteed that the
+    // reflection service will implement this method, and it's not guaranteed
+    // that this method will provide all extensions. Returns
+    // StatusCode::UNIMPLEMENTED if it's not implemented.
+    // This field should be a fully-qualified type name. The format is
+    // <package>.<type>
+    string all_extension_numbers_of_type = 6;
+
+    // List the full names of registered services. The content will not be
+    // checked.
+    string list_services = 7;
+  }
+}
+
+// The type name and extension number sent by the client when requesting
+// file_containing_extension.
+message ExtensionRequest {
+  // Fully-qualified type name. The format should be <package>.<type>
+  string containing_type = 1;
+  int32 extension_number = 2;
+}
+
+// The message sent by the server to answer ServerReflectionInfo method.
+message ServerReflectionResponse {
+  string valid_host = 1;
+  ServerReflectionRequest original_request = 2;
+  // The server sets one of the following fields according to the
+  // message_request in the request.
+  oneof message_response {
+    // This message is used to answer file_by_filename, file_containing_symbol,
+    // file_containing_extension requests with transitive dependencies.
+    // As the repeated label is not allowed in oneof fields, we use a
+    // FileDescriptorResponse message to encapsulate the repeated fields.
+    // The reflection service is allowed to avoid sending FileDescriptorProtos
+    // that were previously sent in response to earlier requests in the stream.
+    FileDescriptorResponse file_descriptor_response = 4;
+
+    // This message is used to answer all_extension_numbers_of_type requests.
+    ExtensionNumberResponse all_extension_numbers_response = 5;
+
+    // This message is used to answer list_services requests.
+    ListServiceResponse list_services_response = 6;
+
+    // This message is used when an error occurs.
+    ErrorResponse error_response = 7;
+  }
+}
+
+// Serialized FileDescriptorProto messages sent by the server answering
+// a file_by_filename, file_containing_symbol, or file_containing_extension
+// request.
+message FileDescriptorResponse {
+  // Serialized FileDescriptorProto messages. We avoid taking a dependency on
+  // descriptor.proto, which uses proto2 only features, by making them opaque
+  // bytes instead.
+  repeated bytes file_descriptor_proto = 1;
+}
+
+// A list of extension numbers sent by the server answering
+// all_extension_numbers_of_type request.
+message ExtensionNumberResponse {
+  // Full name of the base type, including the package name. The format
+  // is <package>.<type>
+  string base_type_name = 1;
+  repeated int32 extension_number = 2;
+}
+
+// A list of ServiceResponse sent by the server answering list_services request.
+message ListServiceResponse {
+  // The information of each service may be expanded in the future, so we use
+  // ServiceResponse message to encapsulate it.
+  repeated ServiceResponse service = 1;
+}
+
+// The information of a single service used by ListServiceResponse to answer
+// list_services request.
+message ServiceResponse {
+  // Full name of a registered service, including its package name. The format
+  // is <package>.<service>
+  string name = 1;
+}
+
+// The error code and error message sent by the server when an error occurs.
+message ErrorResponse {
+  // This field uses the error codes defined in grpc::StatusCode.
+  int32 error_code = 1;
+  string error_message = 2;
+}
diff --git a/vendor/google.golang.org/grpc/reflection/serverreflection.go b/vendor/google.golang.org/grpc/reflection/serverreflection.go
new file mode 100644
index 0000000..dd22a2d
--- /dev/null
+++ b/vendor/google.golang.org/grpc/reflection/serverreflection.go
@@ -0,0 +1,454 @@
+/*
+ *
+ * Copyright 2016 gRPC authors.
+ *
+ * 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.
+ *
+ */
+
+//go:generate protoc --go_out=plugins=grpc:. grpc_reflection_v1alpha/reflection.proto
+
+/*
+Package reflection implements server reflection service.
+
+The service implemented is defined in:
+https://github.com/grpc/grpc/blob/master/src/proto/grpc/reflection/v1alpha/reflection.proto.
+
+To register server reflection on a gRPC server:
+	import "google.golang.org/grpc/reflection"
+
+	s := grpc.NewServer()
+	pb.RegisterYourOwnServer(s, &server{})
+
+	// Register reflection service on gRPC server.
+	reflection.Register(s)
+
+	s.Serve(lis)
+
+*/
+package reflection // import "google.golang.org/grpc/reflection"
+
+import (
+	"bytes"
+	"compress/gzip"
+	"fmt"
+	"io"
+	"io/ioutil"
+	"reflect"
+	"sort"
+	"sync"
+
+	"github.com/golang/protobuf/proto"
+	dpb "github.com/golang/protobuf/protoc-gen-go/descriptor"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/codes"
+	rpb "google.golang.org/grpc/reflection/grpc_reflection_v1alpha"
+	"google.golang.org/grpc/status"
+)
+
+type serverReflectionServer struct {
+	s *grpc.Server
+
+	initSymbols  sync.Once
+	serviceNames []string
+	symbols      map[string]*dpb.FileDescriptorProto // map of fully-qualified names to files
+}
+
+// Register registers the server reflection service on the given gRPC server.
+func Register(s *grpc.Server) {
+	rpb.RegisterServerReflectionServer(s, &serverReflectionServer{
+		s: s,
+	})
+}
+
+// protoMessage is used for type assertion on proto messages.
+// Generated proto message implements function Descriptor(), but Descriptor()
+// is not part of interface proto.Message. This interface is needed to
+// call Descriptor().
+type protoMessage interface {
+	Descriptor() ([]byte, []int)
+}
+
+func (s *serverReflectionServer) getSymbols() (svcNames []string, symbolIndex map[string]*dpb.FileDescriptorProto) {
+	s.initSymbols.Do(func() {
+		serviceInfo := s.s.GetServiceInfo()
+
+		s.symbols = map[string]*dpb.FileDescriptorProto{}
+		s.serviceNames = make([]string, 0, len(serviceInfo))
+		processed := map[string]struct{}{}
+		for svc, info := range serviceInfo {
+			s.serviceNames = append(s.serviceNames, svc)
+			fdenc, ok := parseMetadata(info.Metadata)
+			if !ok {
+				continue
+			}
+			fd, err := decodeFileDesc(fdenc)
+			if err != nil {
+				continue
+			}
+			s.processFile(fd, processed)
+		}
+		sort.Strings(s.serviceNames)
+	})
+
+	return s.serviceNames, s.symbols
+}
+
+func (s *serverReflectionServer) processFile(fd *dpb.FileDescriptorProto, processed map[string]struct{}) {
+	filename := fd.GetName()
+	if _, ok := processed[filename]; ok {
+		return
+	}
+	processed[filename] = struct{}{}
+
+	prefix := fd.GetPackage()
+
+	for _, msg := range fd.MessageType {
+		s.processMessage(fd, prefix, msg)
+	}
+	for _, en := range fd.EnumType {
+		s.processEnum(fd, prefix, en)
+	}
+	for _, ext := range fd.Extension {
+		s.processField(fd, prefix, ext)
+	}
+	for _, svc := range fd.Service {
+		svcName := fqn(prefix, svc.GetName())
+		s.symbols[svcName] = fd
+		for _, meth := range svc.Method {
+			name := fqn(svcName, meth.GetName())
+			s.symbols[name] = fd
+		}
+	}
+
+	for _, dep := range fd.Dependency {
+		fdenc := proto.FileDescriptor(dep)
+		fdDep, err := decodeFileDesc(fdenc)
+		if err != nil {
+			continue
+		}
+		s.processFile(fdDep, processed)
+	}
+}
+
+func (s *serverReflectionServer) processMessage(fd *dpb.FileDescriptorProto, prefix string, msg *dpb.DescriptorProto) {
+	msgName := fqn(prefix, msg.GetName())
+	s.symbols[msgName] = fd
+
+	for _, nested := range msg.NestedType {
+		s.processMessage(fd, msgName, nested)
+	}
+	for _, en := range msg.EnumType {
+		s.processEnum(fd, msgName, en)
+	}
+	for _, ext := range msg.Extension {
+		s.processField(fd, msgName, ext)
+	}
+	for _, fld := range msg.Field {
+		s.processField(fd, msgName, fld)
+	}
+	for _, oneof := range msg.OneofDecl {
+		oneofName := fqn(msgName, oneof.GetName())
+		s.symbols[oneofName] = fd
+	}
+}
+
+func (s *serverReflectionServer) processEnum(fd *dpb.FileDescriptorProto, prefix string, en *dpb.EnumDescriptorProto) {
+	enName := fqn(prefix, en.GetName())
+	s.symbols[enName] = fd
+
+	for _, val := range en.Value {
+		valName := fqn(enName, val.GetName())
+		s.symbols[valName] = fd
+	}
+}
+
+func (s *serverReflectionServer) processField(fd *dpb.FileDescriptorProto, prefix string, fld *dpb.FieldDescriptorProto) {
+	fldName := fqn(prefix, fld.GetName())
+	s.symbols[fldName] = fd
+}
+
+func fqn(prefix, name string) string {
+	if prefix == "" {
+		return name
+	}
+	return prefix + "." + name
+}
+
+// fileDescForType gets the file descriptor for the given type.
+// The given type should be a proto message.
+func (s *serverReflectionServer) fileDescForType(st reflect.Type) (*dpb.FileDescriptorProto, error) {
+	m, ok := reflect.Zero(reflect.PtrTo(st)).Interface().(protoMessage)
+	if !ok {
+		return nil, fmt.Errorf("failed to create message from type: %v", st)
+	}
+	enc, _ := m.Descriptor()
+
+	return decodeFileDesc(enc)
+}
+
+// decodeFileDesc does decompression and unmarshalling on the given
+// file descriptor byte slice.
+func decodeFileDesc(enc []byte) (*dpb.FileDescriptorProto, error) {
+	raw, err := decompress(enc)
+	if err != nil {
+		return nil, fmt.Errorf("failed to decompress enc: %v", err)
+	}
+
+	fd := new(dpb.FileDescriptorProto)
+	if err := proto.Unmarshal(raw, fd); err != nil {
+		return nil, fmt.Errorf("bad descriptor: %v", err)
+	}
+	return fd, nil
+}
+
+// decompress does gzip decompression.
+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
+}
+
+func typeForName(name string) (reflect.Type, error) {
+	pt := proto.MessageType(name)
+	if pt == nil {
+		return nil, fmt.Errorf("unknown type: %q", name)
+	}
+	st := pt.Elem()
+
+	return st, nil
+}
+
+func fileDescContainingExtension(st reflect.Type, ext int32) (*dpb.FileDescriptorProto, error) {
+	m, ok := reflect.Zero(reflect.PtrTo(st)).Interface().(proto.Message)
+	if !ok {
+		return nil, fmt.Errorf("failed to create message from type: %v", st)
+	}
+
+	var extDesc *proto.ExtensionDesc
+	for id, desc := range proto.RegisteredExtensions(m) {
+		if id == ext {
+			extDesc = desc
+			break
+		}
+	}
+
+	if extDesc == nil {
+		return nil, fmt.Errorf("failed to find registered extension for extension number %v", ext)
+	}
+
+	return decodeFileDesc(proto.FileDescriptor(extDesc.Filename))
+}
+
+func (s *serverReflectionServer) allExtensionNumbersForType(st reflect.Type) ([]int32, error) {
+	m, ok := reflect.Zero(reflect.PtrTo(st)).Interface().(proto.Message)
+	if !ok {
+		return nil, fmt.Errorf("failed to create message from type: %v", st)
+	}
+
+	exts := proto.RegisteredExtensions(m)
+	out := make([]int32, 0, len(exts))
+	for id := range exts {
+		out = append(out, id)
+	}
+	return out, nil
+}
+
+// fileDescEncodingByFilename finds the file descriptor for given filename,
+// does marshalling on it and returns the marshalled result.
+func (s *serverReflectionServer) fileDescEncodingByFilename(name string) ([]byte, error) {
+	enc := proto.FileDescriptor(name)
+	if enc == nil {
+		return nil, fmt.Errorf("unknown file: %v", name)
+	}
+	fd, err := decodeFileDesc(enc)
+	if err != nil {
+		return nil, err
+	}
+	return proto.Marshal(fd)
+}
+
+// parseMetadata finds the file descriptor bytes specified meta.
+// For SupportPackageIsVersion4, m is the name of the proto file, we
+// call proto.FileDescriptor to get the byte slice.
+// For SupportPackageIsVersion3, m is a byte slice itself.
+func parseMetadata(meta interface{}) ([]byte, bool) {
+	// Check if meta is the file name.
+	if fileNameForMeta, ok := meta.(string); ok {
+		return proto.FileDescriptor(fileNameForMeta), true
+	}
+
+	// Check if meta is the byte slice.
+	if enc, ok := meta.([]byte); ok {
+		return enc, true
+	}
+
+	return nil, false
+}
+
+// fileDescEncodingContainingSymbol finds the file descriptor containing the given symbol,
+// does marshalling on it and returns the marshalled result.
+// The given symbol can be a type, a service or a method.
+func (s *serverReflectionServer) fileDescEncodingContainingSymbol(name string) ([]byte, error) {
+	_, symbols := s.getSymbols()
+	fd := symbols[name]
+	if fd == nil {
+		// Check if it's a type name that was not present in the
+		// transitive dependencies of the registered services.
+		if st, err := typeForName(name); err == nil {
+			fd, err = s.fileDescForType(st)
+			if err != nil {
+				return nil, err
+			}
+		}
+	}
+
+	if fd == nil {
+		return nil, fmt.Errorf("unknown symbol: %v", name)
+	}
+
+	return proto.Marshal(fd)
+}
+
+// fileDescEncodingContainingExtension finds the file descriptor containing given extension,
+// does marshalling on it and returns the marshalled result.
+func (s *serverReflectionServer) fileDescEncodingContainingExtension(typeName string, extNum int32) ([]byte, error) {
+	st, err := typeForName(typeName)
+	if err != nil {
+		return nil, err
+	}
+	fd, err := fileDescContainingExtension(st, extNum)
+	if err != nil {
+		return nil, err
+	}
+	return proto.Marshal(fd)
+}
+
+// allExtensionNumbersForTypeName returns all extension numbers for the given type.
+func (s *serverReflectionServer) allExtensionNumbersForTypeName(name string) ([]int32, error) {
+	st, err := typeForName(name)
+	if err != nil {
+		return nil, err
+	}
+	extNums, err := s.allExtensionNumbersForType(st)
+	if err != nil {
+		return nil, err
+	}
+	return extNums, nil
+}
+
+// ServerReflectionInfo is the reflection service handler.
+func (s *serverReflectionServer) ServerReflectionInfo(stream rpb.ServerReflection_ServerReflectionInfoServer) error {
+	for {
+		in, err := stream.Recv()
+		if err == io.EOF {
+			return nil
+		}
+		if err != nil {
+			return err
+		}
+
+		out := &rpb.ServerReflectionResponse{
+			ValidHost:       in.Host,
+			OriginalRequest: in,
+		}
+		switch req := in.MessageRequest.(type) {
+		case *rpb.ServerReflectionRequest_FileByFilename:
+			b, err := s.fileDescEncodingByFilename(req.FileByFilename)
+			if err != nil {
+				out.MessageResponse = &rpb.ServerReflectionResponse_ErrorResponse{
+					ErrorResponse: &rpb.ErrorResponse{
+						ErrorCode:    int32(codes.NotFound),
+						ErrorMessage: err.Error(),
+					},
+				}
+			} else {
+				out.MessageResponse = &rpb.ServerReflectionResponse_FileDescriptorResponse{
+					FileDescriptorResponse: &rpb.FileDescriptorResponse{FileDescriptorProto: [][]byte{b}},
+				}
+			}
+		case *rpb.ServerReflectionRequest_FileContainingSymbol:
+			b, err := s.fileDescEncodingContainingSymbol(req.FileContainingSymbol)
+			if err != nil {
+				out.MessageResponse = &rpb.ServerReflectionResponse_ErrorResponse{
+					ErrorResponse: &rpb.ErrorResponse{
+						ErrorCode:    int32(codes.NotFound),
+						ErrorMessage: err.Error(),
+					},
+				}
+			} else {
+				out.MessageResponse = &rpb.ServerReflectionResponse_FileDescriptorResponse{
+					FileDescriptorResponse: &rpb.FileDescriptorResponse{FileDescriptorProto: [][]byte{b}},
+				}
+			}
+		case *rpb.ServerReflectionRequest_FileContainingExtension:
+			typeName := req.FileContainingExtension.ContainingType
+			extNum := req.FileContainingExtension.ExtensionNumber
+			b, err := s.fileDescEncodingContainingExtension(typeName, extNum)
+			if err != nil {
+				out.MessageResponse = &rpb.ServerReflectionResponse_ErrorResponse{
+					ErrorResponse: &rpb.ErrorResponse{
+						ErrorCode:    int32(codes.NotFound),
+						ErrorMessage: err.Error(),
+					},
+				}
+			} else {
+				out.MessageResponse = &rpb.ServerReflectionResponse_FileDescriptorResponse{
+					FileDescriptorResponse: &rpb.FileDescriptorResponse{FileDescriptorProto: [][]byte{b}},
+				}
+			}
+		case *rpb.ServerReflectionRequest_AllExtensionNumbersOfType:
+			extNums, err := s.allExtensionNumbersForTypeName(req.AllExtensionNumbersOfType)
+			if err != nil {
+				out.MessageResponse = &rpb.ServerReflectionResponse_ErrorResponse{
+					ErrorResponse: &rpb.ErrorResponse{
+						ErrorCode:    int32(codes.NotFound),
+						ErrorMessage: err.Error(),
+					},
+				}
+			} else {
+				out.MessageResponse = &rpb.ServerReflectionResponse_AllExtensionNumbersResponse{
+					AllExtensionNumbersResponse: &rpb.ExtensionNumberResponse{
+						BaseTypeName:    req.AllExtensionNumbersOfType,
+						ExtensionNumber: extNums,
+					},
+				}
+			}
+		case *rpb.ServerReflectionRequest_ListServices:
+			svcNames, _ := s.getSymbols()
+			serviceResponses := make([]*rpb.ServiceResponse, len(svcNames))
+			for i, n := range svcNames {
+				serviceResponses[i] = &rpb.ServiceResponse{
+					Name: n,
+				}
+			}
+			out.MessageResponse = &rpb.ServerReflectionResponse_ListServicesResponse{
+				ListServicesResponse: &rpb.ListServiceResponse{
+					Service: serviceResponses,
+				},
+			}
+		default:
+			return status.Errorf(codes.InvalidArgument, "invalid MessageRequest: %v", in.MessageRequest)
+		}
+
+		if err := stream.Send(out); err != nil {
+			return err
+		}
+	}
+}
diff --git a/vendor/google.golang.org/protobuf/encoding/protojson/decode.go b/vendor/google.golang.org/protobuf/encoding/protojson/decode.go
new file mode 100644
index 0000000..07da5db
--- /dev/null
+++ b/vendor/google.golang.org/protobuf/encoding/protojson/decode.go
@@ -0,0 +1,665 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package protojson
+
+import (
+	"encoding/base64"
+	"fmt"
+	"math"
+	"strconv"
+	"strings"
+
+	"google.golang.org/protobuf/internal/encoding/json"
+	"google.golang.org/protobuf/internal/encoding/messageset"
+	"google.golang.org/protobuf/internal/errors"
+	"google.golang.org/protobuf/internal/flags"
+	"google.golang.org/protobuf/internal/genid"
+	"google.golang.org/protobuf/internal/pragma"
+	"google.golang.org/protobuf/internal/set"
+	"google.golang.org/protobuf/proto"
+	pref "google.golang.org/protobuf/reflect/protoreflect"
+	"google.golang.org/protobuf/reflect/protoregistry"
+)
+
+// Unmarshal reads the given []byte into the given proto.Message.
+// The provided message must be mutable (e.g., a non-nil pointer to a message).
+func Unmarshal(b []byte, m proto.Message) error {
+	return UnmarshalOptions{}.Unmarshal(b, m)
+}
+
+// UnmarshalOptions is a configurable JSON format parser.
+type UnmarshalOptions struct {
+	pragma.NoUnkeyedLiterals
+
+	// If AllowPartial is set, input for messages that will result in missing
+	// required fields will not return an error.
+	AllowPartial bool
+
+	// If DiscardUnknown is set, unknown fields are ignored.
+	DiscardUnknown bool
+
+	// Resolver is used for looking up types when unmarshaling
+	// google.protobuf.Any messages or extension fields.
+	// If nil, this defaults to using protoregistry.GlobalTypes.
+	Resolver interface {
+		protoregistry.MessageTypeResolver
+		protoregistry.ExtensionTypeResolver
+	}
+}
+
+// Unmarshal reads the given []byte and populates the given proto.Message
+// using options in the UnmarshalOptions object.
+// It will clear the message first before setting the fields.
+// If it returns an error, the given message may be partially set.
+// The provided message must be mutable (e.g., a non-nil pointer to a message).
+func (o UnmarshalOptions) Unmarshal(b []byte, m proto.Message) error {
+	return o.unmarshal(b, m)
+}
+
+// unmarshal is a centralized function that all unmarshal operations go through.
+// For profiling purposes, avoid changing the name of this function or
+// introducing other code paths for unmarshal that do not go through this.
+func (o UnmarshalOptions) unmarshal(b []byte, m proto.Message) error {
+	proto.Reset(m)
+
+	if o.Resolver == nil {
+		o.Resolver = protoregistry.GlobalTypes
+	}
+
+	dec := decoder{json.NewDecoder(b), o}
+	if err := dec.unmarshalMessage(m.ProtoReflect(), false); err != nil {
+		return err
+	}
+
+	// Check for EOF.
+	tok, err := dec.Read()
+	if err != nil {
+		return err
+	}
+	if tok.Kind() != json.EOF {
+		return dec.unexpectedTokenError(tok)
+	}
+
+	if o.AllowPartial {
+		return nil
+	}
+	return proto.CheckInitialized(m)
+}
+
+type decoder struct {
+	*json.Decoder
+	opts UnmarshalOptions
+}
+
+// newError returns an error object with position info.
+func (d decoder) newError(pos int, f string, x ...interface{}) error {
+	line, column := d.Position(pos)
+	head := fmt.Sprintf("(line %d:%d): ", line, column)
+	return errors.New(head+f, x...)
+}
+
+// unexpectedTokenError returns a syntax error for the given unexpected token.
+func (d decoder) unexpectedTokenError(tok json.Token) error {
+	return d.syntaxError(tok.Pos(), "unexpected token %s", tok.RawString())
+}
+
+// syntaxError returns a syntax error for given position.
+func (d decoder) syntaxError(pos int, f string, x ...interface{}) error {
+	line, column := d.Position(pos)
+	head := fmt.Sprintf("syntax error (line %d:%d): ", line, column)
+	return errors.New(head+f, x...)
+}
+
+// unmarshalMessage unmarshals a message into the given protoreflect.Message.
+func (d decoder) unmarshalMessage(m pref.Message, skipTypeURL bool) error {
+	if unmarshal := wellKnownTypeUnmarshaler(m.Descriptor().FullName()); unmarshal != nil {
+		return unmarshal(d, m)
+	}
+
+	tok, err := d.Read()
+	if err != nil {
+		return err
+	}
+	if tok.Kind() != json.ObjectOpen {
+		return d.unexpectedTokenError(tok)
+	}
+
+	messageDesc := m.Descriptor()
+	if !flags.ProtoLegacy && messageset.IsMessageSet(messageDesc) {
+		return errors.New("no support for proto1 MessageSets")
+	}
+
+	var seenNums set.Ints
+	var seenOneofs set.Ints
+	fieldDescs := messageDesc.Fields()
+	for {
+		// Read field name.
+		tok, err := d.Read()
+		if err != nil {
+			return err
+		}
+		switch tok.Kind() {
+		default:
+			return d.unexpectedTokenError(tok)
+		case json.ObjectClose:
+			return nil
+		case json.Name:
+			// Continue below.
+		}
+
+		name := tok.Name()
+		// Unmarshaling a non-custom embedded message in Any will contain the
+		// JSON field "@type" which should be skipped because it is not a field
+		// of the embedded message, but simply an artifact of the Any format.
+		if skipTypeURL && name == "@type" {
+			d.Read()
+			continue
+		}
+
+		// Get the FieldDescriptor.
+		var fd pref.FieldDescriptor
+		if strings.HasPrefix(name, "[") && strings.HasSuffix(name, "]") {
+			// Only extension names are in [name] format.
+			extName := pref.FullName(name[1 : len(name)-1])
+			extType, err := d.opts.Resolver.FindExtensionByName(extName)
+			if err != nil && err != protoregistry.NotFound {
+				return d.newError(tok.Pos(), "unable to resolve %s: %v", tok.RawString(), err)
+			}
+			if extType != nil {
+				fd = extType.TypeDescriptor()
+				if !messageDesc.ExtensionRanges().Has(fd.Number()) || fd.ContainingMessage().FullName() != messageDesc.FullName() {
+					return d.newError(tok.Pos(), "message %v cannot be extended by %v", messageDesc.FullName(), fd.FullName())
+				}
+			}
+		} else {
+			// The name can either be the JSON name or the proto field name.
+			fd = fieldDescs.ByJSONName(name)
+			if fd == nil {
+				fd = fieldDescs.ByTextName(name)
+			}
+		}
+		if flags.ProtoLegacy {
+			if fd != nil && fd.IsWeak() && fd.Message().IsPlaceholder() {
+				fd = nil // reset since the weak reference is not linked in
+			}
+		}
+
+		if fd == nil {
+			// Field is unknown.
+			if d.opts.DiscardUnknown {
+				if err := d.skipJSONValue(); err != nil {
+					return err
+				}
+				continue
+			}
+			return d.newError(tok.Pos(), "unknown field %v", tok.RawString())
+		}
+
+		// Do not allow duplicate fields.
+		num := uint64(fd.Number())
+		if seenNums.Has(num) {
+			return d.newError(tok.Pos(), "duplicate field %v", tok.RawString())
+		}
+		seenNums.Set(num)
+
+		// No need to set values for JSON null unless the field type is
+		// google.protobuf.Value or google.protobuf.NullValue.
+		if tok, _ := d.Peek(); tok.Kind() == json.Null && !isKnownValue(fd) && !isNullValue(fd) {
+			d.Read()
+			continue
+		}
+
+		switch {
+		case fd.IsList():
+			list := m.Mutable(fd).List()
+			if err := d.unmarshalList(list, fd); err != nil {
+				return err
+			}
+		case fd.IsMap():
+			mmap := m.Mutable(fd).Map()
+			if err := d.unmarshalMap(mmap, fd); err != nil {
+				return err
+			}
+		default:
+			// If field is a oneof, check if it has already been set.
+			if od := fd.ContainingOneof(); od != nil {
+				idx := uint64(od.Index())
+				if seenOneofs.Has(idx) {
+					return d.newError(tok.Pos(), "error parsing %s, oneof %v is already set", tok.RawString(), od.FullName())
+				}
+				seenOneofs.Set(idx)
+			}
+
+			// Required or optional fields.
+			if err := d.unmarshalSingular(m, fd); err != nil {
+				return err
+			}
+		}
+	}
+}
+
+func isKnownValue(fd pref.FieldDescriptor) bool {
+	md := fd.Message()
+	return md != nil && md.FullName() == genid.Value_message_fullname
+}
+
+func isNullValue(fd pref.FieldDescriptor) bool {
+	ed := fd.Enum()
+	return ed != nil && ed.FullName() == genid.NullValue_enum_fullname
+}
+
+// unmarshalSingular unmarshals to the non-repeated field specified
+// by the given FieldDescriptor.
+func (d decoder) unmarshalSingular(m pref.Message, fd pref.FieldDescriptor) error {
+	var val pref.Value
+	var err error
+	switch fd.Kind() {
+	case pref.MessageKind, pref.GroupKind:
+		val = m.NewField(fd)
+		err = d.unmarshalMessage(val.Message(), false)
+	default:
+		val, err = d.unmarshalScalar(fd)
+	}
+
+	if err != nil {
+		return err
+	}
+	m.Set(fd, val)
+	return nil
+}
+
+// unmarshalScalar unmarshals to a scalar/enum protoreflect.Value specified by
+// the given FieldDescriptor.
+func (d decoder) unmarshalScalar(fd pref.FieldDescriptor) (pref.Value, error) {
+	const b32 int = 32
+	const b64 int = 64
+
+	tok, err := d.Read()
+	if err != nil {
+		return pref.Value{}, err
+	}
+
+	kind := fd.Kind()
+	switch kind {
+	case pref.BoolKind:
+		if tok.Kind() == json.Bool {
+			return pref.ValueOfBool(tok.Bool()), nil
+		}
+
+	case pref.Int32Kind, pref.Sint32Kind, pref.Sfixed32Kind:
+		if v, ok := unmarshalInt(tok, b32); ok {
+			return v, nil
+		}
+
+	case pref.Int64Kind, pref.Sint64Kind, pref.Sfixed64Kind:
+		if v, ok := unmarshalInt(tok, b64); ok {
+			return v, nil
+		}
+
+	case pref.Uint32Kind, pref.Fixed32Kind:
+		if v, ok := unmarshalUint(tok, b32); ok {
+			return v, nil
+		}
+
+	case pref.Uint64Kind, pref.Fixed64Kind:
+		if v, ok := unmarshalUint(tok, b64); ok {
+			return v, nil
+		}
+
+	case pref.FloatKind:
+		if v, ok := unmarshalFloat(tok, b32); ok {
+			return v, nil
+		}
+
+	case pref.DoubleKind:
+		if v, ok := unmarshalFloat(tok, b64); ok {
+			return v, nil
+		}
+
+	case pref.StringKind:
+		if tok.Kind() == json.String {
+			return pref.ValueOfString(tok.ParsedString()), nil
+		}
+
+	case pref.BytesKind:
+		if v, ok := unmarshalBytes(tok); ok {
+			return v, nil
+		}
+
+	case pref.EnumKind:
+		if v, ok := unmarshalEnum(tok, fd); ok {
+			return v, nil
+		}
+
+	default:
+		panic(fmt.Sprintf("unmarshalScalar: invalid scalar kind %v", kind))
+	}
+
+	return pref.Value{}, d.newError(tok.Pos(), "invalid value for %v type: %v", kind, tok.RawString())
+}
+
+func unmarshalInt(tok json.Token, bitSize int) (pref.Value, bool) {
+	switch tok.Kind() {
+	case json.Number:
+		return getInt(tok, bitSize)
+
+	case json.String:
+		// Decode number from string.
+		s := strings.TrimSpace(tok.ParsedString())
+		if len(s) != len(tok.ParsedString()) {
+			return pref.Value{}, false
+		}
+		dec := json.NewDecoder([]byte(s))
+		tok, err := dec.Read()
+		if err != nil {
+			return pref.Value{}, false
+		}
+		return getInt(tok, bitSize)
+	}
+	return pref.Value{}, false
+}
+
+func getInt(tok json.Token, bitSize int) (pref.Value, bool) {
+	n, ok := tok.Int(bitSize)
+	if !ok {
+		return pref.Value{}, false
+	}
+	if bitSize == 32 {
+		return pref.ValueOfInt32(int32(n)), true
+	}
+	return pref.ValueOfInt64(n), true
+}
+
+func unmarshalUint(tok json.Token, bitSize int) (pref.Value, bool) {
+	switch tok.Kind() {
+	case json.Number:
+		return getUint(tok, bitSize)
+
+	case json.String:
+		// Decode number from string.
+		s := strings.TrimSpace(tok.ParsedString())
+		if len(s) != len(tok.ParsedString()) {
+			return pref.Value{}, false
+		}
+		dec := json.NewDecoder([]byte(s))
+		tok, err := dec.Read()
+		if err != nil {
+			return pref.Value{}, false
+		}
+		return getUint(tok, bitSize)
+	}
+	return pref.Value{}, false
+}
+
+func getUint(tok json.Token, bitSize int) (pref.Value, bool) {
+	n, ok := tok.Uint(bitSize)
+	if !ok {
+		return pref.Value{}, false
+	}
+	if bitSize == 32 {
+		return pref.ValueOfUint32(uint32(n)), true
+	}
+	return pref.ValueOfUint64(n), true
+}
+
+func unmarshalFloat(tok json.Token, bitSize int) (pref.Value, bool) {
+	switch tok.Kind() {
+	case json.Number:
+		return getFloat(tok, bitSize)
+
+	case json.String:
+		s := tok.ParsedString()
+		switch s {
+		case "NaN":
+			if bitSize == 32 {
+				return pref.ValueOfFloat32(float32(math.NaN())), true
+			}
+			return pref.ValueOfFloat64(math.NaN()), true
+		case "Infinity":
+			if bitSize == 32 {
+				return pref.ValueOfFloat32(float32(math.Inf(+1))), true
+			}
+			return pref.ValueOfFloat64(math.Inf(+1)), true
+		case "-Infinity":
+			if bitSize == 32 {
+				return pref.ValueOfFloat32(float32(math.Inf(-1))), true
+			}
+			return pref.ValueOfFloat64(math.Inf(-1)), true
+		}
+
+		// Decode number from string.
+		if len(s) != len(strings.TrimSpace(s)) {
+			return pref.Value{}, false
+		}
+		dec := json.NewDecoder([]byte(s))
+		tok, err := dec.Read()
+		if err != nil {
+			return pref.Value{}, false
+		}
+		return getFloat(tok, bitSize)
+	}
+	return pref.Value{}, false
+}
+
+func getFloat(tok json.Token, bitSize int) (pref.Value, bool) {
+	n, ok := tok.Float(bitSize)
+	if !ok {
+		return pref.Value{}, false
+	}
+	if bitSize == 32 {
+		return pref.ValueOfFloat32(float32(n)), true
+	}
+	return pref.ValueOfFloat64(n), true
+}
+
+func unmarshalBytes(tok json.Token) (pref.Value, bool) {
+	if tok.Kind() != json.String {
+		return pref.Value{}, false
+	}
+
+	s := tok.ParsedString()
+	enc := base64.StdEncoding
+	if strings.ContainsAny(s, "-_") {
+		enc = base64.URLEncoding
+	}
+	if len(s)%4 != 0 {
+		enc = enc.WithPadding(base64.NoPadding)
+	}
+	b, err := enc.DecodeString(s)
+	if err != nil {
+		return pref.Value{}, false
+	}
+	return pref.ValueOfBytes(b), true
+}
+
+func unmarshalEnum(tok json.Token, fd pref.FieldDescriptor) (pref.Value, bool) {
+	switch tok.Kind() {
+	case json.String:
+		// Lookup EnumNumber based on name.
+		s := tok.ParsedString()
+		if enumVal := fd.Enum().Values().ByName(pref.Name(s)); enumVal != nil {
+			return pref.ValueOfEnum(enumVal.Number()), true
+		}
+
+	case json.Number:
+		if n, ok := tok.Int(32); ok {
+			return pref.ValueOfEnum(pref.EnumNumber(n)), true
+		}
+
+	case json.Null:
+		// This is only valid for google.protobuf.NullValue.
+		if isNullValue(fd) {
+			return pref.ValueOfEnum(0), true
+		}
+	}
+
+	return pref.Value{}, false
+}
+
+func (d decoder) unmarshalList(list pref.List, fd pref.FieldDescriptor) error {
+	tok, err := d.Read()
+	if err != nil {
+		return err
+	}
+	if tok.Kind() != json.ArrayOpen {
+		return d.unexpectedTokenError(tok)
+	}
+
+	switch fd.Kind() {
+	case pref.MessageKind, pref.GroupKind:
+		for {
+			tok, err := d.Peek()
+			if err != nil {
+				return err
+			}
+
+			if tok.Kind() == json.ArrayClose {
+				d.Read()
+				return nil
+			}
+
+			val := list.NewElement()
+			if err := d.unmarshalMessage(val.Message(), false); err != nil {
+				return err
+			}
+			list.Append(val)
+		}
+	default:
+		for {
+			tok, err := d.Peek()
+			if err != nil {
+				return err
+			}
+
+			if tok.Kind() == json.ArrayClose {
+				d.Read()
+				return nil
+			}
+
+			val, err := d.unmarshalScalar(fd)
+			if err != nil {
+				return err
+			}
+			list.Append(val)
+		}
+	}
+
+	return nil
+}
+
+func (d decoder) unmarshalMap(mmap pref.Map, fd pref.FieldDescriptor) error {
+	tok, err := d.Read()
+	if err != nil {
+		return err
+	}
+	if tok.Kind() != json.ObjectOpen {
+		return d.unexpectedTokenError(tok)
+	}
+
+	// Determine ahead whether map entry is a scalar type or a message type in
+	// order to call the appropriate unmarshalMapValue func inside the for loop
+	// below.
+	var unmarshalMapValue func() (pref.Value, error)
+	switch fd.MapValue().Kind() {
+	case pref.MessageKind, pref.GroupKind:
+		unmarshalMapValue = func() (pref.Value, error) {
+			val := mmap.NewValue()
+			if err := d.unmarshalMessage(val.Message(), false); err != nil {
+				return pref.Value{}, err
+			}
+			return val, nil
+		}
+	default:
+		unmarshalMapValue = func() (pref.Value, error) {
+			return d.unmarshalScalar(fd.MapValue())
+		}
+	}
+
+Loop:
+	for {
+		// Read field name.
+		tok, err := d.Read()
+		if err != nil {
+			return err
+		}
+		switch tok.Kind() {
+		default:
+			return d.unexpectedTokenError(tok)
+		case json.ObjectClose:
+			break Loop
+		case json.Name:
+			// Continue.
+		}
+
+		// Unmarshal field name.
+		pkey, err := d.unmarshalMapKey(tok, fd.MapKey())
+		if err != nil {
+			return err
+		}
+
+		// Check for duplicate field name.
+		if mmap.Has(pkey) {
+			return d.newError(tok.Pos(), "duplicate map key %v", tok.RawString())
+		}
+
+		// Read and unmarshal field value.
+		pval, err := unmarshalMapValue()
+		if err != nil {
+			return err
+		}
+
+		mmap.Set(pkey, pval)
+	}
+
+	return nil
+}
+
+// unmarshalMapKey converts given token of Name kind into a protoreflect.MapKey.
+// A map key type is any integral or string type.
+func (d decoder) unmarshalMapKey(tok json.Token, fd pref.FieldDescriptor) (pref.MapKey, error) {
+	const b32 = 32
+	const b64 = 64
+	const base10 = 10
+
+	name := tok.Name()
+	kind := fd.Kind()
+	switch kind {
+	case pref.StringKind:
+		return pref.ValueOfString(name).MapKey(), nil
+
+	case pref.BoolKind:
+		switch name {
+		case "true":
+			return pref.ValueOfBool(true).MapKey(), nil
+		case "false":
+			return pref.ValueOfBool(false).MapKey(), nil
+		}
+
+	case pref.Int32Kind, pref.Sint32Kind, pref.Sfixed32Kind:
+		if n, err := strconv.ParseInt(name, base10, b32); err == nil {
+			return pref.ValueOfInt32(int32(n)).MapKey(), nil
+		}
+
+	case pref.Int64Kind, pref.Sint64Kind, pref.Sfixed64Kind:
+		if n, err := strconv.ParseInt(name, base10, b64); err == nil {
+			return pref.ValueOfInt64(int64(n)).MapKey(), nil
+		}
+
+	case pref.Uint32Kind, pref.Fixed32Kind:
+		if n, err := strconv.ParseUint(name, base10, b32); err == nil {
+			return pref.ValueOfUint32(uint32(n)).MapKey(), nil
+		}
+
+	case pref.Uint64Kind, pref.Fixed64Kind:
+		if n, err := strconv.ParseUint(name, base10, b64); err == nil {
+			return pref.ValueOfUint64(uint64(n)).MapKey(), nil
+		}
+
+	default:
+		panic(fmt.Sprintf("invalid kind for map key: %v", kind))
+	}
+
+	return pref.MapKey{}, d.newError(tok.Pos(), "invalid value for %v key: %s", kind, tok.RawString())
+}
diff --git a/vendor/google.golang.org/protobuf/encoding/protojson/doc.go b/vendor/google.golang.org/protobuf/encoding/protojson/doc.go
new file mode 100644
index 0000000..00ea2fe
--- /dev/null
+++ b/vendor/google.golang.org/protobuf/encoding/protojson/doc.go
@@ -0,0 +1,11 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package protojson marshals and unmarshals protocol buffer messages as JSON
+// format. It follows the guide at
+// https://developers.google.com/protocol-buffers/docs/proto3#json.
+//
+// This package produces a different output than the standard "encoding/json"
+// package, which does not operate correctly on protocol buffer messages.
+package protojson
diff --git a/vendor/google.golang.org/protobuf/encoding/protojson/encode.go b/vendor/google.golang.org/protobuf/encoding/protojson/encode.go
new file mode 100644
index 0000000..ba971f0
--- /dev/null
+++ b/vendor/google.golang.org/protobuf/encoding/protojson/encode.go
@@ -0,0 +1,344 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package protojson
+
+import (
+	"encoding/base64"
+	"fmt"
+
+	"google.golang.org/protobuf/internal/encoding/json"
+	"google.golang.org/protobuf/internal/encoding/messageset"
+	"google.golang.org/protobuf/internal/errors"
+	"google.golang.org/protobuf/internal/filedesc"
+	"google.golang.org/protobuf/internal/flags"
+	"google.golang.org/protobuf/internal/genid"
+	"google.golang.org/protobuf/internal/order"
+	"google.golang.org/protobuf/internal/pragma"
+	"google.golang.org/protobuf/proto"
+	"google.golang.org/protobuf/reflect/protoreflect"
+	pref "google.golang.org/protobuf/reflect/protoreflect"
+	"google.golang.org/protobuf/reflect/protoregistry"
+)
+
+const defaultIndent = "  "
+
+// Format formats the message as a multiline string.
+// This function is only intended for human consumption and ignores errors.
+// Do not depend on the output being stable. It may change over time across
+// different versions of the program.
+func Format(m proto.Message) string {
+	return MarshalOptions{Multiline: true}.Format(m)
+}
+
+// Marshal writes the given proto.Message in JSON format using default options.
+// Do not depend on the output being stable. It may change over time across
+// different versions of the program.
+func Marshal(m proto.Message) ([]byte, error) {
+	return MarshalOptions{}.Marshal(m)
+}
+
+// MarshalOptions is a configurable JSON format marshaler.
+type MarshalOptions struct {
+	pragma.NoUnkeyedLiterals
+
+	// Multiline specifies whether the marshaler should format the output in
+	// indented-form with every textual element on a new line.
+	// If Indent is an empty string, then an arbitrary indent is chosen.
+	Multiline bool
+
+	// Indent specifies the set of indentation characters to use in a multiline
+	// formatted output such that every entry is preceded by Indent and
+	// terminated by a newline. If non-empty, then Multiline is treated as true.
+	// Indent can only be composed of space or tab characters.
+	Indent string
+
+	// AllowPartial allows messages that have missing required fields to marshal
+	// without returning an error. If AllowPartial is false (the default),
+	// Marshal will return error if there are any missing required fields.
+	AllowPartial bool
+
+	// UseProtoNames uses proto field name instead of lowerCamelCase name in JSON
+	// field names.
+	UseProtoNames bool
+
+	// UseEnumNumbers emits enum values as numbers.
+	UseEnumNumbers bool
+
+	// EmitUnpopulated specifies whether to emit unpopulated fields. It does not
+	// emit unpopulated oneof fields or unpopulated extension fields.
+	// The JSON value emitted for unpopulated fields are as follows:
+	//  ╔═══════╤════════════════════════════╗
+	//  ║ JSON  │ Protobuf field             ║
+	//  ╠═══════╪════════════════════════════╣
+	//  ║ false │ proto3 boolean fields      ║
+	//  ║ 0     │ proto3 numeric fields      ║
+	//  ║ ""    │ proto3 string/bytes fields ║
+	//  ║ null  │ proto2 scalar fields       ║
+	//  ║ null  │ message fields             ║
+	//  ║ []    │ list fields                ║
+	//  ║ {}    │ map fields                 ║
+	//  ╚═══════╧════════════════════════════╝
+	EmitUnpopulated bool
+
+	// Resolver is used for looking up types when expanding google.protobuf.Any
+	// messages. If nil, this defaults to using protoregistry.GlobalTypes.
+	Resolver interface {
+		protoregistry.ExtensionTypeResolver
+		protoregistry.MessageTypeResolver
+	}
+}
+
+// Format formats the message as a string.
+// This method is only intended for human consumption and ignores errors.
+// Do not depend on the output being stable. It may change over time across
+// different versions of the program.
+func (o MarshalOptions) Format(m proto.Message) string {
+	if m == nil || !m.ProtoReflect().IsValid() {
+		return "<nil>" // invalid syntax, but okay since this is for debugging
+	}
+	o.AllowPartial = true
+	b, _ := o.Marshal(m)
+	return string(b)
+}
+
+// Marshal marshals the given proto.Message in the JSON format using options in
+// MarshalOptions. Do not depend on the output being stable. It may change over
+// time across different versions of the program.
+func (o MarshalOptions) Marshal(m proto.Message) ([]byte, error) {
+	return o.marshal(m)
+}
+
+// marshal is a centralized function that all marshal operations go through.
+// For profiling purposes, avoid changing the name of this function or
+// introducing other code paths for marshal that do not go through this.
+func (o MarshalOptions) marshal(m proto.Message) ([]byte, error) {
+	if o.Multiline && o.Indent == "" {
+		o.Indent = defaultIndent
+	}
+	if o.Resolver == nil {
+		o.Resolver = protoregistry.GlobalTypes
+	}
+
+	internalEnc, err := json.NewEncoder(o.Indent)
+	if err != nil {
+		return nil, err
+	}
+
+	// Treat nil message interface as an empty message,
+	// in which case the output in an empty JSON object.
+	if m == nil {
+		return []byte("{}"), nil
+	}
+
+	enc := encoder{internalEnc, o}
+	if err := enc.marshalMessage(m.ProtoReflect(), ""); err != nil {
+		return nil, err
+	}
+	if o.AllowPartial {
+		return enc.Bytes(), nil
+	}
+	return enc.Bytes(), proto.CheckInitialized(m)
+}
+
+type encoder struct {
+	*json.Encoder
+	opts MarshalOptions
+}
+
+// typeFieldDesc is a synthetic field descriptor used for the "@type" field.
+var typeFieldDesc = func() protoreflect.FieldDescriptor {
+	var fd filedesc.Field
+	fd.L0.FullName = "@type"
+	fd.L0.Index = -1
+	fd.L1.Cardinality = protoreflect.Optional
+	fd.L1.Kind = protoreflect.StringKind
+	return &fd
+}()
+
+// typeURLFieldRanger wraps a protoreflect.Message and modifies its Range method
+// to additionally iterate over a synthetic field for the type URL.
+type typeURLFieldRanger struct {
+	order.FieldRanger
+	typeURL string
+}
+
+func (m typeURLFieldRanger) Range(f func(pref.FieldDescriptor, pref.Value) bool) {
+	if !f(typeFieldDesc, pref.ValueOfString(m.typeURL)) {
+		return
+	}
+	m.FieldRanger.Range(f)
+}
+
+// unpopulatedFieldRanger wraps a protoreflect.Message and modifies its Range
+// method to additionally iterate over unpopulated fields.
+type unpopulatedFieldRanger struct{ pref.Message }
+
+func (m unpopulatedFieldRanger) Range(f func(pref.FieldDescriptor, pref.Value) bool) {
+	fds := m.Descriptor().Fields()
+	for i := 0; i < fds.Len(); i++ {
+		fd := fds.Get(i)
+		if m.Has(fd) || fd.ContainingOneof() != nil {
+			continue // ignore populated fields and fields within a oneofs
+		}
+
+		v := m.Get(fd)
+		isProto2Scalar := fd.Syntax() == pref.Proto2 && fd.Default().IsValid()
+		isSingularMessage := fd.Cardinality() != pref.Repeated && fd.Message() != nil
+		if isProto2Scalar || isSingularMessage {
+			v = pref.Value{} // use invalid value to emit null
+		}
+		if !f(fd, v) {
+			return
+		}
+	}
+	m.Message.Range(f)
+}
+
+// marshalMessage marshals the fields in the given protoreflect.Message.
+// If the typeURL is non-empty, then a synthetic "@type" field is injected
+// containing the URL as the value.
+func (e encoder) marshalMessage(m pref.Message, typeURL string) error {
+	if !flags.ProtoLegacy && messageset.IsMessageSet(m.Descriptor()) {
+		return errors.New("no support for proto1 MessageSets")
+	}
+
+	if marshal := wellKnownTypeMarshaler(m.Descriptor().FullName()); marshal != nil {
+		return marshal(e, m)
+	}
+
+	e.StartObject()
+	defer e.EndObject()
+
+	var fields order.FieldRanger = m
+	if e.opts.EmitUnpopulated {
+		fields = unpopulatedFieldRanger{m}
+	}
+	if typeURL != "" {
+		fields = typeURLFieldRanger{fields, typeURL}
+	}
+
+	var err error
+	order.RangeFields(fields, order.IndexNameFieldOrder, func(fd pref.FieldDescriptor, v pref.Value) bool {
+		name := fd.JSONName()
+		if e.opts.UseProtoNames {
+			name = fd.TextName()
+		}
+
+		if err = e.WriteName(name); err != nil {
+			return false
+		}
+		if err = e.marshalValue(v, fd); err != nil {
+			return false
+		}
+		return true
+	})
+	return err
+}
+
+// marshalValue marshals the given protoreflect.Value.
+func (e encoder) marshalValue(val pref.Value, fd pref.FieldDescriptor) error {
+	switch {
+	case fd.IsList():
+		return e.marshalList(val.List(), fd)
+	case fd.IsMap():
+		return e.marshalMap(val.Map(), fd)
+	default:
+		return e.marshalSingular(val, fd)
+	}
+}
+
+// marshalSingular marshals the given non-repeated field value. This includes
+// all scalar types, enums, messages, and groups.
+func (e encoder) marshalSingular(val pref.Value, fd pref.FieldDescriptor) error {
+	if !val.IsValid() {
+		e.WriteNull()
+		return nil
+	}
+
+	switch kind := fd.Kind(); kind {
+	case pref.BoolKind:
+		e.WriteBool(val.Bool())
+
+	case pref.StringKind:
+		if e.WriteString(val.String()) != nil {
+			return errors.InvalidUTF8(string(fd.FullName()))
+		}
+
+	case pref.Int32Kind, pref.Sint32Kind, pref.Sfixed32Kind:
+		e.WriteInt(val.Int())
+
+	case pref.Uint32Kind, pref.Fixed32Kind:
+		e.WriteUint(val.Uint())
+
+	case pref.Int64Kind, pref.Sint64Kind, pref.Uint64Kind,
+		pref.Sfixed64Kind, pref.Fixed64Kind:
+		// 64-bit integers are written out as JSON string.
+		e.WriteString(val.String())
+
+	case pref.FloatKind:
+		// Encoder.WriteFloat handles the special numbers NaN and infinites.
+		e.WriteFloat(val.Float(), 32)
+
+	case pref.DoubleKind:
+		// Encoder.WriteFloat handles the special numbers NaN and infinites.
+		e.WriteFloat(val.Float(), 64)
+
+	case pref.BytesKind:
+		e.WriteString(base64.StdEncoding.EncodeToString(val.Bytes()))
+
+	case pref.EnumKind:
+		if fd.Enum().FullName() == genid.NullValue_enum_fullname {
+			e.WriteNull()
+		} else {
+			desc := fd.Enum().Values().ByNumber(val.Enum())
+			if e.opts.UseEnumNumbers || desc == nil {
+				e.WriteInt(int64(val.Enum()))
+			} else {
+				e.WriteString(string(desc.Name()))
+			}
+		}
+
+	case pref.MessageKind, pref.GroupKind:
+		if err := e.marshalMessage(val.Message(), ""); err != nil {
+			return err
+		}
+
+	default:
+		panic(fmt.Sprintf("%v has unknown kind: %v", fd.FullName(), kind))
+	}
+	return nil
+}
+
+// marshalList marshals the given protoreflect.List.
+func (e encoder) marshalList(list pref.List, fd pref.FieldDescriptor) error {
+	e.StartArray()
+	defer e.EndArray()
+
+	for i := 0; i < list.Len(); i++ {
+		item := list.Get(i)
+		if err := e.marshalSingular(item, fd); err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+// marshalMap marshals given protoreflect.Map.
+func (e encoder) marshalMap(mmap pref.Map, fd pref.FieldDescriptor) error {
+	e.StartObject()
+	defer e.EndObject()
+
+	var err error
+	order.RangeEntries(mmap, order.GenericKeyOrder, func(k pref.MapKey, v pref.Value) bool {
+		if err = e.WriteName(k.String()); err != nil {
+			return false
+		}
+		if err = e.marshalSingular(v, fd.MapValue()); err != nil {
+			return false
+		}
+		return true
+	})
+	return err
+}
diff --git a/vendor/google.golang.org/protobuf/encoding/protojson/well_known_types.go b/vendor/google.golang.org/protobuf/encoding/protojson/well_known_types.go
new file mode 100644
index 0000000..72924a9
--- /dev/null
+++ b/vendor/google.golang.org/protobuf/encoding/protojson/well_known_types.go
@@ -0,0 +1,889 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package protojson
+
+import (
+	"bytes"
+	"fmt"
+	"math"
+	"strconv"
+	"strings"
+	"time"
+
+	"google.golang.org/protobuf/internal/encoding/json"
+	"google.golang.org/protobuf/internal/errors"
+	"google.golang.org/protobuf/internal/genid"
+	"google.golang.org/protobuf/internal/strs"
+	"google.golang.org/protobuf/proto"
+	pref "google.golang.org/protobuf/reflect/protoreflect"
+)
+
+type marshalFunc func(encoder, pref.Message) error
+
+// wellKnownTypeMarshaler returns a marshal function if the message type
+// has specialized serialization behavior. It returns nil otherwise.
+func wellKnownTypeMarshaler(name pref.FullName) marshalFunc {
+	if name.Parent() == genid.GoogleProtobuf_package {
+		switch name.Name() {
+		case genid.Any_message_name:
+			return encoder.marshalAny
+		case genid.Timestamp_message_name:
+			return encoder.marshalTimestamp
+		case genid.Duration_message_name:
+			return encoder.marshalDuration
+		case genid.BoolValue_message_name,
+			genid.Int32Value_message_name,
+			genid.Int64Value_message_name,
+			genid.UInt32Value_message_name,
+			genid.UInt64Value_message_name,
+			genid.FloatValue_message_name,
+			genid.DoubleValue_message_name,
+			genid.StringValue_message_name,
+			genid.BytesValue_message_name:
+			return encoder.marshalWrapperType
+		case genid.Struct_message_name:
+			return encoder.marshalStruct
+		case genid.ListValue_message_name:
+			return encoder.marshalListValue
+		case genid.Value_message_name:
+			return encoder.marshalKnownValue
+		case genid.FieldMask_message_name:
+			return encoder.marshalFieldMask
+		case genid.Empty_message_name:
+			return encoder.marshalEmpty
+		}
+	}
+	return nil
+}
+
+type unmarshalFunc func(decoder, pref.Message) error
+
+// wellKnownTypeUnmarshaler returns a unmarshal function if the message type
+// has specialized serialization behavior. It returns nil otherwise.
+func wellKnownTypeUnmarshaler(name pref.FullName) unmarshalFunc {
+	if name.Parent() == genid.GoogleProtobuf_package {
+		switch name.Name() {
+		case genid.Any_message_name:
+			return decoder.unmarshalAny
+		case genid.Timestamp_message_name:
+			return decoder.unmarshalTimestamp
+		case genid.Duration_message_name:
+			return decoder.unmarshalDuration
+		case genid.BoolValue_message_name,
+			genid.Int32Value_message_name,
+			genid.Int64Value_message_name,
+			genid.UInt32Value_message_name,
+			genid.UInt64Value_message_name,
+			genid.FloatValue_message_name,
+			genid.DoubleValue_message_name,
+			genid.StringValue_message_name,
+			genid.BytesValue_message_name:
+			return decoder.unmarshalWrapperType
+		case genid.Struct_message_name:
+			return decoder.unmarshalStruct
+		case genid.ListValue_message_name:
+			return decoder.unmarshalListValue
+		case genid.Value_message_name:
+			return decoder.unmarshalKnownValue
+		case genid.FieldMask_message_name:
+			return decoder.unmarshalFieldMask
+		case genid.Empty_message_name:
+			return decoder.unmarshalEmpty
+		}
+	}
+	return nil
+}
+
+// The JSON representation of an Any message uses the regular representation of
+// the deserialized, embedded message, with an additional field `@type` which
+// contains the type URL. If the embedded message type is well-known and has a
+// custom JSON representation, that representation will be embedded adding a
+// field `value` which holds the custom JSON in addition to the `@type` field.
+
+func (e encoder) marshalAny(m pref.Message) error {
+	fds := m.Descriptor().Fields()
+	fdType := fds.ByNumber(genid.Any_TypeUrl_field_number)
+	fdValue := fds.ByNumber(genid.Any_Value_field_number)
+
+	if !m.Has(fdType) {
+		if !m.Has(fdValue) {
+			// If message is empty, marshal out empty JSON object.
+			e.StartObject()
+			e.EndObject()
+			return nil
+		} else {
+			// Return error if type_url field is not set, but value is set.
+			return errors.New("%s: %v is not set", genid.Any_message_fullname, genid.Any_TypeUrl_field_name)
+		}
+	}
+
+	typeVal := m.Get(fdType)
+	valueVal := m.Get(fdValue)
+
+	// Resolve the type in order to unmarshal value field.
+	typeURL := typeVal.String()
+	emt, err := e.opts.Resolver.FindMessageByURL(typeURL)
+	if err != nil {
+		return errors.New("%s: unable to resolve %q: %v", genid.Any_message_fullname, typeURL, err)
+	}
+
+	em := emt.New()
+	err = proto.UnmarshalOptions{
+		AllowPartial: true, // never check required fields inside an Any
+		Resolver:     e.opts.Resolver,
+	}.Unmarshal(valueVal.Bytes(), em.Interface())
+	if err != nil {
+		return errors.New("%s: unable to unmarshal %q: %v", genid.Any_message_fullname, typeURL, err)
+	}
+
+	// If type of value has custom JSON encoding, marshal out a field "value"
+	// with corresponding custom JSON encoding of the embedded message as a
+	// field.
+	if marshal := wellKnownTypeMarshaler(emt.Descriptor().FullName()); marshal != nil {
+		e.StartObject()
+		defer e.EndObject()
+
+		// Marshal out @type field.
+		e.WriteName("@type")
+		if err := e.WriteString(typeURL); err != nil {
+			return err
+		}
+
+		e.WriteName("value")
+		return marshal(e, em)
+	}
+
+	// Else, marshal out the embedded message's fields in this Any object.
+	if err := e.marshalMessage(em, typeURL); err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func (d decoder) unmarshalAny(m pref.Message) error {
+	// Peek to check for json.ObjectOpen to avoid advancing a read.
+	start, err := d.Peek()
+	if err != nil {
+		return err
+	}
+	if start.Kind() != json.ObjectOpen {
+		return d.unexpectedTokenError(start)
+	}
+
+	// Use another decoder to parse the unread bytes for @type field. This
+	// avoids advancing a read from current decoder because the current JSON
+	// object may contain the fields of the embedded type.
+	dec := decoder{d.Clone(), UnmarshalOptions{}}
+	tok, err := findTypeURL(dec)
+	switch err {
+	case errEmptyObject:
+		// An empty JSON object translates to an empty Any message.
+		d.Read() // Read json.ObjectOpen.
+		d.Read() // Read json.ObjectClose.
+		return nil
+
+	case errMissingType:
+		if d.opts.DiscardUnknown {
+			// Treat all fields as unknowns, similar to an empty object.
+			return d.skipJSONValue()
+		}
+		// Use start.Pos() for line position.
+		return d.newError(start.Pos(), err.Error())
+
+	default:
+		if err != nil {
+			return err
+		}
+	}
+
+	typeURL := tok.ParsedString()
+	emt, err := d.opts.Resolver.FindMessageByURL(typeURL)
+	if err != nil {
+		return d.newError(tok.Pos(), "unable to resolve %v: %q", tok.RawString(), err)
+	}
+
+	// Create new message for the embedded message type and unmarshal into it.
+	em := emt.New()
+	if unmarshal := wellKnownTypeUnmarshaler(emt.Descriptor().FullName()); unmarshal != nil {
+		// If embedded message is a custom type,
+		// unmarshal the JSON "value" field into it.
+		if err := d.unmarshalAnyValue(unmarshal, em); err != nil {
+			return err
+		}
+	} else {
+		// Else unmarshal the current JSON object into it.
+		if err := d.unmarshalMessage(em, true); err != nil {
+			return err
+		}
+	}
+	// Serialize the embedded message and assign the resulting bytes to the
+	// proto value field.
+	b, err := proto.MarshalOptions{
+		AllowPartial:  true, // No need to check required fields inside an Any.
+		Deterministic: true,
+	}.Marshal(em.Interface())
+	if err != nil {
+		return d.newError(start.Pos(), "error in marshaling Any.value field: %v", err)
+	}
+
+	fds := m.Descriptor().Fields()
+	fdType := fds.ByNumber(genid.Any_TypeUrl_field_number)
+	fdValue := fds.ByNumber(genid.Any_Value_field_number)
+
+	m.Set(fdType, pref.ValueOfString(typeURL))
+	m.Set(fdValue, pref.ValueOfBytes(b))
+	return nil
+}
+
+var errEmptyObject = fmt.Errorf(`empty object`)
+var errMissingType = fmt.Errorf(`missing "@type" field`)
+
+// findTypeURL returns the token for the "@type" field value from the given
+// JSON bytes. It is expected that the given bytes start with json.ObjectOpen.
+// It returns errEmptyObject if the JSON object is empty or errMissingType if
+// @type field does not exist. It returns other error if the @type field is not
+// valid or other decoding issues.
+func findTypeURL(d decoder) (json.Token, error) {
+	var typeURL string
+	var typeTok json.Token
+	numFields := 0
+	// Skip start object.
+	d.Read()
+
+Loop:
+	for {
+		tok, err := d.Read()
+		if err != nil {
+			return json.Token{}, err
+		}
+
+		switch tok.Kind() {
+		case json.ObjectClose:
+			if typeURL == "" {
+				// Did not find @type field.
+				if numFields > 0 {
+					return json.Token{}, errMissingType
+				}
+				return json.Token{}, errEmptyObject
+			}
+			break Loop
+
+		case json.Name:
+			numFields++
+			if tok.Name() != "@type" {
+				// Skip value.
+				if err := d.skipJSONValue(); err != nil {
+					return json.Token{}, err
+				}
+				continue
+			}
+
+			// Return error if this was previously set already.
+			if typeURL != "" {
+				return json.Token{}, d.newError(tok.Pos(), `duplicate "@type" field`)
+			}
+			// Read field value.
+			tok, err := d.Read()
+			if err != nil {
+				return json.Token{}, err
+			}
+			if tok.Kind() != json.String {
+				return json.Token{}, d.newError(tok.Pos(), `@type field value is not a string: %v`, tok.RawString())
+			}
+			typeURL = tok.ParsedString()
+			if typeURL == "" {
+				return json.Token{}, d.newError(tok.Pos(), `@type field contains empty value`)
+			}
+			typeTok = tok
+		}
+	}
+
+	return typeTok, nil
+}
+
+// skipJSONValue parses a JSON value (null, boolean, string, number, object and
+// array) in order to advance the read to the next JSON value. It relies on
+// the decoder returning an error if the types are not in valid sequence.
+func (d decoder) skipJSONValue() error {
+	tok, err := d.Read()
+	if err != nil {
+		return err
+	}
+	// Only need to continue reading for objects and arrays.
+	switch tok.Kind() {
+	case json.ObjectOpen:
+		for {
+			tok, err := d.Read()
+			if err != nil {
+				return err
+			}
+			switch tok.Kind() {
+			case json.ObjectClose:
+				return nil
+			case json.Name:
+				// Skip object field value.
+				if err := d.skipJSONValue(); err != nil {
+					return err
+				}
+			}
+		}
+
+	case json.ArrayOpen:
+		for {
+			tok, err := d.Peek()
+			if err != nil {
+				return err
+			}
+			switch tok.Kind() {
+			case json.ArrayClose:
+				d.Read()
+				return nil
+			default:
+				// Skip array item.
+				if err := d.skipJSONValue(); err != nil {
+					return err
+				}
+			}
+		}
+	}
+	return nil
+}
+
+// unmarshalAnyValue unmarshals the given custom-type message from the JSON
+// object's "value" field.
+func (d decoder) unmarshalAnyValue(unmarshal unmarshalFunc, m pref.Message) error {
+	// Skip ObjectOpen, and start reading the fields.
+	d.Read()
+
+	var found bool // Used for detecting duplicate "value".
+	for {
+		tok, err := d.Read()
+		if err != nil {
+			return err
+		}
+		switch tok.Kind() {
+		case json.ObjectClose:
+			if !found {
+				return d.newError(tok.Pos(), `missing "value" field`)
+			}
+			return nil
+
+		case json.Name:
+			switch tok.Name() {
+			case "@type":
+				// Skip the value as this was previously parsed already.
+				d.Read()
+
+			case "value":
+				if found {
+					return d.newError(tok.Pos(), `duplicate "value" field`)
+				}
+				// Unmarshal the field value into the given message.
+				if err := unmarshal(d, m); err != nil {
+					return err
+				}
+				found = true
+
+			default:
+				if d.opts.DiscardUnknown {
+					if err := d.skipJSONValue(); err != nil {
+						return err
+					}
+					continue
+				}
+				return d.newError(tok.Pos(), "unknown field %v", tok.RawString())
+			}
+		}
+	}
+}
+
+// Wrapper types are encoded as JSON primitives like string, number or boolean.
+
+func (e encoder) marshalWrapperType(m pref.Message) error {
+	fd := m.Descriptor().Fields().ByNumber(genid.WrapperValue_Value_field_number)
+	val := m.Get(fd)
+	return e.marshalSingular(val, fd)
+}
+
+func (d decoder) unmarshalWrapperType(m pref.Message) error {
+	fd := m.Descriptor().Fields().ByNumber(genid.WrapperValue_Value_field_number)
+	val, err := d.unmarshalScalar(fd)
+	if err != nil {
+		return err
+	}
+	m.Set(fd, val)
+	return nil
+}
+
+// The JSON representation for Empty is an empty JSON object.
+
+func (e encoder) marshalEmpty(pref.Message) error {
+	e.StartObject()
+	e.EndObject()
+	return nil
+}
+
+func (d decoder) unmarshalEmpty(pref.Message) error {
+	tok, err := d.Read()
+	if err != nil {
+		return err
+	}
+	if tok.Kind() != json.ObjectOpen {
+		return d.unexpectedTokenError(tok)
+	}
+
+	for {
+		tok, err := d.Read()
+		if err != nil {
+			return err
+		}
+		switch tok.Kind() {
+		case json.ObjectClose:
+			return nil
+
+		case json.Name:
+			if d.opts.DiscardUnknown {
+				if err := d.skipJSONValue(); err != nil {
+					return err
+				}
+				continue
+			}
+			return d.newError(tok.Pos(), "unknown field %v", tok.RawString())
+
+		default:
+			return d.unexpectedTokenError(tok)
+		}
+	}
+}
+
+// The JSON representation for Struct is a JSON object that contains the encoded
+// Struct.fields map and follows the serialization rules for a map.
+
+func (e encoder) marshalStruct(m pref.Message) error {
+	fd := m.Descriptor().Fields().ByNumber(genid.Struct_Fields_field_number)
+	return e.marshalMap(m.Get(fd).Map(), fd)
+}
+
+func (d decoder) unmarshalStruct(m pref.Message) error {
+	fd := m.Descriptor().Fields().ByNumber(genid.Struct_Fields_field_number)
+	return d.unmarshalMap(m.Mutable(fd).Map(), fd)
+}
+
+// The JSON representation for ListValue is JSON array that contains the encoded
+// ListValue.values repeated field and follows the serialization rules for a
+// repeated field.
+
+func (e encoder) marshalListValue(m pref.Message) error {
+	fd := m.Descriptor().Fields().ByNumber(genid.ListValue_Values_field_number)
+	return e.marshalList(m.Get(fd).List(), fd)
+}
+
+func (d decoder) unmarshalListValue(m pref.Message) error {
+	fd := m.Descriptor().Fields().ByNumber(genid.ListValue_Values_field_number)
+	return d.unmarshalList(m.Mutable(fd).List(), fd)
+}
+
+// The JSON representation for a Value is dependent on the oneof field that is
+// set. Each of the field in the oneof has its own custom serialization rule. A
+// Value message needs to be a oneof field set, else it is an error.
+
+func (e encoder) marshalKnownValue(m pref.Message) error {
+	od := m.Descriptor().Oneofs().ByName(genid.Value_Kind_oneof_name)
+	fd := m.WhichOneof(od)
+	if fd == nil {
+		return errors.New("%s: none of the oneof fields is set", genid.Value_message_fullname)
+	}
+	if fd.Number() == genid.Value_NumberValue_field_number {
+		if v := m.Get(fd).Float(); math.IsNaN(v) || math.IsInf(v, 0) {
+			return errors.New("%s: invalid %v value", genid.Value_NumberValue_field_fullname, v)
+		}
+	}
+	return e.marshalSingular(m.Get(fd), fd)
+}
+
+func (d decoder) unmarshalKnownValue(m pref.Message) error {
+	tok, err := d.Peek()
+	if err != nil {
+		return err
+	}
+
+	var fd pref.FieldDescriptor
+	var val pref.Value
+	switch tok.Kind() {
+	case json.Null:
+		d.Read()
+		fd = m.Descriptor().Fields().ByNumber(genid.Value_NullValue_field_number)
+		val = pref.ValueOfEnum(0)
+
+	case json.Bool:
+		tok, err := d.Read()
+		if err != nil {
+			return err
+		}
+		fd = m.Descriptor().Fields().ByNumber(genid.Value_BoolValue_field_number)
+		val = pref.ValueOfBool(tok.Bool())
+
+	case json.Number:
+		tok, err := d.Read()
+		if err != nil {
+			return err
+		}
+		fd = m.Descriptor().Fields().ByNumber(genid.Value_NumberValue_field_number)
+		var ok bool
+		val, ok = unmarshalFloat(tok, 64)
+		if !ok {
+			return d.newError(tok.Pos(), "invalid %v: %v", genid.Value_message_fullname, tok.RawString())
+		}
+
+	case json.String:
+		// A JSON string may have been encoded from the number_value field,
+		// e.g. "NaN", "Infinity", etc. Parsing a proto double type also allows
+		// for it to be in JSON string form. Given this custom encoding spec,
+		// however, there is no way to identify that and hence a JSON string is
+		// always assigned to the string_value field, which means that certain
+		// encoding cannot be parsed back to the same field.
+		tok, err := d.Read()
+		if err != nil {
+			return err
+		}
+		fd = m.Descriptor().Fields().ByNumber(genid.Value_StringValue_field_number)
+		val = pref.ValueOfString(tok.ParsedString())
+
+	case json.ObjectOpen:
+		fd = m.Descriptor().Fields().ByNumber(genid.Value_StructValue_field_number)
+		val = m.NewField(fd)
+		if err := d.unmarshalStruct(val.Message()); err != nil {
+			return err
+		}
+
+	case json.ArrayOpen:
+		fd = m.Descriptor().Fields().ByNumber(genid.Value_ListValue_field_number)
+		val = m.NewField(fd)
+		if err := d.unmarshalListValue(val.Message()); err != nil {
+			return err
+		}
+
+	default:
+		return d.newError(tok.Pos(), "invalid %v: %v", genid.Value_message_fullname, tok.RawString())
+	}
+
+	m.Set(fd, val)
+	return nil
+}
+
+// The JSON representation for a Duration is a JSON string that ends in the
+// suffix "s" (indicating seconds) and is preceded by the number of seconds,
+// with nanoseconds expressed as fractional seconds.
+//
+// Durations less than one second are represented with a 0 seconds field and a
+// positive or negative nanos field. For durations of one second or more, a
+// non-zero value for the nanos field must be of the same sign as the seconds
+// field.
+//
+// Duration.seconds must be from -315,576,000,000 to +315,576,000,000 inclusive.
+// Duration.nanos must be from -999,999,999 to +999,999,999 inclusive.
+
+const (
+	secondsInNanos       = 999999999
+	maxSecondsInDuration = 315576000000
+)
+
+func (e encoder) marshalDuration(m pref.Message) error {
+	fds := m.Descriptor().Fields()
+	fdSeconds := fds.ByNumber(genid.Duration_Seconds_field_number)
+	fdNanos := fds.ByNumber(genid.Duration_Nanos_field_number)
+
+	secsVal := m.Get(fdSeconds)
+	nanosVal := m.Get(fdNanos)
+	secs := secsVal.Int()
+	nanos := nanosVal.Int()
+	if secs < -maxSecondsInDuration || secs > maxSecondsInDuration {
+		return errors.New("%s: seconds out of range %v", genid.Duration_message_fullname, secs)
+	}
+	if nanos < -secondsInNanos || nanos > secondsInNanos {
+		return errors.New("%s: nanos out of range %v", genid.Duration_message_fullname, nanos)
+	}
+	if (secs > 0 && nanos < 0) || (secs < 0 && nanos > 0) {
+		return errors.New("%s: signs of seconds and nanos do not match", genid.Duration_message_fullname)
+	}
+	// Generated output always contains 0, 3, 6, or 9 fractional digits,
+	// depending on required precision, followed by the suffix "s".
+	var sign string
+	if secs < 0 || nanos < 0 {
+		sign, secs, nanos = "-", -1*secs, -1*nanos
+	}
+	x := fmt.Sprintf("%s%d.%09d", sign, secs, nanos)
+	x = strings.TrimSuffix(x, "000")
+	x = strings.TrimSuffix(x, "000")
+	x = strings.TrimSuffix(x, ".000")
+	e.WriteString(x + "s")
+	return nil
+}
+
+func (d decoder) unmarshalDuration(m pref.Message) error {
+	tok, err := d.Read()
+	if err != nil {
+		return err
+	}
+	if tok.Kind() != json.String {
+		return d.unexpectedTokenError(tok)
+	}
+
+	secs, nanos, ok := parseDuration(tok.ParsedString())
+	if !ok {
+		return d.newError(tok.Pos(), "invalid %v value %v", genid.Duration_message_fullname, tok.RawString())
+	}
+	// Validate seconds. No need to validate nanos because parseDuration would
+	// have covered that already.
+	if secs < -maxSecondsInDuration || secs > maxSecondsInDuration {
+		return d.newError(tok.Pos(), "%v value out of range: %v", genid.Duration_message_fullname, tok.RawString())
+	}
+
+	fds := m.Descriptor().Fields()
+	fdSeconds := fds.ByNumber(genid.Duration_Seconds_field_number)
+	fdNanos := fds.ByNumber(genid.Duration_Nanos_field_number)
+
+	m.Set(fdSeconds, pref.ValueOfInt64(secs))
+	m.Set(fdNanos, pref.ValueOfInt32(nanos))
+	return nil
+}
+
+// parseDuration parses the given input string for seconds and nanoseconds value
+// for the Duration JSON format. The format is a decimal number with a suffix
+// 's'. It can have optional plus/minus sign. There needs to be at least an
+// integer or fractional part. Fractional part is limited to 9 digits only for
+// nanoseconds precision, regardless of whether there are trailing zero digits.
+// Example values are 1s, 0.1s, 1.s, .1s, +1s, -1s, -.1s.
+func parseDuration(input string) (int64, int32, bool) {
+	b := []byte(input)
+	size := len(b)
+	if size < 2 {
+		return 0, 0, false
+	}
+	if b[size-1] != 's' {
+		return 0, 0, false
+	}
+	b = b[:size-1]
+
+	// Read optional plus/minus symbol.
+	var neg bool
+	switch b[0] {
+	case '-':
+		neg = true
+		b = b[1:]
+	case '+':
+		b = b[1:]
+	}
+	if len(b) == 0 {
+		return 0, 0, false
+	}
+
+	// Read the integer part.
+	var intp []byte
+	switch {
+	case b[0] == '0':
+		b = b[1:]
+
+	case '1' <= b[0] && b[0] <= '9':
+		intp = b[0:]
+		b = b[1:]
+		n := 1
+		for len(b) > 0 && '0' <= b[0] && b[0] <= '9' {
+			n++
+			b = b[1:]
+		}
+		intp = intp[:n]
+
+	case b[0] == '.':
+		// Continue below.
+
+	default:
+		return 0, 0, false
+	}
+
+	hasFrac := false
+	var frac [9]byte
+	if len(b) > 0 {
+		if b[0] != '.' {
+			return 0, 0, false
+		}
+		// Read the fractional part.
+		b = b[1:]
+		n := 0
+		for len(b) > 0 && n < 9 && '0' <= b[0] && b[0] <= '9' {
+			frac[n] = b[0]
+			n++
+			b = b[1:]
+		}
+		// It is not valid if there are more bytes left.
+		if len(b) > 0 {
+			return 0, 0, false
+		}
+		// Pad fractional part with 0s.
+		for i := n; i < 9; i++ {
+			frac[i] = '0'
+		}
+		hasFrac = true
+	}
+
+	var secs int64
+	if len(intp) > 0 {
+		var err error
+		secs, err = strconv.ParseInt(string(intp), 10, 64)
+		if err != nil {
+			return 0, 0, false
+		}
+	}
+
+	var nanos int64
+	if hasFrac {
+		nanob := bytes.TrimLeft(frac[:], "0")
+		if len(nanob) > 0 {
+			var err error
+			nanos, err = strconv.ParseInt(string(nanob), 10, 32)
+			if err != nil {
+				return 0, 0, false
+			}
+		}
+	}
+
+	if neg {
+		if secs > 0 {
+			secs = -secs
+		}
+		if nanos > 0 {
+			nanos = -nanos
+		}
+	}
+	return secs, int32(nanos), true
+}
+
+// The JSON representation for a Timestamp is a JSON string in the RFC 3339
+// format, i.e. "{year}-{month}-{day}T{hour}:{min}:{sec}[.{frac_sec}]Z" where
+// {year} is always expressed using four digits while {month}, {day}, {hour},
+// {min}, and {sec} are zero-padded to two digits each. The fractional seconds,
+// which can go up to 9 digits, up to 1 nanosecond resolution, is optional. The
+// "Z" suffix indicates the timezone ("UTC"); the timezone is required. Encoding
+// should always use UTC (as indicated by "Z") and a decoder should be able to
+// accept both UTC and other timezones (as indicated by an offset).
+//
+// Timestamp.seconds must be from 0001-01-01T00:00:00Z to 9999-12-31T23:59:59Z
+// inclusive.
+// Timestamp.nanos must be from 0 to 999,999,999 inclusive.
+
+const (
+	maxTimestampSeconds = 253402300799
+	minTimestampSeconds = -62135596800
+)
+
+func (e encoder) marshalTimestamp(m pref.Message) error {
+	fds := m.Descriptor().Fields()
+	fdSeconds := fds.ByNumber(genid.Timestamp_Seconds_field_number)
+	fdNanos := fds.ByNumber(genid.Timestamp_Nanos_field_number)
+
+	secsVal := m.Get(fdSeconds)
+	nanosVal := m.Get(fdNanos)
+	secs := secsVal.Int()
+	nanos := nanosVal.Int()
+	if secs < minTimestampSeconds || secs > maxTimestampSeconds {
+		return errors.New("%s: seconds out of range %v", genid.Timestamp_message_fullname, secs)
+	}
+	if nanos < 0 || nanos > secondsInNanos {
+		return errors.New("%s: nanos out of range %v", genid.Timestamp_message_fullname, nanos)
+	}
+	// Uses RFC 3339, where generated output will be Z-normalized and uses 0, 3,
+	// 6 or 9 fractional digits.
+	t := time.Unix(secs, nanos).UTC()
+	x := t.Format("2006-01-02T15:04:05.000000000")
+	x = strings.TrimSuffix(x, "000")
+	x = strings.TrimSuffix(x, "000")
+	x = strings.TrimSuffix(x, ".000")
+	e.WriteString(x + "Z")
+	return nil
+}
+
+func (d decoder) unmarshalTimestamp(m pref.Message) error {
+	tok, err := d.Read()
+	if err != nil {
+		return err
+	}
+	if tok.Kind() != json.String {
+		return d.unexpectedTokenError(tok)
+	}
+
+	t, err := time.Parse(time.RFC3339Nano, tok.ParsedString())
+	if err != nil {
+		return d.newError(tok.Pos(), "invalid %v value %v", genid.Timestamp_message_fullname, tok.RawString())
+	}
+	// Validate seconds. No need to validate nanos because time.Parse would have
+	// covered that already.
+	secs := t.Unix()
+	if secs < minTimestampSeconds || secs > maxTimestampSeconds {
+		return d.newError(tok.Pos(), "%v value out of range: %v", genid.Timestamp_message_fullname, tok.RawString())
+	}
+
+	fds := m.Descriptor().Fields()
+	fdSeconds := fds.ByNumber(genid.Timestamp_Seconds_field_number)
+	fdNanos := fds.ByNumber(genid.Timestamp_Nanos_field_number)
+
+	m.Set(fdSeconds, pref.ValueOfInt64(secs))
+	m.Set(fdNanos, pref.ValueOfInt32(int32(t.Nanosecond())))
+	return nil
+}
+
+// The JSON representation for a FieldMask is a JSON string where paths are
+// separated by a comma. Fields name in each path are converted to/from
+// lower-camel naming conventions. Encoding should fail if the path name would
+// end up differently after a round-trip.
+
+func (e encoder) marshalFieldMask(m pref.Message) error {
+	fd := m.Descriptor().Fields().ByNumber(genid.FieldMask_Paths_field_number)
+	list := m.Get(fd).List()
+	paths := make([]string, 0, list.Len())
+
+	for i := 0; i < list.Len(); i++ {
+		s := list.Get(i).String()
+		if !pref.FullName(s).IsValid() {
+			return errors.New("%s contains invalid path: %q", genid.FieldMask_Paths_field_fullname, s)
+		}
+		// Return error if conversion to camelCase is not reversible.
+		cc := strs.JSONCamelCase(s)
+		if s != strs.JSONSnakeCase(cc) {
+			return errors.New("%s contains irreversible value %q", genid.FieldMask_Paths_field_fullname, s)
+		}
+		paths = append(paths, cc)
+	}
+
+	e.WriteString(strings.Join(paths, ","))
+	return nil
+}
+
+func (d decoder) unmarshalFieldMask(m pref.Message) error {
+	tok, err := d.Read()
+	if err != nil {
+		return err
+	}
+	if tok.Kind() != json.String {
+		return d.unexpectedTokenError(tok)
+	}
+	str := strings.TrimSpace(tok.ParsedString())
+	if str == "" {
+		return nil
+	}
+	paths := strings.Split(str, ",")
+
+	fd := m.Descriptor().Fields().ByNumber(genid.FieldMask_Paths_field_number)
+	list := m.Mutable(fd).List()
+
+	for _, s0 := range paths {
+		s := strs.JSONSnakeCase(s0)
+		if strings.Contains(s0, "_") || !pref.FullName(s).IsValid() {
+			return d.newError(tok.Pos(), "%v contains invalid path: %q", genid.FieldMask_Paths_field_fullname, s0)
+		}
+		list.Append(pref.ValueOfString(s))
+	}
+	return nil
+}
diff --git a/vendor/google.golang.org/protobuf/internal/encoding/json/decode.go b/vendor/google.golang.org/protobuf/internal/encoding/json/decode.go
new file mode 100644
index 0000000..b13fd29
--- /dev/null
+++ b/vendor/google.golang.org/protobuf/internal/encoding/json/decode.go
@@ -0,0 +1,340 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package json
+
+import (
+	"bytes"
+	"fmt"
+	"io"
+	"regexp"
+	"unicode/utf8"
+
+	"google.golang.org/protobuf/internal/errors"
+)
+
+// call specifies which Decoder method was invoked.
+type call uint8
+
+const (
+	readCall call = iota
+	peekCall
+)
+
+const unexpectedFmt = "unexpected token %s"
+
+// ErrUnexpectedEOF means that EOF was encountered in the middle of the input.
+var ErrUnexpectedEOF = errors.New("%v", io.ErrUnexpectedEOF)
+
+// Decoder is a token-based JSON decoder.
+type Decoder struct {
+	// lastCall is last method called, either readCall or peekCall.
+	// Initial value is readCall.
+	lastCall call
+
+	// lastToken contains the last read token.
+	lastToken Token
+
+	// lastErr contains the last read error.
+	lastErr error
+
+	// openStack is a stack containing ObjectOpen and ArrayOpen values. The
+	// top of stack represents the object or the array the current value is
+	// directly located in.
+	openStack []Kind
+
+	// orig is used in reporting line and column.
+	orig []byte
+	// in contains the unconsumed input.
+	in []byte
+}
+
+// NewDecoder returns a Decoder to read the given []byte.
+func NewDecoder(b []byte) *Decoder {
+	return &Decoder{orig: b, in: b}
+}
+
+// Peek looks ahead and returns the next token kind without advancing a read.
+func (d *Decoder) Peek() (Token, error) {
+	defer func() { d.lastCall = peekCall }()
+	if d.lastCall == readCall {
+		d.lastToken, d.lastErr = d.Read()
+	}
+	return d.lastToken, d.lastErr
+}
+
+// Read returns the next JSON token.
+// It will return an error if there is no valid token.
+func (d *Decoder) Read() (Token, error) {
+	const scalar = Null | Bool | Number | String
+
+	defer func() { d.lastCall = readCall }()
+	if d.lastCall == peekCall {
+		return d.lastToken, d.lastErr
+	}
+
+	tok, err := d.parseNext()
+	if err != nil {
+		return Token{}, err
+	}
+
+	switch tok.kind {
+	case EOF:
+		if len(d.openStack) != 0 ||
+			d.lastToken.kind&scalar|ObjectClose|ArrayClose == 0 {
+			return Token{}, ErrUnexpectedEOF
+		}
+
+	case Null:
+		if !d.isValueNext() {
+			return Token{}, d.newSyntaxError(tok.pos, unexpectedFmt, tok.RawString())
+		}
+
+	case Bool, Number:
+		if !d.isValueNext() {
+			return Token{}, d.newSyntaxError(tok.pos, unexpectedFmt, tok.RawString())
+		}
+
+	case String:
+		if d.isValueNext() {
+			break
+		}
+		// This string token should only be for a field name.
+		if d.lastToken.kind&(ObjectOpen|comma) == 0 {
+			return Token{}, d.newSyntaxError(tok.pos, unexpectedFmt, tok.RawString())
+		}
+		if len(d.in) == 0 {
+			return Token{}, ErrUnexpectedEOF
+		}
+		if c := d.in[0]; c != ':' {
+			return Token{}, d.newSyntaxError(d.currPos(), `unexpected character %s, missing ":" after field name`, string(c))
+		}
+		tok.kind = Name
+		d.consume(1)
+
+	case ObjectOpen, ArrayOpen:
+		if !d.isValueNext() {
+			return Token{}, d.newSyntaxError(tok.pos, unexpectedFmt, tok.RawString())
+		}
+		d.openStack = append(d.openStack, tok.kind)
+
+	case ObjectClose:
+		if len(d.openStack) == 0 ||
+			d.lastToken.kind == comma ||
+			d.openStack[len(d.openStack)-1] != ObjectOpen {
+			return Token{}, d.newSyntaxError(tok.pos, unexpectedFmt, tok.RawString())
+		}
+		d.openStack = d.openStack[:len(d.openStack)-1]
+
+	case ArrayClose:
+		if len(d.openStack) == 0 ||
+			d.lastToken.kind == comma ||
+			d.openStack[len(d.openStack)-1] != ArrayOpen {
+			return Token{}, d.newSyntaxError(tok.pos, unexpectedFmt, tok.RawString())
+		}
+		d.openStack = d.openStack[:len(d.openStack)-1]
+
+	case comma:
+		if len(d.openStack) == 0 ||
+			d.lastToken.kind&(scalar|ObjectClose|ArrayClose) == 0 {
+			return Token{}, d.newSyntaxError(tok.pos, unexpectedFmt, tok.RawString())
+		}
+	}
+
+	// Update d.lastToken only after validating token to be in the right sequence.
+	d.lastToken = tok
+
+	if d.lastToken.kind == comma {
+		return d.Read()
+	}
+	return tok, nil
+}
+
+// Any sequence that looks like a non-delimiter (for error reporting).
+var errRegexp = regexp.MustCompile(`^([-+._a-zA-Z0-9]{1,32}|.)`)
+
+// parseNext parses for the next JSON token. It returns a Token object for
+// different types, except for Name. It does not handle whether the next token
+// is in a valid sequence or not.
+func (d *Decoder) parseNext() (Token, error) {
+	// Trim leading spaces.
+	d.consume(0)
+
+	in := d.in
+	if len(in) == 0 {
+		return d.consumeToken(EOF, 0), nil
+	}
+
+	switch in[0] {
+	case 'n':
+		if n := matchWithDelim("null", in); n != 0 {
+			return d.consumeToken(Null, n), nil
+		}
+
+	case 't':
+		if n := matchWithDelim("true", in); n != 0 {
+			return d.consumeBoolToken(true, n), nil
+		}
+
+	case 'f':
+		if n := matchWithDelim("false", in); n != 0 {
+			return d.consumeBoolToken(false, n), nil
+		}
+
+	case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
+		if n, ok := parseNumber(in); ok {
+			return d.consumeToken(Number, n), nil
+		}
+
+	case '"':
+		s, n, err := d.parseString(in)
+		if err != nil {
+			return Token{}, err
+		}
+		return d.consumeStringToken(s, n), nil
+
+	case '{':
+		return d.consumeToken(ObjectOpen, 1), nil
+
+	case '}':
+		return d.consumeToken(ObjectClose, 1), nil
+
+	case '[':
+		return d.consumeToken(ArrayOpen, 1), nil
+
+	case ']':
+		return d.consumeToken(ArrayClose, 1), nil
+
+	case ',':
+		return d.consumeToken(comma, 1), nil
+	}
+	return Token{}, d.newSyntaxError(d.currPos(), "invalid value %s", errRegexp.Find(in))
+}
+
+// newSyntaxError returns an error with line and column information useful for
+// syntax errors.
+func (d *Decoder) newSyntaxError(pos int, f string, x ...interface{}) error {
+	e := errors.New(f, x...)
+	line, column := d.Position(pos)
+	return errors.New("syntax error (line %d:%d): %v", line, column, e)
+}
+
+// Position returns line and column number of given index of the original input.
+// It will panic if index is out of range.
+func (d *Decoder) Position(idx int) (line int, column int) {
+	b := d.orig[:idx]
+	line = bytes.Count(b, []byte("\n")) + 1
+	if i := bytes.LastIndexByte(b, '\n'); i >= 0 {
+		b = b[i+1:]
+	}
+	column = utf8.RuneCount(b) + 1 // ignore multi-rune characters
+	return line, column
+}
+
+// currPos returns the current index position of d.in from d.orig.
+func (d *Decoder) currPos() int {
+	return len(d.orig) - len(d.in)
+}
+
+// matchWithDelim matches s with the input b and verifies that the match
+// terminates with a delimiter of some form (e.g., r"[^-+_.a-zA-Z0-9]").
+// As a special case, EOF is considered a delimiter. It returns the length of s
+// if there is a match, else 0.
+func matchWithDelim(s string, b []byte) int {
+	if !bytes.HasPrefix(b, []byte(s)) {
+		return 0
+	}
+
+	n := len(s)
+	if n < len(b) && isNotDelim(b[n]) {
+		return 0
+	}
+	return n
+}
+
+// isNotDelim returns true if given byte is a not delimiter character.
+func isNotDelim(c byte) bool {
+	return (c == '-' || c == '+' || c == '.' || c == '_' ||
+		('a' <= c && c <= 'z') ||
+		('A' <= c && c <= 'Z') ||
+		('0' <= c && c <= '9'))
+}
+
+// consume consumes n bytes of input and any subsequent whitespace.
+func (d *Decoder) consume(n int) {
+	d.in = d.in[n:]
+	for len(d.in) > 0 {
+		switch d.in[0] {
+		case ' ', '\n', '\r', '\t':
+			d.in = d.in[1:]
+		default:
+			return
+		}
+	}
+}
+
+// isValueNext returns true if next type should be a JSON value: Null,
+// Number, String or Bool.
+func (d *Decoder) isValueNext() bool {
+	if len(d.openStack) == 0 {
+		return d.lastToken.kind == 0
+	}
+
+	start := d.openStack[len(d.openStack)-1]
+	switch start {
+	case ObjectOpen:
+		return d.lastToken.kind&Name != 0
+	case ArrayOpen:
+		return d.lastToken.kind&(ArrayOpen|comma) != 0
+	}
+	panic(fmt.Sprintf(
+		"unreachable logic in Decoder.isValueNext, lastToken.kind: %v, openStack: %v",
+		d.lastToken.kind, start))
+}
+
+// consumeToken constructs a Token for given Kind with raw value derived from
+// current d.in and given size, and consumes the given size-lenght of it.
+func (d *Decoder) consumeToken(kind Kind, size int) Token {
+	tok := Token{
+		kind: kind,
+		raw:  d.in[:size],
+		pos:  len(d.orig) - len(d.in),
+	}
+	d.consume(size)
+	return tok
+}
+
+// consumeBoolToken constructs a Token for a Bool kind with raw value derived from
+// current d.in and given size.
+func (d *Decoder) consumeBoolToken(b bool, size int) Token {
+	tok := Token{
+		kind: Bool,
+		raw:  d.in[:size],
+		pos:  len(d.orig) - len(d.in),
+		boo:  b,
+	}
+	d.consume(size)
+	return tok
+}
+
+// consumeStringToken constructs a Token for a String kind with raw value derived
+// from current d.in and given size.
+func (d *Decoder) consumeStringToken(s string, size int) Token {
+	tok := Token{
+		kind: String,
+		raw:  d.in[:size],
+		pos:  len(d.orig) - len(d.in),
+		str:  s,
+	}
+	d.consume(size)
+	return tok
+}
+
+// Clone returns a copy of the Decoder for use in reading ahead the next JSON
+// object, array or other values without affecting current Decoder.
+func (d *Decoder) Clone() *Decoder {
+	ret := *d
+	ret.openStack = append([]Kind(nil), ret.openStack...)
+	return &ret
+}
diff --git a/vendor/google.golang.org/protobuf/internal/encoding/json/decode_number.go b/vendor/google.golang.org/protobuf/internal/encoding/json/decode_number.go
new file mode 100644
index 0000000..2999d71
--- /dev/null
+++ b/vendor/google.golang.org/protobuf/internal/encoding/json/decode_number.go
@@ -0,0 +1,254 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package json
+
+import (
+	"bytes"
+	"strconv"
+)
+
+// parseNumber reads the given []byte for a valid JSON number. If it is valid,
+// it returns the number of bytes.  Parsing logic follows the definition in
+// https://tools.ietf.org/html/rfc7159#section-6, and is based off
+// encoding/json.isValidNumber function.
+func parseNumber(input []byte) (int, bool) {
+	var n int
+
+	s := input
+	if len(s) == 0 {
+		return 0, false
+	}
+
+	// Optional -
+	if s[0] == '-' {
+		s = s[1:]
+		n++
+		if len(s) == 0 {
+			return 0, false
+		}
+	}
+
+	// Digits
+	switch {
+	case s[0] == '0':
+		s = s[1:]
+		n++
+
+	case '1' <= s[0] && s[0] <= '9':
+		s = s[1:]
+		n++
+		for len(s) > 0 && '0' <= s[0] && s[0] <= '9' {
+			s = s[1:]
+			n++
+		}
+
+	default:
+		return 0, false
+	}
+
+	// . followed by 1 or more digits.
+	if len(s) >= 2 && s[0] == '.' && '0' <= s[1] && s[1] <= '9' {
+		s = s[2:]
+		n += 2
+		for len(s) > 0 && '0' <= s[0] && s[0] <= '9' {
+			s = s[1:]
+			n++
+		}
+	}
+
+	// e or E followed by an optional - or + and
+	// 1 or more digits.
+	if len(s) >= 2 && (s[0] == 'e' || s[0] == 'E') {
+		s = s[1:]
+		n++
+		if s[0] == '+' || s[0] == '-' {
+			s = s[1:]
+			n++
+			if len(s) == 0 {
+				return 0, false
+			}
+		}
+		for len(s) > 0 && '0' <= s[0] && s[0] <= '9' {
+			s = s[1:]
+			n++
+		}
+	}
+
+	// Check that next byte is a delimiter or it is at the end.
+	if n < len(input) && isNotDelim(input[n]) {
+		return 0, false
+	}
+
+	return n, true
+}
+
+// numberParts is the result of parsing out a valid JSON number. It contains
+// the parts of a number. The parts are used for integer conversion.
+type numberParts struct {
+	neg  bool
+	intp []byte
+	frac []byte
+	exp  []byte
+}
+
+// parseNumber constructs numberParts from given []byte. The logic here is
+// similar to consumeNumber above with the difference of having to construct
+// numberParts. The slice fields in numberParts are subslices of the input.
+func parseNumberParts(input []byte) (numberParts, bool) {
+	var neg bool
+	var intp []byte
+	var frac []byte
+	var exp []byte
+
+	s := input
+	if len(s) == 0 {
+		return numberParts{}, false
+	}
+
+	// Optional -
+	if s[0] == '-' {
+		neg = true
+		s = s[1:]
+		if len(s) == 0 {
+			return numberParts{}, false
+		}
+	}
+
+	// Digits
+	switch {
+	case s[0] == '0':
+		// Skip first 0 and no need to store.
+		s = s[1:]
+
+	case '1' <= s[0] && s[0] <= '9':
+		intp = s
+		n := 1
+		s = s[1:]
+		for len(s) > 0 && '0' <= s[0] && s[0] <= '9' {
+			s = s[1:]
+			n++
+		}
+		intp = intp[:n]
+
+	default:
+		return numberParts{}, false
+	}
+
+	// . followed by 1 or more digits.
+	if len(s) >= 2 && s[0] == '.' && '0' <= s[1] && s[1] <= '9' {
+		frac = s[1:]
+		n := 1
+		s = s[2:]
+		for len(s) > 0 && '0' <= s[0] && s[0] <= '9' {
+			s = s[1:]
+			n++
+		}
+		frac = frac[:n]
+	}
+
+	// e or E followed by an optional - or + and
+	// 1 or more digits.
+	if len(s) >= 2 && (s[0] == 'e' || s[0] == 'E') {
+		s = s[1:]
+		exp = s
+		n := 0
+		if s[0] == '+' || s[0] == '-' {
+			s = s[1:]
+			n++
+			if len(s) == 0 {
+				return numberParts{}, false
+			}
+		}
+		for len(s) > 0 && '0' <= s[0] && s[0] <= '9' {
+			s = s[1:]
+			n++
+		}
+		exp = exp[:n]
+	}
+
+	return numberParts{
+		neg:  neg,
+		intp: intp,
+		frac: bytes.TrimRight(frac, "0"), // Remove unnecessary 0s to the right.
+		exp:  exp,
+	}, true
+}
+
+// normalizeToIntString returns an integer string in normal form without the
+// E-notation for given numberParts. It will return false if it is not an
+// integer or if the exponent exceeds than max/min int value.
+func normalizeToIntString(n numberParts) (string, bool) {
+	intpSize := len(n.intp)
+	fracSize := len(n.frac)
+
+	if intpSize == 0 && fracSize == 0 {
+		return "0", true
+	}
+
+	var exp int
+	if len(n.exp) > 0 {
+		i, err := strconv.ParseInt(string(n.exp), 10, 32)
+		if err != nil {
+			return "", false
+		}
+		exp = int(i)
+	}
+
+	var num []byte
+	if exp >= 0 {
+		// For positive E, shift fraction digits into integer part and also pad
+		// with zeroes as needed.
+
+		// If there are more digits in fraction than the E value, then the
+		// number is not an integer.
+		if fracSize > exp {
+			return "", false
+		}
+
+		// Make sure resulting digits are within max value limit to avoid
+		// unnecessarily constructing a large byte slice that may simply fail
+		// later on.
+		const maxDigits = 20 // Max uint64 value has 20 decimal digits.
+		if intpSize+exp > maxDigits {
+			return "", false
+		}
+
+		// Set cap to make a copy of integer part when appended.
+		num = n.intp[:len(n.intp):len(n.intp)]
+		num = append(num, n.frac...)
+		for i := 0; i < exp-fracSize; i++ {
+			num = append(num, '0')
+		}
+	} else {
+		// For negative E, shift digits in integer part out.
+
+		// If there are fractions, then the number is not an integer.
+		if fracSize > 0 {
+			return "", false
+		}
+
+		// index is where the decimal point will be after adjusting for negative
+		// exponent.
+		index := intpSize + exp
+		if index < 0 {
+			return "", false
+		}
+
+		num = n.intp
+		// If any of the digits being shifted to the right of the decimal point
+		// is non-zero, then the number is not an integer.
+		for i := index; i < intpSize; i++ {
+			if num[i] != '0' {
+				return "", false
+			}
+		}
+		num = num[:index]
+	}
+
+	if n.neg {
+		return "-" + string(num), true
+	}
+	return string(num), true
+}
diff --git a/vendor/google.golang.org/protobuf/internal/encoding/json/decode_string.go b/vendor/google.golang.org/protobuf/internal/encoding/json/decode_string.go
new file mode 100644
index 0000000..f7fea7d
--- /dev/null
+++ b/vendor/google.golang.org/protobuf/internal/encoding/json/decode_string.go
@@ -0,0 +1,91 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package json
+
+import (
+	"strconv"
+	"unicode"
+	"unicode/utf16"
+	"unicode/utf8"
+
+	"google.golang.org/protobuf/internal/strs"
+)
+
+func (d *Decoder) parseString(in []byte) (string, int, error) {
+	in0 := in
+	if len(in) == 0 {
+		return "", 0, ErrUnexpectedEOF
+	}
+	if in[0] != '"' {
+		return "", 0, d.newSyntaxError(d.currPos(), "invalid character %q at start of string", in[0])
+	}
+	in = in[1:]
+	i := indexNeedEscapeInBytes(in)
+	in, out := in[i:], in[:i:i] // set cap to prevent mutations
+	for len(in) > 0 {
+		switch r, n := utf8.DecodeRune(in); {
+		case r == utf8.RuneError && n == 1:
+			return "", 0, d.newSyntaxError(d.currPos(), "invalid UTF-8 in string")
+		case r < ' ':
+			return "", 0, d.newSyntaxError(d.currPos(), "invalid character %q in string", r)
+		case r == '"':
+			in = in[1:]
+			n := len(in0) - len(in)
+			return string(out), n, nil
+		case r == '\\':
+			if len(in) < 2 {
+				return "", 0, ErrUnexpectedEOF
+			}
+			switch r := in[1]; r {
+			case '"', '\\', '/':
+				in, out = in[2:], append(out, r)
+			case 'b':
+				in, out = in[2:], append(out, '\b')
+			case 'f':
+				in, out = in[2:], append(out, '\f')
+			case 'n':
+				in, out = in[2:], append(out, '\n')
+			case 'r':
+				in, out = in[2:], append(out, '\r')
+			case 't':
+				in, out = in[2:], append(out, '\t')
+			case 'u':
+				if len(in) < 6 {
+					return "", 0, ErrUnexpectedEOF
+				}
+				v, err := strconv.ParseUint(string(in[2:6]), 16, 16)
+				if err != nil {
+					return "", 0, d.newSyntaxError(d.currPos(), "invalid escape code %q in string", in[:6])
+				}
+				in = in[6:]
+
+				r := rune(v)
+				if utf16.IsSurrogate(r) {
+					if len(in) < 6 {
+						return "", 0, ErrUnexpectedEOF
+					}
+					v, err := strconv.ParseUint(string(in[2:6]), 16, 16)
+					r = utf16.DecodeRune(r, rune(v))
+					if in[0] != '\\' || in[1] != 'u' ||
+						r == unicode.ReplacementChar || err != nil {
+						return "", 0, d.newSyntaxError(d.currPos(), "invalid escape code %q in string", in[:6])
+					}
+					in = in[6:]
+				}
+				out = append(out, string(r)...)
+			default:
+				return "", 0, d.newSyntaxError(d.currPos(), "invalid escape code %q in string", in[:2])
+			}
+		default:
+			i := indexNeedEscapeInBytes(in[n:])
+			in, out = in[n+i:], append(out, in[:n+i]...)
+		}
+	}
+	return "", 0, ErrUnexpectedEOF
+}
+
+// indexNeedEscapeInBytes returns the index of the character that needs
+// escaping. If no characters need escaping, this returns the input length.
+func indexNeedEscapeInBytes(b []byte) int { return indexNeedEscapeInString(strs.UnsafeString(b)) }
diff --git a/vendor/google.golang.org/protobuf/internal/encoding/json/decode_token.go b/vendor/google.golang.org/protobuf/internal/encoding/json/decode_token.go
new file mode 100644
index 0000000..50578d6
--- /dev/null
+++ b/vendor/google.golang.org/protobuf/internal/encoding/json/decode_token.go
@@ -0,0 +1,192 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package json
+
+import (
+	"bytes"
+	"fmt"
+	"strconv"
+)
+
+// Kind represents a token kind expressible in the JSON format.
+type Kind uint16
+
+const (
+	Invalid Kind = (1 << iota) / 2
+	EOF
+	Null
+	Bool
+	Number
+	String
+	Name
+	ObjectOpen
+	ObjectClose
+	ArrayOpen
+	ArrayClose
+
+	// comma is only for parsing in between tokens and
+	// does not need to be exported.
+	comma
+)
+
+func (k Kind) String() string {
+	switch k {
+	case EOF:
+		return "eof"
+	case Null:
+		return "null"
+	case Bool:
+		return "bool"
+	case Number:
+		return "number"
+	case String:
+		return "string"
+	case ObjectOpen:
+		return "{"
+	case ObjectClose:
+		return "}"
+	case Name:
+		return "name"
+	case ArrayOpen:
+		return "["
+	case ArrayClose:
+		return "]"
+	case comma:
+		return ","
+	}
+	return "<invalid>"
+}
+
+// Token provides a parsed token kind and value.
+//
+// Values are provided by the difference accessor methods. The accessor methods
+// Name, Bool, and ParsedString will panic if called on the wrong kind. There
+// are different accessor methods for the Number kind for converting to the
+// appropriate Go numeric type and those methods have the ok return value.
+type Token struct {
+	// Token kind.
+	kind Kind
+	// pos provides the position of the token in the original input.
+	pos int
+	// raw bytes of the serialized token.
+	// This is a subslice into the original input.
+	raw []byte
+	// boo is parsed boolean value.
+	boo bool
+	// str is parsed string value.
+	str string
+}
+
+// Kind returns the token kind.
+func (t Token) Kind() Kind {
+	return t.kind
+}
+
+// RawString returns the read value in string.
+func (t Token) RawString() string {
+	return string(t.raw)
+}
+
+// Pos returns the token position from the input.
+func (t Token) Pos() int {
+	return t.pos
+}
+
+// Name returns the object name if token is Name, else it panics.
+func (t Token) Name() string {
+	if t.kind == Name {
+		return t.str
+	}
+	panic(fmt.Sprintf("Token is not a Name: %v", t.RawString()))
+}
+
+// Bool returns the bool value if token kind is Bool, else it panics.
+func (t Token) Bool() bool {
+	if t.kind == Bool {
+		return t.boo
+	}
+	panic(fmt.Sprintf("Token is not a Bool: %v", t.RawString()))
+}
+
+// ParsedString returns the string value for a JSON string token or the read
+// value in string if token is not a string.
+func (t Token) ParsedString() string {
+	if t.kind == String {
+		return t.str
+	}
+	panic(fmt.Sprintf("Token is not a String: %v", t.RawString()))
+}
+
+// Float returns the floating-point number if token kind is Number.
+//
+// The floating-point precision is specified by the bitSize parameter: 32 for
+// float32 or 64 for float64. If bitSize=32, the result still has type float64,
+// but it will be convertible to float32 without changing its value. It will
+// return false if the number exceeds the floating point limits for given
+// bitSize.
+func (t Token) Float(bitSize int) (float64, bool) {
+	if t.kind != Number {
+		return 0, false
+	}
+	f, err := strconv.ParseFloat(t.RawString(), bitSize)
+	if err != nil {
+		return 0, false
+	}
+	return f, true
+}
+
+// Int returns the signed integer number if token is Number.
+//
+// The given bitSize specifies the integer type that the result must fit into.
+// It returns false if the number is not an integer value or if the result
+// exceeds the limits for given bitSize.
+func (t Token) Int(bitSize int) (int64, bool) {
+	s, ok := t.getIntStr()
+	if !ok {
+		return 0, false
+	}
+	n, err := strconv.ParseInt(s, 10, bitSize)
+	if err != nil {
+		return 0, false
+	}
+	return n, true
+}
+
+// Uint returns the signed integer number if token is Number.
+//
+// The given bitSize specifies the unsigned integer type that the result must
+// fit into. It returns false if the number is not an unsigned integer value
+// or if the result exceeds the limits for given bitSize.
+func (t Token) Uint(bitSize int) (uint64, bool) {
+	s, ok := t.getIntStr()
+	if !ok {
+		return 0, false
+	}
+	n, err := strconv.ParseUint(s, 10, bitSize)
+	if err != nil {
+		return 0, false
+	}
+	return n, true
+}
+
+func (t Token) getIntStr() (string, bool) {
+	if t.kind != Number {
+		return "", false
+	}
+	parts, ok := parseNumberParts(t.raw)
+	if !ok {
+		return "", false
+	}
+	return normalizeToIntString(parts)
+}
+
+// TokenEquals returns true if given Tokens are equal, else false.
+func TokenEquals(x, y Token) bool {
+	return x.kind == y.kind &&
+		x.pos == y.pos &&
+		bytes.Equal(x.raw, y.raw) &&
+		x.boo == y.boo &&
+		x.str == y.str
+}
diff --git a/vendor/google.golang.org/protobuf/internal/encoding/json/encode.go b/vendor/google.golang.org/protobuf/internal/encoding/json/encode.go
new file mode 100644
index 0000000..fbdf348
--- /dev/null
+++ b/vendor/google.golang.org/protobuf/internal/encoding/json/encode.go
@@ -0,0 +1,276 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package json
+
+import (
+	"math"
+	"math/bits"
+	"strconv"
+	"strings"
+	"unicode/utf8"
+
+	"google.golang.org/protobuf/internal/detrand"
+	"google.golang.org/protobuf/internal/errors"
+)
+
+// kind represents an encoding type.
+type kind uint8
+
+const (
+	_ kind = (1 << iota) / 2
+	name
+	scalar
+	objectOpen
+	objectClose
+	arrayOpen
+	arrayClose
+)
+
+// Encoder provides methods to write out JSON constructs and values. The user is
+// responsible for producing valid sequences of JSON constructs and values.
+type Encoder struct {
+	indent   string
+	lastKind kind
+	indents  []byte
+	out      []byte
+}
+
+// NewEncoder returns an Encoder.
+//
+// If indent is a non-empty string, it causes every entry for an Array or Object
+// to be preceded by the indent and trailed by a newline.
+func NewEncoder(indent string) (*Encoder, error) {
+	e := &Encoder{}
+	if len(indent) > 0 {
+		if strings.Trim(indent, " \t") != "" {
+			return nil, errors.New("indent may only be composed of space or tab characters")
+		}
+		e.indent = indent
+	}
+	return e, nil
+}
+
+// Bytes returns the content of the written bytes.
+func (e *Encoder) Bytes() []byte {
+	return e.out
+}
+
+// WriteNull writes out the null value.
+func (e *Encoder) WriteNull() {
+	e.prepareNext(scalar)
+	e.out = append(e.out, "null"...)
+}
+
+// WriteBool writes out the given boolean value.
+func (e *Encoder) WriteBool(b bool) {
+	e.prepareNext(scalar)
+	if b {
+		e.out = append(e.out, "true"...)
+	} else {
+		e.out = append(e.out, "false"...)
+	}
+}
+
+// WriteString writes out the given string in JSON string value. Returns error
+// if input string contains invalid UTF-8.
+func (e *Encoder) WriteString(s string) error {
+	e.prepareNext(scalar)
+	var err error
+	if e.out, err = appendString(e.out, s); err != nil {
+		return err
+	}
+	return nil
+}
+
+// Sentinel error used for indicating invalid UTF-8.
+var errInvalidUTF8 = errors.New("invalid UTF-8")
+
+func appendString(out []byte, in string) ([]byte, error) {
+	out = append(out, '"')
+	i := indexNeedEscapeInString(in)
+	in, out = in[i:], append(out, in[:i]...)
+	for len(in) > 0 {
+		switch r, n := utf8.DecodeRuneInString(in); {
+		case r == utf8.RuneError && n == 1:
+			return out, errInvalidUTF8
+		case r < ' ' || r == '"' || r == '\\':
+			out = append(out, '\\')
+			switch r {
+			case '"', '\\':
+				out = append(out, byte(r))
+			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')
+			default:
+				out = append(out, 'u')
+				out = append(out, "0000"[1+(bits.Len32(uint32(r))-1)/4:]...)
+				out = strconv.AppendUint(out, uint64(r), 16)
+			}
+			in = in[n:]
+		default:
+			i := indexNeedEscapeInString(in[n:])
+			in, out = in[n+i:], append(out, in[:n+i]...)
+		}
+	}
+	out = append(out, '"')
+	return out, nil
+}
+
+// indexNeedEscapeInString returns the index of the character that needs
+// escaping. If no characters need escaping, this returns the input length.
+func indexNeedEscapeInString(s string) int {
+	for i, r := range s {
+		if r < ' ' || r == '\\' || r == '"' || r == utf8.RuneError {
+			return i
+		}
+	}
+	return len(s)
+}
+
+// WriteFloat writes out the given float and bitSize in JSON number value.
+func (e *Encoder) WriteFloat(n float64, bitSize int) {
+	e.prepareNext(scalar)
+	e.out = appendFloat(e.out, n, bitSize)
+}
+
+// appendFloat formats given float in bitSize, and appends to the given []byte.
+func appendFloat(out []byte, n float64, bitSize int) []byte {
+	switch {
+	case math.IsNaN(n):
+		return append(out, `"NaN"`...)
+	case math.IsInf(n, +1):
+		return append(out, `"Infinity"`...)
+	case math.IsInf(n, -1):
+		return append(out, `"-Infinity"`...)
+	}
+
+	// JSON number formatting logic based on encoding/json.
+	// See floatEncoder.encode for reference.
+	fmt := byte('f')
+	if abs := math.Abs(n); abs != 0 {
+		if bitSize == 64 && (abs < 1e-6 || abs >= 1e21) ||
+			bitSize == 32 && (float32(abs) < 1e-6 || float32(abs) >= 1e21) {
+			fmt = 'e'
+		}
+	}
+	out = strconv.AppendFloat(out, n, fmt, -1, bitSize)
+	if fmt == 'e' {
+		n := len(out)
+		if n >= 4 && out[n-4] == 'e' && out[n-3] == '-' && out[n-2] == '0' {
+			out[n-2] = out[n-1]
+			out = out[:n-1]
+		}
+	}
+	return out
+}
+
+// WriteInt writes out the given signed integer in JSON number value.
+func (e *Encoder) WriteInt(n int64) {
+	e.prepareNext(scalar)
+	e.out = append(e.out, strconv.FormatInt(n, 10)...)
+}
+
+// WriteUint writes out the given unsigned integer in JSON number value.
+func (e *Encoder) WriteUint(n uint64) {
+	e.prepareNext(scalar)
+	e.out = append(e.out, strconv.FormatUint(n, 10)...)
+}
+
+// StartObject writes out the '{' symbol.
+func (e *Encoder) StartObject() {
+	e.prepareNext(objectOpen)
+	e.out = append(e.out, '{')
+}
+
+// EndObject writes out the '}' symbol.
+func (e *Encoder) EndObject() {
+	e.prepareNext(objectClose)
+	e.out = append(e.out, '}')
+}
+
+// WriteName writes out the given string in JSON string value and the name
+// separator ':'. Returns error if input string contains invalid UTF-8, which
+// should not be likely as protobuf field names should be valid.
+func (e *Encoder) WriteName(s string) error {
+	e.prepareNext(name)
+	var err error
+	// Append to output regardless of error.
+	e.out, err = appendString(e.out, s)
+	e.out = append(e.out, ':')
+	return err
+}
+
+// StartArray writes out the '[' symbol.
+func (e *Encoder) StartArray() {
+	e.prepareNext(arrayOpen)
+	e.out = append(e.out, '[')
+}
+
+// EndArray writes out the ']' symbol.
+func (e *Encoder) EndArray() {
+	e.prepareNext(arrayClose)
+	e.out = append(e.out, ']')
+}
+
+// prepareNext adds possible comma and indentation for the next value based
+// on last type and indent option. It also updates lastKind to next.
+func (e *Encoder) prepareNext(next kind) {
+	defer func() {
+		// Set lastKind to next.
+		e.lastKind = next
+	}()
+
+	if len(e.indent) == 0 {
+		// Need to add comma on the following condition.
+		if e.lastKind&(scalar|objectClose|arrayClose) != 0 &&
+			next&(name|scalar|objectOpen|arrayOpen) != 0 {
+			e.out = append(e.out, ',')
+			// For single-line output, add a random extra space after each
+			// comma to make output unstable.
+			if detrand.Bool() {
+				e.out = append(e.out, ' ')
+			}
+		}
+		return
+	}
+
+	switch {
+	case e.lastKind&(objectOpen|arrayOpen) != 0:
+		// If next type is NOT closing, add indent and newline.
+		if next&(objectClose|arrayClose) == 0 {
+			e.indents = append(e.indents, e.indent...)
+			e.out = append(e.out, '\n')
+			e.out = append(e.out, e.indents...)
+		}
+
+	case e.lastKind&(scalar|objectClose|arrayClose) != 0:
+		switch {
+		// If next type is either a value or name, add comma and newline.
+		case next&(name|scalar|objectOpen|arrayOpen) != 0:
+			e.out = append(e.out, ',', '\n')
+
+		// If next type is a closing object or array, adjust indentation.
+		case next&(objectClose|arrayClose) != 0:
+			e.indents = e.indents[:len(e.indents)-len(e.indent)]
+			e.out = append(e.out, '\n')
+		}
+		e.out = append(e.out, e.indents...)
+
+	case e.lastKind&name != 0:
+		e.out = append(e.out, ' ')
+		// For multi-line output, add a random extra space after key: to make
+		// output unstable.
+		if detrand.Bool() {
+			e.out = append(e.out, ' ')
+		}
+	}
+}
diff --git a/vendor/google.golang.org/protobuf/types/known/structpb/struct.pb.go b/vendor/google.golang.org/protobuf/types/known/structpb/struct.pb.go
new file mode 100644
index 0000000..5866905
--- /dev/null
+++ b/vendor/google.golang.org/protobuf/types/known/structpb/struct.pb.go
@@ -0,0 +1,810 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// source: google/protobuf/struct.proto
+
+// Package structpb contains generated types for google/protobuf/struct.proto.
+//
+// The messages (i.e., Value, Struct, and ListValue) defined in struct.proto are
+// used to represent arbitrary JSON. The Value message represents a JSON value,
+// the Struct message represents a JSON object, and the ListValue message
+// represents a JSON array. See https://json.org for more information.
+//
+// The Value, Struct, and ListValue types have generated MarshalJSON and
+// UnmarshalJSON methods such that they serialize JSON equivalent to what the
+// messages themselves represent. Use of these types with the
+// "google.golang.org/protobuf/encoding/protojson" package
+// ensures that they will be serialized as their JSON equivalent.
+//
+//
+// Conversion to and from a Go interface
+//
+// The standard Go "encoding/json" package has functionality to serialize
+// arbitrary types to a large degree. The Value.AsInterface, Struct.AsMap, and
+// ListValue.AsSlice methods can convert the protobuf message representation into
+// a form represented by interface{}, map[string]interface{}, and []interface{}.
+// This form can be used with other packages that operate on such data structures
+// and also directly with the standard json package.
+//
+// In order to convert the interface{}, map[string]interface{}, and []interface{}
+// forms back as Value, Struct, and ListValue messages, use the NewStruct,
+// NewList, and NewValue constructor functions.
+//
+//
+// Example usage
+//
+// Consider the following example JSON object:
+//
+//	{
+//		"firstName": "John",
+//		"lastName": "Smith",
+//		"isAlive": true,
+//		"age": 27,
+//		"address": {
+//			"streetAddress": "21 2nd Street",
+//			"city": "New York",
+//			"state": "NY",
+//			"postalCode": "10021-3100"
+//		},
+//		"phoneNumbers": [
+//			{
+//				"type": "home",
+//				"number": "212 555-1234"
+//			},
+//			{
+//				"type": "office",
+//				"number": "646 555-4567"
+//			}
+//		],
+//		"children": [],
+//		"spouse": null
+//	}
+//
+// To construct a Value message representing the above JSON object:
+//
+//	m, err := structpb.NewValue(map[string]interface{}{
+//		"firstName": "John",
+//		"lastName":  "Smith",
+//		"isAlive":   true,
+//		"age":       27,
+//		"address": map[string]interface{}{
+//			"streetAddress": "21 2nd Street",
+//			"city":          "New York",
+//			"state":         "NY",
+//			"postalCode":    "10021-3100",
+//		},
+//		"phoneNumbers": []interface{}{
+//			map[string]interface{}{
+//				"type":   "home",
+//				"number": "212 555-1234",
+//			},
+//			map[string]interface{}{
+//				"type":   "office",
+//				"number": "646 555-4567",
+//			},
+//		},
+//		"children": []interface{}{},
+//		"spouse":   nil,
+//	})
+//	if err != nil {
+//		... // handle error
+//	}
+//	... // make use of m as a *structpb.Value
+//
+package structpb
+
+import (
+	base64 "encoding/base64"
+	protojson "google.golang.org/protobuf/encoding/protojson"
+	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+	math "math"
+	reflect "reflect"
+	sync "sync"
+	utf8 "unicode/utf8"
+)
+
+// `NullValue` is a singleton enumeration to represent the null value for the
+// `Value` type union.
+//
+//  The JSON representation for `NullValue` is JSON `null`.
+type NullValue int32
+
+const (
+	// Null value.
+	NullValue_NULL_VALUE NullValue = 0
+)
+
+// Enum value maps for NullValue.
+var (
+	NullValue_name = map[int32]string{
+		0: "NULL_VALUE",
+	}
+	NullValue_value = map[string]int32{
+		"NULL_VALUE": 0,
+	}
+)
+
+func (x NullValue) Enum() *NullValue {
+	p := new(NullValue)
+	*p = x
+	return p
+}
+
+func (x NullValue) String() string {
+	return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (NullValue) Descriptor() protoreflect.EnumDescriptor {
+	return file_google_protobuf_struct_proto_enumTypes[0].Descriptor()
+}
+
+func (NullValue) Type() protoreflect.EnumType {
+	return &file_google_protobuf_struct_proto_enumTypes[0]
+}
+
+func (x NullValue) Number() protoreflect.EnumNumber {
+	return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Use NullValue.Descriptor instead.
+func (NullValue) EnumDescriptor() ([]byte, []int) {
+	return file_google_protobuf_struct_proto_rawDescGZIP(), []int{0}
+}
+
+// `Struct` represents a structured data value, consisting of fields
+// which map to dynamically typed values. In some languages, `Struct`
+// might be supported by a native representation. For example, in
+// scripting languages like JS a struct is represented as an
+// object. The details of that representation are described together
+// with the proto support for the language.
+//
+// The JSON representation for `Struct` is JSON object.
+type Struct struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// Unordered map of dynamically typed values.
+	Fields map[string]*Value `protobuf:"bytes,1,rep,name=fields,proto3" json:"fields,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
+}
+
+// NewStruct constructs a Struct from a general-purpose Go map.
+// The map keys must be valid UTF-8.
+// The map values are converted using NewValue.
+func NewStruct(v map[string]interface{}) (*Struct, error) {
+	x := &Struct{Fields: make(map[string]*Value, len(v))}
+	for k, v := range v {
+		if !utf8.ValidString(k) {
+			return nil, protoimpl.X.NewError("invalid UTF-8 in string: %q", k)
+		}
+		var err error
+		x.Fields[k], err = NewValue(v)
+		if err != nil {
+			return nil, err
+		}
+	}
+	return x, nil
+}
+
+// AsMap converts x to a general-purpose Go map.
+// The map values are converted by calling Value.AsInterface.
+func (x *Struct) AsMap() map[string]interface{} {
+	vs := make(map[string]interface{})
+	for k, v := range x.GetFields() {
+		vs[k] = v.AsInterface()
+	}
+	return vs
+}
+
+func (x *Struct) MarshalJSON() ([]byte, error) {
+	return protojson.Marshal(x)
+}
+
+func (x *Struct) UnmarshalJSON(b []byte) error {
+	return protojson.Unmarshal(b, x)
+}
+
+func (x *Struct) Reset() {
+	*x = Struct{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_google_protobuf_struct_proto_msgTypes[0]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *Struct) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Struct) ProtoMessage() {}
+
+func (x *Struct) ProtoReflect() protoreflect.Message {
+	mi := &file_google_protobuf_struct_proto_msgTypes[0]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use Struct.ProtoReflect.Descriptor instead.
+func (*Struct) Descriptor() ([]byte, []int) {
+	return file_google_protobuf_struct_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *Struct) GetFields() map[string]*Value {
+	if x != nil {
+		return x.Fields
+	}
+	return nil
+}
+
+// `Value` represents a dynamically typed value which can be either
+// null, a number, a string, a boolean, a recursive struct value, or a
+// list of values. A producer of value is expected to set one of that
+// variants, absence of any variant indicates an error.
+//
+// The JSON representation for `Value` is JSON value.
+type Value struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// The kind of value.
+	//
+	// Types that are assignable to Kind:
+	//	*Value_NullValue
+	//	*Value_NumberValue
+	//	*Value_StringValue
+	//	*Value_BoolValue
+	//	*Value_StructValue
+	//	*Value_ListValue
+	Kind isValue_Kind `protobuf_oneof:"kind"`
+}
+
+// NewValue constructs a Value from a general-purpose Go interface.
+//
+//	╔════════════════════════╤════════════════════════════════════════════╗
+//	║ Go type                │ Conversion                                 ║
+//	╠════════════════════════╪════════════════════════════════════════════╣
+//	║ nil                    │ stored as NullValue                        ║
+//	║ bool                   │ stored as BoolValue                        ║
+//	║ int, int32, int64      │ stored as NumberValue                      ║
+//	║ uint, uint32, uint64   │ stored as NumberValue                      ║
+//	║ float32, float64       │ stored as NumberValue                      ║
+//	║ string                 │ stored as StringValue; must be valid UTF-8 ║
+//	║ []byte                 │ stored as StringValue; base64-encoded      ║
+//	║ map[string]interface{} │ stored as StructValue                      ║
+//	║ []interface{}          │ stored as ListValue                        ║
+//	╚════════════════════════╧════════════════════════════════════════════╝
+//
+// When converting an int64 or uint64 to a NumberValue, numeric precision loss
+// is possible since they are stored as a float64.
+func NewValue(v interface{}) (*Value, error) {
+	switch v := v.(type) {
+	case nil:
+		return NewNullValue(), nil
+	case bool:
+		return NewBoolValue(v), nil
+	case int:
+		return NewNumberValue(float64(v)), nil
+	case int32:
+		return NewNumberValue(float64(v)), nil
+	case int64:
+		return NewNumberValue(float64(v)), nil
+	case uint:
+		return NewNumberValue(float64(v)), nil
+	case uint32:
+		return NewNumberValue(float64(v)), nil
+	case uint64:
+		return NewNumberValue(float64(v)), nil
+	case float32:
+		return NewNumberValue(float64(v)), nil
+	case float64:
+		return NewNumberValue(float64(v)), nil
+	case string:
+		if !utf8.ValidString(v) {
+			return nil, protoimpl.X.NewError("invalid UTF-8 in string: %q", v)
+		}
+		return NewStringValue(v), nil
+	case []byte:
+		s := base64.StdEncoding.EncodeToString(v)
+		return NewStringValue(s), nil
+	case map[string]interface{}:
+		v2, err := NewStruct(v)
+		if err != nil {
+			return nil, err
+		}
+		return NewStructValue(v2), nil
+	case []interface{}:
+		v2, err := NewList(v)
+		if err != nil {
+			return nil, err
+		}
+		return NewListValue(v2), nil
+	default:
+		return nil, protoimpl.X.NewError("invalid type: %T", v)
+	}
+}
+
+// NewNullValue constructs a new null Value.
+func NewNullValue() *Value {
+	return &Value{Kind: &Value_NullValue{NullValue: NullValue_NULL_VALUE}}
+}
+
+// NewBoolValue constructs a new boolean Value.
+func NewBoolValue(v bool) *Value {
+	return &Value{Kind: &Value_BoolValue{BoolValue: v}}
+}
+
+// NewNumberValue constructs a new number Value.
+func NewNumberValue(v float64) *Value {
+	return &Value{Kind: &Value_NumberValue{NumberValue: v}}
+}
+
+// NewStringValue constructs a new string Value.
+func NewStringValue(v string) *Value {
+	return &Value{Kind: &Value_StringValue{StringValue: v}}
+}
+
+// NewStructValue constructs a new struct Value.
+func NewStructValue(v *Struct) *Value {
+	return &Value{Kind: &Value_StructValue{StructValue: v}}
+}
+
+// NewListValue constructs a new list Value.
+func NewListValue(v *ListValue) *Value {
+	return &Value{Kind: &Value_ListValue{ListValue: v}}
+}
+
+// AsInterface converts x to a general-purpose Go interface.
+//
+// Calling Value.MarshalJSON and "encoding/json".Marshal on this output produce
+// semantically equivalent JSON (assuming no errors occur).
+//
+// Floating-point values (i.e., "NaN", "Infinity", and "-Infinity") are
+// converted as strings to remain compatible with MarshalJSON.
+func (x *Value) AsInterface() interface{} {
+	switch v := x.GetKind().(type) {
+	case *Value_NumberValue:
+		if v != nil {
+			switch {
+			case math.IsNaN(v.NumberValue):
+				return "NaN"
+			case math.IsInf(v.NumberValue, +1):
+				return "Infinity"
+			case math.IsInf(v.NumberValue, -1):
+				return "-Infinity"
+			default:
+				return v.NumberValue
+			}
+		}
+	case *Value_StringValue:
+		if v != nil {
+			return v.StringValue
+		}
+	case *Value_BoolValue:
+		if v != nil {
+			return v.BoolValue
+		}
+	case *Value_StructValue:
+		if v != nil {
+			return v.StructValue.AsMap()
+		}
+	case *Value_ListValue:
+		if v != nil {
+			return v.ListValue.AsSlice()
+		}
+	}
+	return nil
+}
+
+func (x *Value) MarshalJSON() ([]byte, error) {
+	return protojson.Marshal(x)
+}
+
+func (x *Value) UnmarshalJSON(b []byte) error {
+	return protojson.Unmarshal(b, x)
+}
+
+func (x *Value) Reset() {
+	*x = Value{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_google_protobuf_struct_proto_msgTypes[1]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *Value) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Value) ProtoMessage() {}
+
+func (x *Value) ProtoReflect() protoreflect.Message {
+	mi := &file_google_protobuf_struct_proto_msgTypes[1]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use Value.ProtoReflect.Descriptor instead.
+func (*Value) Descriptor() ([]byte, []int) {
+	return file_google_protobuf_struct_proto_rawDescGZIP(), []int{1}
+}
+
+func (m *Value) GetKind() isValue_Kind {
+	if m != nil {
+		return m.Kind
+	}
+	return nil
+}
+
+func (x *Value) GetNullValue() NullValue {
+	if x, ok := x.GetKind().(*Value_NullValue); ok {
+		return x.NullValue
+	}
+	return NullValue_NULL_VALUE
+}
+
+func (x *Value) GetNumberValue() float64 {
+	if x, ok := x.GetKind().(*Value_NumberValue); ok {
+		return x.NumberValue
+	}
+	return 0
+}
+
+func (x *Value) GetStringValue() string {
+	if x, ok := x.GetKind().(*Value_StringValue); ok {
+		return x.StringValue
+	}
+	return ""
+}
+
+func (x *Value) GetBoolValue() bool {
+	if x, ok := x.GetKind().(*Value_BoolValue); ok {
+		return x.BoolValue
+	}
+	return false
+}
+
+func (x *Value) GetStructValue() *Struct {
+	if x, ok := x.GetKind().(*Value_StructValue); ok {
+		return x.StructValue
+	}
+	return nil
+}
+
+func (x *Value) GetListValue() *ListValue {
+	if x, ok := x.GetKind().(*Value_ListValue); ok {
+		return x.ListValue
+	}
+	return nil
+}
+
+type isValue_Kind interface {
+	isValue_Kind()
+}
+
+type Value_NullValue struct {
+	// Represents a null value.
+	NullValue NullValue `protobuf:"varint,1,opt,name=null_value,json=nullValue,proto3,enum=google.protobuf.NullValue,oneof"`
+}
+
+type Value_NumberValue struct {
+	// Represents a double value.
+	NumberValue float64 `protobuf:"fixed64,2,opt,name=number_value,json=numberValue,proto3,oneof"`
+}
+
+type Value_StringValue struct {
+	// Represents a string value.
+	StringValue string `protobuf:"bytes,3,opt,name=string_value,json=stringValue,proto3,oneof"`
+}
+
+type Value_BoolValue struct {
+	// Represents a boolean value.
+	BoolValue bool `protobuf:"varint,4,opt,name=bool_value,json=boolValue,proto3,oneof"`
+}
+
+type Value_StructValue struct {
+	// Represents a structured value.
+	StructValue *Struct `protobuf:"bytes,5,opt,name=struct_value,json=structValue,proto3,oneof"`
+}
+
+type Value_ListValue struct {
+	// Represents a repeated `Value`.
+	ListValue *ListValue `protobuf:"bytes,6,opt,name=list_value,json=listValue,proto3,oneof"`
+}
+
+func (*Value_NullValue) isValue_Kind() {}
+
+func (*Value_NumberValue) isValue_Kind() {}
+
+func (*Value_StringValue) isValue_Kind() {}
+
+func (*Value_BoolValue) isValue_Kind() {}
+
+func (*Value_StructValue) isValue_Kind() {}
+
+func (*Value_ListValue) isValue_Kind() {}
+
+// `ListValue` is a wrapper around a repeated field of values.
+//
+// The JSON representation for `ListValue` is JSON array.
+type ListValue struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// Repeated field of dynamically typed values.
+	Values []*Value `protobuf:"bytes,1,rep,name=values,proto3" json:"values,omitempty"`
+}
+
+// NewList constructs a ListValue from a general-purpose Go slice.
+// The slice elements are converted using NewValue.
+func NewList(v []interface{}) (*ListValue, error) {
+	x := &ListValue{Values: make([]*Value, len(v))}
+	for i, v := range v {
+		var err error
+		x.Values[i], err = NewValue(v)
+		if err != nil {
+			return nil, err
+		}
+	}
+	return x, nil
+}
+
+// AsSlice converts x to a general-purpose Go slice.
+// The slice elements are converted by calling Value.AsInterface.
+func (x *ListValue) AsSlice() []interface{} {
+	vs := make([]interface{}, len(x.GetValues()))
+	for i, v := range x.GetValues() {
+		vs[i] = v.AsInterface()
+	}
+	return vs
+}
+
+func (x *ListValue) MarshalJSON() ([]byte, error) {
+	return protojson.Marshal(x)
+}
+
+func (x *ListValue) UnmarshalJSON(b []byte) error {
+	return protojson.Unmarshal(b, x)
+}
+
+func (x *ListValue) Reset() {
+	*x = ListValue{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_google_protobuf_struct_proto_msgTypes[2]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *ListValue) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ListValue) ProtoMessage() {}
+
+func (x *ListValue) ProtoReflect() protoreflect.Message {
+	mi := &file_google_protobuf_struct_proto_msgTypes[2]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use ListValue.ProtoReflect.Descriptor instead.
+func (*ListValue) Descriptor() ([]byte, []int) {
+	return file_google_protobuf_struct_proto_rawDescGZIP(), []int{2}
+}
+
+func (x *ListValue) GetValues() []*Value {
+	if x != nil {
+		return x.Values
+	}
+	return nil
+}
+
+var File_google_protobuf_struct_proto protoreflect.FileDescriptor
+
+var file_google_protobuf_struct_proto_rawDesc = []byte{
+	0x0a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75,
+	0x66, 0x2f, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0f,
+	0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x22,
+	0x98, 0x01, 0x0a, 0x06, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x12, 0x3b, 0x0a, 0x06, 0x66, 0x69,
+	0x65, 0x6c, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x67, 0x6f, 0x6f,
+	0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72,
+	0x75, 0x63, 0x74, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52,
+	0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x1a, 0x51, 0x0a, 0x0b, 0x46, 0x69, 0x65, 0x6c, 0x64,
+	0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20,
+	0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2c, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75,
+	0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
+	0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52,
+	0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xb2, 0x02, 0x0a, 0x05, 0x56,
+	0x61, 0x6c, 0x75, 0x65, 0x12, 0x3b, 0x0a, 0x0a, 0x6e, 0x75, 0x6c, 0x6c, 0x5f, 0x76, 0x61, 0x6c,
+	0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
+	0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4e, 0x75, 0x6c, 0x6c, 0x56,
+	0x61, 0x6c, 0x75, 0x65, 0x48, 0x00, 0x52, 0x09, 0x6e, 0x75, 0x6c, 0x6c, 0x56, 0x61, 0x6c, 0x75,
+	0x65, 0x12, 0x23, 0x0a, 0x0c, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x5f, 0x76, 0x61, 0x6c, 0x75,
+	0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, 0x48, 0x00, 0x52, 0x0b, 0x6e, 0x75, 0x6d, 0x62, 0x65,
+	0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x23, 0x0a, 0x0c, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67,
+	0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0b,
+	0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x1f, 0x0a, 0x0a, 0x62,
+	0x6f, 0x6f, 0x6c, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x48,
+	0x00, 0x52, 0x09, 0x62, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x3c, 0x0a, 0x0c,
+	0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x05, 0x20, 0x01,
+	0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74,
+	0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x48, 0x00, 0x52, 0x0b, 0x73,
+	0x74, 0x72, 0x75, 0x63, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x3b, 0x0a, 0x0a, 0x6c, 0x69,
+	0x73, 0x74, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a,
+	0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
+	0x2e, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x48, 0x00, 0x52, 0x09, 0x6c, 0x69,
+	0x73, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x06, 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x22,
+	0x3b, 0x0a, 0x09, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x2e, 0x0a, 0x06,
+	0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x67,
+	0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x56,
+	0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x2a, 0x1b, 0x0a, 0x09,
+	0x4e, 0x75, 0x6c, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x0e, 0x0a, 0x0a, 0x4e, 0x55, 0x4c,
+	0x4c, 0x5f, 0x56, 0x41, 0x4c, 0x55, 0x45, 0x10, 0x00, 0x42, 0x7f, 0x0a, 0x13, 0x63, 0x6f, 0x6d,
+	0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
+	0x42, 0x0b, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a,
+	0x2f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2e, 0x6f,
+	0x72, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x79, 0x70, 0x65,
+	0x73, 0x2f, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x2f, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x70, 0x62,
+	0xf8, 0x01, 0x01, 0xa2, 0x02, 0x03, 0x47, 0x50, 0x42, 0xaa, 0x02, 0x1e, 0x47, 0x6f, 0x6f, 0x67,
+	0x6c, 0x65, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x57, 0x65, 0x6c, 0x6c,
+	0x4b, 0x6e, 0x6f, 0x77, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74,
+	0x6f, 0x33,
+}
+
+var (
+	file_google_protobuf_struct_proto_rawDescOnce sync.Once
+	file_google_protobuf_struct_proto_rawDescData = file_google_protobuf_struct_proto_rawDesc
+)
+
+func file_google_protobuf_struct_proto_rawDescGZIP() []byte {
+	file_google_protobuf_struct_proto_rawDescOnce.Do(func() {
+		file_google_protobuf_struct_proto_rawDescData = protoimpl.X.CompressGZIP(file_google_protobuf_struct_proto_rawDescData)
+	})
+	return file_google_protobuf_struct_proto_rawDescData
+}
+
+var file_google_protobuf_struct_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
+var file_google_protobuf_struct_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
+var file_google_protobuf_struct_proto_goTypes = []interface{}{
+	(NullValue)(0),    // 0: google.protobuf.NullValue
+	(*Struct)(nil),    // 1: google.protobuf.Struct
+	(*Value)(nil),     // 2: google.protobuf.Value
+	(*ListValue)(nil), // 3: google.protobuf.ListValue
+	nil,               // 4: google.protobuf.Struct.FieldsEntry
+}
+var file_google_protobuf_struct_proto_depIdxs = []int32{
+	4, // 0: google.protobuf.Struct.fields:type_name -> google.protobuf.Struct.FieldsEntry
+	0, // 1: google.protobuf.Value.null_value:type_name -> google.protobuf.NullValue
+	1, // 2: google.protobuf.Value.struct_value:type_name -> google.protobuf.Struct
+	3, // 3: google.protobuf.Value.list_value:type_name -> google.protobuf.ListValue
+	2, // 4: google.protobuf.ListValue.values:type_name -> google.protobuf.Value
+	2, // 5: google.protobuf.Struct.FieldsEntry.value:type_name -> google.protobuf.Value
+	6, // [6:6] is the sub-list for method output_type
+	6, // [6:6] is the sub-list for method input_type
+	6, // [6:6] is the sub-list for extension type_name
+	6, // [6:6] is the sub-list for extension extendee
+	0, // [0:6] is the sub-list for field type_name
+}
+
+func init() { file_google_protobuf_struct_proto_init() }
+func file_google_protobuf_struct_proto_init() {
+	if File_google_protobuf_struct_proto != nil {
+		return
+	}
+	if !protoimpl.UnsafeEnabled {
+		file_google_protobuf_struct_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*Struct); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_google_protobuf_struct_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*Value); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_google_protobuf_struct_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*ListValue); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+	}
+	file_google_protobuf_struct_proto_msgTypes[1].OneofWrappers = []interface{}{
+		(*Value_NullValue)(nil),
+		(*Value_NumberValue)(nil),
+		(*Value_StringValue)(nil),
+		(*Value_BoolValue)(nil),
+		(*Value_StructValue)(nil),
+		(*Value_ListValue)(nil),
+	}
+	type x struct{}
+	out := protoimpl.TypeBuilder{
+		File: protoimpl.DescBuilder{
+			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+			RawDescriptor: file_google_protobuf_struct_proto_rawDesc,
+			NumEnums:      1,
+			NumMessages:   4,
+			NumExtensions: 0,
+			NumServices:   0,
+		},
+		GoTypes:           file_google_protobuf_struct_proto_goTypes,
+		DependencyIndexes: file_google_protobuf_struct_proto_depIdxs,
+		EnumInfos:         file_google_protobuf_struct_proto_enumTypes,
+		MessageInfos:      file_google_protobuf_struct_proto_msgTypes,
+	}.Build()
+	File_google_protobuf_struct_proto = out.File
+	file_google_protobuf_struct_proto_rawDesc = nil
+	file_google_protobuf_struct_proto_goTypes = nil
+	file_google_protobuf_struct_proto_depIdxs = nil
+}
diff --git a/vendor/google.golang.org/protobuf/types/known/wrapperspb/wrappers.pb.go b/vendor/google.golang.org/protobuf/types/known/wrapperspb/wrappers.pb.go
new file mode 100644
index 0000000..895a804
--- /dev/null
+++ b/vendor/google.golang.org/protobuf/types/known/wrapperspb/wrappers.pb.go
@@ -0,0 +1,760 @@
+// 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.
+
+// Wrappers for primitive (non-message) types. These types are useful
+// for embedding primitives in the `google.protobuf.Any` type and for places
+// where we need to distinguish between the absence of a primitive
+// typed field and its default value.
+//
+// These wrappers have no meaningful use within repeated fields as they lack
+// the ability to detect presence on individual elements.
+// These wrappers have no meaningful use within a map or a oneof since
+// individual entries of a map or fields of a oneof can already detect presence.
+
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// source: google/protobuf/wrappers.proto
+
+package wrapperspb
+
+import (
+	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+	reflect "reflect"
+	sync "sync"
+)
+
+// Wrapper message for `double`.
+//
+// The JSON representation for `DoubleValue` is JSON number.
+type DoubleValue struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// The double value.
+	Value float64 `protobuf:"fixed64,1,opt,name=value,proto3" json:"value,omitempty"`
+}
+
+// Double stores v in a new DoubleValue and returns a pointer to it.
+func Double(v float64) *DoubleValue {
+	return &DoubleValue{Value: v}
+}
+
+func (x *DoubleValue) Reset() {
+	*x = DoubleValue{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_google_protobuf_wrappers_proto_msgTypes[0]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *DoubleValue) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*DoubleValue) ProtoMessage() {}
+
+func (x *DoubleValue) ProtoReflect() protoreflect.Message {
+	mi := &file_google_protobuf_wrappers_proto_msgTypes[0]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use DoubleValue.ProtoReflect.Descriptor instead.
+func (*DoubleValue) Descriptor() ([]byte, []int) {
+	return file_google_protobuf_wrappers_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *DoubleValue) GetValue() float64 {
+	if x != nil {
+		return x.Value
+	}
+	return 0
+}
+
+// Wrapper message for `float`.
+//
+// The JSON representation for `FloatValue` is JSON number.
+type FloatValue struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// The float value.
+	Value float32 `protobuf:"fixed32,1,opt,name=value,proto3" json:"value,omitempty"`
+}
+
+// Float stores v in a new FloatValue and returns a pointer to it.
+func Float(v float32) *FloatValue {
+	return &FloatValue{Value: v}
+}
+
+func (x *FloatValue) Reset() {
+	*x = FloatValue{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_google_protobuf_wrappers_proto_msgTypes[1]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *FloatValue) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*FloatValue) ProtoMessage() {}
+
+func (x *FloatValue) ProtoReflect() protoreflect.Message {
+	mi := &file_google_protobuf_wrappers_proto_msgTypes[1]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use FloatValue.ProtoReflect.Descriptor instead.
+func (*FloatValue) Descriptor() ([]byte, []int) {
+	return file_google_protobuf_wrappers_proto_rawDescGZIP(), []int{1}
+}
+
+func (x *FloatValue) GetValue() float32 {
+	if x != nil {
+		return x.Value
+	}
+	return 0
+}
+
+// Wrapper message for `int64`.
+//
+// The JSON representation for `Int64Value` is JSON string.
+type Int64Value struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// The int64 value.
+	Value int64 `protobuf:"varint,1,opt,name=value,proto3" json:"value,omitempty"`
+}
+
+// Int64 stores v in a new Int64Value and returns a pointer to it.
+func Int64(v int64) *Int64Value {
+	return &Int64Value{Value: v}
+}
+
+func (x *Int64Value) Reset() {
+	*x = Int64Value{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_google_protobuf_wrappers_proto_msgTypes[2]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *Int64Value) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Int64Value) ProtoMessage() {}
+
+func (x *Int64Value) ProtoReflect() protoreflect.Message {
+	mi := &file_google_protobuf_wrappers_proto_msgTypes[2]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use Int64Value.ProtoReflect.Descriptor instead.
+func (*Int64Value) Descriptor() ([]byte, []int) {
+	return file_google_protobuf_wrappers_proto_rawDescGZIP(), []int{2}
+}
+
+func (x *Int64Value) GetValue() int64 {
+	if x != nil {
+		return x.Value
+	}
+	return 0
+}
+
+// Wrapper message for `uint64`.
+//
+// The JSON representation for `UInt64Value` is JSON string.
+type UInt64Value struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// The uint64 value.
+	Value uint64 `protobuf:"varint,1,opt,name=value,proto3" json:"value,omitempty"`
+}
+
+// UInt64 stores v in a new UInt64Value and returns a pointer to it.
+func UInt64(v uint64) *UInt64Value {
+	return &UInt64Value{Value: v}
+}
+
+func (x *UInt64Value) Reset() {
+	*x = UInt64Value{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_google_protobuf_wrappers_proto_msgTypes[3]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *UInt64Value) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*UInt64Value) ProtoMessage() {}
+
+func (x *UInt64Value) ProtoReflect() protoreflect.Message {
+	mi := &file_google_protobuf_wrappers_proto_msgTypes[3]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use UInt64Value.ProtoReflect.Descriptor instead.
+func (*UInt64Value) Descriptor() ([]byte, []int) {
+	return file_google_protobuf_wrappers_proto_rawDescGZIP(), []int{3}
+}
+
+func (x *UInt64Value) GetValue() uint64 {
+	if x != nil {
+		return x.Value
+	}
+	return 0
+}
+
+// Wrapper message for `int32`.
+//
+// The JSON representation for `Int32Value` is JSON number.
+type Int32Value struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// The int32 value.
+	Value int32 `protobuf:"varint,1,opt,name=value,proto3" json:"value,omitempty"`
+}
+
+// Int32 stores v in a new Int32Value and returns a pointer to it.
+func Int32(v int32) *Int32Value {
+	return &Int32Value{Value: v}
+}
+
+func (x *Int32Value) Reset() {
+	*x = Int32Value{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_google_protobuf_wrappers_proto_msgTypes[4]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *Int32Value) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Int32Value) ProtoMessage() {}
+
+func (x *Int32Value) ProtoReflect() protoreflect.Message {
+	mi := &file_google_protobuf_wrappers_proto_msgTypes[4]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use Int32Value.ProtoReflect.Descriptor instead.
+func (*Int32Value) Descriptor() ([]byte, []int) {
+	return file_google_protobuf_wrappers_proto_rawDescGZIP(), []int{4}
+}
+
+func (x *Int32Value) GetValue() int32 {
+	if x != nil {
+		return x.Value
+	}
+	return 0
+}
+
+// Wrapper message for `uint32`.
+//
+// The JSON representation for `UInt32Value` is JSON number.
+type UInt32Value struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// The uint32 value.
+	Value uint32 `protobuf:"varint,1,opt,name=value,proto3" json:"value,omitempty"`
+}
+
+// UInt32 stores v in a new UInt32Value and returns a pointer to it.
+func UInt32(v uint32) *UInt32Value {
+	return &UInt32Value{Value: v}
+}
+
+func (x *UInt32Value) Reset() {
+	*x = UInt32Value{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_google_protobuf_wrappers_proto_msgTypes[5]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *UInt32Value) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*UInt32Value) ProtoMessage() {}
+
+func (x *UInt32Value) ProtoReflect() protoreflect.Message {
+	mi := &file_google_protobuf_wrappers_proto_msgTypes[5]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use UInt32Value.ProtoReflect.Descriptor instead.
+func (*UInt32Value) Descriptor() ([]byte, []int) {
+	return file_google_protobuf_wrappers_proto_rawDescGZIP(), []int{5}
+}
+
+func (x *UInt32Value) GetValue() uint32 {
+	if x != nil {
+		return x.Value
+	}
+	return 0
+}
+
+// Wrapper message for `bool`.
+//
+// The JSON representation for `BoolValue` is JSON `true` and `false`.
+type BoolValue struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// The bool value.
+	Value bool `protobuf:"varint,1,opt,name=value,proto3" json:"value,omitempty"`
+}
+
+// Bool stores v in a new BoolValue and returns a pointer to it.
+func Bool(v bool) *BoolValue {
+	return &BoolValue{Value: v}
+}
+
+func (x *BoolValue) Reset() {
+	*x = BoolValue{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_google_protobuf_wrappers_proto_msgTypes[6]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *BoolValue) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*BoolValue) ProtoMessage() {}
+
+func (x *BoolValue) ProtoReflect() protoreflect.Message {
+	mi := &file_google_protobuf_wrappers_proto_msgTypes[6]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use BoolValue.ProtoReflect.Descriptor instead.
+func (*BoolValue) Descriptor() ([]byte, []int) {
+	return file_google_protobuf_wrappers_proto_rawDescGZIP(), []int{6}
+}
+
+func (x *BoolValue) GetValue() bool {
+	if x != nil {
+		return x.Value
+	}
+	return false
+}
+
+// Wrapper message for `string`.
+//
+// The JSON representation for `StringValue` is JSON string.
+type StringValue struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// The string value.
+	Value string `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"`
+}
+
+// String stores v in a new StringValue and returns a pointer to it.
+func String(v string) *StringValue {
+	return &StringValue{Value: v}
+}
+
+func (x *StringValue) Reset() {
+	*x = StringValue{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_google_protobuf_wrappers_proto_msgTypes[7]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *StringValue) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*StringValue) ProtoMessage() {}
+
+func (x *StringValue) ProtoReflect() protoreflect.Message {
+	mi := &file_google_protobuf_wrappers_proto_msgTypes[7]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use StringValue.ProtoReflect.Descriptor instead.
+func (*StringValue) Descriptor() ([]byte, []int) {
+	return file_google_protobuf_wrappers_proto_rawDescGZIP(), []int{7}
+}
+
+func (x *StringValue) GetValue() string {
+	if x != nil {
+		return x.Value
+	}
+	return ""
+}
+
+// Wrapper message for `bytes`.
+//
+// The JSON representation for `BytesValue` is JSON string.
+type BytesValue struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// The bytes value.
+	Value []byte `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"`
+}
+
+// Bytes stores v in a new BytesValue and returns a pointer to it.
+func Bytes(v []byte) *BytesValue {
+	return &BytesValue{Value: v}
+}
+
+func (x *BytesValue) Reset() {
+	*x = BytesValue{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_google_protobuf_wrappers_proto_msgTypes[8]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *BytesValue) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*BytesValue) ProtoMessage() {}
+
+func (x *BytesValue) ProtoReflect() protoreflect.Message {
+	mi := &file_google_protobuf_wrappers_proto_msgTypes[8]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use BytesValue.ProtoReflect.Descriptor instead.
+func (*BytesValue) Descriptor() ([]byte, []int) {
+	return file_google_protobuf_wrappers_proto_rawDescGZIP(), []int{8}
+}
+
+func (x *BytesValue) GetValue() []byte {
+	if x != nil {
+		return x.Value
+	}
+	return nil
+}
+
+var File_google_protobuf_wrappers_proto protoreflect.FileDescriptor
+
+var file_google_protobuf_wrappers_proto_rawDesc = []byte{
+	0x0a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75,
+	0x66, 0x2f, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+	0x12, 0x0f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75,
+	0x66, 0x22, 0x23, 0x0a, 0x0b, 0x44, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65,
+	0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x01, 0x52,
+	0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x22, 0x0a, 0x0a, 0x46, 0x6c, 0x6f, 0x61, 0x74, 0x56,
+	0x61, 0x6c, 0x75, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20,
+	0x01, 0x28, 0x02, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x22, 0x0a, 0x0a, 0x49, 0x6e,
+	0x74, 0x36, 0x34, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75,
+	0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x23,
+	0x0a, 0x0b, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x14, 0x0a,
+	0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x76, 0x61,
+	0x6c, 0x75, 0x65, 0x22, 0x22, 0x0a, 0x0a, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75,
+	0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05,
+	0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x23, 0x0a, 0x0b, 0x55, 0x49, 0x6e, 0x74, 0x33,
+	0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18,
+	0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x21, 0x0a, 0x09,
+	0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c,
+	0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22,
+	0x23, 0x0a, 0x0b, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x14,
+	0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76,
+	0x61, 0x6c, 0x75, 0x65, 0x22, 0x22, 0x0a, 0x0a, 0x42, 0x79, 0x74, 0x65, 0x73, 0x56, 0x61, 0x6c,
+	0x75, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28,
+	0x0c, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x83, 0x01, 0x0a, 0x13, 0x63, 0x6f, 0x6d,
+	0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
+	0x42, 0x0d, 0x57, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50,
+	0x01, 0x5a, 0x31, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67,
+	0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x79,
+	0x70, 0x65, 0x73, 0x2f, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x2f, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65,
+	0x72, 0x73, 0x70, 0x62, 0xf8, 0x01, 0x01, 0xa2, 0x02, 0x03, 0x47, 0x50, 0x42, 0xaa, 0x02, 0x1e,
+	0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e,
+	0x57, 0x65, 0x6c, 0x6c, 0x4b, 0x6e, 0x6f, 0x77, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x73, 0x62, 0x06,
+	0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+}
+
+var (
+	file_google_protobuf_wrappers_proto_rawDescOnce sync.Once
+	file_google_protobuf_wrappers_proto_rawDescData = file_google_protobuf_wrappers_proto_rawDesc
+)
+
+func file_google_protobuf_wrappers_proto_rawDescGZIP() []byte {
+	file_google_protobuf_wrappers_proto_rawDescOnce.Do(func() {
+		file_google_protobuf_wrappers_proto_rawDescData = protoimpl.X.CompressGZIP(file_google_protobuf_wrappers_proto_rawDescData)
+	})
+	return file_google_protobuf_wrappers_proto_rawDescData
+}
+
+var file_google_protobuf_wrappers_proto_msgTypes = make([]protoimpl.MessageInfo, 9)
+var file_google_protobuf_wrappers_proto_goTypes = []interface{}{
+	(*DoubleValue)(nil), // 0: google.protobuf.DoubleValue
+	(*FloatValue)(nil),  // 1: google.protobuf.FloatValue
+	(*Int64Value)(nil),  // 2: google.protobuf.Int64Value
+	(*UInt64Value)(nil), // 3: google.protobuf.UInt64Value
+	(*Int32Value)(nil),  // 4: google.protobuf.Int32Value
+	(*UInt32Value)(nil), // 5: google.protobuf.UInt32Value
+	(*BoolValue)(nil),   // 6: google.protobuf.BoolValue
+	(*StringValue)(nil), // 7: google.protobuf.StringValue
+	(*BytesValue)(nil),  // 8: google.protobuf.BytesValue
+}
+var file_google_protobuf_wrappers_proto_depIdxs = []int32{
+	0, // [0:0] is the sub-list for method output_type
+	0, // [0:0] is the sub-list for method input_type
+	0, // [0:0] is the sub-list for extension type_name
+	0, // [0:0] is the sub-list for extension extendee
+	0, // [0:0] is the sub-list for field type_name
+}
+
+func init() { file_google_protobuf_wrappers_proto_init() }
+func file_google_protobuf_wrappers_proto_init() {
+	if File_google_protobuf_wrappers_proto != nil {
+		return
+	}
+	if !protoimpl.UnsafeEnabled {
+		file_google_protobuf_wrappers_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*DoubleValue); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_google_protobuf_wrappers_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*FloatValue); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_google_protobuf_wrappers_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*Int64Value); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_google_protobuf_wrappers_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*UInt64Value); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_google_protobuf_wrappers_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*Int32Value); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_google_protobuf_wrappers_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*UInt32Value); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_google_protobuf_wrappers_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*BoolValue); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_google_protobuf_wrappers_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*StringValue); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_google_protobuf_wrappers_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*BytesValue); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+	}
+	type x struct{}
+	out := protoimpl.TypeBuilder{
+		File: protoimpl.DescBuilder{
+			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+			RawDescriptor: file_google_protobuf_wrappers_proto_rawDesc,
+			NumEnums:      0,
+			NumMessages:   9,
+			NumExtensions: 0,
+			NumServices:   0,
+		},
+		GoTypes:           file_google_protobuf_wrappers_proto_goTypes,
+		DependencyIndexes: file_google_protobuf_wrappers_proto_depIdxs,
+		MessageInfos:      file_google_protobuf_wrappers_proto_msgTypes,
+	}.Build()
+	File_google_protobuf_wrappers_proto = out.File
+	file_google_protobuf_wrappers_proto_rawDesc = nil
+	file_google_protobuf_wrappers_proto_goTypes = nil
+	file_google_protobuf_wrappers_proto_depIdxs = nil
+}
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 461fc51..3ff631e 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -2,25 +2,52 @@
 github.com/davecgh/go-spew/spew
 # github.com/golang/protobuf v1.5.2
 ## explicit
+github.com/golang/protobuf/jsonpb
 github.com/golang/protobuf/proto
+github.com/golang/protobuf/protoc-gen-go/descriptor
 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
+# github.com/grpc-ecosystem/go-grpc-middleware v1.3.0
+github.com/grpc-ecosystem/go-grpc-middleware
+github.com/grpc-ecosystem/go-grpc-middleware/tags
+github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing
+github.com/grpc-ecosystem/go-grpc-middleware/util/metautils
+# github.com/jhump/protoreflect v1.10.2
+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/dynamic/grpcdynamic
+github.com/jhump/protoreflect/grpcreflect
+github.com/jhump/protoreflect/internal
+github.com/jhump/protoreflect/internal/codec
 # github.com/opencord/voltha-lib-go/v7 v7.1.5
 ## explicit
+github.com/opencord/voltha-lib-go/v7/pkg/grpc
 github.com/opencord/voltha-lib-go/v7/pkg/log
 github.com/opencord/voltha-lib-go/v7/pkg/probe
 github.com/opencord/voltha-lib-go/v7/pkg/version
 # github.com/opencord/voltha-protos/v5 v5.2.3
 ## explicit
+github.com/opencord/voltha-protos/v5/go/adapter_service
 github.com/opencord/voltha-protos/v5/go/common
+github.com/opencord/voltha-protos/v5/go/core_adapter
+github.com/opencord/voltha-protos/v5/go/core_service
 github.com/opencord/voltha-protos/v5/go/ext/config
 github.com/opencord/voltha-protos/v5/go/extension
 github.com/opencord/voltha-protos/v5/go/health
+github.com/opencord/voltha-protos/v5/go/inter_adapter
+github.com/opencord/voltha-protos/v5/go/olt_inter_adapter_service
 github.com/opencord/voltha-protos/v5/go/omci
+github.com/opencord/voltha-protos/v5/go/onu_inter_adapter_service
 github.com/opencord/voltha-protos/v5/go/openflow_13
+github.com/opencord/voltha-protos/v5/go/openolt
+github.com/opencord/voltha-protos/v5/go/tech_profile
 github.com/opencord/voltha-protos/v5/go/voltha
 # github.com/opentracing/opentracing-go v1.2.0
 github.com/opentracing/opentracing-go
@@ -66,6 +93,7 @@
 go.uber.org/zap/internal/exit
 go.uber.org/zap/zapcore
 # golang.org/x/net v0.0.0-20210614182718-04defd469f4e
+golang.org/x/net/context
 golang.org/x/net/http/httpguts
 golang.org/x/net/http2
 golang.org/x/net/http2/hpack
@@ -115,18 +143,22 @@
 google.golang.org/grpc/metadata
 google.golang.org/grpc/naming
 google.golang.org/grpc/peer
+google.golang.org/grpc/reflection
+google.golang.org/grpc/reflection/grpc_reflection_v1alpha
 google.golang.org/grpc/resolver
 google.golang.org/grpc/serviceconfig
 google.golang.org/grpc/stats
 google.golang.org/grpc/status
 google.golang.org/grpc/tap
 # google.golang.org/protobuf v1.27.1
+google.golang.org/protobuf/encoding/protojson
 google.golang.org/protobuf/encoding/prototext
 google.golang.org/protobuf/encoding/protowire
 google.golang.org/protobuf/internal/descfmt
 google.golang.org/protobuf/internal/descopts
 google.golang.org/protobuf/internal/detrand
 google.golang.org/protobuf/internal/encoding/defval
+google.golang.org/protobuf/internal/encoding/json
 google.golang.org/protobuf/internal/encoding/messageset
 google.golang.org/protobuf/internal/encoding/tag
 google.golang.org/protobuf/internal/encoding/text
@@ -151,7 +183,9 @@
 google.golang.org/protobuf/types/known/anypb
 google.golang.org/protobuf/types/known/durationpb
 google.golang.org/protobuf/types/known/emptypb
+google.golang.org/protobuf/types/known/structpb
 google.golang.org/protobuf/types/known/timestamppb
+google.golang.org/protobuf/types/known/wrapperspb
 # gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
 gopkg.in/yaml.v3
 # github.com/coreos/bbolt v1.3.4 => go.etcd.io/bbolt v1.3.4