From c84ed6813e24b6d64d2eea7e39188ddae11528c6 Mon Sep 17 00:00:00 2001
From: Yuchen Zeng <zyc@google.com>
Date: Wed, 4 May 2016 16:30:11 -0700
Subject: [PATCH] Proto server reflection

---
 BUILD                                         |   24 +
 Makefile                                      |  155 +-
 build.yaml                                    |   27 +
 .../impl/proto_server_reflection_plugin.h     |   74 +
 .../include/grpc++/impl/reflection.grpc.pb.h  |  555 ++++
 .../include/grpc++/impl/reflection.pb.h       | 1128 ++++++++
 .../reflection/proto_server_reflection.cc     |  172 ++
 .../reflection/proto_server_reflection.h      |   92 +
 .../proto_server_reflection_plugin.cc         |   89 +
 extensions/reflection/reflection.grpc.pb.cc   |  245 ++
 extensions/reflection/reflection.pb.cc        | 2448 +++++++++++++++++
 .../grpc/reflection/v1alpha/reflection.proto  |  118 +
 templates/Makefile.template                   |    7 +-
 .../proto_reflection_descriptor_database.cc   |  238 ++
 .../proto_reflection_descriptor_database.h    |   95 +
 test/cpp/util/reflection_debug/Makefile       |   50 +
 .../reflection_debug/reflection_client.cc     |  216 ++
 .../extensions/gen_reflection_proto.sh        |   33 +
 tools/run_tests/sources_and_headers.json      |   43 +
 tools/run_tests/tests.json                    |   21 +
 vsprojects/grpc.sln                           |   21 +
 .../grpc++_reflection.vcxproj                 |  176 ++
 .../grpc++_reflection.vcxproj.filters         |   52 +
 .../reflection_debug_test.vcxproj             |  206 ++
 .../reflection_debug_test.vcxproj.filters     |   32 +
 25 files changed, 6309 insertions(+), 8 deletions(-)
 create mode 100644 extensions/include/grpc++/impl/proto_server_reflection_plugin.h
 create mode 100644 extensions/include/grpc++/impl/reflection.grpc.pb.h
 create mode 100644 extensions/include/grpc++/impl/reflection.pb.h
 create mode 100644 extensions/reflection/proto_server_reflection.cc
 create mode 100644 extensions/reflection/proto_server_reflection.h
 create mode 100644 extensions/reflection/proto_server_reflection_plugin.cc
 create mode 100644 extensions/reflection/reflection.grpc.pb.cc
 create mode 100644 extensions/reflection/reflection.pb.cc
 create mode 100644 src/proto/grpc/reflection/v1alpha/reflection.proto
 create mode 100644 test/cpp/util/proto_reflection_descriptor_database.cc
 create mode 100644 test/cpp/util/proto_reflection_descriptor_database.h
 create mode 100644 test/cpp/util/reflection_debug/Makefile
 create mode 100644 test/cpp/util/reflection_debug/reflection_client.cc
 create mode 100755 tools/codegen/extensions/gen_reflection_proto.sh
 create mode 100644 vsprojects/vcxproj/grpc++_reflection/grpc++_reflection.vcxproj
 create mode 100644 vsprojects/vcxproj/grpc++_reflection/grpc++_reflection.vcxproj.filters
 create mode 100644 vsprojects/vcxproj/test/reflection_debug_test/reflection_debug_test.vcxproj
 create mode 100644 vsprojects/vcxproj/test/reflection_debug_test/reflection_debug_test.vcxproj.filters

diff --git a/BUILD b/BUILD
index b4b10b535e..a885f3ca8c 100644
--- a/BUILD
+++ b/BUILD
@@ -983,6 +983,30 @@ cc_library(
 
 
 
+cc_library(
+  name = "grpc++_reflection",
+  srcs = [
+    "extensions/reflection/proto_server_reflection.h",
+    "extensions/reflection/proto_server_reflection.cc",
+    "extensions/reflection/proto_server_reflection_plugin.cc",
+    "extensions/reflection/reflection.grpc.pb.cc",
+    "extensions/reflection/reflection.pb.cc",
+  ],
+  hdrs = [
+    "extensions/include/grpc++/impl/proto_server_reflection_plugin.h",
+    "extensions/include/grpc++/impl/reflection.grpc.pb.h",
+    "extensions/include/grpc++/impl/reflection.pb.h",
+  ],
+  includes = [
+    "include",
+    ".",
+  ],
+  deps = [
+  ],
+)
+
+
+
 cc_library(
   name = "grpc++_unsecure",
   srcs = [
diff --git a/Makefile b/Makefile
index 922e0b0568..aca0fb2c3f 100644
--- a/Makefile
+++ b/Makefile
@@ -84,6 +84,7 @@ BINDIR = $(BUILDDIR_ABSOLUTE)/bins
 OBJDIR = $(BUILDDIR_ABSOLUTE)/objs
 LIBDIR = $(BUILDDIR_ABSOLUTE)/libs
 GENDIR = $(BUILDDIR_ABSOLUTE)/gens
+EXTDIR = $(BUILDDIR_ABSOLUTE)/extensions
 
 # Configurations
 
@@ -362,7 +363,7 @@ CPPFLAGS += -fPIC
 LDFLAGS += -fPIC
 endif
 
-INCLUDES = . include $(GENDIR)
+INCLUDES = . include $(GENDIR) $(EXTDIR) $(EXTDIR)/include
 LDFLAGS += -Llibs/$(CONFIG)
 
 ifeq ($(SYSTEM),Darwin)
@@ -1033,6 +1034,7 @@ qps_test: $(BINDIR)/$(CONFIG)/qps_test
 qps_worker: $(BINDIR)/$(CONFIG)/qps_worker
 reconnect_interop_client: $(BINDIR)/$(CONFIG)/reconnect_interop_client
 reconnect_interop_server: $(BINDIR)/$(CONFIG)/reconnect_interop_server
+reflection_debug_test: $(BINDIR)/$(CONFIG)/reflection_debug_test
 secure_auth_context_test: $(BINDIR)/$(CONFIG)/secure_auth_context_test
 secure_sync_unary_ping_pong_test: $(BINDIR)/$(CONFIG)/secure_sync_unary_ping_pong_test
 server_crash_test: $(BINDIR)/$(CONFIG)/server_crash_test
@@ -1161,13 +1163,13 @@ static: static_c static_cxx
 static_c: pc_c pc_c_unsecure cache.mk pc_c_zookeeper $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a static_zookeeper_libs
 
 
-static_cxx: pc_cxx pc_cxx_unsecure cache.mk  $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a
+static_cxx: pc_cxx pc_cxx_unsecure cache.mk  $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a
 
 shared: shared_c shared_cxx
 
 shared_c: pc_c pc_c_unsecure cache.mk pc_c_zookeeper $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)gpr$(SHARED_VERSION).$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc$(SHARED_VERSION).$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION).$(SHARED_EXT) shared_zookeeper_libs
 
-shared_cxx: pc_cxx pc_cxx_unsecure cache.mk $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++$(SHARED_VERSION).$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION).$(SHARED_EXT)
+shared_cxx: pc_cxx pc_cxx_unsecure cache.mk $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++$(SHARED_VERSION).$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION).$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION).$(SHARED_EXT)
 
 shared_csharp: shared_c  $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION).$(SHARED_EXT)
 ifeq ($(HAS_ZOOKEEPER),true)
@@ -1399,6 +1401,7 @@ buildtests_cxx: buildtests_zookeeper privatelibs_cxx \
   $(BINDIR)/$(CONFIG)/qps_worker \
   $(BINDIR)/$(CONFIG)/reconnect_interop_client \
   $(BINDIR)/$(CONFIG)/reconnect_interop_server \
+  $(BINDIR)/$(CONFIG)/reflection_debug_test \
   $(BINDIR)/$(CONFIG)/secure_auth_context_test \
   $(BINDIR)/$(CONFIG)/secure_sync_unary_ping_pong_test \
   $(BINDIR)/$(CONFIG)/server_crash_test \
@@ -1728,6 +1731,8 @@ test_cxx: test_zookeeper buildtests_cxx
 	$(Q) $(BINDIR)/$(CONFIG)/qps_openloop_test || ( echo test qps_openloop_test failed ; exit 1 )
 	$(E) "[RUN]     Testing qps_test"
 	$(Q) $(BINDIR)/$(CONFIG)/qps_test || ( echo test qps_test failed ; exit 1 )
+	$(E) "[RUN]     Testing reflection_debug_test"
+	$(Q) $(BINDIR)/$(CONFIG)/reflection_debug_test || ( echo test reflection_debug_test failed ; exit 1 )
 	$(E) "[RUN]     Testing secure_auth_context_test"
 	$(Q) $(BINDIR)/$(CONFIG)/secure_auth_context_test || ( echo test secure_auth_context_test failed ; exit 1 )
 	$(E) "[RUN]     Testing secure_sync_unary_ping_pong_test"
@@ -1808,6 +1813,8 @@ strip-static_cxx: static_cxx
 ifeq ($(CONFIG),opt)
 	$(E) "[STRIP]   Stripping libgrpc++.a"
 	$(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/libgrpc++.a
+	$(E) "[STRIP]   Stripping libgrpc++_reflection.a"
+	$(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a
 	$(E) "[STRIP]   Stripping libgrpc++_unsecure.a"
 	$(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a
 endif
@@ -1830,6 +1837,8 @@ strip-shared_cxx: shared_cxx
 ifeq ($(CONFIG),opt)
 	$(E) "[STRIP]   Stripping $(SHARED_PREFIX)grpc++$(SHARED_VERSION).$(SHARED_EXT)"
 	$(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++$(SHARED_VERSION).$(SHARED_EXT)
+	$(E) "[STRIP]   Stripping $(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION).$(SHARED_EXT)"
+	$(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION).$(SHARED_EXT)
 	$(E) "[STRIP]   Stripping $(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION).$(SHARED_EXT)"
 	$(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION).$(SHARED_EXT)
 endif
@@ -2131,8 +2140,8 @@ install-headers_c:
 
 install-headers_cxx:
 	$(E) "[INSTALL] Installing public C++ headers"
-	$(Q) $(foreach h, $(PUBLIC_HEADERS_CXX), $(INSTALL) -d $(prefix)/$(dir $(h)) && ) exit 0 || exit 1
-	$(Q) $(foreach h, $(PUBLIC_HEADERS_CXX), $(INSTALL) $(h) $(prefix)/$(h) && ) exit 0 || exit 1
+	$(Q) $(foreach h, $(PUBLIC_HEADERS_CXX), $(INSTALL) -d $(prefix)/$(patsubst extensions/%,%,$(dir $(h))) && ) exit 0 || exit 1
+	$(Q) $(foreach h, $(PUBLIC_HEADERS_CXX), $(INSTALL) $(h) $(prefix)/$(patsubst extensions/%,%,$(h)) && ) exit 0 || exit 1
 
 install-static: install-static_c install-static_cxx
 
@@ -2156,6 +2165,9 @@ install-static_cxx: static_cxx strip-static_cxx install-pkg-config_cxx
 	$(E) "[INSTALL] Installing libgrpc++.a"
 	$(Q) $(INSTALL) -d $(prefix)/lib
 	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++.a $(prefix)/lib/libgrpc++.a
+	$(E) "[INSTALL] Installing libgrpc++_reflection.a"
+	$(Q) $(INSTALL) -d $(prefix)/lib
+	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(prefix)/lib/libgrpc++_reflection.a
 	$(E) "[INSTALL] Installing libgrpc++_unsecure.a"
 	$(Q) $(INSTALL) -d $(prefix)/lib
 	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(prefix)/lib/libgrpc++_unsecure.a
@@ -2217,6 +2229,15 @@ ifeq ($(SYSTEM),MINGW32)
 else ifneq ($(SYSTEM),Darwin)
 	$(Q) ln -sf $(SHARED_PREFIX)grpc++$(SHARED_VERSION).$(SHARED_EXT) $(prefix)/lib/libgrpc++.so.0
 	$(Q) ln -sf $(SHARED_PREFIX)grpc++$(SHARED_VERSION).$(SHARED_EXT) $(prefix)/lib/libgrpc++.so
+endif
+	$(E) "[INSTALL] Installing $(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION).$(SHARED_EXT)"
+	$(Q) $(INSTALL) -d $(prefix)/lib
+	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION).$(SHARED_EXT) $(prefix)/lib/$(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION).$(SHARED_EXT)
+ifeq ($(SYSTEM),MINGW32)
+	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++_reflection-imp.a $(prefix)/lib/libgrpc++_reflection-imp.a
+else ifneq ($(SYSTEM),Darwin)
+	$(Q) ln -sf $(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION).$(SHARED_EXT) $(prefix)/lib/libgrpc++_reflection.so.0
+	$(Q) ln -sf $(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION).$(SHARED_EXT) $(prefix)/lib/libgrpc++_reflection.so
 endif
 	$(E) "[INSTALL] Installing $(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION).$(SHARED_EXT)"
 	$(Q) $(INSTALL) -d $(prefix)/lib
@@ -3343,6 +3364,80 @@ endif
 endif
 
 
+LIBGRPC++_REFLECTION_SRC = \
+    extensions/reflection/proto_server_reflection.cc \
+    extensions/reflection/proto_server_reflection_plugin.cc \
+    extensions/reflection/reflection.grpc.pb.cc \
+    extensions/reflection/reflection.pb.cc \
+
+PUBLIC_HEADERS_CXX += \
+    extensions/include/grpc++/impl/proto_server_reflection_plugin.h \
+    extensions/include/grpc++/impl/reflection.grpc.pb.h \
+    extensions/include/grpc++/impl/reflection.pb.h \
+
+LIBGRPC++_REFLECTION_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC++_REFLECTION_SRC))))
+
+
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure libraries if you don't have OpenSSL.
+
+$(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a: openssl_dep_error
+
+$(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION).$(SHARED_EXT): openssl_dep_error
+
+else
+
+ifeq ($(NO_PROTOBUF),true)
+
+# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay.
+
+$(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a: protobuf_dep_error
+
+$(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION).$(SHARED_EXT): protobuf_dep_error
+
+else
+
+$(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(PROTOBUF_DEP) $(LIBGRPC++_REFLECTION_OBJS) 
+	$(E) "[AR]      Creating $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a
+	$(Q) $(AR) $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBGRPC++_REFLECTION_OBJS) 
+ifeq ($(SYSTEM),Darwin)
+	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a
+endif
+
+
+
+ifeq ($(SYSTEM),MINGW32)
+$(LIBDIR)/$(CONFIG)/grpc++_reflection$(SHARED_VERSION).$(SHARED_EXT): $(LIBGRPC++_REFLECTION_OBJS)  $(ZLIB_DEP) $(PROTOBUF_DEP) $(OPENSSL_DEP)
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared grpc++_reflection.def -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc++_reflection$(SHARED_VERSION).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc++_reflection$(SHARED_VERSION)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc++_reflection$(SHARED_VERSION).$(SHARED_EXT) $(LIBGRPC++_REFLECTION_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF)
+else
+$(LIBDIR)/$(CONFIG)/libgrpc++_reflection$(SHARED_VERSION).$(SHARED_EXT): $(LIBGRPC++_REFLECTION_OBJS)  $(ZLIB_DEP) $(PROTOBUF_DEP) $(OPENSSL_DEP)
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+ifeq ($(SYSTEM),Darwin)
+	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION).$(SHARED_EXT) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc++_reflection$(SHARED_VERSION).$(SHARED_EXT) $(LIBGRPC++_REFLECTION_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF)
+else
+	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc++_reflection.so.0 -o $(LIBDIR)/$(CONFIG)/libgrpc++_reflection$(SHARED_VERSION).$(SHARED_EXT) $(LIBGRPC++_REFLECTION_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF)
+	$(Q) ln -sf $(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION).$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc++_reflection$(SHARED_VERSION).so.0
+	$(Q) ln -sf $(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION).$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc++_reflection$(SHARED_VERSION).so
+endif
+endif
+
+endif
+
+endif
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(LIBGRPC++_REFLECTION_OBJS:.o=.dep)
+endif
+endif
+
+
 LIBGRPC++_TEST_CONFIG_SRC = \
     test/cpp/util/test_config.cc \
 
@@ -11393,6 +11488,52 @@ endif
 $(OBJDIR)/$(CONFIG)/test/cpp/interop/reconnect_interop_server.o: $(GENDIR)/src/proto/grpc/testing/empty.pb.cc $(GENDIR)/src/proto/grpc/testing/empty.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/test.pb.cc $(GENDIR)/src/proto/grpc/testing/test.grpc.pb.cc
 
 
+REFLECTION_DEBUG_TEST_SRC = \
+    test/cpp/util/proto_reflection_descriptor_database.cc \
+    test/cpp/util/reflection_debug/reflection_client.cc \
+
+REFLECTION_DEBUG_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(REFLECTION_DEBUG_TEST_SRC))))
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
+$(BINDIR)/$(CONFIG)/reflection_debug_test: openssl_dep_error
+
+else
+
+
+
+
+ifeq ($(NO_PROTOBUF),true)
+
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+
+$(BINDIR)/$(CONFIG)/reflection_debug_test: protobuf_dep_error
+
+else
+
+$(BINDIR)/$(CONFIG)/reflection_debug_test: $(PROTOBUF_DEP) $(REFLECTION_DEBUG_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(LDXX) $(LDFLAGS) $(REFLECTION_DEBUG_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/reflection_debug_test
+
+endif
+
+endif
+
+$(OBJDIR)/$(CONFIG)/test/cpp/util/proto_reflection_descriptor_database.o:  $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+$(OBJDIR)/$(CONFIG)/test/cpp/util/reflection_debug/reflection_client.o:  $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+deps_reflection_debug_test: $(REFLECTION_DEBUG_TEST_OBJS:.o=.dep)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(REFLECTION_DEBUG_TEST_OBJS:.o=.dep)
+endif
+endif
+
+
 SECURE_AUTH_CONTEXT_TEST_SRC = \
     test/cpp/common/secure_auth_context_test.cc \
 
@@ -14311,6 +14452,10 @@ ifneq ($(OPENSSL_DEP),)
 # This is to ensure the embedded OpenSSL is built beforehand, properly
 # installing headers to their final destination on the drive. We need this
 # otherwise parallel compilation will fail if a source is compiled first.
+extensions/reflection/proto_server_reflection.cc: $(OPENSSL_DEP)
+extensions/reflection/proto_server_reflection_plugin.cc: $(OPENSSL_DEP)
+extensions/reflection/reflection.grpc.pb.cc: $(OPENSSL_DEP)
+extensions/reflection/reflection.pb.cc: $(OPENSSL_DEP)
 src/core/ext/transport/chttp2/client/secure/secure_channel_create.c: $(OPENSSL_DEP)
 src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c: $(OPENSSL_DEP)
 src/core/lib/http/httpcli_security_connector.c: $(OPENSSL_DEP)
diff --git a/build.yaml b/build.yaml
index 441752dc3d..deae7444dc 100644
--- a/build.yaml
+++ b/build.yaml
@@ -883,6 +883,20 @@ libs:
   - grpc++_codegen
   secure: check
   vs_project_guid: '{C187A093-A0FE-489D-A40A-6E33DE0F9FEB}'
+- name: grpc++_reflection
+  build: all
+  language: c++
+  public_headers:
+  - extensions/include/grpc++/impl/proto_server_reflection_plugin.h
+  - extensions/include/grpc++/impl/reflection.grpc.pb.h
+  - extensions/include/grpc++/impl/reflection.pb.h
+  headers:
+  - extensions/reflection/proto_server_reflection.h
+  src:
+  - extensions/reflection/proto_server_reflection.cc
+  - extensions/reflection/proto_server_reflection_plugin.cc
+  - extensions/reflection/reflection.grpc.pb.cc
+  - extensions/reflection/reflection.pb.cc
 - name: grpc++_test_config
   build: private
   language: c++
@@ -2884,6 +2898,19 @@ targets:
   - gpr_test_util
   - gpr
   - grpc++_test_config
+- name: reflection_debug_test
+  build: test
+  language: c++
+  headers:
+  - test/cpp/util/proto_reflection_descriptor_database.h
+  src:
+  - test/cpp/util/proto_reflection_descriptor_database.cc
+  - test/cpp/util/reflection_debug/reflection_client.cc
+  deps:
+  - grpc++_reflection
+  - grpc++
+  - grpc
+  - gpr
 - name: secure_auth_context_test
   gtest: true
   build: test
diff --git a/extensions/include/grpc++/impl/proto_server_reflection_plugin.h b/extensions/include/grpc++/impl/proto_server_reflection_plugin.h
new file mode 100644
index 0000000000..adc6eb7bc3
--- /dev/null
+++ b/extensions/include/grpc++/impl/proto_server_reflection_plugin.h
@@ -0,0 +1,74 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * 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.
+ *
+ */
+
+#ifndef GRPCXX_PROTO_SERVER_REFLECTION_PLUGIN_H
+#define GRPCXX_PROTO_SERVER_REFLECTION_PLUGIN_H
+
+#include <memory>
+
+#include <grpc++/impl/server_builder_plugin.h>
+#include <grpc++/support/config.h>
+
+namespace grpc {
+class ServerInitializer;
+class ProtoServerReflection;
+}  // namespace grpc
+
+namespace grpc {
+namespace reflection {
+
+class ProtoServerReflectionPlugin : public ::grpc::ServerBuilderPlugin {
+ public:
+  ProtoServerReflectionPlugin();
+  ::grpc::string name() GRPC_OVERRIDE;
+  void InitServer(::grpc::ServerInitializer* si) GRPC_OVERRIDE;
+  void Finish(::grpc::ServerInitializer* si) GRPC_OVERRIDE;
+  void ChangeArguments(const ::grpc::string& name, void* value) GRPC_OVERRIDE;
+  bool has_async_methods() const GRPC_OVERRIDE;
+  bool has_sync_methods() const GRPC_OVERRIDE;
+
+ private:
+  std::shared_ptr<::grpc::ProtoServerReflection> reflection_service;
+};
+
+std::unique_ptr<::grpc::ServerBuilderPlugin> CreateProtoReflection() {
+  return std::unique_ptr<::grpc::ServerBuilderPlugin>(
+      new ProtoServerReflectionPlugin());
+}
+
+void grpc_AddServerBuilderPlugin_reflection();
+
+}  // namespace reflection
+}  // namespace grpc
+
+#endif  // GRPCXX_PROTO_SERVER_REFLECTION_PLUGIN_H
diff --git a/extensions/include/grpc++/impl/reflection.grpc.pb.h b/extensions/include/grpc++/impl/reflection.grpc.pb.h
new file mode 100644
index 0000000000..f600929636
--- /dev/null
+++ b/extensions/include/grpc++/impl/reflection.grpc.pb.h
@@ -0,0 +1,555 @@
+// Generated by the gRPC protobuf plugin.
+// If you make any local change, they will be lost.
+// source: reflection.proto
+#ifndef GRPC_reflection_2eproto__INCLUDED
+#define GRPC_reflection_2eproto__INCLUDED
+
+#include <grpc++/impl/reflection.pb.h>
+
+#include <grpc++/impl/codegen/async_stream.h>
+#include <grpc++/impl/codegen/async_unary_call.h>
+#include <grpc++/impl/codegen/proto_utils.h>
+#include <grpc++/impl/codegen/rpc_method.h>
+#include <grpc++/impl/codegen/service_type.h>
+#include <grpc++/impl/codegen/status.h>
+#include <grpc++/impl/codegen/stub_options.h>
+#include <grpc++/impl/codegen/sync_stream.h>
+
+namespace grpc {
+class CompletionQueue;
+class Channel;
+class RpcService;
+class ServerCompletionQueue;
+class ServerContext;
+}  // namespace grpc
+
+namespace grpc {
+namespace reflection {
+namespace v1alpha {
+
+class ServerReflection GRPC_FINAL {
+ public:
+  class StubInterface {
+   public:
+    virtual ~StubInterface() {}
+    virtual ::grpc::Status ListService(
+        ::grpc::ClientContext* context,
+        const ::grpc::reflection::v1alpha::EmptyRequest& request,
+        ::grpc::reflection::v1alpha::ListServiceResponse* response) = 0;
+    std::unique_ptr<::grpc::ClientAsyncResponseReaderInterface<
+        ::grpc::reflection::v1alpha::ListServiceResponse>>
+    AsyncListService(::grpc::ClientContext* context,
+                     const ::grpc::reflection::v1alpha::EmptyRequest& request,
+                     ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr<::grpc::ClientAsyncResponseReaderInterface<
+          ::grpc::reflection::v1alpha::ListServiceResponse>>(
+          AsyncListServiceRaw(context, request, cq));
+    }
+    virtual ::grpc::Status GetFileByName(
+        ::grpc::ClientContext* context,
+        const ::grpc::reflection::v1alpha::FileNameRequest& request,
+        ::grpc::reflection::v1alpha::FileDescriptorProtoResponse* response) = 0;
+    std::unique_ptr<::grpc::ClientAsyncResponseReaderInterface<
+        ::grpc::reflection::v1alpha::FileDescriptorProtoResponse>>
+    AsyncGetFileByName(
+        ::grpc::ClientContext* context,
+        const ::grpc::reflection::v1alpha::FileNameRequest& request,
+        ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr<::grpc::ClientAsyncResponseReaderInterface<
+          ::grpc::reflection::v1alpha::FileDescriptorProtoResponse>>(
+          AsyncGetFileByNameRaw(context, request, cq));
+    }
+    virtual ::grpc::Status GetFileContainingSymbol(
+        ::grpc::ClientContext* context,
+        const ::grpc::reflection::v1alpha::SymbolRequest& request,
+        ::grpc::reflection::v1alpha::FileDescriptorProtoResponse* response) = 0;
+    std::unique_ptr<::grpc::ClientAsyncResponseReaderInterface<
+        ::grpc::reflection::v1alpha::FileDescriptorProtoResponse>>
+    AsyncGetFileContainingSymbol(
+        ::grpc::ClientContext* context,
+        const ::grpc::reflection::v1alpha::SymbolRequest& request,
+        ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr<::grpc::ClientAsyncResponseReaderInterface<
+          ::grpc::reflection::v1alpha::FileDescriptorProtoResponse>>(
+          AsyncGetFileContainingSymbolRaw(context, request, cq));
+    }
+    virtual ::grpc::Status GetFileContainingExtension(
+        ::grpc::ClientContext* context,
+        const ::grpc::reflection::v1alpha::ExtensionRequest& request,
+        ::grpc::reflection::v1alpha::FileDescriptorProtoResponse* response) = 0;
+    std::unique_ptr<::grpc::ClientAsyncResponseReaderInterface<
+        ::grpc::reflection::v1alpha::FileDescriptorProtoResponse>>
+    AsyncGetFileContainingExtension(
+        ::grpc::ClientContext* context,
+        const ::grpc::reflection::v1alpha::ExtensionRequest& request,
+        ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr<::grpc::ClientAsyncResponseReaderInterface<
+          ::grpc::reflection::v1alpha::FileDescriptorProtoResponse>>(
+          AsyncGetFileContainingExtensionRaw(context, request, cq));
+    }
+    virtual ::grpc::Status GetAllExtensionNumbers(
+        ::grpc::ClientContext* context,
+        const ::grpc::reflection::v1alpha::TypeRequest& request,
+        ::grpc::reflection::v1alpha::ExtensionNumberResponse* response) = 0;
+    std::unique_ptr<::grpc::ClientAsyncResponseReaderInterface<
+        ::grpc::reflection::v1alpha::ExtensionNumberResponse>>
+    AsyncGetAllExtensionNumbers(
+        ::grpc::ClientContext* context,
+        const ::grpc::reflection::v1alpha::TypeRequest& request,
+        ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr<::grpc::ClientAsyncResponseReaderInterface<
+          ::grpc::reflection::v1alpha::ExtensionNumberResponse>>(
+          AsyncGetAllExtensionNumbersRaw(context, request, cq));
+    }
+
+   private:
+    virtual ::grpc::ClientAsyncResponseReaderInterface<
+        ::grpc::reflection::v1alpha::ListServiceResponse>*
+    AsyncListServiceRaw(
+        ::grpc::ClientContext* context,
+        const ::grpc::reflection::v1alpha::EmptyRequest& request,
+        ::grpc::CompletionQueue* cq) = 0;
+    virtual ::grpc::ClientAsyncResponseReaderInterface<
+        ::grpc::reflection::v1alpha::FileDescriptorProtoResponse>*
+    AsyncGetFileByNameRaw(
+        ::grpc::ClientContext* context,
+        const ::grpc::reflection::v1alpha::FileNameRequest& request,
+        ::grpc::CompletionQueue* cq) = 0;
+    virtual ::grpc::ClientAsyncResponseReaderInterface<
+        ::grpc::reflection::v1alpha::FileDescriptorProtoResponse>*
+    AsyncGetFileContainingSymbolRaw(
+        ::grpc::ClientContext* context,
+        const ::grpc::reflection::v1alpha::SymbolRequest& request,
+        ::grpc::CompletionQueue* cq) = 0;
+    virtual ::grpc::ClientAsyncResponseReaderInterface<
+        ::grpc::reflection::v1alpha::FileDescriptorProtoResponse>*
+    AsyncGetFileContainingExtensionRaw(
+        ::grpc::ClientContext* context,
+        const ::grpc::reflection::v1alpha::ExtensionRequest& request,
+        ::grpc::CompletionQueue* cq) = 0;
+    virtual ::grpc::ClientAsyncResponseReaderInterface<
+        ::grpc::reflection::v1alpha::ExtensionNumberResponse>*
+    AsyncGetAllExtensionNumbersRaw(
+        ::grpc::ClientContext* context,
+        const ::grpc::reflection::v1alpha::TypeRequest& request,
+        ::grpc::CompletionQueue* cq) = 0;
+  };
+  class Stub GRPC_FINAL : public StubInterface {
+   public:
+    Stub(const std::shared_ptr<::grpc::ChannelInterface>& channel);
+    ::grpc::Status ListService(
+        ::grpc::ClientContext* context,
+        const ::grpc::reflection::v1alpha::EmptyRequest& request,
+        ::grpc::reflection::v1alpha::ListServiceResponse* response)
+        GRPC_OVERRIDE;
+    std::unique_ptr<::grpc::ClientAsyncResponseReader<
+        ::grpc::reflection::v1alpha::ListServiceResponse>>
+    AsyncListService(::grpc::ClientContext* context,
+                     const ::grpc::reflection::v1alpha::EmptyRequest& request,
+                     ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr<::grpc::ClientAsyncResponseReader<
+          ::grpc::reflection::v1alpha::ListServiceResponse>>(
+          AsyncListServiceRaw(context, request, cq));
+    }
+    ::grpc::Status GetFileByName(
+        ::grpc::ClientContext* context,
+        const ::grpc::reflection::v1alpha::FileNameRequest& request,
+        ::grpc::reflection::v1alpha::FileDescriptorProtoResponse* response)
+        GRPC_OVERRIDE;
+    std::unique_ptr<::grpc::ClientAsyncResponseReader<
+        ::grpc::reflection::v1alpha::FileDescriptorProtoResponse>>
+    AsyncGetFileByName(
+        ::grpc::ClientContext* context,
+        const ::grpc::reflection::v1alpha::FileNameRequest& request,
+        ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr<::grpc::ClientAsyncResponseReader<
+          ::grpc::reflection::v1alpha::FileDescriptorProtoResponse>>(
+          AsyncGetFileByNameRaw(context, request, cq));
+    }
+    ::grpc::Status GetFileContainingSymbol(
+        ::grpc::ClientContext* context,
+        const ::grpc::reflection::v1alpha::SymbolRequest& request,
+        ::grpc::reflection::v1alpha::FileDescriptorProtoResponse* response)
+        GRPC_OVERRIDE;
+    std::unique_ptr<::grpc::ClientAsyncResponseReader<
+        ::grpc::reflection::v1alpha::FileDescriptorProtoResponse>>
+    AsyncGetFileContainingSymbol(
+        ::grpc::ClientContext* context,
+        const ::grpc::reflection::v1alpha::SymbolRequest& request,
+        ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr<::grpc::ClientAsyncResponseReader<
+          ::grpc::reflection::v1alpha::FileDescriptorProtoResponse>>(
+          AsyncGetFileContainingSymbolRaw(context, request, cq));
+    }
+    ::grpc::Status GetFileContainingExtension(
+        ::grpc::ClientContext* context,
+        const ::grpc::reflection::v1alpha::ExtensionRequest& request,
+        ::grpc::reflection::v1alpha::FileDescriptorProtoResponse* response)
+        GRPC_OVERRIDE;
+    std::unique_ptr<::grpc::ClientAsyncResponseReader<
+        ::grpc::reflection::v1alpha::FileDescriptorProtoResponse>>
+    AsyncGetFileContainingExtension(
+        ::grpc::ClientContext* context,
+        const ::grpc::reflection::v1alpha::ExtensionRequest& request,
+        ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr<::grpc::ClientAsyncResponseReader<
+          ::grpc::reflection::v1alpha::FileDescriptorProtoResponse>>(
+          AsyncGetFileContainingExtensionRaw(context, request, cq));
+    }
+    ::grpc::Status GetAllExtensionNumbers(
+        ::grpc::ClientContext* context,
+        const ::grpc::reflection::v1alpha::TypeRequest& request,
+        ::grpc::reflection::v1alpha::ExtensionNumberResponse* response)
+        GRPC_OVERRIDE;
+    std::unique_ptr<::grpc::ClientAsyncResponseReader<
+        ::grpc::reflection::v1alpha::ExtensionNumberResponse>>
+    AsyncGetAllExtensionNumbers(
+        ::grpc::ClientContext* context,
+        const ::grpc::reflection::v1alpha::TypeRequest& request,
+        ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr<::grpc::ClientAsyncResponseReader<
+          ::grpc::reflection::v1alpha::ExtensionNumberResponse>>(
+          AsyncGetAllExtensionNumbersRaw(context, request, cq));
+    }
+
+   private:
+    std::shared_ptr<::grpc::ChannelInterface> channel_;
+    ::grpc::ClientAsyncResponseReader<
+        ::grpc::reflection::v1alpha::ListServiceResponse>*
+    AsyncListServiceRaw(
+        ::grpc::ClientContext* context,
+        const ::grpc::reflection::v1alpha::EmptyRequest& request,
+        ::grpc::CompletionQueue* cq) GRPC_OVERRIDE;
+    ::grpc::ClientAsyncResponseReader<
+        ::grpc::reflection::v1alpha::FileDescriptorProtoResponse>*
+    AsyncGetFileByNameRaw(
+        ::grpc::ClientContext* context,
+        const ::grpc::reflection::v1alpha::FileNameRequest& request,
+        ::grpc::CompletionQueue* cq) GRPC_OVERRIDE;
+    ::grpc::ClientAsyncResponseReader<
+        ::grpc::reflection::v1alpha::FileDescriptorProtoResponse>*
+    AsyncGetFileContainingSymbolRaw(
+        ::grpc::ClientContext* context,
+        const ::grpc::reflection::v1alpha::SymbolRequest& request,
+        ::grpc::CompletionQueue* cq) GRPC_OVERRIDE;
+    ::grpc::ClientAsyncResponseReader<
+        ::grpc::reflection::v1alpha::FileDescriptorProtoResponse>*
+    AsyncGetFileContainingExtensionRaw(
+        ::grpc::ClientContext* context,
+        const ::grpc::reflection::v1alpha::ExtensionRequest& request,
+        ::grpc::CompletionQueue* cq) GRPC_OVERRIDE;
+    ::grpc::ClientAsyncResponseReader<
+        ::grpc::reflection::v1alpha::ExtensionNumberResponse>*
+    AsyncGetAllExtensionNumbersRaw(
+        ::grpc::ClientContext* context,
+        const ::grpc::reflection::v1alpha::TypeRequest& request,
+        ::grpc::CompletionQueue* cq) GRPC_OVERRIDE;
+    const ::grpc::RpcMethod rpcmethod_ListService_;
+    const ::grpc::RpcMethod rpcmethod_GetFileByName_;
+    const ::grpc::RpcMethod rpcmethod_GetFileContainingSymbol_;
+    const ::grpc::RpcMethod rpcmethod_GetFileContainingExtension_;
+    const ::grpc::RpcMethod rpcmethod_GetAllExtensionNumbers_;
+  };
+  static std::unique_ptr<Stub> NewStub(
+      const std::shared_ptr<::grpc::ChannelInterface>& channel,
+      const ::grpc::StubOptions& options = ::grpc::StubOptions());
+
+  class Service : public ::grpc::Service {
+   public:
+    Service();
+    virtual ~Service();
+    virtual ::grpc::Status ListService(
+        ::grpc::ServerContext* context,
+        const ::grpc::reflection::v1alpha::EmptyRequest* request,
+        ::grpc::reflection::v1alpha::ListServiceResponse* response);
+    virtual ::grpc::Status GetFileByName(
+        ::grpc::ServerContext* context,
+        const ::grpc::reflection::v1alpha::FileNameRequest* request,
+        ::grpc::reflection::v1alpha::FileDescriptorProtoResponse* response);
+    virtual ::grpc::Status GetFileContainingSymbol(
+        ::grpc::ServerContext* context,
+        const ::grpc::reflection::v1alpha::SymbolRequest* request,
+        ::grpc::reflection::v1alpha::FileDescriptorProtoResponse* response);
+    virtual ::grpc::Status GetFileContainingExtension(
+        ::grpc::ServerContext* context,
+        const ::grpc::reflection::v1alpha::ExtensionRequest* request,
+        ::grpc::reflection::v1alpha::FileDescriptorProtoResponse* response);
+    virtual ::grpc::Status GetAllExtensionNumbers(
+        ::grpc::ServerContext* context,
+        const ::grpc::reflection::v1alpha::TypeRequest* request,
+        ::grpc::reflection::v1alpha::ExtensionNumberResponse* response);
+  };
+  template <class BaseClass>
+  class WithAsyncMethod_ListService : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(Service* service) {}
+
+   public:
+    WithAsyncMethod_ListService() { ::grpc::Service::MarkMethodAsync(0); }
+    ~WithAsyncMethod_ListService() GRPC_OVERRIDE {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status ListService(
+        ::grpc::ServerContext* context,
+        const ::grpc::reflection::v1alpha::EmptyRequest* request,
+        ::grpc::reflection::v1alpha::ListServiceResponse* response)
+        GRPC_FINAL GRPC_OVERRIDE {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    void RequestListService(
+        ::grpc::ServerContext* context,
+        ::grpc::reflection::v1alpha::EmptyRequest* request,
+        ::grpc::ServerAsyncResponseWriter<
+            ::grpc::reflection::v1alpha::ListServiceResponse>* response,
+        ::grpc::CompletionQueue* new_call_cq,
+        ::grpc::ServerCompletionQueue* notification_cq, void* tag) {
+      ::grpc::Service::RequestAsyncUnary(0, context, request, response,
+                                         new_call_cq, notification_cq, tag);
+    }
+  };
+  template <class BaseClass>
+  class WithAsyncMethod_GetFileByName : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(Service* service) {}
+
+   public:
+    WithAsyncMethod_GetFileByName() { ::grpc::Service::MarkMethodAsync(1); }
+    ~WithAsyncMethod_GetFileByName() GRPC_OVERRIDE {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status GetFileByName(
+        ::grpc::ServerContext* context,
+        const ::grpc::reflection::v1alpha::FileNameRequest* request,
+        ::grpc::reflection::v1alpha::FileDescriptorProtoResponse* response)
+        GRPC_FINAL GRPC_OVERRIDE {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    void RequestGetFileByName(
+        ::grpc::ServerContext* context,
+        ::grpc::reflection::v1alpha::FileNameRequest* request,
+        ::grpc::ServerAsyncResponseWriter<
+            ::grpc::reflection::v1alpha::FileDescriptorProtoResponse>* response,
+        ::grpc::CompletionQueue* new_call_cq,
+        ::grpc::ServerCompletionQueue* notification_cq, void* tag) {
+      ::grpc::Service::RequestAsyncUnary(1, context, request, response,
+                                         new_call_cq, notification_cq, tag);
+    }
+  };
+  template <class BaseClass>
+  class WithAsyncMethod_GetFileContainingSymbol : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(Service* service) {}
+
+   public:
+    WithAsyncMethod_GetFileContainingSymbol() {
+      ::grpc::Service::MarkMethodAsync(2);
+    }
+    ~WithAsyncMethod_GetFileContainingSymbol() GRPC_OVERRIDE {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status GetFileContainingSymbol(
+        ::grpc::ServerContext* context,
+        const ::grpc::reflection::v1alpha::SymbolRequest* request,
+        ::grpc::reflection::v1alpha::FileDescriptorProtoResponse* response)
+        GRPC_FINAL GRPC_OVERRIDE {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    void RequestGetFileContainingSymbol(
+        ::grpc::ServerContext* context,
+        ::grpc::reflection::v1alpha::SymbolRequest* request,
+        ::grpc::ServerAsyncResponseWriter<
+            ::grpc::reflection::v1alpha::FileDescriptorProtoResponse>* response,
+        ::grpc::CompletionQueue* new_call_cq,
+        ::grpc::ServerCompletionQueue* notification_cq, void* tag) {
+      ::grpc::Service::RequestAsyncUnary(2, context, request, response,
+                                         new_call_cq, notification_cq, tag);
+    }
+  };
+  template <class BaseClass>
+  class WithAsyncMethod_GetFileContainingExtension : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(Service* service) {}
+
+   public:
+    WithAsyncMethod_GetFileContainingExtension() {
+      ::grpc::Service::MarkMethodAsync(3);
+    }
+    ~WithAsyncMethod_GetFileContainingExtension() GRPC_OVERRIDE {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status GetFileContainingExtension(
+        ::grpc::ServerContext* context,
+        const ::grpc::reflection::v1alpha::ExtensionRequest* request,
+        ::grpc::reflection::v1alpha::FileDescriptorProtoResponse* response)
+        GRPC_FINAL GRPC_OVERRIDE {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    void RequestGetFileContainingExtension(
+        ::grpc::ServerContext* context,
+        ::grpc::reflection::v1alpha::ExtensionRequest* request,
+        ::grpc::ServerAsyncResponseWriter<
+            ::grpc::reflection::v1alpha::FileDescriptorProtoResponse>* response,
+        ::grpc::CompletionQueue* new_call_cq,
+        ::grpc::ServerCompletionQueue* notification_cq, void* tag) {
+      ::grpc::Service::RequestAsyncUnary(3, context, request, response,
+                                         new_call_cq, notification_cq, tag);
+    }
+  };
+  template <class BaseClass>
+  class WithAsyncMethod_GetAllExtensionNumbers : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(Service* service) {}
+
+   public:
+    WithAsyncMethod_GetAllExtensionNumbers() {
+      ::grpc::Service::MarkMethodAsync(4);
+    }
+    ~WithAsyncMethod_GetAllExtensionNumbers() GRPC_OVERRIDE {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status GetAllExtensionNumbers(
+        ::grpc::ServerContext* context,
+        const ::grpc::reflection::v1alpha::TypeRequest* request,
+        ::grpc::reflection::v1alpha::ExtensionNumberResponse* response)
+        GRPC_FINAL GRPC_OVERRIDE {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    void RequestGetAllExtensionNumbers(
+        ::grpc::ServerContext* context,
+        ::grpc::reflection::v1alpha::TypeRequest* request,
+        ::grpc::ServerAsyncResponseWriter<
+            ::grpc::reflection::v1alpha::ExtensionNumberResponse>* response,
+        ::grpc::CompletionQueue* new_call_cq,
+        ::grpc::ServerCompletionQueue* notification_cq, void* tag) {
+      ::grpc::Service::RequestAsyncUnary(4, context, request, response,
+                                         new_call_cq, notification_cq, tag);
+    }
+  };
+  typedef WithAsyncMethod_ListService<
+      WithAsyncMethod_GetFileByName<WithAsyncMethod_GetFileContainingSymbol<
+          WithAsyncMethod_GetFileContainingExtension<
+              WithAsyncMethod_GetAllExtensionNumbers<Service>>>>>
+      AsyncService;
+  template <class BaseClass>
+  class WithGenericMethod_ListService : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(Service* service) {}
+
+   public:
+    WithGenericMethod_ListService() { ::grpc::Service::MarkMethodGeneric(0); }
+    ~WithGenericMethod_ListService() GRPC_OVERRIDE {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status ListService(
+        ::grpc::ServerContext* context,
+        const ::grpc::reflection::v1alpha::EmptyRequest* request,
+        ::grpc::reflection::v1alpha::ListServiceResponse* response)
+        GRPC_FINAL GRPC_OVERRIDE {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+  };
+  template <class BaseClass>
+  class WithGenericMethod_GetFileByName : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(Service* service) {}
+
+   public:
+    WithGenericMethod_GetFileByName() { ::grpc::Service::MarkMethodGeneric(1); }
+    ~WithGenericMethod_GetFileByName() GRPC_OVERRIDE {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status GetFileByName(
+        ::grpc::ServerContext* context,
+        const ::grpc::reflection::v1alpha::FileNameRequest* request,
+        ::grpc::reflection::v1alpha::FileDescriptorProtoResponse* response)
+        GRPC_FINAL GRPC_OVERRIDE {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+  };
+  template <class BaseClass>
+  class WithGenericMethod_GetFileContainingSymbol : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(Service* service) {}
+
+   public:
+    WithGenericMethod_GetFileContainingSymbol() {
+      ::grpc::Service::MarkMethodGeneric(2);
+    }
+    ~WithGenericMethod_GetFileContainingSymbol() GRPC_OVERRIDE {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status GetFileContainingSymbol(
+        ::grpc::ServerContext* context,
+        const ::grpc::reflection::v1alpha::SymbolRequest* request,
+        ::grpc::reflection::v1alpha::FileDescriptorProtoResponse* response)
+        GRPC_FINAL GRPC_OVERRIDE {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+  };
+  template <class BaseClass>
+  class WithGenericMethod_GetFileContainingExtension : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(Service* service) {}
+
+   public:
+    WithGenericMethod_GetFileContainingExtension() {
+      ::grpc::Service::MarkMethodGeneric(3);
+    }
+    ~WithGenericMethod_GetFileContainingExtension() GRPC_OVERRIDE {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status GetFileContainingExtension(
+        ::grpc::ServerContext* context,
+        const ::grpc::reflection::v1alpha::ExtensionRequest* request,
+        ::grpc::reflection::v1alpha::FileDescriptorProtoResponse* response)
+        GRPC_FINAL GRPC_OVERRIDE {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+  };
+  template <class BaseClass>
+  class WithGenericMethod_GetAllExtensionNumbers : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(Service* service) {}
+
+   public:
+    WithGenericMethod_GetAllExtensionNumbers() {
+      ::grpc::Service::MarkMethodGeneric(4);
+    }
+    ~WithGenericMethod_GetAllExtensionNumbers() GRPC_OVERRIDE {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status GetAllExtensionNumbers(
+        ::grpc::ServerContext* context,
+        const ::grpc::reflection::v1alpha::TypeRequest* request,
+        ::grpc::reflection::v1alpha::ExtensionNumberResponse* response)
+        GRPC_FINAL GRPC_OVERRIDE {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+  };
+};
+
+}  // namespace v1alpha
+}  // namespace reflection
+}  // namespace grpc
+
+#endif  // GRPC_reflection_2eproto__INCLUDED
diff --git a/extensions/include/grpc++/impl/reflection.pb.h b/extensions/include/grpc++/impl/reflection.pb.h
new file mode 100644
index 0000000000..b054e28de9
--- /dev/null
+++ b/extensions/include/grpc++/impl/reflection.pb.h
@@ -0,0 +1,1128 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: reflection.proto
+
+#ifndef PROTOBUF_reflection_2eproto__INCLUDED
+#define PROTOBUF_reflection_2eproto__INCLUDED
+
+#include <string>
+
+#include <google/protobuf/stubs/common.h>
+
+#if GOOGLE_PROTOBUF_VERSION < 3000000
+#error This file was generated by a newer version of protoc which is
+#error incompatible with your Protocol Buffer headers.  Please update
+#error your headers.
+#endif
+#if 3000000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION
+#error This file was generated by an older version of protoc which is
+#error incompatible with your Protocol Buffer headers.  Please
+#error regenerate this file with a newer version of protoc.
+#endif
+
+#include <google/protobuf/arena.h>
+#include <google/protobuf/arenastring.h>
+#include <google/protobuf/extension_set.h>
+#include <google/protobuf/generated_message_util.h>
+#include <google/protobuf/message.h>
+#include <google/protobuf/metadata.h>
+#include <google/protobuf/repeated_field.h>
+#include <google/protobuf/unknown_field_set.h>
+// @@protoc_insertion_point(includes)
+
+namespace grpc {
+namespace reflection {
+namespace v1alpha {
+
+// Internal implementation detail -- do not call these.
+void protobuf_AddDesc_reflection_2eproto();
+void protobuf_AssignDesc_reflection_2eproto();
+void protobuf_ShutdownFile_reflection_2eproto();
+
+class EmptyRequest;
+class ExtensionNumberResponse;
+class ExtensionRequest;
+class FileDescriptorProtoResponse;
+class FileNameRequest;
+class ListServiceResponse;
+class SymbolRequest;
+class TypeRequest;
+
+// ===================================================================
+
+class EmptyRequest : public ::google::protobuf::Message {
+ public:
+  EmptyRequest();
+  virtual ~EmptyRequest();
+
+  EmptyRequest(const EmptyRequest& from);
+
+  inline EmptyRequest& operator=(const EmptyRequest& from) {
+    CopyFrom(from);
+    return *this;
+  }
+
+  static const ::google::protobuf::Descriptor* descriptor();
+  static const EmptyRequest& default_instance();
+
+  void Swap(EmptyRequest* other);
+
+  // implements Message ----------------------------------------------
+
+  inline EmptyRequest* New() const { return New(NULL); }
+
+  EmptyRequest* New(::google::protobuf::Arena* arena) const;
+  void CopyFrom(const ::google::protobuf::Message& from);
+  void MergeFrom(const ::google::protobuf::Message& from);
+  void CopyFrom(const EmptyRequest& from);
+  void MergeFrom(const EmptyRequest& from);
+  void Clear();
+  bool IsInitialized() const;
+
+  int ByteSize() const;
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input);
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const;
+  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(
+      ::google::protobuf::uint8* output) const;
+  int GetCachedSize() const { return _cached_size_; }
+
+ private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const;
+  void InternalSwap(EmptyRequest* other);
+
+ private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return _internal_metadata_.arena();
+  }
+  inline void* MaybeArenaPtr() const {
+    return _internal_metadata_.raw_arena_ptr();
+  }
+
+ public:
+  ::google::protobuf::Metadata GetMetadata() const;
+
+  // nested types ----------------------------------------------------
+
+  // accessors -------------------------------------------------------
+
+  // @@protoc_insertion_point(class_scope:grpc.reflection.v1alpha.EmptyRequest)
+ private:
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  bool _is_default_instance_;
+  mutable int _cached_size_;
+  friend void protobuf_AddDesc_reflection_2eproto();
+  friend void protobuf_AssignDesc_reflection_2eproto();
+  friend void protobuf_ShutdownFile_reflection_2eproto();
+
+  void InitAsDefaultInstance();
+  static EmptyRequest* default_instance_;
+};
+// -------------------------------------------------------------------
+
+class FileNameRequest : public ::google::protobuf::Message {
+ public:
+  FileNameRequest();
+  virtual ~FileNameRequest();
+
+  FileNameRequest(const FileNameRequest& from);
+
+  inline FileNameRequest& operator=(const FileNameRequest& from) {
+    CopyFrom(from);
+    return *this;
+  }
+
+  static const ::google::protobuf::Descriptor* descriptor();
+  static const FileNameRequest& default_instance();
+
+  void Swap(FileNameRequest* other);
+
+  // implements Message ----------------------------------------------
+
+  inline FileNameRequest* New() const { return New(NULL); }
+
+  FileNameRequest* New(::google::protobuf::Arena* arena) const;
+  void CopyFrom(const ::google::protobuf::Message& from);
+  void MergeFrom(const ::google::protobuf::Message& from);
+  void CopyFrom(const FileNameRequest& from);
+  void MergeFrom(const FileNameRequest& from);
+  void Clear();
+  bool IsInitialized() const;
+
+  int ByteSize() const;
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input);
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const;
+  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(
+      ::google::protobuf::uint8* output) const;
+  int GetCachedSize() const { return _cached_size_; }
+
+ private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const;
+  void InternalSwap(FileNameRequest* other);
+
+ private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return _internal_metadata_.arena();
+  }
+  inline void* MaybeArenaPtr() const {
+    return _internal_metadata_.raw_arena_ptr();
+  }
+
+ public:
+  ::google::protobuf::Metadata GetMetadata() const;
+
+  // nested types ----------------------------------------------------
+
+  // accessors -------------------------------------------------------
+
+  // optional string filename = 1;
+  void clear_filename();
+  static const int kFilenameFieldNumber = 1;
+  const ::std::string& filename() const;
+  void set_filename(const ::std::string& value);
+  void set_filename(const char* value);
+  void set_filename(const char* value, size_t size);
+  ::std::string* mutable_filename();
+  ::std::string* release_filename();
+  void set_allocated_filename(::std::string* filename);
+
+  // @@protoc_insertion_point(class_scope:grpc.reflection.v1alpha.FileNameRequest)
+ private:
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  bool _is_default_instance_;
+  ::google::protobuf::internal::ArenaStringPtr filename_;
+  mutable int _cached_size_;
+  friend void protobuf_AddDesc_reflection_2eproto();
+  friend void protobuf_AssignDesc_reflection_2eproto();
+  friend void protobuf_ShutdownFile_reflection_2eproto();
+
+  void InitAsDefaultInstance();
+  static FileNameRequest* default_instance_;
+};
+// -------------------------------------------------------------------
+
+class SymbolRequest : public ::google::protobuf::Message {
+ public:
+  SymbolRequest();
+  virtual ~SymbolRequest();
+
+  SymbolRequest(const SymbolRequest& from);
+
+  inline SymbolRequest& operator=(const SymbolRequest& from) {
+    CopyFrom(from);
+    return *this;
+  }
+
+  static const ::google::protobuf::Descriptor* descriptor();
+  static const SymbolRequest& default_instance();
+
+  void Swap(SymbolRequest* other);
+
+  // implements Message ----------------------------------------------
+
+  inline SymbolRequest* New() const { return New(NULL); }
+
+  SymbolRequest* New(::google::protobuf::Arena* arena) const;
+  void CopyFrom(const ::google::protobuf::Message& from);
+  void MergeFrom(const ::google::protobuf::Message& from);
+  void CopyFrom(const SymbolRequest& from);
+  void MergeFrom(const SymbolRequest& from);
+  void Clear();
+  bool IsInitialized() const;
+
+  int ByteSize() const;
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input);
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const;
+  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(
+      ::google::protobuf::uint8* output) const;
+  int GetCachedSize() const { return _cached_size_; }
+
+ private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const;
+  void InternalSwap(SymbolRequest* other);
+
+ private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return _internal_metadata_.arena();
+  }
+  inline void* MaybeArenaPtr() const {
+    return _internal_metadata_.raw_arena_ptr();
+  }
+
+ public:
+  ::google::protobuf::Metadata GetMetadata() const;
+
+  // nested types ----------------------------------------------------
+
+  // accessors -------------------------------------------------------
+
+  // optional string symbol = 1;
+  void clear_symbol();
+  static const int kSymbolFieldNumber = 1;
+  const ::std::string& symbol() const;
+  void set_symbol(const ::std::string& value);
+  void set_symbol(const char* value);
+  void set_symbol(const char* value, size_t size);
+  ::std::string* mutable_symbol();
+  ::std::string* release_symbol();
+  void set_allocated_symbol(::std::string* symbol);
+
+  // @@protoc_insertion_point(class_scope:grpc.reflection.v1alpha.SymbolRequest)
+ private:
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  bool _is_default_instance_;
+  ::google::protobuf::internal::ArenaStringPtr symbol_;
+  mutable int _cached_size_;
+  friend void protobuf_AddDesc_reflection_2eproto();
+  friend void protobuf_AssignDesc_reflection_2eproto();
+  friend void protobuf_ShutdownFile_reflection_2eproto();
+
+  void InitAsDefaultInstance();
+  static SymbolRequest* default_instance_;
+};
+// -------------------------------------------------------------------
+
+class ExtensionRequest : public ::google::protobuf::Message {
+ public:
+  ExtensionRequest();
+  virtual ~ExtensionRequest();
+
+  ExtensionRequest(const ExtensionRequest& from);
+
+  inline ExtensionRequest& operator=(const ExtensionRequest& from) {
+    CopyFrom(from);
+    return *this;
+  }
+
+  static const ::google::protobuf::Descriptor* descriptor();
+  static const ExtensionRequest& default_instance();
+
+  void Swap(ExtensionRequest* other);
+
+  // implements Message ----------------------------------------------
+
+  inline ExtensionRequest* New() const { return New(NULL); }
+
+  ExtensionRequest* New(::google::protobuf::Arena* arena) const;
+  void CopyFrom(const ::google::protobuf::Message& from);
+  void MergeFrom(const ::google::protobuf::Message& from);
+  void CopyFrom(const ExtensionRequest& from);
+  void MergeFrom(const ExtensionRequest& from);
+  void Clear();
+  bool IsInitialized() const;
+
+  int ByteSize() const;
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input);
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const;
+  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(
+      ::google::protobuf::uint8* output) const;
+  int GetCachedSize() const { return _cached_size_; }
+
+ private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const;
+  void InternalSwap(ExtensionRequest* other);
+
+ private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return _internal_metadata_.arena();
+  }
+  inline void* MaybeArenaPtr() const {
+    return _internal_metadata_.raw_arena_ptr();
+  }
+
+ public:
+  ::google::protobuf::Metadata GetMetadata() const;
+
+  // nested types ----------------------------------------------------
+
+  // accessors -------------------------------------------------------
+
+  // optional string containing_type = 1;
+  void clear_containing_type();
+  static const int kContainingTypeFieldNumber = 1;
+  const ::std::string& containing_type() const;
+  void set_containing_type(const ::std::string& value);
+  void set_containing_type(const char* value);
+  void set_containing_type(const char* value, size_t size);
+  ::std::string* mutable_containing_type();
+  ::std::string* release_containing_type();
+  void set_allocated_containing_type(::std::string* containing_type);
+
+  // optional int32 extension_number = 2;
+  void clear_extension_number();
+  static const int kExtensionNumberFieldNumber = 2;
+  ::google::protobuf::int32 extension_number() const;
+  void set_extension_number(::google::protobuf::int32 value);
+
+  // @@protoc_insertion_point(class_scope:grpc.reflection.v1alpha.ExtensionRequest)
+ private:
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  bool _is_default_instance_;
+  ::google::protobuf::internal::ArenaStringPtr containing_type_;
+  ::google::protobuf::int32 extension_number_;
+  mutable int _cached_size_;
+  friend void protobuf_AddDesc_reflection_2eproto();
+  friend void protobuf_AssignDesc_reflection_2eproto();
+  friend void protobuf_ShutdownFile_reflection_2eproto();
+
+  void InitAsDefaultInstance();
+  static ExtensionRequest* default_instance_;
+};
+// -------------------------------------------------------------------
+
+class TypeRequest : public ::google::protobuf::Message {
+ public:
+  TypeRequest();
+  virtual ~TypeRequest();
+
+  TypeRequest(const TypeRequest& from);
+
+  inline TypeRequest& operator=(const TypeRequest& from) {
+    CopyFrom(from);
+    return *this;
+  }
+
+  static const ::google::protobuf::Descriptor* descriptor();
+  static const TypeRequest& default_instance();
+
+  void Swap(TypeRequest* other);
+
+  // implements Message ----------------------------------------------
+
+  inline TypeRequest* New() const { return New(NULL); }
+
+  TypeRequest* New(::google::protobuf::Arena* arena) const;
+  void CopyFrom(const ::google::protobuf::Message& from);
+  void MergeFrom(const ::google::protobuf::Message& from);
+  void CopyFrom(const TypeRequest& from);
+  void MergeFrom(const TypeRequest& from);
+  void Clear();
+  bool IsInitialized() const;
+
+  int ByteSize() const;
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input);
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const;
+  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(
+      ::google::protobuf::uint8* output) const;
+  int GetCachedSize() const { return _cached_size_; }
+
+ private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const;
+  void InternalSwap(TypeRequest* other);
+
+ private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return _internal_metadata_.arena();
+  }
+  inline void* MaybeArenaPtr() const {
+    return _internal_metadata_.raw_arena_ptr();
+  }
+
+ public:
+  ::google::protobuf::Metadata GetMetadata() const;
+
+  // nested types ----------------------------------------------------
+
+  // accessors -------------------------------------------------------
+
+  // optional string type = 1;
+  void clear_type();
+  static const int kTypeFieldNumber = 1;
+  const ::std::string& type() const;
+  void set_type(const ::std::string& value);
+  void set_type(const char* value);
+  void set_type(const char* value, size_t size);
+  ::std::string* mutable_type();
+  ::std::string* release_type();
+  void set_allocated_type(::std::string* type);
+
+  // @@protoc_insertion_point(class_scope:grpc.reflection.v1alpha.TypeRequest)
+ private:
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  bool _is_default_instance_;
+  ::google::protobuf::internal::ArenaStringPtr type_;
+  mutable int _cached_size_;
+  friend void protobuf_AddDesc_reflection_2eproto();
+  friend void protobuf_AssignDesc_reflection_2eproto();
+  friend void protobuf_ShutdownFile_reflection_2eproto();
+
+  void InitAsDefaultInstance();
+  static TypeRequest* default_instance_;
+};
+// -------------------------------------------------------------------
+
+class ListServiceResponse : public ::google::protobuf::Message {
+ public:
+  ListServiceResponse();
+  virtual ~ListServiceResponse();
+
+  ListServiceResponse(const ListServiceResponse& from);
+
+  inline ListServiceResponse& operator=(const ListServiceResponse& from) {
+    CopyFrom(from);
+    return *this;
+  }
+
+  static const ::google::protobuf::Descriptor* descriptor();
+  static const ListServiceResponse& default_instance();
+
+  void Swap(ListServiceResponse* other);
+
+  // implements Message ----------------------------------------------
+
+  inline ListServiceResponse* New() const { return New(NULL); }
+
+  ListServiceResponse* New(::google::protobuf::Arena* arena) const;
+  void CopyFrom(const ::google::protobuf::Message& from);
+  void MergeFrom(const ::google::protobuf::Message& from);
+  void CopyFrom(const ListServiceResponse& from);
+  void MergeFrom(const ListServiceResponse& from);
+  void Clear();
+  bool IsInitialized() const;
+
+  int ByteSize() const;
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input);
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const;
+  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(
+      ::google::protobuf::uint8* output) const;
+  int GetCachedSize() const { return _cached_size_; }
+
+ private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const;
+  void InternalSwap(ListServiceResponse* other);
+
+ private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return _internal_metadata_.arena();
+  }
+  inline void* MaybeArenaPtr() const {
+    return _internal_metadata_.raw_arena_ptr();
+  }
+
+ public:
+  ::google::protobuf::Metadata GetMetadata() const;
+
+  // nested types ----------------------------------------------------
+
+  // accessors -------------------------------------------------------
+
+  // repeated string services = 1;
+  int services_size() const;
+  void clear_services();
+  static const int kServicesFieldNumber = 1;
+  const ::std::string& services(int index) const;
+  ::std::string* mutable_services(int index);
+  void set_services(int index, const ::std::string& value);
+  void set_services(int index, const char* value);
+  void set_services(int index, const char* value, size_t size);
+  ::std::string* add_services();
+  void add_services(const ::std::string& value);
+  void add_services(const char* value);
+  void add_services(const char* value, size_t size);
+  const ::google::protobuf::RepeatedPtrField< ::std::string>& services() const;
+  ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_services();
+
+  // @@protoc_insertion_point(class_scope:grpc.reflection.v1alpha.ListServiceResponse)
+ private:
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  bool _is_default_instance_;
+  ::google::protobuf::RepeatedPtrField< ::std::string> services_;
+  mutable int _cached_size_;
+  friend void protobuf_AddDesc_reflection_2eproto();
+  friend void protobuf_AssignDesc_reflection_2eproto();
+  friend void protobuf_ShutdownFile_reflection_2eproto();
+
+  void InitAsDefaultInstance();
+  static ListServiceResponse* default_instance_;
+};
+// -------------------------------------------------------------------
+
+class FileDescriptorProtoResponse : public ::google::protobuf::Message {
+ public:
+  FileDescriptorProtoResponse();
+  virtual ~FileDescriptorProtoResponse();
+
+  FileDescriptorProtoResponse(const FileDescriptorProtoResponse& from);
+
+  inline FileDescriptorProtoResponse& operator=(
+      const FileDescriptorProtoResponse& from) {
+    CopyFrom(from);
+    return *this;
+  }
+
+  static const ::google::protobuf::Descriptor* descriptor();
+  static const FileDescriptorProtoResponse& default_instance();
+
+  void Swap(FileDescriptorProtoResponse* other);
+
+  // implements Message ----------------------------------------------
+
+  inline FileDescriptorProtoResponse* New() const { return New(NULL); }
+
+  FileDescriptorProtoResponse* New(::google::protobuf::Arena* arena) const;
+  void CopyFrom(const ::google::protobuf::Message& from);
+  void MergeFrom(const ::google::protobuf::Message& from);
+  void CopyFrom(const FileDescriptorProtoResponse& from);
+  void MergeFrom(const FileDescriptorProtoResponse& from);
+  void Clear();
+  bool IsInitialized() const;
+
+  int ByteSize() const;
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input);
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const;
+  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(
+      ::google::protobuf::uint8* output) const;
+  int GetCachedSize() const { return _cached_size_; }
+
+ private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const;
+  void InternalSwap(FileDescriptorProtoResponse* other);
+
+ private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return _internal_metadata_.arena();
+  }
+  inline void* MaybeArenaPtr() const {
+    return _internal_metadata_.raw_arena_ptr();
+  }
+
+ public:
+  ::google::protobuf::Metadata GetMetadata() const;
+
+  // nested types ----------------------------------------------------
+
+  // accessors -------------------------------------------------------
+
+  // optional bytes file_descriptor_proto = 1;
+  void clear_file_descriptor_proto();
+  static const int kFileDescriptorProtoFieldNumber = 1;
+  const ::std::string& file_descriptor_proto() const;
+  void set_file_descriptor_proto(const ::std::string& value);
+  void set_file_descriptor_proto(const char* value);
+  void set_file_descriptor_proto(const void* value, size_t size);
+  ::std::string* mutable_file_descriptor_proto();
+  ::std::string* release_file_descriptor_proto();
+  void set_allocated_file_descriptor_proto(
+      ::std::string* file_descriptor_proto);
+
+  // @@protoc_insertion_point(class_scope:grpc.reflection.v1alpha.FileDescriptorProtoResponse)
+ private:
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  bool _is_default_instance_;
+  ::google::protobuf::internal::ArenaStringPtr file_descriptor_proto_;
+  mutable int _cached_size_;
+  friend void protobuf_AddDesc_reflection_2eproto();
+  friend void protobuf_AssignDesc_reflection_2eproto();
+  friend void protobuf_ShutdownFile_reflection_2eproto();
+
+  void InitAsDefaultInstance();
+  static FileDescriptorProtoResponse* default_instance_;
+};
+// -------------------------------------------------------------------
+
+class ExtensionNumberResponse : public ::google::protobuf::Message {
+ public:
+  ExtensionNumberResponse();
+  virtual ~ExtensionNumberResponse();
+
+  ExtensionNumberResponse(const ExtensionNumberResponse& from);
+
+  inline ExtensionNumberResponse& operator=(
+      const ExtensionNumberResponse& from) {
+    CopyFrom(from);
+    return *this;
+  }
+
+  static const ::google::protobuf::Descriptor* descriptor();
+  static const ExtensionNumberResponse& default_instance();
+
+  void Swap(ExtensionNumberResponse* other);
+
+  // implements Message ----------------------------------------------
+
+  inline ExtensionNumberResponse* New() const { return New(NULL); }
+
+  ExtensionNumberResponse* New(::google::protobuf::Arena* arena) const;
+  void CopyFrom(const ::google::protobuf::Message& from);
+  void MergeFrom(const ::google::protobuf::Message& from);
+  void CopyFrom(const ExtensionNumberResponse& from);
+  void MergeFrom(const ExtensionNumberResponse& from);
+  void Clear();
+  bool IsInitialized() const;
+
+  int ByteSize() const;
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input);
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const;
+  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(
+      ::google::protobuf::uint8* output) const;
+  int GetCachedSize() const { return _cached_size_; }
+
+ private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const;
+  void InternalSwap(ExtensionNumberResponse* other);
+
+ private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return _internal_metadata_.arena();
+  }
+  inline void* MaybeArenaPtr() const {
+    return _internal_metadata_.raw_arena_ptr();
+  }
+
+ public:
+  ::google::protobuf::Metadata GetMetadata() const;
+
+  // nested types ----------------------------------------------------
+
+  // accessors -------------------------------------------------------
+
+  // repeated int32 extension_number = 1;
+  int extension_number_size() const;
+  void clear_extension_number();
+  static const int kExtensionNumberFieldNumber = 1;
+  ::google::protobuf::int32 extension_number(int index) const;
+  void set_extension_number(int index, ::google::protobuf::int32 value);
+  void add_extension_number(::google::protobuf::int32 value);
+  const ::google::protobuf::RepeatedField< ::google::protobuf::int32>&
+  extension_number() const;
+  ::google::protobuf::RepeatedField< ::google::protobuf::int32>*
+  mutable_extension_number();
+
+  // @@protoc_insertion_point(class_scope:grpc.reflection.v1alpha.ExtensionNumberResponse)
+ private:
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  bool _is_default_instance_;
+  ::google::protobuf::RepeatedField< ::google::protobuf::int32>
+      extension_number_;
+  mutable int _extension_number_cached_byte_size_;
+  mutable int _cached_size_;
+  friend void protobuf_AddDesc_reflection_2eproto();
+  friend void protobuf_AssignDesc_reflection_2eproto();
+  friend void protobuf_ShutdownFile_reflection_2eproto();
+
+  void InitAsDefaultInstance();
+  static ExtensionNumberResponse* default_instance_;
+};
+// ===================================================================
+
+// ===================================================================
+
+#if !PROTOBUF_INLINE_NOT_IN_HEADERS
+// EmptyRequest
+
+// -------------------------------------------------------------------
+
+// FileNameRequest
+
+// optional string filename = 1;
+inline void FileNameRequest::clear_filename() {
+  filename_.ClearToEmptyNoArena(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline const ::std::string& FileNameRequest::filename() const {
+  // @@protoc_insertion_point(field_get:grpc.reflection.v1alpha.FileNameRequest.filename)
+  return filename_.GetNoArena(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void FileNameRequest::set_filename(const ::std::string& value) {
+  filename_.SetNoArena(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:grpc.reflection.v1alpha.FileNameRequest.filename)
+}
+inline void FileNameRequest::set_filename(const char* value) {
+  filename_.SetNoArena(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:grpc.reflection.v1alpha.FileNameRequest.filename)
+}
+inline void FileNameRequest::set_filename(const char* value, size_t size) {
+  filename_.SetNoArena(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:grpc.reflection.v1alpha.FileNameRequest.filename)
+}
+inline ::std::string* FileNameRequest::mutable_filename() {
+  // @@protoc_insertion_point(field_mutable:grpc.reflection.v1alpha.FileNameRequest.filename)
+  return filename_.MutableNoArena(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* FileNameRequest::release_filename() {
+  return filename_.ReleaseNoArena(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void FileNameRequest::set_allocated_filename(::std::string* filename) {
+  if (filename != NULL) {
+  } else {
+  }
+  filename_.SetAllocatedNoArena(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited(), filename);
+  // @@protoc_insertion_point(field_set_allocated:grpc.reflection.v1alpha.FileNameRequest.filename)
+}
+
+// -------------------------------------------------------------------
+
+// SymbolRequest
+
+// optional string symbol = 1;
+inline void SymbolRequest::clear_symbol() {
+  symbol_.ClearToEmptyNoArena(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline const ::std::string& SymbolRequest::symbol() const {
+  // @@protoc_insertion_point(field_get:grpc.reflection.v1alpha.SymbolRequest.symbol)
+  return symbol_.GetNoArena(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void SymbolRequest::set_symbol(const ::std::string& value) {
+  symbol_.SetNoArena(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:grpc.reflection.v1alpha.SymbolRequest.symbol)
+}
+inline void SymbolRequest::set_symbol(const char* value) {
+  symbol_.SetNoArena(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:grpc.reflection.v1alpha.SymbolRequest.symbol)
+}
+inline void SymbolRequest::set_symbol(const char* value, size_t size) {
+  symbol_.SetNoArena(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:grpc.reflection.v1alpha.SymbolRequest.symbol)
+}
+inline ::std::string* SymbolRequest::mutable_symbol() {
+  // @@protoc_insertion_point(field_mutable:grpc.reflection.v1alpha.SymbolRequest.symbol)
+  return symbol_.MutableNoArena(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* SymbolRequest::release_symbol() {
+  return symbol_.ReleaseNoArena(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void SymbolRequest::set_allocated_symbol(::std::string* symbol) {
+  if (symbol != NULL) {
+  } else {
+  }
+  symbol_.SetAllocatedNoArena(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited(), symbol);
+  // @@protoc_insertion_point(field_set_allocated:grpc.reflection.v1alpha.SymbolRequest.symbol)
+}
+
+// -------------------------------------------------------------------
+
+// ExtensionRequest
+
+// optional string containing_type = 1;
+inline void ExtensionRequest::clear_containing_type() {
+  containing_type_.ClearToEmptyNoArena(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline const ::std::string& ExtensionRequest::containing_type() const {
+  // @@protoc_insertion_point(field_get:grpc.reflection.v1alpha.ExtensionRequest.containing_type)
+  return containing_type_.GetNoArena(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void ExtensionRequest::set_containing_type(const ::std::string& value) {
+  containing_type_.SetNoArena(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:grpc.reflection.v1alpha.ExtensionRequest.containing_type)
+}
+inline void ExtensionRequest::set_containing_type(const char* value) {
+  containing_type_.SetNoArena(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:grpc.reflection.v1alpha.ExtensionRequest.containing_type)
+}
+inline void ExtensionRequest::set_containing_type(const char* value,
+                                                  size_t size) {
+  containing_type_.SetNoArena(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:grpc.reflection.v1alpha.ExtensionRequest.containing_type)
+}
+inline ::std::string* ExtensionRequest::mutable_containing_type() {
+  // @@protoc_insertion_point(field_mutable:grpc.reflection.v1alpha.ExtensionRequest.containing_type)
+  return containing_type_.MutableNoArena(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* ExtensionRequest::release_containing_type() {
+  return containing_type_.ReleaseNoArena(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void ExtensionRequest::set_allocated_containing_type(
+    ::std::string* containing_type) {
+  if (containing_type != NULL) {
+  } else {
+  }
+  containing_type_.SetAllocatedNoArena(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      containing_type);
+  // @@protoc_insertion_point(field_set_allocated:grpc.reflection.v1alpha.ExtensionRequest.containing_type)
+}
+
+// optional int32 extension_number = 2;
+inline void ExtensionRequest::clear_extension_number() {
+  extension_number_ = 0;
+}
+inline ::google::protobuf::int32 ExtensionRequest::extension_number() const {
+  // @@protoc_insertion_point(field_get:grpc.reflection.v1alpha.ExtensionRequest.extension_number)
+  return extension_number_;
+}
+inline void ExtensionRequest::set_extension_number(
+    ::google::protobuf::int32 value) {
+  extension_number_ = value;
+  // @@protoc_insertion_point(field_set:grpc.reflection.v1alpha.ExtensionRequest.extension_number)
+}
+
+// -------------------------------------------------------------------
+
+// TypeRequest
+
+// optional string type = 1;
+inline void TypeRequest::clear_type() {
+  type_.ClearToEmptyNoArena(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline const ::std::string& TypeRequest::type() const {
+  // @@protoc_insertion_point(field_get:grpc.reflection.v1alpha.TypeRequest.type)
+  return type_.GetNoArena(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void TypeRequest::set_type(const ::std::string& value) {
+  type_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+                   value);
+  // @@protoc_insertion_point(field_set:grpc.reflection.v1alpha.TypeRequest.type)
+}
+inline void TypeRequest::set_type(const char* value) {
+  type_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+                   ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:grpc.reflection.v1alpha.TypeRequest.type)
+}
+inline void TypeRequest::set_type(const char* value, size_t size) {
+  type_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+                   ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:grpc.reflection.v1alpha.TypeRequest.type)
+}
+inline ::std::string* TypeRequest::mutable_type() {
+  // @@protoc_insertion_point(field_mutable:grpc.reflection.v1alpha.TypeRequest.type)
+  return type_.MutableNoArena(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* TypeRequest::release_type() {
+  return type_.ReleaseNoArena(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void TypeRequest::set_allocated_type(::std::string* type) {
+  if (type != NULL) {
+  } else {
+  }
+  type_.SetAllocatedNoArena(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited(), type);
+  // @@protoc_insertion_point(field_set_allocated:grpc.reflection.v1alpha.TypeRequest.type)
+}
+
+// -------------------------------------------------------------------
+
+// ListServiceResponse
+
+// repeated string services = 1;
+inline int ListServiceResponse::services_size() const {
+  return services_.size();
+}
+inline void ListServiceResponse::clear_services() { services_.Clear(); }
+inline const ::std::string& ListServiceResponse::services(int index) const {
+  // @@protoc_insertion_point(field_get:grpc.reflection.v1alpha.ListServiceResponse.services)
+  return services_.Get(index);
+}
+inline ::std::string* ListServiceResponse::mutable_services(int index) {
+  // @@protoc_insertion_point(field_mutable:grpc.reflection.v1alpha.ListServiceResponse.services)
+  return services_.Mutable(index);
+}
+inline void ListServiceResponse::set_services(int index,
+                                              const ::std::string& value) {
+  // @@protoc_insertion_point(field_set:grpc.reflection.v1alpha.ListServiceResponse.services)
+  services_.Mutable(index)->assign(value);
+}
+inline void ListServiceResponse::set_services(int index, const char* value) {
+  services_.Mutable(index)->assign(value);
+  // @@protoc_insertion_point(field_set_char:grpc.reflection.v1alpha.ListServiceResponse.services)
+}
+inline void ListServiceResponse::set_services(int index, const char* value,
+                                              size_t size) {
+  services_.Mutable(index)->assign(reinterpret_cast<const char*>(value), size);
+  // @@protoc_insertion_point(field_set_pointer:grpc.reflection.v1alpha.ListServiceResponse.services)
+}
+inline ::std::string* ListServiceResponse::add_services() {
+  return services_.Add();
+}
+inline void ListServiceResponse::add_services(const ::std::string& value) {
+  services_.Add()->assign(value);
+  // @@protoc_insertion_point(field_add:grpc.reflection.v1alpha.ListServiceResponse.services)
+}
+inline void ListServiceResponse::add_services(const char* value) {
+  services_.Add()->assign(value);
+  // @@protoc_insertion_point(field_add_char:grpc.reflection.v1alpha.ListServiceResponse.services)
+}
+inline void ListServiceResponse::add_services(const char* value, size_t size) {
+  services_.Add()->assign(reinterpret_cast<const char*>(value), size);
+  // @@protoc_insertion_point(field_add_pointer:grpc.reflection.v1alpha.ListServiceResponse.services)
+}
+inline const ::google::protobuf::RepeatedPtrField< ::std::string>&
+ListServiceResponse::services() const {
+  // @@protoc_insertion_point(field_list:grpc.reflection.v1alpha.ListServiceResponse.services)
+  return services_;
+}
+inline ::google::protobuf::RepeatedPtrField< ::std::string>*
+ListServiceResponse::mutable_services() {
+  // @@protoc_insertion_point(field_mutable_list:grpc.reflection.v1alpha.ListServiceResponse.services)
+  return &services_;
+}
+
+// -------------------------------------------------------------------
+
+// FileDescriptorProtoResponse
+
+// optional bytes file_descriptor_proto = 1;
+inline void FileDescriptorProtoResponse::clear_file_descriptor_proto() {
+  file_descriptor_proto_.ClearToEmptyNoArena(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline const ::std::string& FileDescriptorProtoResponse::file_descriptor_proto()
+    const {
+  // @@protoc_insertion_point(field_get:grpc.reflection.v1alpha.FileDescriptorProtoResponse.file_descriptor_proto)
+  return file_descriptor_proto_.GetNoArena(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void FileDescriptorProtoResponse::set_file_descriptor_proto(
+    const ::std::string& value) {
+  file_descriptor_proto_.SetNoArena(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:grpc.reflection.v1alpha.FileDescriptorProtoResponse.file_descriptor_proto)
+}
+inline void FileDescriptorProtoResponse::set_file_descriptor_proto(
+    const char* value) {
+  file_descriptor_proto_.SetNoArena(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:grpc.reflection.v1alpha.FileDescriptorProtoResponse.file_descriptor_proto)
+}
+inline void FileDescriptorProtoResponse::set_file_descriptor_proto(
+    const void* value, size_t size) {
+  file_descriptor_proto_.SetNoArena(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:grpc.reflection.v1alpha.FileDescriptorProtoResponse.file_descriptor_proto)
+}
+inline ::std::string*
+FileDescriptorProtoResponse::mutable_file_descriptor_proto() {
+  // @@protoc_insertion_point(field_mutable:grpc.reflection.v1alpha.FileDescriptorProtoResponse.file_descriptor_proto)
+  return file_descriptor_proto_.MutableNoArena(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string*
+FileDescriptorProtoResponse::release_file_descriptor_proto() {
+  return file_descriptor_proto_.ReleaseNoArena(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void FileDescriptorProtoResponse::set_allocated_file_descriptor_proto(
+    ::std::string* file_descriptor_proto) {
+  if (file_descriptor_proto != NULL) {
+  } else {
+  }
+  file_descriptor_proto_.SetAllocatedNoArena(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      file_descriptor_proto);
+  // @@protoc_insertion_point(field_set_allocated:grpc.reflection.v1alpha.FileDescriptorProtoResponse.file_descriptor_proto)
+}
+
+// -------------------------------------------------------------------
+
+// ExtensionNumberResponse
+
+// repeated int32 extension_number = 1;
+inline int ExtensionNumberResponse::extension_number_size() const {
+  return extension_number_.size();
+}
+inline void ExtensionNumberResponse::clear_extension_number() {
+  extension_number_.Clear();
+}
+inline ::google::protobuf::int32 ExtensionNumberResponse::extension_number(
+    int index) const {
+  // @@protoc_insertion_point(field_get:grpc.reflection.v1alpha.ExtensionNumberResponse.extension_number)
+  return extension_number_.Get(index);
+}
+inline void ExtensionNumberResponse::set_extension_number(
+    int index, ::google::protobuf::int32 value) {
+  extension_number_.Set(index, value);
+  // @@protoc_insertion_point(field_set:grpc.reflection.v1alpha.ExtensionNumberResponse.extension_number)
+}
+inline void ExtensionNumberResponse::add_extension_number(
+    ::google::protobuf::int32 value) {
+  extension_number_.Add(value);
+  // @@protoc_insertion_point(field_add:grpc.reflection.v1alpha.ExtensionNumberResponse.extension_number)
+}
+inline const ::google::protobuf::RepeatedField< ::google::protobuf::int32>&
+ExtensionNumberResponse::extension_number() const {
+  // @@protoc_insertion_point(field_list:grpc.reflection.v1alpha.ExtensionNumberResponse.extension_number)
+  return extension_number_;
+}
+inline ::google::protobuf::RepeatedField< ::google::protobuf::int32>*
+ExtensionNumberResponse::mutable_extension_number() {
+  // @@protoc_insertion_point(field_mutable_list:grpc.reflection.v1alpha.ExtensionNumberResponse.extension_number)
+  return &extension_number_;
+}
+
+#endif  // !PROTOBUF_INLINE_NOT_IN_HEADERS
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
+// @@protoc_insertion_point(namespace_scope)
+
+}  // namespace v1alpha
+}  // namespace reflection
+}  // namespace grpc
+
+// @@protoc_insertion_point(global_scope)
+
+#endif  // PROTOBUF_reflection_2eproto__INCLUDED
diff --git a/extensions/reflection/proto_server_reflection.cc b/extensions/reflection/proto_server_reflection.cc
new file mode 100644
index 0000000000..0662bb595a
--- /dev/null
+++ b/extensions/reflection/proto_server_reflection.cc
@@ -0,0 +1,172 @@
+/*
+ *
+ * Copyright 2016, Google Inc.
+ * All rights reserved.
+ *
+ * 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.
+ *
+ */
+
+#include <iostream>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/descriptor.pb.h>
+#include <grpc++/grpc++.h>
+
+#include "reflection/proto_server_reflection.h"
+
+using grpc::Status;
+using grpc::StatusCode;
+using google::protobuf::MethodDescriptor;
+using google::protobuf::ServiceDescriptor;
+using google::protobuf::Descriptor;
+using google::protobuf::FileDescriptor;
+using google::protobuf::FieldDescriptor;
+using google::protobuf::DescriptorPool;
+using google::protobuf::FileDescriptorProto;
+using grpc::reflection::v1alpha::EmptyRequest;
+using grpc::reflection::v1alpha::ListServiceResponse;
+using grpc::reflection::v1alpha::FileNameRequest;
+using grpc::reflection::v1alpha::SymbolRequest;
+using grpc::reflection::v1alpha::ExtensionRequest;
+using grpc::reflection::v1alpha::TypeRequest;
+using grpc::reflection::v1alpha::FileDescriptorProtoResponse;
+using grpc::reflection::v1alpha::ExtensionNumberResponse;
+
+namespace grpc {
+
+ProtoServerReflection::ProtoServerReflection()
+    : descriptor_pool_(DescriptorPool::generated_pool()) {}
+
+void ProtoServerReflection::SetServiceList(
+    const std::vector<grpc::string>* services) {
+  services_ = services;
+}
+
+Status ProtoServerReflection::ListService(ServerContext* context,
+                                          const EmptyRequest* request,
+                                          ListServiceResponse* response) {
+  if (services_ == nullptr) {
+    return Status(StatusCode::NOT_FOUND, "Services not found.");
+  }
+  for (auto it = services_->begin(); it != services_->end(); ++it) {
+    response->add_services(*it);
+  }
+  return Status::OK;
+}
+
+Status ProtoServerReflection::GetFileByName(
+    ServerContext* context, const FileNameRequest* request,
+    FileDescriptorProtoResponse* response) {
+  if (descriptor_pool_ == nullptr) {
+    return Status::CANCELLED;
+  }
+
+  const FileDescriptor* file_desc =
+      descriptor_pool_->FindFileByName(request->filename());
+  if (file_desc == nullptr) {
+    return Status(StatusCode::NOT_FOUND, "File not found.");
+  }
+  FillFileDescriptorProtoResponse(file_desc, response);
+  // file_desc->CopyTo(response->mutable_file_descriptor_proto());
+  return Status::OK;
+}
+
+Status ProtoServerReflection::GetFileContainingSymbol(
+    ServerContext* context, const SymbolRequest* request,
+    FileDescriptorProtoResponse* response) {
+  if (descriptor_pool_ == nullptr) {
+    return Status::CANCELLED;
+  }
+
+  const FileDescriptor* file_desc =
+      descriptor_pool_->FindFileContainingSymbol(request->symbol());
+  if (file_desc == nullptr) {
+    return Status(StatusCode::NOT_FOUND, "Symbol not found.");
+  }
+  FillFileDescriptorProtoResponse(file_desc, response);
+  // file_desc->CopyTo(response->mutable_file_descriptor_proto());
+  return Status::OK;
+}
+
+Status ProtoServerReflection::GetFileContainingExtension(
+    ServerContext* context, const ExtensionRequest* request,
+    FileDescriptorProtoResponse* response) {
+  if (descriptor_pool_ == nullptr) {
+    return Status::CANCELLED;
+  }
+
+  const Descriptor* desc =
+      descriptor_pool_->FindMessageTypeByName(request->containing_type());
+  if (desc == nullptr) {
+    return Status(StatusCode::NOT_FOUND, "Type not found.");
+  }
+
+  const FieldDescriptor* field_desc = descriptor_pool_->FindExtensionByNumber(
+      desc, request->extension_number());
+  if (field_desc == nullptr) {
+    return Status(StatusCode::NOT_FOUND, "Extension not found.");
+  }
+  FillFileDescriptorProtoResponse(field_desc->file(), response);
+  // field_desc->file()->CopyTo(response->mutable_file_descriptor_proto());
+  return Status::OK;
+}
+
+Status ProtoServerReflection::GetAllExtensionNumbers(
+    ServerContext* context, const TypeRequest* request,
+    ExtensionNumberResponse* response) {
+  if (descriptor_pool_ == nullptr) {
+    return Status::CANCELLED;
+  }
+
+  const Descriptor* desc =
+      descriptor_pool_->FindMessageTypeByName(request->type());
+  if (desc == nullptr) {
+    return Status(StatusCode::NOT_FOUND, "Type not found.");
+  }
+
+  std::vector<const FieldDescriptor*> extensions;
+  descriptor_pool_->FindAllExtensions(desc, &extensions);
+  for (auto extension : extensions) {
+    response->add_extension_number(extension->number());
+  }
+  return Status::OK;
+}
+
+void ProtoServerReflection::FillFileDescriptorProtoResponse(
+    const FileDescriptor* file_desc, FileDescriptorProtoResponse* response) {
+  FileDescriptorProto file_desc_proto;
+  grpc::string data;
+  file_desc->CopyTo(&file_desc_proto);
+  file_desc_proto.SerializeToString(&data);
+  response->set_file_descriptor_proto(data);
+}
+
+}  // namespace grpc
diff --git a/extensions/reflection/proto_server_reflection.h b/extensions/reflection/proto_server_reflection.h
new file mode 100644
index 0000000000..5fe23191ff
--- /dev/null
+++ b/extensions/reflection/proto_server_reflection.h
@@ -0,0 +1,92 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * 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.
+ *
+ */
+
+#ifndef GRPC_EXTENSIONS_REFLECTION_PROTO_SERVER_REFLECTION_H
+#define GRPC_EXTENSIONS_REFLECTION_PROTO_SERVER_REFLECTION_H
+
+#include <iostream>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/descriptor.pb.h>
+#include <grpc++/grpc++.h>
+
+#include <grpc++/impl/reflection.grpc.pb.h>
+
+namespace grpc {
+
+class ProtoServerReflection GRPC_FINAL
+    : public reflection::v1alpha::ServerReflection::Service {
+ public:
+  ProtoServerReflection();
+
+  ProtoServerReflection(const Server* server);
+
+  void SetServiceList(const std::vector<grpc::string>* services);
+
+  Status ListService(
+      ServerContext* context, const reflection::v1alpha::EmptyRequest* request,
+      reflection::v1alpha::ListServiceResponse* response) GRPC_OVERRIDE;
+
+  Status GetFileByName(
+      ServerContext* context,
+      const reflection::v1alpha::FileNameRequest* request,
+      reflection::v1alpha::FileDescriptorProtoResponse* response) GRPC_OVERRIDE;
+
+  Status GetFileContainingSymbol(
+      ServerContext* context, const reflection::v1alpha::SymbolRequest* request,
+      reflection::v1alpha::FileDescriptorProtoResponse* response) GRPC_OVERRIDE;
+
+  Status GetFileContainingExtension(
+      ServerContext* context,
+      const reflection::v1alpha::ExtensionRequest* request,
+      reflection::v1alpha::FileDescriptorProtoResponse* response) GRPC_OVERRIDE;
+
+  Status GetAllExtensionNumbers(
+      ServerContext* context, const reflection::v1alpha::TypeRequest* request,
+      reflection::v1alpha::ExtensionNumberResponse* response) GRPC_OVERRIDE;
+
+ private:
+  void FillFileDescriptorProtoResponse(
+      const google::protobuf::FileDescriptor* file_desc,
+      reflection::v1alpha::FileDescriptorProtoResponse* response);
+
+  const google::protobuf::DescriptorPool* descriptor_pool_;
+  const std::vector<string>* services_;
+};
+
+}  // namespace grpc
+
+#endif  // GRPC_EXTENSIONS_REFLECTION_PROTO_SERVER_REFLECTION_H
diff --git a/extensions/reflection/proto_server_reflection_plugin.cc b/extensions/reflection/proto_server_reflection_plugin.cc
new file mode 100644
index 0000000000..6adfa45047
--- /dev/null
+++ b/extensions/reflection/proto_server_reflection_plugin.cc
@@ -0,0 +1,89 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * 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.
+ *
+ */
+
+#include <grpc++/impl/proto_server_reflection_plugin.h>
+#include <grpc++/impl/server_builder_plugin.h>
+#include <grpc++/impl/server_initializer.h>
+#include <grpc++/server.h>
+
+#include "reflection/proto_server_reflection.h"
+
+namespace grpc {
+namespace reflection {
+
+ProtoServerReflectionPlugin::ProtoServerReflectionPlugin()
+    : reflection_service(new grpc::ProtoServerReflection()) {}
+
+grpc::string ProtoServerReflectionPlugin::name() { return "p1"; }
+
+void ProtoServerReflectionPlugin::InitServer(grpc::ServerInitializer* si) {
+  si->RegisterService(reflection_service);
+}
+
+void ProtoServerReflectionPlugin::Finish(grpc::ServerInitializer* si) {
+  reflection_service->SetServiceList(si->GetServiceList());
+}
+
+void ProtoServerReflectionPlugin::ChangeArguments(const grpc::string& name,
+                                                  void* value) {}
+
+bool ProtoServerReflectionPlugin::has_sync_methods() const {
+  if (reflection_service != nullptr) {
+    return reflection_service->has_synchronous_methods();
+  }
+  return false;
+}
+
+bool ProtoServerReflectionPlugin::has_async_methods() const {
+  if (reflection_service != nullptr) {
+    return reflection_service->has_async_methods();
+  }
+  return false;
+}
+
+void grpc_AddServerBuilderPlugin_reflection() {
+  static bool already_here = false;
+  if (already_here) return;
+  already_here = true;
+  ::grpc::ServerBuilder::InternalAddPluginFactory(&CreateProtoReflection);
+}
+
+// Force AddServerBuilderPlugin() to be called at static initialization time.
+struct StaticPluginInitializer_reflection {
+  StaticPluginInitializer_reflection() {
+    grpc_AddServerBuilderPlugin_reflection();
+  }
+} static_plugin_initializer_reflection_;
+
+}  // namespace reflection
+}  // namespace grpc
diff --git a/extensions/reflection/reflection.grpc.pb.cc b/extensions/reflection/reflection.grpc.pb.cc
new file mode 100644
index 0000000000..c098e52752
--- /dev/null
+++ b/extensions/reflection/reflection.grpc.pb.cc
@@ -0,0 +1,245 @@
+// Generated by the gRPC protobuf plugin.
+// If you make any local change, they will be lost.
+// source: reflection.proto
+
+#include <grpc++/impl/reflection.grpc.pb.h>
+#include <grpc++/impl/reflection.pb.h>
+
+#include <grpc++/impl/codegen/async_stream.h>
+#include <grpc++/impl/codegen/async_unary_call.h>
+#include <grpc++/impl/codegen/channel_interface.h>
+#include <grpc++/impl/codegen/client_unary_call.h>
+#include <grpc++/impl/codegen/method_handler_impl.h>
+#include <grpc++/impl/codegen/rpc_service_method.h>
+#include <grpc++/impl/codegen/service_type.h>
+#include <grpc++/impl/codegen/sync_stream.h>
+namespace grpc {
+namespace reflection {
+namespace v1alpha {
+
+static const char* ServerReflection_method_names[] = {
+    "/grpc.reflection.v1alpha.ServerReflection/ListService",
+    "/grpc.reflection.v1alpha.ServerReflection/GetFileByName",
+    "/grpc.reflection.v1alpha.ServerReflection/GetFileContainingSymbol",
+    "/grpc.reflection.v1alpha.ServerReflection/GetFileContainingExtension",
+    "/grpc.reflection.v1alpha.ServerReflection/GetAllExtensionNumbers",
+};
+
+std::unique_ptr<ServerReflection::Stub> ServerReflection::NewStub(
+    const std::shared_ptr< ::grpc::ChannelInterface>& channel,
+    const ::grpc::StubOptions& options) {
+  std::unique_ptr<ServerReflection::Stub> stub(
+      new ServerReflection::Stub(channel));
+  return stub;
+}
+
+ServerReflection::Stub::Stub(
+    const std::shared_ptr< ::grpc::ChannelInterface>& channel)
+    : channel_(channel),
+      rpcmethod_ListService_(ServerReflection_method_names[0],
+                             ::grpc::RpcMethod::NORMAL_RPC, channel),
+      rpcmethod_GetFileByName_(ServerReflection_method_names[1],
+                               ::grpc::RpcMethod::NORMAL_RPC, channel),
+      rpcmethod_GetFileContainingSymbol_(ServerReflection_method_names[2],
+                                         ::grpc::RpcMethod::NORMAL_RPC,
+                                         channel),
+      rpcmethod_GetFileContainingExtension_(ServerReflection_method_names[3],
+                                            ::grpc::RpcMethod::NORMAL_RPC,
+                                            channel),
+      rpcmethod_GetAllExtensionNumbers_(ServerReflection_method_names[4],
+                                        ::grpc::RpcMethod::NORMAL_RPC,
+                                        channel) {}
+
+::grpc::Status ServerReflection::Stub::ListService(
+    ::grpc::ClientContext* context,
+    const ::grpc::reflection::v1alpha::EmptyRequest& request,
+    ::grpc::reflection::v1alpha::ListServiceResponse* response) {
+  return ::grpc::BlockingUnaryCall(channel_.get(), rpcmethod_ListService_,
+                                   context, request, response);
+}
+
+::grpc::ClientAsyncResponseReader<
+    ::grpc::reflection::v1alpha::ListServiceResponse>*
+ServerReflection::Stub::AsyncListServiceRaw(
+    ::grpc::ClientContext* context,
+    const ::grpc::reflection::v1alpha::EmptyRequest& request,
+    ::grpc::CompletionQueue* cq) {
+  return new ::grpc::ClientAsyncResponseReader<
+      ::grpc::reflection::v1alpha::ListServiceResponse>(
+      channel_.get(), cq, rpcmethod_ListService_, context, request);
+}
+
+::grpc::Status ServerReflection::Stub::GetFileByName(
+    ::grpc::ClientContext* context,
+    const ::grpc::reflection::v1alpha::FileNameRequest& request,
+    ::grpc::reflection::v1alpha::FileDescriptorProtoResponse* response) {
+  return ::grpc::BlockingUnaryCall(channel_.get(), rpcmethod_GetFileByName_,
+                                   context, request, response);
+}
+
+::grpc::ClientAsyncResponseReader<
+    ::grpc::reflection::v1alpha::FileDescriptorProtoResponse>*
+ServerReflection::Stub::AsyncGetFileByNameRaw(
+    ::grpc::ClientContext* context,
+    const ::grpc::reflection::v1alpha::FileNameRequest& request,
+    ::grpc::CompletionQueue* cq) {
+  return new ::grpc::ClientAsyncResponseReader<
+      ::grpc::reflection::v1alpha::FileDescriptorProtoResponse>(
+      channel_.get(), cq, rpcmethod_GetFileByName_, context, request);
+}
+
+::grpc::Status ServerReflection::Stub::GetFileContainingSymbol(
+    ::grpc::ClientContext* context,
+    const ::grpc::reflection::v1alpha::SymbolRequest& request,
+    ::grpc::reflection::v1alpha::FileDescriptorProtoResponse* response) {
+  return ::grpc::BlockingUnaryCall(channel_.get(),
+                                   rpcmethod_GetFileContainingSymbol_, context,
+                                   request, response);
+}
+
+::grpc::ClientAsyncResponseReader<
+    ::grpc::reflection::v1alpha::FileDescriptorProtoResponse>*
+ServerReflection::Stub::AsyncGetFileContainingSymbolRaw(
+    ::grpc::ClientContext* context,
+    const ::grpc::reflection::v1alpha::SymbolRequest& request,
+    ::grpc::CompletionQueue* cq) {
+  return new ::grpc::ClientAsyncResponseReader<
+      ::grpc::reflection::v1alpha::FileDescriptorProtoResponse>(
+      channel_.get(), cq, rpcmethod_GetFileContainingSymbol_, context, request);
+}
+
+::grpc::Status ServerReflection::Stub::GetFileContainingExtension(
+    ::grpc::ClientContext* context,
+    const ::grpc::reflection::v1alpha::ExtensionRequest& request,
+    ::grpc::reflection::v1alpha::FileDescriptorProtoResponse* response) {
+  return ::grpc::BlockingUnaryCall(channel_.get(),
+                                   rpcmethod_GetFileContainingExtension_,
+                                   context, request, response);
+}
+
+::grpc::ClientAsyncResponseReader<
+    ::grpc::reflection::v1alpha::FileDescriptorProtoResponse>*
+ServerReflection::Stub::AsyncGetFileContainingExtensionRaw(
+    ::grpc::ClientContext* context,
+    const ::grpc::reflection::v1alpha::ExtensionRequest& request,
+    ::grpc::CompletionQueue* cq) {
+  return new ::grpc::ClientAsyncResponseReader<
+      ::grpc::reflection::v1alpha::FileDescriptorProtoResponse>(
+      channel_.get(), cq, rpcmethod_GetFileContainingExtension_, context,
+      request);
+}
+
+::grpc::Status ServerReflection::Stub::GetAllExtensionNumbers(
+    ::grpc::ClientContext* context,
+    const ::grpc::reflection::v1alpha::TypeRequest& request,
+    ::grpc::reflection::v1alpha::ExtensionNumberResponse* response) {
+  return ::grpc::BlockingUnaryCall(channel_.get(),
+                                   rpcmethod_GetAllExtensionNumbers_, context,
+                                   request, response);
+}
+
+::grpc::ClientAsyncResponseReader<
+    ::grpc::reflection::v1alpha::ExtensionNumberResponse>*
+ServerReflection::Stub::AsyncGetAllExtensionNumbersRaw(
+    ::grpc::ClientContext* context,
+    const ::grpc::reflection::v1alpha::TypeRequest& request,
+    ::grpc::CompletionQueue* cq) {
+  return new ::grpc::ClientAsyncResponseReader<
+      ::grpc::reflection::v1alpha::ExtensionNumberResponse>(
+      channel_.get(), cq, rpcmethod_GetAllExtensionNumbers_, context, request);
+}
+
+ServerReflection::Service::Service() {
+  (void)ServerReflection_method_names;
+  AddMethod(new ::grpc::RpcServiceMethod(
+      ServerReflection_method_names[0], ::grpc::RpcMethod::NORMAL_RPC,
+      new ::grpc::RpcMethodHandler<
+          ServerReflection::Service, ::grpc::reflection::v1alpha::EmptyRequest,
+          ::grpc::reflection::v1alpha::ListServiceResponse>(
+          std::mem_fn(&ServerReflection::Service::ListService), this)));
+  AddMethod(new ::grpc::RpcServiceMethod(
+      ServerReflection_method_names[1], ::grpc::RpcMethod::NORMAL_RPC,
+      new ::grpc::RpcMethodHandler<
+          ServerReflection::Service,
+          ::grpc::reflection::v1alpha::FileNameRequest,
+          ::grpc::reflection::v1alpha::FileDescriptorProtoResponse>(
+          std::mem_fn(&ServerReflection::Service::GetFileByName), this)));
+  AddMethod(new ::grpc::RpcServiceMethod(
+      ServerReflection_method_names[2], ::grpc::RpcMethod::NORMAL_RPC,
+      new ::grpc::RpcMethodHandler<
+          ServerReflection::Service, ::grpc::reflection::v1alpha::SymbolRequest,
+          ::grpc::reflection::v1alpha::FileDescriptorProtoResponse>(
+          std::mem_fn(&ServerReflection::Service::GetFileContainingSymbol),
+          this)));
+  AddMethod(new ::grpc::RpcServiceMethod(
+      ServerReflection_method_names[3], ::grpc::RpcMethod::NORMAL_RPC,
+      new ::grpc::RpcMethodHandler<
+          ServerReflection::Service,
+          ::grpc::reflection::v1alpha::ExtensionRequest,
+          ::grpc::reflection::v1alpha::FileDescriptorProtoResponse>(
+          std::mem_fn(&ServerReflection::Service::GetFileContainingExtension),
+          this)));
+  AddMethod(new ::grpc::RpcServiceMethod(
+      ServerReflection_method_names[4], ::grpc::RpcMethod::NORMAL_RPC,
+      new ::grpc::RpcMethodHandler<
+          ServerReflection::Service, ::grpc::reflection::v1alpha::TypeRequest,
+          ::grpc::reflection::v1alpha::ExtensionNumberResponse>(
+          std::mem_fn(&ServerReflection::Service::GetAllExtensionNumbers),
+          this)));
+}
+
+ServerReflection::Service::~Service() {}
+
+::grpc::Status ServerReflection::Service::ListService(
+    ::grpc::ServerContext* context,
+    const ::grpc::reflection::v1alpha::EmptyRequest* request,
+    ::grpc::reflection::v1alpha::ListServiceResponse* response) {
+  (void)context;
+  (void)request;
+  (void)response;
+  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+}
+
+::grpc::Status ServerReflection::Service::GetFileByName(
+    ::grpc::ServerContext* context,
+    const ::grpc::reflection::v1alpha::FileNameRequest* request,
+    ::grpc::reflection::v1alpha::FileDescriptorProtoResponse* response) {
+  (void)context;
+  (void)request;
+  (void)response;
+  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+}
+
+::grpc::Status ServerReflection::Service::GetFileContainingSymbol(
+    ::grpc::ServerContext* context,
+    const ::grpc::reflection::v1alpha::SymbolRequest* request,
+    ::grpc::reflection::v1alpha::FileDescriptorProtoResponse* response) {
+  (void)context;
+  (void)request;
+  (void)response;
+  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+}
+
+::grpc::Status ServerReflection::Service::GetFileContainingExtension(
+    ::grpc::ServerContext* context,
+    const ::grpc::reflection::v1alpha::ExtensionRequest* request,
+    ::grpc::reflection::v1alpha::FileDescriptorProtoResponse* response) {
+  (void)context;
+  (void)request;
+  (void)response;
+  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+}
+
+::grpc::Status ServerReflection::Service::GetAllExtensionNumbers(
+    ::grpc::ServerContext* context,
+    const ::grpc::reflection::v1alpha::TypeRequest* request,
+    ::grpc::reflection::v1alpha::ExtensionNumberResponse* response) {
+  (void)context;
+  (void)request;
+  (void)response;
+  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+}
+
+}  // namespace grpc
+}  // namespace reflection
+}  // namespace v1alpha
diff --git a/extensions/reflection/reflection.pb.cc b/extensions/reflection/reflection.pb.cc
new file mode 100644
index 0000000000..97b3cb8791
--- /dev/null
+++ b/extensions/reflection/reflection.pb.cc
@@ -0,0 +1,2448 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: reflection.proto
+
+#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION
+#include <grpc++/impl/reflection.pb.h>
+
+#include <algorithm>
+
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/generated_message_reflection.h>
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/reflection_ops.h>
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/once.h>
+#include <google/protobuf/stubs/port.h>
+#include <google/protobuf/wire_format.h>
+#include <google/protobuf/wire_format_lite_inl.h>
+// @@protoc_insertion_point(includes)
+
+namespace grpc {
+namespace reflection {
+namespace v1alpha {
+
+namespace {
+
+const ::google::protobuf::Descriptor* EmptyRequest_descriptor_ = NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+    EmptyRequest_reflection_ = NULL;
+const ::google::protobuf::Descriptor* FileNameRequest_descriptor_ = NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+    FileNameRequest_reflection_ = NULL;
+const ::google::protobuf::Descriptor* SymbolRequest_descriptor_ = NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+    SymbolRequest_reflection_ = NULL;
+const ::google::protobuf::Descriptor* ExtensionRequest_descriptor_ = NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+    ExtensionRequest_reflection_ = NULL;
+const ::google::protobuf::Descriptor* TypeRequest_descriptor_ = NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+    TypeRequest_reflection_ = NULL;
+const ::google::protobuf::Descriptor* ListServiceResponse_descriptor_ = NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+    ListServiceResponse_reflection_ = NULL;
+const ::google::protobuf::Descriptor* FileDescriptorProtoResponse_descriptor_ =
+    NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+    FileDescriptorProtoResponse_reflection_ = NULL;
+const ::google::protobuf::Descriptor* ExtensionNumberResponse_descriptor_ =
+    NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+    ExtensionNumberResponse_reflection_ = NULL;
+
+}  // namespace
+
+void protobuf_AssignDesc_reflection_2eproto() {
+  protobuf_AddDesc_reflection_2eproto();
+  const ::google::protobuf::FileDescriptor* file =
+      ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName(
+          "reflection.proto");
+  GOOGLE_CHECK(file != NULL);
+  EmptyRequest_descriptor_ = file->message_type(0);
+  static const int EmptyRequest_offsets_[1] = {};
+  EmptyRequest_reflection_ = ::google::protobuf::internal::
+      GeneratedMessageReflection::NewGeneratedMessageReflection(
+          EmptyRequest_descriptor_, EmptyRequest::default_instance_,
+          EmptyRequest_offsets_, -1, -1, -1, sizeof(EmptyRequest),
+          GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EmptyRequest,
+                                                         _internal_metadata_),
+          GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(
+              EmptyRequest, _is_default_instance_));
+  FileNameRequest_descriptor_ = file->message_type(1);
+  static const int FileNameRequest_offsets_[1] = {
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileNameRequest,
+                                                     filename_),
+  };
+  FileNameRequest_reflection_ = ::google::protobuf::internal::
+      GeneratedMessageReflection::NewGeneratedMessageReflection(
+          FileNameRequest_descriptor_, FileNameRequest::default_instance_,
+          FileNameRequest_offsets_, -1, -1, -1, sizeof(FileNameRequest),
+          GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileNameRequest,
+                                                         _internal_metadata_),
+          GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(
+              FileNameRequest, _is_default_instance_));
+  SymbolRequest_descriptor_ = file->message_type(2);
+  static const int SymbolRequest_offsets_[1] = {
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SymbolRequest, symbol_),
+  };
+  SymbolRequest_reflection_ = ::google::protobuf::internal::
+      GeneratedMessageReflection::NewGeneratedMessageReflection(
+          SymbolRequest_descriptor_, SymbolRequest::default_instance_,
+          SymbolRequest_offsets_, -1, -1, -1, sizeof(SymbolRequest),
+          GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SymbolRequest,
+                                                         _internal_metadata_),
+          GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(
+              SymbolRequest, _is_default_instance_));
+  ExtensionRequest_descriptor_ = file->message_type(3);
+  static const int ExtensionRequest_offsets_[2] = {
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ExtensionRequest,
+                                                     containing_type_),
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ExtensionRequest,
+                                                     extension_number_),
+  };
+  ExtensionRequest_reflection_ = ::google::protobuf::internal::
+      GeneratedMessageReflection::NewGeneratedMessageReflection(
+          ExtensionRequest_descriptor_, ExtensionRequest::default_instance_,
+          ExtensionRequest_offsets_, -1, -1, -1, sizeof(ExtensionRequest),
+          GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ExtensionRequest,
+                                                         _internal_metadata_),
+          GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(
+              ExtensionRequest, _is_default_instance_));
+  TypeRequest_descriptor_ = file->message_type(4);
+  static const int TypeRequest_offsets_[1] = {
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(TypeRequest, type_),
+  };
+  TypeRequest_reflection_ = ::google::protobuf::internal::
+      GeneratedMessageReflection::NewGeneratedMessageReflection(
+          TypeRequest_descriptor_, TypeRequest::default_instance_,
+          TypeRequest_offsets_, -1, -1, -1, sizeof(TypeRequest),
+          GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(TypeRequest,
+                                                         _internal_metadata_),
+          GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(
+              TypeRequest, _is_default_instance_));
+  ListServiceResponse_descriptor_ = file->message_type(5);
+  static const int ListServiceResponse_offsets_[1] = {
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ListServiceResponse,
+                                                     services_),
+  };
+  ListServiceResponse_reflection_ = ::google::protobuf::internal::
+      GeneratedMessageReflection::NewGeneratedMessageReflection(
+          ListServiceResponse_descriptor_,
+          ListServiceResponse::default_instance_, ListServiceResponse_offsets_,
+          -1, -1, -1, sizeof(ListServiceResponse),
+          GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ListServiceResponse,
+                                                         _internal_metadata_),
+          GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(
+              ListServiceResponse, _is_default_instance_));
+  FileDescriptorProtoResponse_descriptor_ = file->message_type(6);
+  static const int FileDescriptorProtoResponse_offsets_[1] = {
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(
+          FileDescriptorProtoResponse, file_descriptor_proto_),
+  };
+  FileDescriptorProtoResponse_reflection_ = ::google::protobuf::internal::
+      GeneratedMessageReflection::NewGeneratedMessageReflection(
+          FileDescriptorProtoResponse_descriptor_,
+          FileDescriptorProtoResponse::default_instance_,
+          FileDescriptorProtoResponse_offsets_, -1, -1, -1,
+          sizeof(FileDescriptorProtoResponse),
+          GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(
+              FileDescriptorProtoResponse, _internal_metadata_),
+          GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(
+              FileDescriptorProtoResponse, _is_default_instance_));
+  ExtensionNumberResponse_descriptor_ = file->message_type(7);
+  static const int ExtensionNumberResponse_offsets_[1] = {
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ExtensionNumberResponse,
+                                                     extension_number_),
+  };
+  ExtensionNumberResponse_reflection_ = ::google::protobuf::internal::
+      GeneratedMessageReflection::NewGeneratedMessageReflection(
+          ExtensionNumberResponse_descriptor_,
+          ExtensionNumberResponse::default_instance_,
+          ExtensionNumberResponse_offsets_, -1, -1, -1,
+          sizeof(ExtensionNumberResponse),
+          GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(
+              ExtensionNumberResponse, _internal_metadata_),
+          GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(
+              ExtensionNumberResponse, _is_default_instance_));
+}
+
+namespace {
+
+GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_);
+inline void protobuf_AssignDescriptorsOnce() {
+  ::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_,
+                                     &protobuf_AssignDesc_reflection_2eproto);
+}
+
+void protobuf_RegisterTypes(const ::std::string&) {
+  protobuf_AssignDescriptorsOnce();
+  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
+      EmptyRequest_descriptor_, &EmptyRequest::default_instance());
+  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
+      FileNameRequest_descriptor_, &FileNameRequest::default_instance());
+  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
+      SymbolRequest_descriptor_, &SymbolRequest::default_instance());
+  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
+      ExtensionRequest_descriptor_, &ExtensionRequest::default_instance());
+  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
+      TypeRequest_descriptor_, &TypeRequest::default_instance());
+  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
+      ListServiceResponse_descriptor_,
+      &ListServiceResponse::default_instance());
+  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
+      FileDescriptorProtoResponse_descriptor_,
+      &FileDescriptorProtoResponse::default_instance());
+  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
+      ExtensionNumberResponse_descriptor_,
+      &ExtensionNumberResponse::default_instance());
+}
+
+}  // namespace
+
+void protobuf_ShutdownFile_reflection_2eproto() {
+  delete EmptyRequest::default_instance_;
+  delete EmptyRequest_reflection_;
+  delete FileNameRequest::default_instance_;
+  delete FileNameRequest_reflection_;
+  delete SymbolRequest::default_instance_;
+  delete SymbolRequest_reflection_;
+  delete ExtensionRequest::default_instance_;
+  delete ExtensionRequest_reflection_;
+  delete TypeRequest::default_instance_;
+  delete TypeRequest_reflection_;
+  delete ListServiceResponse::default_instance_;
+  delete ListServiceResponse_reflection_;
+  delete FileDescriptorProtoResponse::default_instance_;
+  delete FileDescriptorProtoResponse_reflection_;
+  delete ExtensionNumberResponse::default_instance_;
+  delete ExtensionNumberResponse_reflection_;
+}
+
+void protobuf_AddDesc_reflection_2eproto() {
+  static bool already_here = false;
+  if (already_here) return;
+  already_here = true;
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  ::google::protobuf::DescriptorPool::InternalAddGeneratedFile(
+      "\n\020reflection.proto\022\027grpc.reflection.v1al"
+      "pha\"\016\n\014EmptyRequest\"#\n\017FileNameRequest\022\020"
+      "\n\010filename\030\001 \001(\t\"\037\n\rSymbolRequest\022\016\n\006sym"
+      "bol\030\001 \001(\t\"E\n\020ExtensionRequest\022\027\n\017contain"
+      "ing_type\030\001 \001(\t\022\030\n\020extension_number\030\002 \001(\005"
+      "\"\033\n\013TypeRequest\022\014\n\004type\030\001 "
+      "\001(\t\"\'\n\023ListSer"
+      "viceResponse\022\020\n\010services\030\001 \003(\t\"<\n\033FileDe"
+      "scriptorProtoResponse\022\035\n\025file_descriptor"
+      "_proto\030\001 \001(\014\"3\n\027ExtensionNumberResponse\022"
+      "\030\n\020extension_number\030\001 \003(\0052\333\004\n\020ServerRefl"
+      "ection\022d\n\013ListService\022%.grpc.reflection."
+      "v1alpha.EmptyRequest\032,.grpc.reflection.v"
+      "1alpha.ListServiceResponse\"\000\022q\n\rGetFileB"
+      "yName\022(.grpc.reflection.v1alpha.FileName"
+      "Request\0324.grpc.reflection.v1alpha.FileDe"
+      "scriptorProtoResponse\"\000\022y\n\027GetFileContai"
+      "ningSymbol\022&.grpc.reflection.v1alpha.Sym"
+      "bolRequest\0324.grpc.reflection.v1alpha.Fil"
+      "eDescriptorProtoResponse\"\000\022\177\n\032GetFileCon"
+      "tainingExtension\022).grpc.reflection.v1alp"
+      "ha.ExtensionRequest\0324.grpc.reflection.v1"
+      "alpha.FileDescriptorProtoResponse\"\000\022r\n\026G"
+      "etAllExtensionNumbers\022$.grpc.reflection."
+      "v1alpha.TypeRequest\0320.grpc.reflection.v1"
+      "alpha.ExtensionNumberResponse\"\000b\006proto3",
+      999);
+  ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
+      "reflection.proto", &protobuf_RegisterTypes);
+  EmptyRequest::default_instance_ = new EmptyRequest();
+  FileNameRequest::default_instance_ = new FileNameRequest();
+  SymbolRequest::default_instance_ = new SymbolRequest();
+  ExtensionRequest::default_instance_ = new ExtensionRequest();
+  TypeRequest::default_instance_ = new TypeRequest();
+  ListServiceResponse::default_instance_ = new ListServiceResponse();
+  FileDescriptorProtoResponse::default_instance_ =
+      new FileDescriptorProtoResponse();
+  ExtensionNumberResponse::default_instance_ = new ExtensionNumberResponse();
+  EmptyRequest::default_instance_->InitAsDefaultInstance();
+  FileNameRequest::default_instance_->InitAsDefaultInstance();
+  SymbolRequest::default_instance_->InitAsDefaultInstance();
+  ExtensionRequest::default_instance_->InitAsDefaultInstance();
+  TypeRequest::default_instance_->InitAsDefaultInstance();
+  ListServiceResponse::default_instance_->InitAsDefaultInstance();
+  FileDescriptorProtoResponse::default_instance_->InitAsDefaultInstance();
+  ExtensionNumberResponse::default_instance_->InitAsDefaultInstance();
+  ::google::protobuf::internal::OnShutdown(
+      &protobuf_ShutdownFile_reflection_2eproto);
+}
+
+// Force AddDescriptors() to be called at static initialization time.
+struct StaticDescriptorInitializer_reflection_2eproto {
+  StaticDescriptorInitializer_reflection_2eproto() {
+    protobuf_AddDesc_reflection_2eproto();
+  }
+} static_descriptor_initializer_reflection_2eproto_;
+
+namespace {
+
+static void MergeFromFail(int line) GOOGLE_ATTRIBUTE_COLD;
+static void MergeFromFail(int line) {
+  GOOGLE_CHECK(false) << __FILE__ << ":" << line;
+}
+
+}  // namespace
+
+// ===================================================================
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+EmptyRequest::EmptyRequest()
+    : ::google::protobuf::Message(), _internal_metadata_(NULL) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:grpc.reflection.v1alpha.EmptyRequest)
+}
+
+void EmptyRequest::InitAsDefaultInstance() { _is_default_instance_ = true; }
+
+EmptyRequest::EmptyRequest(const EmptyRequest& from)
+    : ::google::protobuf::Message(), _internal_metadata_(NULL) {
+  SharedCtor();
+  MergeFrom(from);
+  // @@protoc_insertion_point(copy_constructor:grpc.reflection.v1alpha.EmptyRequest)
+}
+
+void EmptyRequest::SharedCtor() {
+  _is_default_instance_ = false;
+  _cached_size_ = 0;
+}
+
+EmptyRequest::~EmptyRequest() {
+  // @@protoc_insertion_point(destructor:grpc.reflection.v1alpha.EmptyRequest)
+  SharedDtor();
+}
+
+void EmptyRequest::SharedDtor() {
+  if (this != default_instance_) {
+  }
+}
+
+void EmptyRequest::SetCachedSize(int size) const {
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const ::google::protobuf::Descriptor* EmptyRequest::descriptor() {
+  protobuf_AssignDescriptorsOnce();
+  return EmptyRequest_descriptor_;
+}
+
+const EmptyRequest& EmptyRequest::default_instance() {
+  if (default_instance_ == NULL) protobuf_AddDesc_reflection_2eproto();
+  return *default_instance_;
+}
+
+EmptyRequest* EmptyRequest::default_instance_ = NULL;
+
+EmptyRequest* EmptyRequest::New(::google::protobuf::Arena* arena) const {
+  EmptyRequest* n = new EmptyRequest;
+  if (arena != NULL) {
+    arena->Own(n);
+  }
+  return n;
+}
+
+void EmptyRequest::Clear() {}
+
+bool EmptyRequest::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) \
+  if (!(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:grpc.reflection.v1alpha.EmptyRequest)
+  for (;;) {
+    ::std::pair< ::google::protobuf::uint32, bool> p =
+        input->ReadTagWithCutoff(127);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+  handle_unusual:
+    if (tag == 0 ||
+        ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
+      goto success;
+    }
+    DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag));
+  }
+success:
+  // @@protoc_insertion_point(parse_success:grpc.reflection.v1alpha.EmptyRequest)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:grpc.reflection.v1alpha.EmptyRequest)
+  return false;
+#undef DO_
+}
+
+void EmptyRequest::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:grpc.reflection.v1alpha.EmptyRequest)
+  // @@protoc_insertion_point(serialize_end:grpc.reflection.v1alpha.EmptyRequest)
+}
+
+::google::protobuf::uint8* EmptyRequest::SerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:grpc.reflection.v1alpha.EmptyRequest)
+  // @@protoc_insertion_point(serialize_to_array_end:grpc.reflection.v1alpha.EmptyRequest)
+  return target;
+}
+
+int EmptyRequest::ByteSize() const {
+  int total_size = 0;
+
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = total_size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+  return total_size;
+}
+
+void EmptyRequest::MergeFrom(const ::google::protobuf::Message& from) {
+  if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+  const EmptyRequest* source =
+      ::google::protobuf::internal::DynamicCastToGenerated<const EmptyRequest>(
+          &from);
+  if (source == NULL) {
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+    MergeFrom(*source);
+  }
+}
+
+void EmptyRequest::MergeFrom(const EmptyRequest& from) {
+  if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+}
+
+void EmptyRequest::CopyFrom(const ::google::protobuf::Message& from) {
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void EmptyRequest::CopyFrom(const EmptyRequest& from) {
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool EmptyRequest::IsInitialized() const { return true; }
+
+void EmptyRequest::Swap(EmptyRequest* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void EmptyRequest::InternalSwap(EmptyRequest* other) {
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  std::swap(_cached_size_, other->_cached_size_);
+}
+
+::google::protobuf::Metadata EmptyRequest::GetMetadata() const {
+  protobuf_AssignDescriptorsOnce();
+  ::google::protobuf::Metadata metadata;
+  metadata.descriptor = EmptyRequest_descriptor_;
+  metadata.reflection = EmptyRequest_reflection_;
+  return metadata;
+}
+
+#if PROTOBUF_INLINE_NOT_IN_HEADERS
+// EmptyRequest
+
+#endif  // PROTOBUF_INLINE_NOT_IN_HEADERS
+
+// ===================================================================
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int FileNameRequest::kFilenameFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+FileNameRequest::FileNameRequest()
+    : ::google::protobuf::Message(), _internal_metadata_(NULL) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:grpc.reflection.v1alpha.FileNameRequest)
+}
+
+void FileNameRequest::InitAsDefaultInstance() { _is_default_instance_ = true; }
+
+FileNameRequest::FileNameRequest(const FileNameRequest& from)
+    : ::google::protobuf::Message(), _internal_metadata_(NULL) {
+  SharedCtor();
+  MergeFrom(from);
+  // @@protoc_insertion_point(copy_constructor:grpc.reflection.v1alpha.FileNameRequest)
+}
+
+void FileNameRequest::SharedCtor() {
+  _is_default_instance_ = false;
+  ::google::protobuf::internal::GetEmptyString();
+  _cached_size_ = 0;
+  filename_.UnsafeSetDefault(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+
+FileNameRequest::~FileNameRequest() {
+  // @@protoc_insertion_point(destructor:grpc.reflection.v1alpha.FileNameRequest)
+  SharedDtor();
+}
+
+void FileNameRequest::SharedDtor() {
+  filename_.DestroyNoArena(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (this != default_instance_) {
+  }
+}
+
+void FileNameRequest::SetCachedSize(int size) const {
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const ::google::protobuf::Descriptor* FileNameRequest::descriptor() {
+  protobuf_AssignDescriptorsOnce();
+  return FileNameRequest_descriptor_;
+}
+
+const FileNameRequest& FileNameRequest::default_instance() {
+  if (default_instance_ == NULL) protobuf_AddDesc_reflection_2eproto();
+  return *default_instance_;
+}
+
+FileNameRequest* FileNameRequest::default_instance_ = NULL;
+
+FileNameRequest* FileNameRequest::New(::google::protobuf::Arena* arena) const {
+  FileNameRequest* n = new FileNameRequest;
+  if (arena != NULL) {
+    arena->Own(n);
+  }
+  return n;
+}
+
+void FileNameRequest::Clear() {
+  filename_.ClearToEmptyNoArena(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+
+bool FileNameRequest::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) \
+  if (!(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:grpc.reflection.v1alpha.FileNameRequest)
+  for (;;) {
+    ::std::pair< ::google::protobuf::uint32, bool> p =
+        input->ReadTagWithCutoff(127);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (
+        ::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // optional string filename = 1;
+      case 1: {
+        if (tag == 10) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+              input, this->mutable_filename()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+              this->filename().data(), this->filename().length(),
+              ::google::protobuf::internal::WireFormatLite::PARSE,
+              "grpc.reflection.v1alpha.FileNameRequest.filename"));
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectAtEnd()) goto success;
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0 ||
+            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+                ::google::protobuf::internal::WireFormatLite::
+                    WIRETYPE_END_GROUP) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormatLite::SkipField(input,
+                                                                    tag));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:grpc.reflection.v1alpha.FileNameRequest)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:grpc.reflection.v1alpha.FileNameRequest)
+  return false;
+#undef DO_
+}
+
+void FileNameRequest::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:grpc.reflection.v1alpha.FileNameRequest)
+  // optional string filename = 1;
+  if (this->filename().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+        this->filename().data(), this->filename().length(),
+        ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+        "grpc.reflection.v1alpha.FileNameRequest.filename");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+        1, this->filename(), output);
+  }
+
+  // @@protoc_insertion_point(serialize_end:grpc.reflection.v1alpha.FileNameRequest)
+}
+
+::google::protobuf::uint8* FileNameRequest::SerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:grpc.reflection.v1alpha.FileNameRequest)
+  // optional string filename = 1;
+  if (this->filename().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+        this->filename().data(), this->filename().length(),
+        ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+        "grpc.reflection.v1alpha.FileNameRequest.filename");
+    target = ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        1, this->filename(), target);
+  }
+
+  // @@protoc_insertion_point(serialize_to_array_end:grpc.reflection.v1alpha.FileNameRequest)
+  return target;
+}
+
+int FileNameRequest::ByteSize() const {
+  int total_size = 0;
+
+  // optional string filename = 1;
+  if (this->filename().size() > 0) {
+    total_size += 1 + ::google::protobuf::internal::WireFormatLite::StringSize(
+                          this->filename());
+  }
+
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = total_size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+  return total_size;
+}
+
+void FileNameRequest::MergeFrom(const ::google::protobuf::Message& from) {
+  if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+  const FileNameRequest* source =
+      ::google::protobuf::internal::DynamicCastToGenerated<
+          const FileNameRequest>(&from);
+  if (source == NULL) {
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+    MergeFrom(*source);
+  }
+}
+
+void FileNameRequest::MergeFrom(const FileNameRequest& from) {
+  if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+  if (from.filename().size() > 0) {
+    filename_.AssignWithDefault(
+        &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+        from.filename_);
+  }
+}
+
+void FileNameRequest::CopyFrom(const ::google::protobuf::Message& from) {
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void FileNameRequest::CopyFrom(const FileNameRequest& from) {
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool FileNameRequest::IsInitialized() const { return true; }
+
+void FileNameRequest::Swap(FileNameRequest* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void FileNameRequest::InternalSwap(FileNameRequest* other) {
+  filename_.Swap(&other->filename_);
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  std::swap(_cached_size_, other->_cached_size_);
+}
+
+::google::protobuf::Metadata FileNameRequest::GetMetadata() const {
+  protobuf_AssignDescriptorsOnce();
+  ::google::protobuf::Metadata metadata;
+  metadata.descriptor = FileNameRequest_descriptor_;
+  metadata.reflection = FileNameRequest_reflection_;
+  return metadata;
+}
+
+#if PROTOBUF_INLINE_NOT_IN_HEADERS
+// FileNameRequest
+
+// optional string filename = 1;
+void FileNameRequest::clear_filename() {
+  filename_.ClearToEmptyNoArena(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+const ::std::string& FileNameRequest::filename() const {
+  // @@protoc_insertion_point(field_get:grpc.reflection.v1alpha.FileNameRequest.filename)
+  return filename_.GetNoArena(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+void FileNameRequest::set_filename(const ::std::string& value) {
+  filename_.SetNoArena(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:grpc.reflection.v1alpha.FileNameRequest.filename)
+}
+void FileNameRequest::set_filename(const char* value) {
+  filename_.SetNoArena(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:grpc.reflection.v1alpha.FileNameRequest.filename)
+}
+void FileNameRequest::set_filename(const char* value, size_t size) {
+  filename_.SetNoArena(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:grpc.reflection.v1alpha.FileNameRequest.filename)
+}
+::std::string* FileNameRequest::mutable_filename() {
+  // @@protoc_insertion_point(field_mutable:grpc.reflection.v1alpha.FileNameRequest.filename)
+  return filename_.MutableNoArena(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+::std::string* FileNameRequest::release_filename() {
+  return filename_.ReleaseNoArena(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+void FileNameRequest::set_allocated_filename(::std::string* filename) {
+  if (filename != NULL) {
+  } else {
+  }
+  filename_.SetAllocatedNoArena(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited(), filename);
+  // @@protoc_insertion_point(field_set_allocated:grpc.reflection.v1alpha.FileNameRequest.filename)
+}
+
+#endif  // PROTOBUF_INLINE_NOT_IN_HEADERS
+
+// ===================================================================
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int SymbolRequest::kSymbolFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+SymbolRequest::SymbolRequest()
+    : ::google::protobuf::Message(), _internal_metadata_(NULL) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:grpc.reflection.v1alpha.SymbolRequest)
+}
+
+void SymbolRequest::InitAsDefaultInstance() { _is_default_instance_ = true; }
+
+SymbolRequest::SymbolRequest(const SymbolRequest& from)
+    : ::google::protobuf::Message(), _internal_metadata_(NULL) {
+  SharedCtor();
+  MergeFrom(from);
+  // @@protoc_insertion_point(copy_constructor:grpc.reflection.v1alpha.SymbolRequest)
+}
+
+void SymbolRequest::SharedCtor() {
+  _is_default_instance_ = false;
+  ::google::protobuf::internal::GetEmptyString();
+  _cached_size_ = 0;
+  symbol_.UnsafeSetDefault(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+
+SymbolRequest::~SymbolRequest() {
+  // @@protoc_insertion_point(destructor:grpc.reflection.v1alpha.SymbolRequest)
+  SharedDtor();
+}
+
+void SymbolRequest::SharedDtor() {
+  symbol_.DestroyNoArena(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (this != default_instance_) {
+  }
+}
+
+void SymbolRequest::SetCachedSize(int size) const {
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const ::google::protobuf::Descriptor* SymbolRequest::descriptor() {
+  protobuf_AssignDescriptorsOnce();
+  return SymbolRequest_descriptor_;
+}
+
+const SymbolRequest& SymbolRequest::default_instance() {
+  if (default_instance_ == NULL) protobuf_AddDesc_reflection_2eproto();
+  return *default_instance_;
+}
+
+SymbolRequest* SymbolRequest::default_instance_ = NULL;
+
+SymbolRequest* SymbolRequest::New(::google::protobuf::Arena* arena) const {
+  SymbolRequest* n = new SymbolRequest;
+  if (arena != NULL) {
+    arena->Own(n);
+  }
+  return n;
+}
+
+void SymbolRequest::Clear() {
+  symbol_.ClearToEmptyNoArena(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+
+bool SymbolRequest::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) \
+  if (!(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:grpc.reflection.v1alpha.SymbolRequest)
+  for (;;) {
+    ::std::pair< ::google::protobuf::uint32, bool> p =
+        input->ReadTagWithCutoff(127);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (
+        ::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // optional string symbol = 1;
+      case 1: {
+        if (tag == 10) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+              input, this->mutable_symbol()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+              this->symbol().data(), this->symbol().length(),
+              ::google::protobuf::internal::WireFormatLite::PARSE,
+              "grpc.reflection.v1alpha.SymbolRequest.symbol"));
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectAtEnd()) goto success;
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0 ||
+            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+                ::google::protobuf::internal::WireFormatLite::
+                    WIRETYPE_END_GROUP) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormatLite::SkipField(input,
+                                                                    tag));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:grpc.reflection.v1alpha.SymbolRequest)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:grpc.reflection.v1alpha.SymbolRequest)
+  return false;
+#undef DO_
+}
+
+void SymbolRequest::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:grpc.reflection.v1alpha.SymbolRequest)
+  // optional string symbol = 1;
+  if (this->symbol().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+        this->symbol().data(), this->symbol().length(),
+        ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+        "grpc.reflection.v1alpha.SymbolRequest.symbol");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+        1, this->symbol(), output);
+  }
+
+  // @@protoc_insertion_point(serialize_end:grpc.reflection.v1alpha.SymbolRequest)
+}
+
+::google::protobuf::uint8* SymbolRequest::SerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:grpc.reflection.v1alpha.SymbolRequest)
+  // optional string symbol = 1;
+  if (this->symbol().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+        this->symbol().data(), this->symbol().length(),
+        ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+        "grpc.reflection.v1alpha.SymbolRequest.symbol");
+    target = ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        1, this->symbol(), target);
+  }
+
+  // @@protoc_insertion_point(serialize_to_array_end:grpc.reflection.v1alpha.SymbolRequest)
+  return target;
+}
+
+int SymbolRequest::ByteSize() const {
+  int total_size = 0;
+
+  // optional string symbol = 1;
+  if (this->symbol().size() > 0) {
+    total_size += 1 + ::google::protobuf::internal::WireFormatLite::StringSize(
+                          this->symbol());
+  }
+
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = total_size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+  return total_size;
+}
+
+void SymbolRequest::MergeFrom(const ::google::protobuf::Message& from) {
+  if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+  const SymbolRequest* source =
+      ::google::protobuf::internal::DynamicCastToGenerated<const SymbolRequest>(
+          &from);
+  if (source == NULL) {
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+    MergeFrom(*source);
+  }
+}
+
+void SymbolRequest::MergeFrom(const SymbolRequest& from) {
+  if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+  if (from.symbol().size() > 0) {
+    symbol_.AssignWithDefault(
+        &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+        from.symbol_);
+  }
+}
+
+void SymbolRequest::CopyFrom(const ::google::protobuf::Message& from) {
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void SymbolRequest::CopyFrom(const SymbolRequest& from) {
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool SymbolRequest::IsInitialized() const { return true; }
+
+void SymbolRequest::Swap(SymbolRequest* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void SymbolRequest::InternalSwap(SymbolRequest* other) {
+  symbol_.Swap(&other->symbol_);
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  std::swap(_cached_size_, other->_cached_size_);
+}
+
+::google::protobuf::Metadata SymbolRequest::GetMetadata() const {
+  protobuf_AssignDescriptorsOnce();
+  ::google::protobuf::Metadata metadata;
+  metadata.descriptor = SymbolRequest_descriptor_;
+  metadata.reflection = SymbolRequest_reflection_;
+  return metadata;
+}
+
+#if PROTOBUF_INLINE_NOT_IN_HEADERS
+// SymbolRequest
+
+// optional string symbol = 1;
+void SymbolRequest::clear_symbol() {
+  symbol_.ClearToEmptyNoArena(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+const ::std::string& SymbolRequest::symbol() const {
+  // @@protoc_insertion_point(field_get:grpc.reflection.v1alpha.SymbolRequest.symbol)
+  return symbol_.GetNoArena(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+void SymbolRequest::set_symbol(const ::std::string& value) {
+  symbol_.SetNoArena(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:grpc.reflection.v1alpha.SymbolRequest.symbol)
+}
+void SymbolRequest::set_symbol(const char* value) {
+  symbol_.SetNoArena(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:grpc.reflection.v1alpha.SymbolRequest.symbol)
+}
+void SymbolRequest::set_symbol(const char* value, size_t size) {
+  symbol_.SetNoArena(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:grpc.reflection.v1alpha.SymbolRequest.symbol)
+}
+::std::string* SymbolRequest::mutable_symbol() {
+  // @@protoc_insertion_point(field_mutable:grpc.reflection.v1alpha.SymbolRequest.symbol)
+  return symbol_.MutableNoArena(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+::std::string* SymbolRequest::release_symbol() {
+  return symbol_.ReleaseNoArena(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+void SymbolRequest::set_allocated_symbol(::std::string* symbol) {
+  if (symbol != NULL) {
+  } else {
+  }
+  symbol_.SetAllocatedNoArena(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited(), symbol);
+  // @@protoc_insertion_point(field_set_allocated:grpc.reflection.v1alpha.SymbolRequest.symbol)
+}
+
+#endif  // PROTOBUF_INLINE_NOT_IN_HEADERS
+
+// ===================================================================
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int ExtensionRequest::kContainingTypeFieldNumber;
+const int ExtensionRequest::kExtensionNumberFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+ExtensionRequest::ExtensionRequest()
+    : ::google::protobuf::Message(), _internal_metadata_(NULL) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:grpc.reflection.v1alpha.ExtensionRequest)
+}
+
+void ExtensionRequest::InitAsDefaultInstance() { _is_default_instance_ = true; }
+
+ExtensionRequest::ExtensionRequest(const ExtensionRequest& from)
+    : ::google::protobuf::Message(), _internal_metadata_(NULL) {
+  SharedCtor();
+  MergeFrom(from);
+  // @@protoc_insertion_point(copy_constructor:grpc.reflection.v1alpha.ExtensionRequest)
+}
+
+void ExtensionRequest::SharedCtor() {
+  _is_default_instance_ = false;
+  ::google::protobuf::internal::GetEmptyString();
+  _cached_size_ = 0;
+  containing_type_.UnsafeSetDefault(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  extension_number_ = 0;
+}
+
+ExtensionRequest::~ExtensionRequest() {
+  // @@protoc_insertion_point(destructor:grpc.reflection.v1alpha.ExtensionRequest)
+  SharedDtor();
+}
+
+void ExtensionRequest::SharedDtor() {
+  containing_type_.DestroyNoArena(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (this != default_instance_) {
+  }
+}
+
+void ExtensionRequest::SetCachedSize(int size) const {
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const ::google::protobuf::Descriptor* ExtensionRequest::descriptor() {
+  protobuf_AssignDescriptorsOnce();
+  return ExtensionRequest_descriptor_;
+}
+
+const ExtensionRequest& ExtensionRequest::default_instance() {
+  if (default_instance_ == NULL) protobuf_AddDesc_reflection_2eproto();
+  return *default_instance_;
+}
+
+ExtensionRequest* ExtensionRequest::default_instance_ = NULL;
+
+ExtensionRequest* ExtensionRequest::New(
+    ::google::protobuf::Arena* arena) const {
+  ExtensionRequest* n = new ExtensionRequest;
+  if (arena != NULL) {
+    arena->Own(n);
+  }
+  return n;
+}
+
+void ExtensionRequest::Clear() {
+  containing_type_.ClearToEmptyNoArena(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  extension_number_ = 0;
+}
+
+bool ExtensionRequest::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) \
+  if (!(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:grpc.reflection.v1alpha.ExtensionRequest)
+  for (;;) {
+    ::std::pair< ::google::protobuf::uint32, bool> p =
+        input->ReadTagWithCutoff(127);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (
+        ::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // optional string containing_type = 1;
+      case 1: {
+        if (tag == 10) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+              input, this->mutable_containing_type()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+              this->containing_type().data(), this->containing_type().length(),
+              ::google::protobuf::internal::WireFormatLite::PARSE,
+              "grpc.reflection.v1alpha.ExtensionRequest.containing_type"));
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(16)) goto parse_extension_number;
+        break;
+      }
+
+      // optional int32 extension_number = 2;
+      case 2: {
+        if (tag == 16) {
+        parse_extension_number:
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+               ::google::protobuf::int32,
+               ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
+              input, &extension_number_)));
+
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectAtEnd()) goto success;
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0 ||
+            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+                ::google::protobuf::internal::WireFormatLite::
+                    WIRETYPE_END_GROUP) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormatLite::SkipField(input,
+                                                                    tag));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:grpc.reflection.v1alpha.ExtensionRequest)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:grpc.reflection.v1alpha.ExtensionRequest)
+  return false;
+#undef DO_
+}
+
+void ExtensionRequest::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:grpc.reflection.v1alpha.ExtensionRequest)
+  // optional string containing_type = 1;
+  if (this->containing_type().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+        this->containing_type().data(), this->containing_type().length(),
+        ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+        "grpc.reflection.v1alpha.ExtensionRequest.containing_type");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+        1, this->containing_type(), output);
+  }
+
+  // optional int32 extension_number = 2;
+  if (this->extension_number() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteInt32(
+        2, this->extension_number(), output);
+  }
+
+  // @@protoc_insertion_point(serialize_end:grpc.reflection.v1alpha.ExtensionRequest)
+}
+
+::google::protobuf::uint8* ExtensionRequest::SerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:grpc.reflection.v1alpha.ExtensionRequest)
+  // optional string containing_type = 1;
+  if (this->containing_type().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+        this->containing_type().data(), this->containing_type().length(),
+        ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+        "grpc.reflection.v1alpha.ExtensionRequest.containing_type");
+    target = ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        1, this->containing_type(), target);
+  }
+
+  // optional int32 extension_number = 2;
+  if (this->extension_number() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(
+        2, this->extension_number(), target);
+  }
+
+  // @@protoc_insertion_point(serialize_to_array_end:grpc.reflection.v1alpha.ExtensionRequest)
+  return target;
+}
+
+int ExtensionRequest::ByteSize() const {
+  int total_size = 0;
+
+  // optional string containing_type = 1;
+  if (this->containing_type().size() > 0) {
+    total_size += 1 + ::google::protobuf::internal::WireFormatLite::StringSize(
+                          this->containing_type());
+  }
+
+  // optional int32 extension_number = 2;
+  if (this->extension_number() != 0) {
+    total_size += 1 + ::google::protobuf::internal::WireFormatLite::Int32Size(
+                          this->extension_number());
+  }
+
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = total_size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+  return total_size;
+}
+
+void ExtensionRequest::MergeFrom(const ::google::protobuf::Message& from) {
+  if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+  const ExtensionRequest* source =
+      ::google::protobuf::internal::DynamicCastToGenerated<
+          const ExtensionRequest>(&from);
+  if (source == NULL) {
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+    MergeFrom(*source);
+  }
+}
+
+void ExtensionRequest::MergeFrom(const ExtensionRequest& from) {
+  if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+  if (from.containing_type().size() > 0) {
+    containing_type_.AssignWithDefault(
+        &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+        from.containing_type_);
+  }
+  if (from.extension_number() != 0) {
+    set_extension_number(from.extension_number());
+  }
+}
+
+void ExtensionRequest::CopyFrom(const ::google::protobuf::Message& from) {
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void ExtensionRequest::CopyFrom(const ExtensionRequest& from) {
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool ExtensionRequest::IsInitialized() const { return true; }
+
+void ExtensionRequest::Swap(ExtensionRequest* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void ExtensionRequest::InternalSwap(ExtensionRequest* other) {
+  containing_type_.Swap(&other->containing_type_);
+  std::swap(extension_number_, other->extension_number_);
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  std::swap(_cached_size_, other->_cached_size_);
+}
+
+::google::protobuf::Metadata ExtensionRequest::GetMetadata() const {
+  protobuf_AssignDescriptorsOnce();
+  ::google::protobuf::Metadata metadata;
+  metadata.descriptor = ExtensionRequest_descriptor_;
+  metadata.reflection = ExtensionRequest_reflection_;
+  return metadata;
+}
+
+#if PROTOBUF_INLINE_NOT_IN_HEADERS
+// ExtensionRequest
+
+// optional string containing_type = 1;
+void ExtensionRequest::clear_containing_type() {
+  containing_type_.ClearToEmptyNoArena(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+const ::std::string& ExtensionRequest::containing_type() const {
+  // @@protoc_insertion_point(field_get:grpc.reflection.v1alpha.ExtensionRequest.containing_type)
+  return containing_type_.GetNoArena(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+void ExtensionRequest::set_containing_type(const ::std::string& value) {
+  containing_type_.SetNoArena(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:grpc.reflection.v1alpha.ExtensionRequest.containing_type)
+}
+void ExtensionRequest::set_containing_type(const char* value) {
+  containing_type_.SetNoArena(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:grpc.reflection.v1alpha.ExtensionRequest.containing_type)
+}
+void ExtensionRequest::set_containing_type(const char* value, size_t size) {
+  containing_type_.SetNoArena(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:grpc.reflection.v1alpha.ExtensionRequest.containing_type)
+}
+::std::string* ExtensionRequest::mutable_containing_type() {
+  // @@protoc_insertion_point(field_mutable:grpc.reflection.v1alpha.ExtensionRequest.containing_type)
+  return containing_type_.MutableNoArena(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+::std::string* ExtensionRequest::release_containing_type() {
+  return containing_type_.ReleaseNoArena(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+void ExtensionRequest::set_allocated_containing_type(
+    ::std::string* containing_type) {
+  if (containing_type != NULL) {
+  } else {
+  }
+  containing_type_.SetAllocatedNoArena(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      containing_type);
+  // @@protoc_insertion_point(field_set_allocated:grpc.reflection.v1alpha.ExtensionRequest.containing_type)
+}
+
+// optional int32 extension_number = 2;
+void ExtensionRequest::clear_extension_number() { extension_number_ = 0; }
+::google::protobuf::int32 ExtensionRequest::extension_number() const {
+  // @@protoc_insertion_point(field_get:grpc.reflection.v1alpha.ExtensionRequest.extension_number)
+  return extension_number_;
+}
+void ExtensionRequest::set_extension_number(::google::protobuf::int32 value) {
+  extension_number_ = value;
+  // @@protoc_insertion_point(field_set:grpc.reflection.v1alpha.ExtensionRequest.extension_number)
+}
+
+#endif  // PROTOBUF_INLINE_NOT_IN_HEADERS
+
+// ===================================================================
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int TypeRequest::kTypeFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+TypeRequest::TypeRequest()
+    : ::google::protobuf::Message(), _internal_metadata_(NULL) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:grpc.reflection.v1alpha.TypeRequest)
+}
+
+void TypeRequest::InitAsDefaultInstance() { _is_default_instance_ = true; }
+
+TypeRequest::TypeRequest(const TypeRequest& from)
+    : ::google::protobuf::Message(), _internal_metadata_(NULL) {
+  SharedCtor();
+  MergeFrom(from);
+  // @@protoc_insertion_point(copy_constructor:grpc.reflection.v1alpha.TypeRequest)
+}
+
+void TypeRequest::SharedCtor() {
+  _is_default_instance_ = false;
+  ::google::protobuf::internal::GetEmptyString();
+  _cached_size_ = 0;
+  type_.UnsafeSetDefault(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+
+TypeRequest::~TypeRequest() {
+  // @@protoc_insertion_point(destructor:grpc.reflection.v1alpha.TypeRequest)
+  SharedDtor();
+}
+
+void TypeRequest::SharedDtor() {
+  type_.DestroyNoArena(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (this != default_instance_) {
+  }
+}
+
+void TypeRequest::SetCachedSize(int size) const {
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const ::google::protobuf::Descriptor* TypeRequest::descriptor() {
+  protobuf_AssignDescriptorsOnce();
+  return TypeRequest_descriptor_;
+}
+
+const TypeRequest& TypeRequest::default_instance() {
+  if (default_instance_ == NULL) protobuf_AddDesc_reflection_2eproto();
+  return *default_instance_;
+}
+
+TypeRequest* TypeRequest::default_instance_ = NULL;
+
+TypeRequest* TypeRequest::New(::google::protobuf::Arena* arena) const {
+  TypeRequest* n = new TypeRequest;
+  if (arena != NULL) {
+    arena->Own(n);
+  }
+  return n;
+}
+
+void TypeRequest::Clear() {
+  type_.ClearToEmptyNoArena(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+
+bool TypeRequest::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) \
+  if (!(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:grpc.reflection.v1alpha.TypeRequest)
+  for (;;) {
+    ::std::pair< ::google::protobuf::uint32, bool> p =
+        input->ReadTagWithCutoff(127);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (
+        ::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // optional string type = 1;
+      case 1: {
+        if (tag == 10) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+              input, this->mutable_type()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+              this->type().data(), this->type().length(),
+              ::google::protobuf::internal::WireFormatLite::PARSE,
+              "grpc.reflection.v1alpha.TypeRequest.type"));
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectAtEnd()) goto success;
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0 ||
+            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+                ::google::protobuf::internal::WireFormatLite::
+                    WIRETYPE_END_GROUP) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormatLite::SkipField(input,
+                                                                    tag));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:grpc.reflection.v1alpha.TypeRequest)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:grpc.reflection.v1alpha.TypeRequest)
+  return false;
+#undef DO_
+}
+
+void TypeRequest::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:grpc.reflection.v1alpha.TypeRequest)
+  // optional string type = 1;
+  if (this->type().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+        this->type().data(), this->type().length(),
+        ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+        "grpc.reflection.v1alpha.TypeRequest.type");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+        1, this->type(), output);
+  }
+
+  // @@protoc_insertion_point(serialize_end:grpc.reflection.v1alpha.TypeRequest)
+}
+
+::google::protobuf::uint8* TypeRequest::SerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:grpc.reflection.v1alpha.TypeRequest)
+  // optional string type = 1;
+  if (this->type().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+        this->type().data(), this->type().length(),
+        ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+        "grpc.reflection.v1alpha.TypeRequest.type");
+    target = ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        1, this->type(), target);
+  }
+
+  // @@protoc_insertion_point(serialize_to_array_end:grpc.reflection.v1alpha.TypeRequest)
+  return target;
+}
+
+int TypeRequest::ByteSize() const {
+  int total_size = 0;
+
+  // optional string type = 1;
+  if (this->type().size() > 0) {
+    total_size += 1 + ::google::protobuf::internal::WireFormatLite::StringSize(
+                          this->type());
+  }
+
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = total_size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+  return total_size;
+}
+
+void TypeRequest::MergeFrom(const ::google::protobuf::Message& from) {
+  if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+  const TypeRequest* source =
+      ::google::protobuf::internal::DynamicCastToGenerated<const TypeRequest>(
+          &from);
+  if (source == NULL) {
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+    MergeFrom(*source);
+  }
+}
+
+void TypeRequest::MergeFrom(const TypeRequest& from) {
+  if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+  if (from.type().size() > 0) {
+    type_.AssignWithDefault(
+        &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+        from.type_);
+  }
+}
+
+void TypeRequest::CopyFrom(const ::google::protobuf::Message& from) {
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void TypeRequest::CopyFrom(const TypeRequest& from) {
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool TypeRequest::IsInitialized() const { return true; }
+
+void TypeRequest::Swap(TypeRequest* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void TypeRequest::InternalSwap(TypeRequest* other) {
+  type_.Swap(&other->type_);
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  std::swap(_cached_size_, other->_cached_size_);
+}
+
+::google::protobuf::Metadata TypeRequest::GetMetadata() const {
+  protobuf_AssignDescriptorsOnce();
+  ::google::protobuf::Metadata metadata;
+  metadata.descriptor = TypeRequest_descriptor_;
+  metadata.reflection = TypeRequest_reflection_;
+  return metadata;
+}
+
+#if PROTOBUF_INLINE_NOT_IN_HEADERS
+// TypeRequest
+
+// optional string type = 1;
+void TypeRequest::clear_type() {
+  type_.ClearToEmptyNoArena(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+const ::std::string& TypeRequest::type() const {
+  // @@protoc_insertion_point(field_get:grpc.reflection.v1alpha.TypeRequest.type)
+  return type_.GetNoArena(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+void TypeRequest::set_type(const ::std::string& value) {
+  type_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+                   value);
+  // @@protoc_insertion_point(field_set:grpc.reflection.v1alpha.TypeRequest.type)
+}
+void TypeRequest::set_type(const char* value) {
+  type_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+                   ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:grpc.reflection.v1alpha.TypeRequest.type)
+}
+void TypeRequest::set_type(const char* value, size_t size) {
+  type_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+                   ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:grpc.reflection.v1alpha.TypeRequest.type)
+}
+::std::string* TypeRequest::mutable_type() {
+  // @@protoc_insertion_point(field_mutable:grpc.reflection.v1alpha.TypeRequest.type)
+  return type_.MutableNoArena(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+::std::string* TypeRequest::release_type() {
+  return type_.ReleaseNoArena(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+void TypeRequest::set_allocated_type(::std::string* type) {
+  if (type != NULL) {
+  } else {
+  }
+  type_.SetAllocatedNoArena(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited(), type);
+  // @@protoc_insertion_point(field_set_allocated:grpc.reflection.v1alpha.TypeRequest.type)
+}
+
+#endif  // PROTOBUF_INLINE_NOT_IN_HEADERS
+
+// ===================================================================
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int ListServiceResponse::kServicesFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+ListServiceResponse::ListServiceResponse()
+    : ::google::protobuf::Message(), _internal_metadata_(NULL) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:grpc.reflection.v1alpha.ListServiceResponse)
+}
+
+void ListServiceResponse::InitAsDefaultInstance() {
+  _is_default_instance_ = true;
+}
+
+ListServiceResponse::ListServiceResponse(const ListServiceResponse& from)
+    : ::google::protobuf::Message(), _internal_metadata_(NULL) {
+  SharedCtor();
+  MergeFrom(from);
+  // @@protoc_insertion_point(copy_constructor:grpc.reflection.v1alpha.ListServiceResponse)
+}
+
+void ListServiceResponse::SharedCtor() {
+  _is_default_instance_ = false;
+  ::google::protobuf::internal::GetEmptyString();
+  _cached_size_ = 0;
+}
+
+ListServiceResponse::~ListServiceResponse() {
+  // @@protoc_insertion_point(destructor:grpc.reflection.v1alpha.ListServiceResponse)
+  SharedDtor();
+}
+
+void ListServiceResponse::SharedDtor() {
+  if (this != default_instance_) {
+  }
+}
+
+void ListServiceResponse::SetCachedSize(int size) const {
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const ::google::protobuf::Descriptor* ListServiceResponse::descriptor() {
+  protobuf_AssignDescriptorsOnce();
+  return ListServiceResponse_descriptor_;
+}
+
+const ListServiceResponse& ListServiceResponse::default_instance() {
+  if (default_instance_ == NULL) protobuf_AddDesc_reflection_2eproto();
+  return *default_instance_;
+}
+
+ListServiceResponse* ListServiceResponse::default_instance_ = NULL;
+
+ListServiceResponse* ListServiceResponse::New(
+    ::google::protobuf::Arena* arena) const {
+  ListServiceResponse* n = new ListServiceResponse;
+  if (arena != NULL) {
+    arena->Own(n);
+  }
+  return n;
+}
+
+void ListServiceResponse::Clear() { services_.Clear(); }
+
+bool ListServiceResponse::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) \
+  if (!(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:grpc.reflection.v1alpha.ListServiceResponse)
+  for (;;) {
+    ::std::pair< ::google::protobuf::uint32, bool> p =
+        input->ReadTagWithCutoff(127);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (
+        ::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // repeated string services = 1;
+      case 1: {
+        if (tag == 10) {
+        parse_services:
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+              input, this->add_services()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+              this->services(this->services_size() - 1).data(),
+              this->services(this->services_size() - 1).length(),
+              ::google::protobuf::internal::WireFormatLite::PARSE,
+              "grpc.reflection.v1alpha.ListServiceResponse.services"));
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(10)) goto parse_services;
+        if (input->ExpectAtEnd()) goto success;
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0 ||
+            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+                ::google::protobuf::internal::WireFormatLite::
+                    WIRETYPE_END_GROUP) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormatLite::SkipField(input,
+                                                                    tag));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:grpc.reflection.v1alpha.ListServiceResponse)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:grpc.reflection.v1alpha.ListServiceResponse)
+  return false;
+#undef DO_
+}
+
+void ListServiceResponse::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:grpc.reflection.v1alpha.ListServiceResponse)
+  // repeated string services = 1;
+  for (int i = 0; i < this->services_size(); i++) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+        this->services(i).data(), this->services(i).length(),
+        ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+        "grpc.reflection.v1alpha.ListServiceResponse.services");
+    ::google::protobuf::internal::WireFormatLite::WriteString(
+        1, this->services(i), output);
+  }
+
+  // @@protoc_insertion_point(serialize_end:grpc.reflection.v1alpha.ListServiceResponse)
+}
+
+::google::protobuf::uint8* ListServiceResponse::SerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:grpc.reflection.v1alpha.ListServiceResponse)
+  // repeated string services = 1;
+  for (int i = 0; i < this->services_size(); i++) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+        this->services(i).data(), this->services(i).length(),
+        ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+        "grpc.reflection.v1alpha.ListServiceResponse.services");
+    target = ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        1, this->services(i), target);
+  }
+
+  // @@protoc_insertion_point(serialize_to_array_end:grpc.reflection.v1alpha.ListServiceResponse)
+  return target;
+}
+
+int ListServiceResponse::ByteSize() const {
+  int total_size = 0;
+
+  // repeated string services = 1;
+  total_size += 1 * this->services_size();
+  for (int i = 0; i < this->services_size(); i++) {
+    total_size += ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->services(i));
+  }
+
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = total_size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+  return total_size;
+}
+
+void ListServiceResponse::MergeFrom(const ::google::protobuf::Message& from) {
+  if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+  const ListServiceResponse* source =
+      ::google::protobuf::internal::DynamicCastToGenerated<
+          const ListServiceResponse>(&from);
+  if (source == NULL) {
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+    MergeFrom(*source);
+  }
+}
+
+void ListServiceResponse::MergeFrom(const ListServiceResponse& from) {
+  if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+  services_.MergeFrom(from.services_);
+}
+
+void ListServiceResponse::CopyFrom(const ::google::protobuf::Message& from) {
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void ListServiceResponse::CopyFrom(const ListServiceResponse& from) {
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool ListServiceResponse::IsInitialized() const { return true; }
+
+void ListServiceResponse::Swap(ListServiceResponse* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void ListServiceResponse::InternalSwap(ListServiceResponse* other) {
+  services_.UnsafeArenaSwap(&other->services_);
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  std::swap(_cached_size_, other->_cached_size_);
+}
+
+::google::protobuf::Metadata ListServiceResponse::GetMetadata() const {
+  protobuf_AssignDescriptorsOnce();
+  ::google::protobuf::Metadata metadata;
+  metadata.descriptor = ListServiceResponse_descriptor_;
+  metadata.reflection = ListServiceResponse_reflection_;
+  return metadata;
+}
+
+#if PROTOBUF_INLINE_NOT_IN_HEADERS
+// ListServiceResponse
+
+// repeated string services = 1;
+int ListServiceResponse::services_size() const { return services_.size(); }
+void ListServiceResponse::clear_services() { services_.Clear(); }
+const ::std::string& ListServiceResponse::services(int index) const {
+  // @@protoc_insertion_point(field_get:grpc.reflection.v1alpha.ListServiceResponse.services)
+  return services_.Get(index);
+}
+::std::string* ListServiceResponse::mutable_services(int index) {
+  // @@protoc_insertion_point(field_mutable:grpc.reflection.v1alpha.ListServiceResponse.services)
+  return services_.Mutable(index);
+}
+void ListServiceResponse::set_services(int index, const ::std::string& value) {
+  // @@protoc_insertion_point(field_set:grpc.reflection.v1alpha.ListServiceResponse.services)
+  services_.Mutable(index)->assign(value);
+}
+void ListServiceResponse::set_services(int index, const char* value) {
+  services_.Mutable(index)->assign(value);
+  // @@protoc_insertion_point(field_set_char:grpc.reflection.v1alpha.ListServiceResponse.services)
+}
+void ListServiceResponse::set_services(int index, const char* value,
+                                       size_t size) {
+  services_.Mutable(index)->assign(reinterpret_cast<const char*>(value), size);
+  // @@protoc_insertion_point(field_set_pointer:grpc.reflection.v1alpha.ListServiceResponse.services)
+}
+::std::string* ListServiceResponse::add_services() { return services_.Add(); }
+void ListServiceResponse::add_services(const ::std::string& value) {
+  services_.Add()->assign(value);
+  // @@protoc_insertion_point(field_add:grpc.reflection.v1alpha.ListServiceResponse.services)
+}
+void ListServiceResponse::add_services(const char* value) {
+  services_.Add()->assign(value);
+  // @@protoc_insertion_point(field_add_char:grpc.reflection.v1alpha.ListServiceResponse.services)
+}
+void ListServiceResponse::add_services(const char* value, size_t size) {
+  services_.Add()->assign(reinterpret_cast<const char*>(value), size);
+  // @@protoc_insertion_point(field_add_pointer:grpc.reflection.v1alpha.ListServiceResponse.services)
+}
+const ::google::protobuf::RepeatedPtrField< ::std::string>&
+ListServiceResponse::services() const {
+  // @@protoc_insertion_point(field_list:grpc.reflection.v1alpha.ListServiceResponse.services)
+  return services_;
+}
+::google::protobuf::RepeatedPtrField< ::std::string>*
+ListServiceResponse::mutable_services() {
+  // @@protoc_insertion_point(field_mutable_list:grpc.reflection.v1alpha.ListServiceResponse.services)
+  return &services_;
+}
+
+#endif  // PROTOBUF_INLINE_NOT_IN_HEADERS
+
+// ===================================================================
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int FileDescriptorProtoResponse::kFileDescriptorProtoFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+FileDescriptorProtoResponse::FileDescriptorProtoResponse()
+    : ::google::protobuf::Message(), _internal_metadata_(NULL) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:grpc.reflection.v1alpha.FileDescriptorProtoResponse)
+}
+
+void FileDescriptorProtoResponse::InitAsDefaultInstance() {
+  _is_default_instance_ = true;
+}
+
+FileDescriptorProtoResponse::FileDescriptorProtoResponse(
+    const FileDescriptorProtoResponse& from)
+    : ::google::protobuf::Message(), _internal_metadata_(NULL) {
+  SharedCtor();
+  MergeFrom(from);
+  // @@protoc_insertion_point(copy_constructor:grpc.reflection.v1alpha.FileDescriptorProtoResponse)
+}
+
+void FileDescriptorProtoResponse::SharedCtor() {
+  _is_default_instance_ = false;
+  ::google::protobuf::internal::GetEmptyString();
+  _cached_size_ = 0;
+  file_descriptor_proto_.UnsafeSetDefault(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+
+FileDescriptorProtoResponse::~FileDescriptorProtoResponse() {
+  // @@protoc_insertion_point(destructor:grpc.reflection.v1alpha.FileDescriptorProtoResponse)
+  SharedDtor();
+}
+
+void FileDescriptorProtoResponse::SharedDtor() {
+  file_descriptor_proto_.DestroyNoArena(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (this != default_instance_) {
+  }
+}
+
+void FileDescriptorProtoResponse::SetCachedSize(int size) const {
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const ::google::protobuf::Descriptor*
+FileDescriptorProtoResponse::descriptor() {
+  protobuf_AssignDescriptorsOnce();
+  return FileDescriptorProtoResponse_descriptor_;
+}
+
+const FileDescriptorProtoResponse&
+FileDescriptorProtoResponse::default_instance() {
+  if (default_instance_ == NULL) protobuf_AddDesc_reflection_2eproto();
+  return *default_instance_;
+}
+
+FileDescriptorProtoResponse* FileDescriptorProtoResponse::default_instance_ =
+    NULL;
+
+FileDescriptorProtoResponse* FileDescriptorProtoResponse::New(
+    ::google::protobuf::Arena* arena) const {
+  FileDescriptorProtoResponse* n = new FileDescriptorProtoResponse;
+  if (arena != NULL) {
+    arena->Own(n);
+  }
+  return n;
+}
+
+void FileDescriptorProtoResponse::Clear() {
+  file_descriptor_proto_.ClearToEmptyNoArena(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+
+bool FileDescriptorProtoResponse::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) \
+  if (!(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:grpc.reflection.v1alpha.FileDescriptorProtoResponse)
+  for (;;) {
+    ::std::pair< ::google::protobuf::uint32, bool> p =
+        input->ReadTagWithCutoff(127);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (
+        ::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // optional bytes file_descriptor_proto = 1;
+      case 1: {
+        if (tag == 10) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadBytes(
+              input, this->mutable_file_descriptor_proto()));
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectAtEnd()) goto success;
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0 ||
+            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+                ::google::protobuf::internal::WireFormatLite::
+                    WIRETYPE_END_GROUP) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormatLite::SkipField(input,
+                                                                    tag));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:grpc.reflection.v1alpha.FileDescriptorProtoResponse)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:grpc.reflection.v1alpha.FileDescriptorProtoResponse)
+  return false;
+#undef DO_
+}
+
+void FileDescriptorProtoResponse::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:grpc.reflection.v1alpha.FileDescriptorProtoResponse)
+  // optional bytes file_descriptor_proto = 1;
+  if (this->file_descriptor_proto().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteBytesMaybeAliased(
+        1, this->file_descriptor_proto(), output);
+  }
+
+  // @@protoc_insertion_point(serialize_end:grpc.reflection.v1alpha.FileDescriptorProtoResponse)
+}
+
+::google::protobuf::uint8*
+FileDescriptorProtoResponse::SerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:grpc.reflection.v1alpha.FileDescriptorProtoResponse)
+  // optional bytes file_descriptor_proto = 1;
+  if (this->file_descriptor_proto().size() > 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteBytesToArray(
+        1, this->file_descriptor_proto(), target);
+  }
+
+  // @@protoc_insertion_point(serialize_to_array_end:grpc.reflection.v1alpha.FileDescriptorProtoResponse)
+  return target;
+}
+
+int FileDescriptorProtoResponse::ByteSize() const {
+  int total_size = 0;
+
+  // optional bytes file_descriptor_proto = 1;
+  if (this->file_descriptor_proto().size() > 0) {
+    total_size += 1 + ::google::protobuf::internal::WireFormatLite::BytesSize(
+                          this->file_descriptor_proto());
+  }
+
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = total_size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+  return total_size;
+}
+
+void FileDescriptorProtoResponse::MergeFrom(
+    const ::google::protobuf::Message& from) {
+  if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+  const FileDescriptorProtoResponse* source =
+      ::google::protobuf::internal::DynamicCastToGenerated<
+          const FileDescriptorProtoResponse>(&from);
+  if (source == NULL) {
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+    MergeFrom(*source);
+  }
+}
+
+void FileDescriptorProtoResponse::MergeFrom(
+    const FileDescriptorProtoResponse& from) {
+  if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+  if (from.file_descriptor_proto().size() > 0) {
+    file_descriptor_proto_.AssignWithDefault(
+        &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+        from.file_descriptor_proto_);
+  }
+}
+
+void FileDescriptorProtoResponse::CopyFrom(
+    const ::google::protobuf::Message& from) {
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void FileDescriptorProtoResponse::CopyFrom(
+    const FileDescriptorProtoResponse& from) {
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool FileDescriptorProtoResponse::IsInitialized() const { return true; }
+
+void FileDescriptorProtoResponse::Swap(FileDescriptorProtoResponse* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void FileDescriptorProtoResponse::InternalSwap(
+    FileDescriptorProtoResponse* other) {
+  file_descriptor_proto_.Swap(&other->file_descriptor_proto_);
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  std::swap(_cached_size_, other->_cached_size_);
+}
+
+::google::protobuf::Metadata FileDescriptorProtoResponse::GetMetadata() const {
+  protobuf_AssignDescriptorsOnce();
+  ::google::protobuf::Metadata metadata;
+  metadata.descriptor = FileDescriptorProtoResponse_descriptor_;
+  metadata.reflection = FileDescriptorProtoResponse_reflection_;
+  return metadata;
+}
+
+#if PROTOBUF_INLINE_NOT_IN_HEADERS
+// FileDescriptorProtoResponse
+
+// optional bytes file_descriptor_proto = 1;
+void FileDescriptorProtoResponse::clear_file_descriptor_proto() {
+  file_descriptor_proto_.ClearToEmptyNoArena(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+const ::std::string& FileDescriptorProtoResponse::file_descriptor_proto()
+    const {
+  // @@protoc_insertion_point(field_get:grpc.reflection.v1alpha.FileDescriptorProtoResponse.file_descriptor_proto)
+  return file_descriptor_proto_.GetNoArena(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+void FileDescriptorProtoResponse::set_file_descriptor_proto(
+    const ::std::string& value) {
+  file_descriptor_proto_.SetNoArena(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:grpc.reflection.v1alpha.FileDescriptorProtoResponse.file_descriptor_proto)
+}
+void FileDescriptorProtoResponse::set_file_descriptor_proto(const char* value) {
+  file_descriptor_proto_.SetNoArena(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:grpc.reflection.v1alpha.FileDescriptorProtoResponse.file_descriptor_proto)
+}
+void FileDescriptorProtoResponse::set_file_descriptor_proto(const void* value,
+                                                            size_t size) {
+  file_descriptor_proto_.SetNoArena(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:grpc.reflection.v1alpha.FileDescriptorProtoResponse.file_descriptor_proto)
+}
+::std::string* FileDescriptorProtoResponse::mutable_file_descriptor_proto() {
+  // @@protoc_insertion_point(field_mutable:grpc.reflection.v1alpha.FileDescriptorProtoResponse.file_descriptor_proto)
+  return file_descriptor_proto_.MutableNoArena(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+::std::string* FileDescriptorProtoResponse::release_file_descriptor_proto() {
+  return file_descriptor_proto_.ReleaseNoArena(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+void FileDescriptorProtoResponse::set_allocated_file_descriptor_proto(
+    ::std::string* file_descriptor_proto) {
+  if (file_descriptor_proto != NULL) {
+  } else {
+  }
+  file_descriptor_proto_.SetAllocatedNoArena(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      file_descriptor_proto);
+  // @@protoc_insertion_point(field_set_allocated:grpc.reflection.v1alpha.FileDescriptorProtoResponse.file_descriptor_proto)
+}
+
+#endif  // PROTOBUF_INLINE_NOT_IN_HEADERS
+
+// ===================================================================
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int ExtensionNumberResponse::kExtensionNumberFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+ExtensionNumberResponse::ExtensionNumberResponse()
+    : ::google::protobuf::Message(), _internal_metadata_(NULL) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:grpc.reflection.v1alpha.ExtensionNumberResponse)
+}
+
+void ExtensionNumberResponse::InitAsDefaultInstance() {
+  _is_default_instance_ = true;
+}
+
+ExtensionNumberResponse::ExtensionNumberResponse(
+    const ExtensionNumberResponse& from)
+    : ::google::protobuf::Message(), _internal_metadata_(NULL) {
+  SharedCtor();
+  MergeFrom(from);
+  // @@protoc_insertion_point(copy_constructor:grpc.reflection.v1alpha.ExtensionNumberResponse)
+}
+
+void ExtensionNumberResponse::SharedCtor() {
+  _is_default_instance_ = false;
+  _cached_size_ = 0;
+}
+
+ExtensionNumberResponse::~ExtensionNumberResponse() {
+  // @@protoc_insertion_point(destructor:grpc.reflection.v1alpha.ExtensionNumberResponse)
+  SharedDtor();
+}
+
+void ExtensionNumberResponse::SharedDtor() {
+  if (this != default_instance_) {
+  }
+}
+
+void ExtensionNumberResponse::SetCachedSize(int size) const {
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const ::google::protobuf::Descriptor* ExtensionNumberResponse::descriptor() {
+  protobuf_AssignDescriptorsOnce();
+  return ExtensionNumberResponse_descriptor_;
+}
+
+const ExtensionNumberResponse& ExtensionNumberResponse::default_instance() {
+  if (default_instance_ == NULL) protobuf_AddDesc_reflection_2eproto();
+  return *default_instance_;
+}
+
+ExtensionNumberResponse* ExtensionNumberResponse::default_instance_ = NULL;
+
+ExtensionNumberResponse* ExtensionNumberResponse::New(
+    ::google::protobuf::Arena* arena) const {
+  ExtensionNumberResponse* n = new ExtensionNumberResponse;
+  if (arena != NULL) {
+    arena->Own(n);
+  }
+  return n;
+}
+
+void ExtensionNumberResponse::Clear() { extension_number_.Clear(); }
+
+bool ExtensionNumberResponse::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) \
+  if (!(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:grpc.reflection.v1alpha.ExtensionNumberResponse)
+  for (;;) {
+    ::std::pair< ::google::protobuf::uint32, bool> p =
+        input->ReadTagWithCutoff(127);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (
+        ::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // repeated int32 extension_number = 1;
+      case 1: {
+        if (tag == 10) {
+          DO_((
+              ::google::protobuf::internal::WireFormatLite::ReadPackedPrimitive<
+                  ::google::protobuf::int32,
+                  ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
+                  input, this->mutable_extension_number())));
+        } else if (tag == 8) {
+          DO_((
+              ::google::protobuf::internal::WireFormatLite::
+                  ReadRepeatedPrimitiveNoInline<
+                      ::google::protobuf::int32,
+                      ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
+                      1, 10, input, this->mutable_extension_number())));
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectAtEnd()) goto success;
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0 ||
+            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+                ::google::protobuf::internal::WireFormatLite::
+                    WIRETYPE_END_GROUP) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormatLite::SkipField(input,
+                                                                    tag));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:grpc.reflection.v1alpha.ExtensionNumberResponse)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:grpc.reflection.v1alpha.ExtensionNumberResponse)
+  return false;
+#undef DO_
+}
+
+void ExtensionNumberResponse::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:grpc.reflection.v1alpha.ExtensionNumberResponse)
+  // repeated int32 extension_number = 1;
+  if (this->extension_number_size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteTag(
+        1,
+        ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
+        output);
+    output->WriteVarint32(_extension_number_cached_byte_size_);
+  }
+  for (int i = 0; i < this->extension_number_size(); i++) {
+    ::google::protobuf::internal::WireFormatLite::WriteInt32NoTag(
+        this->extension_number(i), output);
+  }
+
+  // @@protoc_insertion_point(serialize_end:grpc.reflection.v1alpha.ExtensionNumberResponse)
+}
+
+::google::protobuf::uint8*
+ExtensionNumberResponse::SerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:grpc.reflection.v1alpha.ExtensionNumberResponse)
+  // repeated int32 extension_number = 1;
+  if (this->extension_number_size() > 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(
+        1,
+        ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
+        target);
+    target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray(
+        _extension_number_cached_byte_size_, target);
+  }
+  for (int i = 0; i < this->extension_number_size(); i++) {
+    target =
+        ::google::protobuf::internal::WireFormatLite::WriteInt32NoTagToArray(
+            this->extension_number(i), target);
+  }
+
+  // @@protoc_insertion_point(serialize_to_array_end:grpc.reflection.v1alpha.ExtensionNumberResponse)
+  return target;
+}
+
+int ExtensionNumberResponse::ByteSize() const {
+  int total_size = 0;
+
+  // repeated int32 extension_number = 1;
+  {
+    int data_size = 0;
+    for (int i = 0; i < this->extension_number_size(); i++) {
+      data_size += ::google::protobuf::internal::WireFormatLite::Int32Size(
+          this->extension_number(i));
+    }
+    if (data_size > 0) {
+      total_size += 1 + ::google::protobuf::internal::WireFormatLite::Int32Size(
+                            data_size);
+    }
+    GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+    _extension_number_cached_byte_size_ = data_size;
+    GOOGLE_SAFE_CONCURRENT_WRITES_END();
+    total_size += data_size;
+  }
+
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = total_size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+  return total_size;
+}
+
+void ExtensionNumberResponse::MergeFrom(
+    const ::google::protobuf::Message& from) {
+  if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+  const ExtensionNumberResponse* source =
+      ::google::protobuf::internal::DynamicCastToGenerated<
+          const ExtensionNumberResponse>(&from);
+  if (source == NULL) {
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+    MergeFrom(*source);
+  }
+}
+
+void ExtensionNumberResponse::MergeFrom(const ExtensionNumberResponse& from) {
+  if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+  extension_number_.MergeFrom(from.extension_number_);
+}
+
+void ExtensionNumberResponse::CopyFrom(
+    const ::google::protobuf::Message& from) {
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void ExtensionNumberResponse::CopyFrom(const ExtensionNumberResponse& from) {
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool ExtensionNumberResponse::IsInitialized() const { return true; }
+
+void ExtensionNumberResponse::Swap(ExtensionNumberResponse* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void ExtensionNumberResponse::InternalSwap(ExtensionNumberResponse* other) {
+  extension_number_.UnsafeArenaSwap(&other->extension_number_);
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  std::swap(_cached_size_, other->_cached_size_);
+}
+
+::google::protobuf::Metadata ExtensionNumberResponse::GetMetadata() const {
+  protobuf_AssignDescriptorsOnce();
+  ::google::protobuf::Metadata metadata;
+  metadata.descriptor = ExtensionNumberResponse_descriptor_;
+  metadata.reflection = ExtensionNumberResponse_reflection_;
+  return metadata;
+}
+
+#if PROTOBUF_INLINE_NOT_IN_HEADERS
+// ExtensionNumberResponse
+
+// repeated int32 extension_number = 1;
+int ExtensionNumberResponse::extension_number_size() const {
+  return extension_number_.size();
+}
+void ExtensionNumberResponse::clear_extension_number() {
+  extension_number_.Clear();
+}
+::google::protobuf::int32 ExtensionNumberResponse::extension_number(
+    int index) const {
+  // @@protoc_insertion_point(field_get:grpc.reflection.v1alpha.ExtensionNumberResponse.extension_number)
+  return extension_number_.Get(index);
+}
+void ExtensionNumberResponse::set_extension_number(
+    int index, ::google::protobuf::int32 value) {
+  extension_number_.Set(index, value);
+  // @@protoc_insertion_point(field_set:grpc.reflection.v1alpha.ExtensionNumberResponse.extension_number)
+}
+void ExtensionNumberResponse::add_extension_number(
+    ::google::protobuf::int32 value) {
+  extension_number_.Add(value);
+  // @@protoc_insertion_point(field_add:grpc.reflection.v1alpha.ExtensionNumberResponse.extension_number)
+}
+const ::google::protobuf::RepeatedField< ::google::protobuf::int32>&
+ExtensionNumberResponse::extension_number() const {
+  // @@protoc_insertion_point(field_list:grpc.reflection.v1alpha.ExtensionNumberResponse.extension_number)
+  return extension_number_;
+}
+::google::protobuf::RepeatedField< ::google::protobuf::int32>*
+ExtensionNumberResponse::mutable_extension_number() {
+  // @@protoc_insertion_point(field_mutable_list:grpc.reflection.v1alpha.ExtensionNumberResponse.extension_number)
+  return &extension_number_;
+}
+
+#endif  // PROTOBUF_INLINE_NOT_IN_HEADERS
+
+// @@protoc_insertion_point(namespace_scope)
+
+}  // namespace v1alpha
+}  // namespace reflection
+}  // namespace grpc
+
+// @@protoc_insertion_point(global_scope)
diff --git a/src/proto/grpc/reflection/v1alpha/reflection.proto b/src/proto/grpc/reflection/v1alpha/reflection.proto
new file mode 100644
index 0000000000..4b13bd1e51
--- /dev/null
+++ b/src/proto/grpc/reflection/v1alpha/reflection.proto
@@ -0,0 +1,118 @@
+// Copyright 2016, Google Inc.
+// All rights reserved.
+//
+// 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.
+
+// Service exported by server reflection
+
+syntax = "proto3";
+
+package grpc.reflection.v1alpha;
+
+service ServerReflection {
+  // List the full names of registered services.
+  rpc ListService(EmptyRequest) returns (ListServiceResponse) {
+  }
+
+  // Find a proto file by file name.
+  rpc GetFileByName(FileNameRequest) returns (FileDescriptorProtoResponse) {
+  }
+
+  // Find the proto file that declares the given fully-qualified symbol name.
+  rpc GetFileContainingSymbol(SymbolRequest)
+      returns (FileDescriptorProtoResponse) {
+  }
+
+  // Find the proto file which defines an extension extending the given message
+  // type with the given field number.
+  rpc GetFileContainingExtension(ExtensionRequest)
+      returns (FileDescriptorProtoResponse) {
+  }
+
+  // Finds the tag numbers used by all known extensions of extendee_type, and
+  // appends them to ExtensionNumberResponse in an undefined order.
+  // This 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.
+  rpc GetAllExtensionNumbers(TypeRequest) returns (ExtensionNumberResponse) {
+  }
+}
+
+// An empty message sent by the client when calling ListService method.
+message EmptyRequest {
+}
+
+// The filename sent by the client when calling GetFileByName method.
+message FileNameRequest {
+  // Name of the proto file.
+  string filename = 1;
+}
+
+// The symbol name sent by the client when calling GetFileContainingSymbol
+// method.
+message SymbolRequest {
+  // Fully-qualified symbol name (e.g. <package>.<service>[.<method>] or
+  // <package>.<type>).
+  string symbol = 1;
+}
+
+// The type name and extension number sent by the client when calling
+// GetFileContainingExtension method.
+message ExtensionRequest {
+  // Fully-qualified type name. The format should be <package>.<type>
+  string containing_type = 1;
+  int32 extension_number = 2;
+}
+
+// The type name sent by the client when calling GetAllExtensionNumbers method.
+message TypeRequest {
+  // Fully-qualified type name. The format should be <package>.<type>
+  string type = 1;
+}
+
+// A list of service names sent by the server answering ListService method.
+message ListServiceResponse {
+  // Full names of registered services, including package names. The format
+  // is <package>.<service>
+  repeated string services = 1;
+}
+
+// A serialized FileDescriptorProto sent by the server answering
+// GetFileByName, GetFileContainingSymbol, GetFileContainingExtension methods.
+message FileDescriptorProtoResponse {
+  // Serialized FileDescriptorProto message. Some languages have limited support
+  // for working with descriptors. The can only obtain an opaque binary blob
+  // that contains serialized FileDescriptorProto message.
+  bytes file_descriptor_proto = 1;
+}
+
+// A list of extension numbers sent by the server answering
+// GetAllExtensionNumbers method.
+message ExtensionNumberResponse {
+  repeated int32 extension_number = 1;
+}
diff --git a/templates/Makefile.template b/templates/Makefile.template
index e84ceebf22..1d8183edb1 100644
--- a/templates/Makefile.template
+++ b/templates/Makefile.template
@@ -100,6 +100,7 @@
   OBJDIR = $(BUILDDIR_ABSOLUTE)/objs
   LIBDIR = $(BUILDDIR_ABSOLUTE)/libs
   GENDIR = $(BUILDDIR_ABSOLUTE)/gens
+  EXTDIR = $(BUILDDIR_ABSOLUTE)/extensions
 
   # Configurations
 
@@ -237,7 +238,7 @@
   LDFLAGS += -fPIC
   endif
 
-  INCLUDES = . include $(GENDIR)
+  INCLUDES = . include $(GENDIR) $(EXTDIR) $(EXTDIR)/include
   LDFLAGS += -Llibs/$(CONFIG)
 
   ifeq ($(SYSTEM),Darwin)
@@ -1278,8 +1279,8 @@
 
   install-headers_cxx:
   	$(E) "[INSTALL] Installing public C++ headers"
-  	$(Q) $(foreach h, $(PUBLIC_HEADERS_CXX), $(INSTALL) -d $(prefix)/$(dir $(h)) && ) exit 0 || exit 1
-  	$(Q) $(foreach h, $(PUBLIC_HEADERS_CXX), $(INSTALL) $(h) $(prefix)/$(h) && ) exit 0 || exit 1
+  	$(Q) $(foreach h, $(PUBLIC_HEADERS_CXX), $(INSTALL) -d $(prefix)/$(patsubst extensions/%,%,$(dir $(h))) && ) exit 0 || exit 1
+  	$(Q) $(foreach h, $(PUBLIC_HEADERS_CXX), $(INSTALL) $(h) $(prefix)/$(patsubst extensions/%,%,$(h)) && ) exit 0 || exit 1
 
   install-static: install-static_c install-static_cxx
 
diff --git a/test/cpp/util/proto_reflection_descriptor_database.cc b/test/cpp/util/proto_reflection_descriptor_database.cc
new file mode 100644
index 0000000000..c2ed93c12b
--- /dev/null
+++ b/test/cpp/util/proto_reflection_descriptor_database.cc
@@ -0,0 +1,238 @@
+/*
+ *
+ * Copyright 2016, Google Inc.
+ * All rights reserved.
+ *
+ * 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.
+ *
+ */
+
+#include "proto_reflection_descriptor_database.h"
+
+#include <vector>
+
+#include <grpc/support/log.h>
+
+namespace grpc {
+
+ProtoReflectionDescriptorDatabase::ProtoReflectionDescriptorDatabase(
+    std::unique_ptr<reflection::v1alpha::ServerReflection::Stub> stub)
+    : stub_(std::move(stub)) {}
+
+ProtoReflectionDescriptorDatabase::ProtoReflectionDescriptorDatabase(
+    std::shared_ptr<grpc::Channel> channel)
+    : stub_(reflection::v1alpha::ServerReflection::NewStub(channel)) {}
+
+ProtoReflectionDescriptorDatabase::~ProtoReflectionDescriptorDatabase() {}
+
+bool ProtoReflectionDescriptorDatabase::FindFileByName(
+    const string& filename, google::protobuf::FileDescriptorProto* output) {
+  if (cached_db_.FindFileByName(filename, output)) {
+    return true;
+  }
+
+  if (known_files_.find(filename) != known_files_.end()) {
+    return false;
+  }
+
+  ClientContext ctx;
+  reflection::v1alpha::FileNameRequest request;
+  request.set_filename(filename);
+  reflection::v1alpha::FileDescriptorProtoResponse response;
+
+  Status status = stub_->GetFileByName(&ctx, request, &response);
+  if (status.ok()) {
+    // const google::protobuf::FileDescriptorProto* file_proto =
+    //     response.mutable_file_descriptor_proto();
+    const google::protobuf::FileDescriptorProto file_proto =
+        ParseFileDescriptorProtoResponse(&response);
+    known_files_.insert(file_proto.name());
+    cached_db_.Add(file_proto);
+  } else if (status.error_code() == StatusCode::NOT_FOUND) {
+    gpr_log(GPR_INFO, "NOT_FOUND from server for FindFileByName(%s)",
+            filename.c_str());
+  } else {
+    gpr_log(GPR_INFO,
+            "Error on FindFileByName(%s)\n\tError code: %d\n"
+            "\tError Message: %s",
+            filename.c_str(), status.error_code(),
+            status.error_message().c_str());
+  }
+
+  return cached_db_.FindFileByName(filename, output);
+}
+
+bool ProtoReflectionDescriptorDatabase::FindFileContainingSymbol(
+    const string& symbol_name, google::protobuf::FileDescriptorProto* output) {
+  if (cached_db_.FindFileContainingSymbol(symbol_name, output)) {
+    return true;
+  }
+
+  if (missing_symbols_.find(symbol_name) != missing_symbols_.end()) {
+    return false;
+  }
+
+  ClientContext ctx;
+  reflection::v1alpha::SymbolRequest request;
+  request.set_symbol(symbol_name);
+  reflection::v1alpha::FileDescriptorProtoResponse response;
+
+  Status status = stub_->GetFileContainingSymbol(&ctx, request, &response);
+  if (status.ok()) {
+    const google::protobuf::FileDescriptorProto file_proto =
+        ParseFileDescriptorProtoResponse(&response);
+    if (known_files_.find(file_proto.name()) == known_files_.end()) {
+      known_files_.insert(file_proto.name());
+      cached_db_.Add(file_proto);
+    }
+  } else if (status.error_code() == StatusCode::NOT_FOUND) {
+    missing_symbols_.insert(symbol_name);
+    gpr_log(GPR_INFO, "NOT_FOUND from server for FindFileContainingSymbol(%s)",
+            symbol_name.c_str());
+  } else {
+    gpr_log(GPR_INFO,
+            "Error on FindFileContainingSymbol(%s)\n"
+            "\tError code: %d\n\tError Message: %s",
+            symbol_name.c_str(), status.error_code(),
+            status.error_message().c_str());
+  }
+
+  return cached_db_.FindFileContainingSymbol(symbol_name, output);
+}
+
+bool ProtoReflectionDescriptorDatabase::FindFileContainingExtension(
+    const string& containing_type, int field_number,
+    google::protobuf::FileDescriptorProto* output) {
+  if (cached_db_.FindFileContainingExtension(containing_type, field_number,
+                                             output)) {
+    return true;
+  }
+
+  if (missing_extensions_.find(containing_type) != missing_extensions_.end() &&
+      missing_extensions_[containing_type].find(field_number) !=
+          missing_extensions_[containing_type].end()) {
+    gpr_log(GPR_INFO, "nested map.");
+    return false;
+  }
+
+  ClientContext ctx;
+  reflection::v1alpha::ExtensionRequest request;
+  request.set_containing_type(containing_type);
+  request.set_extension_number(field_number);
+  reflection::v1alpha::FileDescriptorProtoResponse response;
+
+  Status status = stub_->GetFileContainingExtension(&ctx, request, &response);
+  if (status.ok()) {
+    const google::protobuf::FileDescriptorProto file_proto =
+        ParseFileDescriptorProtoResponse(&response);
+    if (known_files_.find(file_proto.name()) == known_files_.end()) {
+      known_files_.insert(file_proto.name());
+      cached_db_.Add(file_proto);
+    }
+  } else if (status.error_code() == StatusCode::NOT_FOUND) {
+    if (missing_extensions_.find(containing_type) ==
+        missing_extensions_.end()) {
+      missing_extensions_[containing_type] = {};
+    }
+    missing_extensions_[containing_type].insert(field_number);
+    gpr_log(GPR_INFO,
+            "NOT_FOUND from server for FindFileContainingExtension(%s, %d)",
+            containing_type.c_str(), field_number);
+  } else {
+    gpr_log(GPR_INFO,
+            "Error on FindFileContainingExtension(%s, %d)\n"
+            "\tError code: %d\n\tError Message: %s",
+            containing_type.c_str(), field_number, status.error_code(),
+            status.error_message().c_str());
+  }
+
+  return cached_db_.FindFileContainingExtension(containing_type, field_number,
+                                                output);
+}
+
+bool ProtoReflectionDescriptorDatabase::FindAllExtensionNumbers(
+    const string& extendee_type, std::vector<int>* output) {
+  if (cached_extension_numbers_.find(extendee_type) !=
+      cached_extension_numbers_.end()) {
+    *output = cached_extension_numbers_[extendee_type];
+    return true;
+  }
+
+  ClientContext ctx;
+  reflection::v1alpha::TypeRequest request;
+  request.set_type(extendee_type);
+  reflection::v1alpha::ExtensionNumberResponse response;
+
+  Status status = stub_->GetAllExtensionNumbers(&ctx, request, &response);
+  if (status.ok()) {
+    auto number = response.extension_number();
+    *output = std::vector<int>(number.begin(), number.end());
+    cached_extension_numbers_[extendee_type] = *output;
+    return true;
+  } else if (status.error_code() == StatusCode::NOT_FOUND) {
+    gpr_log(GPR_INFO, "NOT_FOUND from server for FindAllExtensionNumbers(%s)",
+            extendee_type.c_str());
+  } else {
+    gpr_log(GPR_INFO,
+            "Error on FindAllExtensionNumbersExtension(%s)\n"
+            "\tError code: %d\n\tError Message: %s",
+            extendee_type.c_str(), status.error_code(),
+            status.error_message().c_str());
+  }
+  return false;
+}
+
+bool ProtoReflectionDescriptorDatabase::GetServices(
+    std::vector<std::string>* output) {
+  ClientContext ctx;
+  reflection::v1alpha::EmptyRequest request;
+  reflection::v1alpha::ListServiceResponse response;
+
+  Status status = stub_->ListService(&ctx, request, &response);
+  if (status.ok()) {
+    for (int i = 0; i < response.services_size(); ++i) {
+      (*output).push_back(response.services(i));
+    }
+    return true;
+  } else {
+    gpr_log(GPR_INFO,
+            "Error on GetServices()\n\tError code: %d\n"
+            "\tError Message: %s",
+            status.error_code(), status.error_message().c_str());
+  }
+  return false;
+}
+
+const google::protobuf::FileDescriptorProto
+ProtoReflectionDescriptorDatabase::ParseFileDescriptorProtoResponse(
+    reflection::v1alpha::FileDescriptorProtoResponse* response) {
+  google::protobuf::FileDescriptorProto file_desc_proto;
+  file_desc_proto.ParseFromString(response->file_descriptor_proto());
+  return file_desc_proto;
+}
+
+}  // namespace grpc
diff --git a/test/cpp/util/proto_reflection_descriptor_database.h b/test/cpp/util/proto_reflection_descriptor_database.h
new file mode 100644
index 0000000000..bf94654c3d
--- /dev/null
+++ b/test/cpp/util/proto_reflection_descriptor_database.h
@@ -0,0 +1,95 @@
+/*
+ *
+ * Copyright 2016, Google Inc.
+ * All rights reserved.
+ *
+ * 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.
+ *
+ */
+
+#include <memory>
+#include <unordered_map>
+#include <unordered_set>
+#include <vector>
+
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/descriptor_database.h>
+#include <grpc++/grpc++.h>
+#include <grpc++/impl/reflection.grpc.pb.h>
+
+// #include "reflection.grpc.pb.h"
+
+namespace grpc {
+
+class ProtoReflectionDescriptorDatabase
+    : public google::protobuf::DescriptorDatabase {
+ public:
+  explicit ProtoReflectionDescriptorDatabase(
+      std::unique_ptr<reflection::v1alpha::ServerReflection::Stub> stub);
+
+  explicit ProtoReflectionDescriptorDatabase(
+      std::shared_ptr<grpc::Channel> channel);
+
+  virtual ~ProtoReflectionDescriptorDatabase();
+
+  // DescriptorDatabase methods
+  bool FindFileByName(const string& filename,
+                      google::protobuf::FileDescriptorProto* output)
+      GRPC_OVERRIDE;
+
+  bool FindFileContainingSymbol(const string& symbol_name,
+                                google::protobuf::FileDescriptorProto* output)
+      GRPC_OVERRIDE;
+
+  bool FindFileContainingExtension(
+      const string& containing_type, int field_number,
+      google::protobuf::FileDescriptorProto* output) GRPC_OVERRIDE;
+
+  bool FindAllExtensionNumbers(const string& extendee_type,
+                               std::vector<int>* output) GRPC_OVERRIDE;
+
+  bool GetServices(std::vector<std::string>* output);
+
+  grpc::reflection::v1alpha::ServerReflection::Stub* stub() {
+    return stub_.get();
+  }
+
+ private:
+  const google::protobuf::FileDescriptorProto ParseFileDescriptorProtoResponse(
+      reflection::v1alpha::FileDescriptorProtoResponse* response);
+
+  std::unique_ptr<grpc::reflection::v1alpha::ServerReflection::Stub> stub_;
+  std::unordered_set<string> known_files_;
+  std::unordered_set<string> missing_symbols_;
+  std::unordered_map<string, std::unordered_set<int>> missing_extensions_;
+  std::unordered_map<string, std::vector<int>> cached_extension_numbers_;
+
+  google::protobuf::SimpleDescriptorDatabase cached_db_;
+};
+
+}  // namespace grpc
diff --git a/test/cpp/util/reflection_debug/Makefile b/test/cpp/util/reflection_debug/Makefile
new file mode 100644
index 0000000000..9eea5ae734
--- /dev/null
+++ b/test/cpp/util/reflection_debug/Makefile
@@ -0,0 +1,50 @@
+
+# Copyright 2015-2016, Google Inc.
+# All rights reserved.
+#
+# 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.
+#
+
+CXX = g++
+INCLUDES += -I. -I..
+CPPFLAGS += -I/usr/local/include -pthread
+CXXFLAGS += -std=c++11 ${INCLUDES}
+LDFLAGS += -L/usr/local/lib -lgrpc++_unsecure -lgrpc -lgrpc++_reflection -lprotobuf -lpthread -ldl
+VPATH = ..
+
+# PROTOS_PATH = ../../../src/cpp/plugin/reflection
+
+vpath %.proto $(PROTOS_PATH)
+
+all: reflection_client
+
+reflection_client: proto_reflection_descriptor_database.o reflection_client.o
+	$(CXX) $(INCLUDES) $^ $(LDFLAGS) -o $@
+
+
+clean:
+	rm -f *.o reflection_client
diff --git a/test/cpp/util/reflection_debug/reflection_client.cc b/test/cpp/util/reflection_debug/reflection_client.cc
new file mode 100644
index 0000000000..fb40627514
--- /dev/null
+++ b/test/cpp/util/reflection_debug/reflection_client.cc
@@ -0,0 +1,216 @@
+/*
+ *
+ * Copyright 2016, Google Inc.
+ * All rights reserved.
+ *
+ * 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.
+ *
+ */
+
+#include <iomanip>
+#include <iostream>
+#include <memory>
+#include <string>
+
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/descriptor.pb.h>
+#include <grpc++/grpc++.h>
+
+#include "proto_reflection_descriptor_database.h"
+// #include "reflection.grpc.pb.h"
+
+using grpc::Channel;
+using grpc::ClientContext;
+using grpc::Status;
+using grpc::ProtoReflectionDescriptorDatabase;
+using grpc::reflection::v1alpha::ServerReflection;
+using grpc::reflection::v1alpha::EmptyRequest;
+using grpc::reflection::v1alpha::ListServiceResponse;
+using google::protobuf::FileDescriptorProto;
+using google::protobuf::DescriptorPool;
+using google::protobuf::ServiceDescriptor;
+using google::protobuf::MethodDescriptor;
+using google::protobuf::Descriptor;
+using google::protobuf::FieldDescriptor;
+
+class ReflectionClient {
+ public:
+  ReflectionClient(std::shared_ptr<Channel> channel)
+      : db_(new ProtoReflectionDescriptorDatabase(
+            ServerReflection::NewStub(channel))),
+        desc_pool_(new DescriptorPool(db_.get())) {}
+
+  void PrintInfo() {
+    EmptyRequest request;
+    ListServiceResponse response;
+    ClientContext context;
+    Status status = db_->stub()->ListService(&context, request, &response);
+    if (status.ok()) {
+      std::string padding = "";
+      std::cout << "Service amount:" << response.services_size() << std::endl;
+      for (int i = 0; i < response.services_size(); ++i) {
+        if (i != response.services_size() - 1) {
+          std::cout << padding << "│ " << std::endl;
+          std::cout << padding << "├─" << response.services(i) << std::endl;
+          PrintService(desc_pool_->FindServiceByName(response.services(i)),
+                       padding + "│ ");
+        } else {
+          std::cout << padding << "│ " << std::endl;
+          std::cout << padding << "└─" << response.services(i) << std::endl;
+          PrintService(desc_pool_->FindServiceByName(response.services(i)),
+                       padding + "  ");
+        }
+      }
+    } else {
+      std::cout << status.error_message();
+    }
+  }
+
+  void PrintService(const ServiceDescriptor* service_desc,
+                    const std::string padding) {
+    if (service_desc != nullptr) {
+      std::cout << padding << "│ Method amount:" << service_desc->method_count()
+                << std::endl;
+      for (int i = 0; i < service_desc->method_count(); ++i) {
+        if (i != service_desc->method_count() - 1) {
+          std::cout << padding << "├─" << service_desc->method(i)->name()
+                    << std::endl;
+          PrintMethod(service_desc->method(i), padding + "│ ");
+        } else {
+          std::cout << padding << "└─" << service_desc->method(i)->name()
+                    << std::endl;
+          PrintMethod(service_desc->method(i), padding + "  ");
+        }
+      }
+    }
+  }
+
+  void PrintMethod(const MethodDescriptor* method_desc,
+                   const std::string padding) {
+    if (method_desc != nullptr) {
+      std::cout << padding
+                << "├─input type: " << method_desc->input_type()->name()
+                << std::endl;
+      PrintMessageType(method_desc->input_type(), padding + "│ ");
+      std::cout << padding
+                << "└─output type: " << method_desc->output_type()->name()
+                << std::endl;
+      PrintMessageType(method_desc->output_type(), padding + "  ");
+    }
+  }
+
+  void PrintMessageType(const Descriptor* type_desc,
+                        const std::string padding) {
+    if (type_desc != nullptr) {
+      if (type_desc->field_count() > 0) {
+        std::cout << padding << "│ Field amount:" << type_desc->field_count()
+                  << std::endl;
+      }
+      for (int i = 0; i < type_desc->field_count(); ++i) {
+        if (i != type_desc->field_count() - 1) {
+          const FieldDescriptor* field = type_desc->field(i);
+          std::cout << padding << "├─ " << std::left << std::setw(15)
+                    << kLabelToName[field->label()] << std::setw(30)
+                    << " name: " + field->name() << std::setw(50)
+                    << " type: " +
+                           (field->type() == FieldDescriptor::Type::TYPE_MESSAGE
+                                ? field->message_type()->name()
+                                : field->type_name())
+                    << std::endl;
+        } else {
+          const FieldDescriptor* field = type_desc->field(i);
+          std::cout << padding << "└─ " << std::left << std::setw(15)
+                    << kLabelToName[field->label()] << std::setw(30)
+                    << " name: " + field->name() << std::setw(50)
+                    << " type: " +
+                           (field->type() == FieldDescriptor::Type::TYPE_MESSAGE
+                                ? field->message_type()->name()
+                                : field->type_name())
+                    << std::endl;
+        }
+      }
+    }
+  }
+
+  void Test() {
+    {
+      FileDescriptorProto output;
+      bool found = db_->FindFileByName("helloworld.proto", &output);
+      if (found) std::cout << output.name() << std::endl;
+    }
+    {
+      FileDescriptorProto output;
+      bool found =
+          db_->FindFileContainingSymbol("helloworld.Greeter.SayHello", &output);
+      if (found) std::cout << output.name() << std::endl;
+    }
+    {
+      FileDescriptorProto output;
+      bool found = db_->FindFileContainingExtension(
+          "helloworld.Greeter.HelloRequest", 1, &output);
+      found = db_->FindFileContainingExtension(
+          "helloworld.Greeter.HelloRequest", 1, &output);
+      if (found) std::cout << output.name() << std::endl;
+    }
+    DescriptorPool pool(db_.get());
+    std::cout << pool.FindServiceByName("helloworld.Greeter")->name()
+              << std::endl;
+  }
+
+ private:
+  const char* const kLabelToName[FieldDescriptor::Label::MAX_LABEL + 1] = {
+      "ERROR",  // 0 is reserved for errors
+
+      "optional",  // LABEL_OPTIONAL
+      "required",  // LABEL_REQUIRED
+      "repeated",  // LABEL_REPEATED
+  };
+
+  std::unique_ptr<ProtoReflectionDescriptorDatabase> db_;
+  std::unique_ptr<DescriptorPool> desc_pool_;
+};
+
+int main(int argc, char** argv) {
+  int port = 50051;
+  if (argc == 2) {
+    try {
+      port = std::stoi(argv[1]);
+      if (port > 65535 || port < 1024) {
+        throw std::out_of_range("Port number out of range.");
+      }
+    } catch (std::invalid_argument&) {
+    } catch (std::out_of_range&) {
+    }
+  }
+
+  ReflectionClient reflection_client(grpc::CreateChannel(
+      "localhost:" + std::to_string(port), grpc::InsecureChannelCredentials()));
+
+  reflection_client.PrintInfo();
+
+  return 0;
+}
diff --git a/tools/codegen/extensions/gen_reflection_proto.sh b/tools/codegen/extensions/gen_reflection_proto.sh
new file mode 100755
index 0000000000..f0bb6e5ccc
--- /dev/null
+++ b/tools/codegen/extensions/gen_reflection_proto.sh
@@ -0,0 +1,33 @@
+#!/bin/bash
+PROTO_DIR="src/proto/grpc/reflection/v1alpha"
+PROTO_FILE="reflection"
+HEADER_DIR="extensions/include/grpc++/impl"
+SRC_DIR="extensions/reflection"
+INCLUDE_DIR="grpc++/impl"
+TMP_DIR="tmp"
+GRPC_PLUGIN="bins/opt/grpc_cpp_plugin"
+PROTOC=protoc
+
+set -e
+
+TMP_DIR=${TMP_DIR}_${PROTO_FILE}
+
+cd $(dirname $0)/../../..
+
+[ ! -d $HEADER_DIR ] && mkdir -p $HEADER_DIR || :
+[ ! -d $SRC_DIR ] && mkdir -p $SRC_DIR || :
+[ ! -d $TMP_DIR ] && mkdir -p $TMP_DIR || :
+
+$PROTOC -I$PROTO_DIR --cpp_out=$TMP_DIR ${PROTO_DIR}/${PROTO_FILE}.proto
+$PROTOC -I$PROTO_DIR --grpc_out=$TMP_DIR --plugin=protoc-gen-grpc=${GRPC_PLUGIN} ${PROTO_DIR}/${PROTO_FILE}.proto
+
+sed -i "s/\"${PROTO_FILE}.pb.h\"/<${INCLUDE_DIR/\//\\\/}\/${PROTO_FILE}.pb.h>/g" ${TMP_DIR}/${PROTO_FILE}.pb.cc
+sed -i "s/\"${PROTO_FILE}.pb.h\"/<${INCLUDE_DIR/\//\\\/}\/${PROTO_FILE}.pb.h>/g" ${TMP_DIR}/${PROTO_FILE}.grpc.pb.cc
+sed -i "s/\"${PROTO_FILE}.grpc.pb.h\"/<${INCLUDE_DIR/\//\\\/}\/${PROTO_FILE}.grpc.pb.h>/g" ${TMP_DIR}/${PROTO_FILE}.grpc.pb.cc
+sed -i "s/\"${PROTO_FILE}.pb.h\"/<${INCLUDE_DIR/\//\\\/}\/${PROTO_FILE}.pb.h>/g" ${TMP_DIR}/${PROTO_FILE}.grpc.pb.h
+
+/bin/mv ${TMP_DIR}/${PROTO_FILE}.pb.h ${HEADER_DIR}
+/bin/mv ${TMP_DIR}/${PROTO_FILE}.grpc.pb.h ${HEADER_DIR}
+/bin/mv ${TMP_DIR}/${PROTO_FILE}.pb.cc ${SRC_DIR}
+/bin/mv ${TMP_DIR}/${PROTO_FILE}.grpc.pb.cc ${SRC_DIR}
+/bin/rm -r $TMP_DIR
diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json
index f546f3b995..e87f9099a5 100644
--- a/tools/run_tests/sources_and_headers.json
+++ b/tools/run_tests/sources_and_headers.json
@@ -2551,6 +2551,26 @@
     "third_party": false, 
     "type": "target"
   }, 
+  {
+    "deps": [
+      "gpr", 
+      "grpc", 
+      "grpc++", 
+      "grpc++_reflection"
+    ], 
+    "headers": [
+      "test/cpp/util/proto_reflection_descriptor_database.h"
+    ], 
+    "language": "c++", 
+    "name": "reflection_debug_test", 
+    "src": [
+      "test/cpp/util/proto_reflection_descriptor_database.cc", 
+      "test/cpp/util/proto_reflection_descriptor_database.h", 
+      "test/cpp/util/reflection_debug/reflection_client.cc"
+    ], 
+    "third_party": false, 
+    "type": "target"
+  }, 
   {
     "deps": [
       "gpr", 
@@ -4311,6 +4331,29 @@
     "third_party": false, 
     "type": "lib"
   }, 
+  {
+    "deps": [], 
+    "headers": [
+      "extensions/include/grpc++/impl/proto_server_reflection_plugin.h", 
+      "extensions/include/grpc++/impl/reflection.grpc.pb.h", 
+      "extensions/include/grpc++/impl/reflection.pb.h", 
+      "extensions/reflection/proto_server_reflection.h"
+    ], 
+    "language": "c++", 
+    "name": "grpc++_reflection", 
+    "src": [
+      "extensions/include/grpc++/impl/proto_server_reflection_plugin.h", 
+      "extensions/include/grpc++/impl/reflection.grpc.pb.h", 
+      "extensions/include/grpc++/impl/reflection.pb.h", 
+      "extensions/reflection/proto_server_reflection.cc", 
+      "extensions/reflection/proto_server_reflection.h", 
+      "extensions/reflection/proto_server_reflection_plugin.cc", 
+      "extensions/reflection/reflection.grpc.pb.cc", 
+      "extensions/reflection/reflection.pb.cc"
+    ], 
+    "third_party": false, 
+    "type": "lib"
+  }, 
   {
     "deps": [], 
     "headers": [
diff --git a/tools/run_tests/tests.json b/tools/run_tests/tests.json
index cf1154426f..e24542d5fe 100644
--- a/tools/run_tests/tests.json
+++ b/tools/run_tests/tests.json
@@ -2408,6 +2408,27 @@
       "posix"
     ]
   }, 
+  {
+    "args": [], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "gtest": false, 
+    "language": "c++", 
+    "name": "reflection_debug_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ]
+  }, 
   {
     "args": [], 
     "ci_platforms": [
diff --git a/vsprojects/grpc.sln b/vsprojects/grpc.sln
index 029c9ed7c1..dcb5e212fa 100644
--- a/vsprojects/grpc.sln
+++ b/vsprojects/grpc.sln
@@ -93,6 +93,11 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "grpc++", "vcxproj\.\grpc++\
 		{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
 	EndProjectSection
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "grpc++_reflection", "vcxproj\.\grpc++_reflection\grpc++_reflection.vcxproj", "{5F575402-3F89-5D1A-6910-9DB8BF5D2BAB}"
+	ProjectSection(myProperties) = preProject
+        	lib = "True"
+	EndProjectSection
+EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "grpc++_unsecure", "vcxproj\.\grpc++_unsecure\grpc++_unsecure.vcxproj", "{6EE56155-DF7C-4F6E-BFC4-F6F776BEB211}"
 	ProjectSection(myProperties) = preProject
         	lib = "True"
@@ -343,6 +348,22 @@ Global
 		{C187A093-A0FE-489D-A40A-6E33DE0F9FEB}.Release-DLL|Win32.Build.0 = Release-DLL|Win32
 		{C187A093-A0FE-489D-A40A-6E33DE0F9FEB}.Release-DLL|x64.ActiveCfg = Release-DLL|x64
 		{C187A093-A0FE-489D-A40A-6E33DE0F9FEB}.Release-DLL|x64.Build.0 = Release-DLL|x64
+		{5F575402-3F89-5D1A-6910-9DB8BF5D2BAB}.Debug|Win32.ActiveCfg = Debug|Win32
+		{5F575402-3F89-5D1A-6910-9DB8BF5D2BAB}.Debug|x64.ActiveCfg = Debug|x64
+		{5F575402-3F89-5D1A-6910-9DB8BF5D2BAB}.Release|Win32.ActiveCfg = Release|Win32
+		{5F575402-3F89-5D1A-6910-9DB8BF5D2BAB}.Release|x64.ActiveCfg = Release|x64
+		{5F575402-3F89-5D1A-6910-9DB8BF5D2BAB}.Debug|Win32.Build.0 = Debug|Win32
+		{5F575402-3F89-5D1A-6910-9DB8BF5D2BAB}.Debug|x64.Build.0 = Debug|x64
+		{5F575402-3F89-5D1A-6910-9DB8BF5D2BAB}.Release|Win32.Build.0 = Release|Win32
+		{5F575402-3F89-5D1A-6910-9DB8BF5D2BAB}.Release|x64.Build.0 = Release|x64
+		{5F575402-3F89-5D1A-6910-9DB8BF5D2BAB}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+		{5F575402-3F89-5D1A-6910-9DB8BF5D2BAB}.Debug-DLL|Win32.Build.0 = Debug|Win32
+		{5F575402-3F89-5D1A-6910-9DB8BF5D2BAB}.Debug-DLL|x64.ActiveCfg = Debug|x64
+		{5F575402-3F89-5D1A-6910-9DB8BF5D2BAB}.Debug-DLL|x64.Build.0 = Debug|x64
+		{5F575402-3F89-5D1A-6910-9DB8BF5D2BAB}.Release-DLL|Win32.ActiveCfg = Release|Win32
+		{5F575402-3F89-5D1A-6910-9DB8BF5D2BAB}.Release-DLL|Win32.Build.0 = Release|Win32
+		{5F575402-3F89-5D1A-6910-9DB8BF5D2BAB}.Release-DLL|x64.ActiveCfg = Release|x64
+		{5F575402-3F89-5D1A-6910-9DB8BF5D2BAB}.Release-DLL|x64.Build.0 = Release|x64
 		{6EE56155-DF7C-4F6E-BFC4-F6F776BEB211}.Debug|Win32.ActiveCfg = Debug|Win32
 		{6EE56155-DF7C-4F6E-BFC4-F6F776BEB211}.Debug|x64.ActiveCfg = Debug|x64
 		{6EE56155-DF7C-4F6E-BFC4-F6F776BEB211}.Release|Win32.ActiveCfg = Release|Win32
diff --git a/vsprojects/vcxproj/grpc++_reflection/grpc++_reflection.vcxproj b/vsprojects/vcxproj/grpc++_reflection/grpc++_reflection.vcxproj
new file mode 100644
index 0000000000..82b2b85f9e
--- /dev/null
+++ b/vsprojects/vcxproj/grpc++_reflection/grpc++_reflection.vcxproj
@@ -0,0 +1,176 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{5F575402-3F89-5D1A-6910-9DB8BF5D2BAB}</ProjectGuid>
+    <IgnoreWarnIntDirInTempDetected>true</IgnoreWarnIntDirInTempDetected>
+    <IntDir>$(SolutionDir)IntDir\$(MSBuildProjectName)\</IntDir>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(VisualStudioVersion)' == '10.0'" Label="Configuration">
+    <PlatformToolset>v100</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(VisualStudioVersion)' == '11.0'" Label="Configuration">
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(VisualStudioVersion)' == '12.0'" Label="Configuration">
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(VisualStudioVersion)' == '14.0'" Label="Configuration">
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)'=='Debug'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)'=='Release'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="$(SolutionDir)\..\vsprojects\global.props" />
+    <Import Project="$(SolutionDir)\..\vsprojects\winsock.props" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)'=='Debug'">
+    <TargetName>grpc++_reflection</TargetName>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)'=='Release'">
+    <TargetName>grpc++_reflection</TargetName>
+  </PropertyGroup>
+    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+      <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+      <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+
+    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+      <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+      <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+
+    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>MaxSpeed</Optimization>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+      <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+      <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+  </ItemDefinitionGroup>
+
+    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>MaxSpeed</Optimization>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+      <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+      <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+  </ItemDefinitionGroup>
+
+  <ItemGroup>
+    <ClInclude Include="$(SolutionDir)\..\extensions\include\grpc++\impl\proto_server_reflection_plugin.h" />
+    <ClInclude Include="$(SolutionDir)\..\extensions\include\grpc++\impl\reflection.grpc.pb.h" />
+    <ClInclude Include="$(SolutionDir)\..\extensions\include\grpc++\impl\reflection.pb.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="$(SolutionDir)\..\extensions\reflection\proto_server_reflection.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="$(SolutionDir)\..\extensions\reflection\proto_server_reflection.cc">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\extensions\reflection\proto_server_reflection_plugin.cc">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\extensions\reflection\reflection.grpc.pb.cc">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\extensions\reflection\reflection.pb.cc">
+    </ClCompile>
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+  <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
+    <PropertyGroup>
+      <ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
+    </PropertyGroup>
+  </Target>
+</Project>
+
diff --git a/vsprojects/vcxproj/grpc++_reflection/grpc++_reflection.vcxproj.filters b/vsprojects/vcxproj/grpc++_reflection/grpc++_reflection.vcxproj.filters
new file mode 100644
index 0000000000..a5457bed00
--- /dev/null
+++ b/vsprojects/vcxproj/grpc++_reflection/grpc++_reflection.vcxproj.filters
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <ClCompile Include="$(SolutionDir)\..\extensions\reflection\proto_server_reflection.cc">
+      <Filter>extensions\reflection</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\extensions\reflection\proto_server_reflection_plugin.cc">
+      <Filter>extensions\reflection</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\extensions\reflection\reflection.grpc.pb.cc">
+      <Filter>extensions\reflection</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\extensions\reflection\reflection.pb.cc">
+      <Filter>extensions\reflection</Filter>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="$(SolutionDir)\..\extensions\include\grpc++\impl\proto_server_reflection_plugin.h">
+      <Filter>extensions\include\grpc++\impl</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\extensions\include\grpc++\impl\reflection.grpc.pb.h">
+      <Filter>extensions\include\grpc++\impl</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\extensions\include\grpc++\impl\reflection.pb.h">
+      <Filter>extensions\include\grpc++\impl</Filter>
+    </ClInclude>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="$(SolutionDir)\..\extensions\reflection\proto_server_reflection.h">
+      <Filter>extensions\reflection</Filter>
+    </ClInclude>
+  </ItemGroup>
+
+  <ItemGroup>
+    <Filter Include="extensions">
+      <UniqueIdentifier>{8fd45ce8-8f02-367f-e3f7-4c0ae0e36566}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="extensions\include">
+      <UniqueIdentifier>{1a18dfcc-bedf-226e-6929-377aba53249b}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="extensions\include\grpc++">
+      <UniqueIdentifier>{83bf0cce-01da-a93c-0ff3-a1abca63ec5f}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="extensions\include\grpc++\impl">
+      <UniqueIdentifier>{d34e8821-f67b-a793-3419-e2781ab9b3ee}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="extensions\reflection">
+      <UniqueIdentifier>{11feb184-a1d9-5485-26f0-538ddb50deff}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+</Project>
+
diff --git a/vsprojects/vcxproj/test/reflection_debug_test/reflection_debug_test.vcxproj b/vsprojects/vcxproj/test/reflection_debug_test/reflection_debug_test.vcxproj
new file mode 100644
index 0000000000..757e1cd535
--- /dev/null
+++ b/vsprojects/vcxproj/test/reflection_debug_test/reflection_debug_test.vcxproj
@@ -0,0 +1,206 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.props" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\1.0.204.1.props')" />
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{037B9EA1-03CC-6A3B-4E4B-DB17C3D59CF8}</ProjectGuid>
+    <IgnoreWarnIntDirInTempDetected>true</IgnoreWarnIntDirInTempDetected>
+    <IntDir>$(SolutionDir)IntDir\$(MSBuildProjectName)\</IntDir>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(VisualStudioVersion)' == '10.0'" Label="Configuration">
+    <PlatformToolset>v100</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(VisualStudioVersion)' == '11.0'" Label="Configuration">
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(VisualStudioVersion)' == '12.0'" Label="Configuration">
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(VisualStudioVersion)' == '14.0'" Label="Configuration">
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)'=='Debug'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)'=='Release'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="$(SolutionDir)\..\vsprojects\cpptest.props" />
+    <Import Project="$(SolutionDir)\..\vsprojects\global.props" />
+    <Import Project="$(SolutionDir)\..\vsprojects\openssl.props" />
+    <Import Project="$(SolutionDir)\..\vsprojects\protobuf.props" />
+    <Import Project="$(SolutionDir)\..\vsprojects\winsock.props" />
+    <Import Project="$(SolutionDir)\..\vsprojects\zlib.props" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)'=='Debug'">
+    <TargetName>reflection_debug_test</TargetName>
+    <Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib>
+    <Configuration-grpc_dependencies_zlib>Debug</Configuration-grpc_dependencies_zlib>
+    <Linkage-grpc_dependencies_openssl>static</Linkage-grpc_dependencies_openssl>
+    <Configuration-grpc_dependencies_openssl>Debug</Configuration-grpc_dependencies_openssl>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)'=='Release'">
+    <TargetName>reflection_debug_test</TargetName>
+    <Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib>
+    <Configuration-grpc_dependencies_zlib>Release</Configuration-grpc_dependencies_zlib>
+    <Linkage-grpc_dependencies_openssl>static</Linkage-grpc_dependencies_openssl>
+    <Configuration-grpc_dependencies_openssl>Release</Configuration-grpc_dependencies_openssl>
+  </PropertyGroup>
+    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+      <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+      <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+
+    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+      <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+      <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+
+    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>MaxSpeed</Optimization>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+      <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+      <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+  </ItemDefinitionGroup>
+
+    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>MaxSpeed</Optimization>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+      <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+      <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+  </ItemDefinitionGroup>
+
+  <ItemGroup>
+    <ClInclude Include="$(SolutionDir)\..\test\cpp\util\proto_reflection_descriptor_database.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="$(SolutionDir)\..\test\cpp\util\proto_reflection_descriptor_database.cc">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\test\cpp\util\reflection_debug\reflection_client.cc">
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc++_reflection\grpc++_reflection.vcxproj">
+      <Project>{5F575402-3F89-5D1A-6910-9DB8BF5D2BAB}</Project>
+    </ProjectReference>
+    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc++\grpc++.vcxproj">
+      <Project>{C187A093-A0FE-489D-A40A-6E33DE0F9FEB}</Project>
+    </ProjectReference>
+    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc\grpc.vcxproj">
+      <Project>{29D16885-7228-4C31-81ED-5F9187C7F2A9}</Project>
+    </ProjectReference>
+    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\gpr\gpr.vcxproj">
+      <Project>{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}</Project>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="packages.config" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies.zlib.redist.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies\grpc.dependencies.zlib.targets')" />
+  <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies.zlib.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies\grpc.dependencies.zlib.targets')" />
+  <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies.openssl.redist.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies\grpc.dependencies.openssl.targets')" />
+  <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies\grpc.dependencies.openssl.targets')" />
+  </ImportGroup>
+  <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
+    <PropertyGroup>
+      <ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
+    </PropertyGroup>
+    <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies.zlib.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies.zlib.redist.targets')" />
+    <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies.zlib.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies.zlib.targets')" />
+    <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies.openssl.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies.openssl.redist.targets')" />
+    <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.props')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.props')" />
+    <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.targets')" />
+  </Target>
+</Project>
+
diff --git a/vsprojects/vcxproj/test/reflection_debug_test/reflection_debug_test.vcxproj.filters b/vsprojects/vcxproj/test/reflection_debug_test/reflection_debug_test.vcxproj.filters
new file mode 100644
index 0000000000..6258acedcc
--- /dev/null
+++ b/vsprojects/vcxproj/test/reflection_debug_test/reflection_debug_test.vcxproj.filters
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <ClCompile Include="$(SolutionDir)\..\test\cpp\util\proto_reflection_descriptor_database.cc">
+      <Filter>test\cpp\util</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\test\cpp\util\reflection_debug\reflection_client.cc">
+      <Filter>test\cpp\util\reflection_debug</Filter>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="$(SolutionDir)\..\test\cpp\util\proto_reflection_descriptor_database.h">
+      <Filter>test\cpp\util</Filter>
+    </ClInclude>
+  </ItemGroup>
+
+  <ItemGroup>
+    <Filter Include="test">
+      <UniqueIdentifier>{fdf7e642-420d-9e18-7a3c-19dca964f218}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="test\cpp">
+      <UniqueIdentifier>{562b3927-e256-190d-ab72-6b4b04ffb8b2}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="test\cpp\util">
+      <UniqueIdentifier>{8ed08be4-a27c-d51c-d587-a02cf3dc5abc}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="test\cpp\util\reflection_debug">
+      <UniqueIdentifier>{b84b1385-e0b2-239b-bac2-81a16bc90249}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+</Project>
+
-- 
GitLab