diff --git a/grpc/src/compiler/config.h b/grpc/src/compiler/config.h
new file mode 100644
index 0000000..4adc594
--- /dev/null
+++ b/grpc/src/compiler/config.h
@@ -0,0 +1,40 @@
+/*
+ *
+ * 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 SRC_COMPILER_CONFIG_H
+#define SRC_COMPILER_CONFIG_H
+
+// This file is here only because schema_interface.h, which is copied from gRPC,
+// includes it. There is nothing for Flatbuffers to configure.
+
+#endif  // SRC_COMPILER_CONFIG_H
diff --git a/grpc/src/compiler/cpp_generator.cc b/grpc/src/compiler/cpp_generator.cc
new file mode 100644
index 0000000..6cfd22e
--- /dev/null
+++ b/grpc/src/compiler/cpp_generator.cc
@@ -0,0 +1,1780 @@
+/*
+ *
+ * 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 <map>
+
+#include "src/compiler/cpp_generator.h"
+#include "flatbuffers/util.h"
+
+#include <sstream>
+
+namespace grpc_cpp_generator {
+namespace {
+
+grpc::string message_header_ext() { return "_generated.h"; }
+grpc::string service_header_ext() { return ".grpc.fb.h"; }
+
+template <class T>
+grpc::string as_string(T x) {
+  std::ostringstream out;
+  out << x;
+  return out.str();
+}
+
+inline bool ClientOnlyStreaming(const grpc_generator::Method *method) {
+  return method->ClientStreaming() && !method->ServerStreaming();
+}
+
+inline bool ServerOnlyStreaming(const grpc_generator::Method *method) {
+  return !method->ClientStreaming() && method->ServerStreaming();
+}
+
+grpc::string FilenameIdentifier(const grpc::string &filename) {
+  grpc::string result;
+  for (unsigned i = 0; i < filename.size(); i++) {
+    char c = filename[i];
+    if (isalnum(c)) {
+      result.push_back(c);
+    } else {
+      static char hex[] = "0123456789abcdef";
+      result.push_back('_');
+      result.push_back(hex[(c >> 4) & 0xf]);
+      result.push_back(hex[c & 0xf]);
+    }
+  }
+  return result;
+}
+}  // namespace
+
+template <class T, size_t N>
+T *array_end(T (&array)[N]) {
+  return array + N;
+}
+
+void PrintIncludes(grpc_generator::Printer *printer,
+                   const std::vector<grpc::string> &headers,
+                   const Parameters &params) {
+  std::map<grpc::string, grpc::string> vars;
+
+  vars["l"] = params.use_system_headers ? '<' : '"';
+  vars["r"] = params.use_system_headers ? '>' : '"';
+
+  auto &s = params.grpc_search_path;
+  if (!s.empty()) {
+    vars["l"] += s;
+    if (s[s.size() - 1] != '/') {
+      vars["l"] += '/';
+    }
+  }
+
+  for (auto i = headers.begin(); i != headers.end(); i++) {
+    vars["h"] = *i;
+    printer->Print(vars, "#include $l$$h$$r$\n");
+  }
+}
+
+grpc::string GetHeaderPrologue(grpc_generator::File *file,
+                               const Parameters & /*params*/) {
+  grpc::string output;
+  {
+    // Scope the output stream so it closes and finalizes output to the string.
+    auto printer = file->CreatePrinter(&output);
+    std::map<grpc::string, grpc::string> vars;
+
+    vars["filename"] = file->filename();
+    vars["filename_identifier"] = FilenameIdentifier(file->filename());
+    vars["filename_base"] = file->filename_without_ext();
+    vars["message_header_ext"] = message_header_ext();
+
+    printer->Print(vars, "// Generated by the gRPC C++ plugin.\n");
+    printer->Print(vars,
+                   "// If you make any local change, they will be lost.\n");
+    printer->Print(vars, "// source: $filename$\n");
+    grpc::string leading_comments = file->GetLeadingComments("//");
+    if (!leading_comments.empty()) {
+      printer->Print(vars, "// Original file comments:\n");
+      printer->Print(leading_comments.c_str());
+    }
+    printer->Print(vars, "#ifndef GRPC_$filename_identifier$__INCLUDED\n");
+    printer->Print(vars, "#define GRPC_$filename_identifier$__INCLUDED\n");
+    printer->Print(vars, "\n");
+    printer->Print(vars, "#include \"$filename_base$$message_header_ext$\"\n");
+    printer->Print(vars, file->additional_headers().c_str());
+    printer->Print(vars, "\n");
+  }
+  return output;
+}
+
+grpc::string GetHeaderIncludes(grpc_generator::File *file,
+                               const Parameters &params) {
+  grpc::string output;
+  {
+    // Scope the output stream so it closes and finalizes output to the string.
+    auto printer = file->CreatePrinter(&output);
+    std::map<grpc::string, grpc::string> vars;
+
+    static const char *headers_strs[] = {
+        "grpc++/impl/codegen/async_stream.h",
+        "grpc++/impl/codegen/async_unary_call.h",
+        "grpc++/impl/codegen/method_handler_impl.h",
+        "grpc++/impl/codegen/proto_utils.h",
+        "grpc++/impl/codegen/rpc_method.h",
+        "grpc++/impl/codegen/service_type.h",
+        "grpc++/impl/codegen/status.h",
+        "grpc++/impl/codegen/stub_options.h",
+        "grpc++/impl/codegen/sync_stream.h"};
+    std::vector<grpc::string> headers(headers_strs, array_end(headers_strs));
+    PrintIncludes(printer.get(), headers, params);
+    printer->Print(vars, "\n");
+    printer->Print(vars, "namespace grpc {\n");
+    printer->Print(vars, "class CompletionQueue;\n");
+    printer->Print(vars, "class Channel;\n");
+    printer->Print(vars, "class ServerCompletionQueue;\n");
+    printer->Print(vars, "class ServerContext;\n");
+    printer->Print(vars, "}  // namespace grpc\n\n");
+
+    if (!file->package().empty()) {
+      std::vector<grpc::string> parts = file->package_parts();
+
+      for (auto part = parts.begin(); part != parts.end(); part++) {
+        vars["part"] = *part;
+        printer->Print(vars, "namespace $part$ {\n");
+      }
+      printer->Print(vars, "\n");
+    }
+  }
+  return output;
+}
+
+void PrintHeaderClientMethodInterfaces(
+    grpc_generator::Printer *printer, const grpc_generator::Method *method,
+    std::map<grpc::string, grpc::string> *vars, bool is_public) {
+  (*vars)["Method"] = method->name();
+  (*vars)["Request"] = method->input_type_name();
+  (*vars)["Response"] = method->output_type_name();
+
+  struct {
+    grpc::string prefix;
+    grpc::string method_params;  // extra arguments to method
+    grpc::string raw_args;       // extra arguments to raw version of method
+  } async_prefixes[] = {{"Async", ", void* tag", ", tag"},
+                        {"PrepareAsync", "", ""}};
+
+  if (is_public) {
+    if (method->NoStreaming()) {
+      printer->Print(
+          *vars,
+          "virtual ::grpc::Status $Method$(::grpc::ClientContext* context, "
+          "const $Request$& request, $Response$* response) = 0;\n");
+      for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
+        auto& async_prefix = async_prefixes[i];
+        (*vars)["AsyncPrefix"] = async_prefix.prefix;
+        printer->Print(
+            *vars,
+            "std::unique_ptr< "
+            "::grpc::ClientAsyncResponseReaderInterface< $Response$>> "
+            "$AsyncPrefix$$Method$(::grpc::ClientContext* context, "
+            "const $Request$& request, "
+            "::grpc::CompletionQueue* cq) {\n");
+        printer->Indent();
+        printer->Print(
+            *vars,
+            "return std::unique_ptr< "
+            "::grpc::ClientAsyncResponseReaderInterface< $Response$>>("
+            "$AsyncPrefix$$Method$Raw(context, request, cq));\n");
+        printer->Outdent();
+        printer->Print("}\n");
+      }
+    } else if (ClientOnlyStreaming(method)) {
+      printer->Print(
+          *vars,
+          "std::unique_ptr< ::grpc::ClientWriterInterface< $Request$>>"
+          " $Method$("
+          "::grpc::ClientContext* context, $Response$* response) {\n");
+      printer->Indent();
+      printer->Print(
+          *vars,
+          "return std::unique_ptr< ::grpc::ClientWriterInterface< $Request$>>"
+          "($Method$Raw(context, response));\n");
+      printer->Outdent();
+      printer->Print("}\n");
+      for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
+        auto& async_prefix = async_prefixes[i];
+        (*vars)["AsyncPrefix"] = async_prefix.prefix;
+        (*vars)["AsyncMethodParams"] = async_prefix.method_params;
+        (*vars)["AsyncRawArgs"] = async_prefix.raw_args;
+        printer->Print(
+            *vars,
+            "std::unique_ptr< ::grpc::ClientAsyncWriterInterface< $Request$>>"
+            " $AsyncPrefix$$Method$(::grpc::ClientContext* context, "
+            "$Response$* "
+            "response, "
+            "::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n");
+        printer->Indent();
+        printer->Print(*vars,
+                       "return std::unique_ptr< "
+                       "::grpc::ClientAsyncWriterInterface< $Request$>>("
+                       "$AsyncPrefix$$Method$Raw(context, response, "
+                       "cq$AsyncRawArgs$));\n");
+        printer->Outdent();
+        printer->Print("}\n");
+      }
+    } else if (ServerOnlyStreaming(method)) {
+      printer->Print(
+          *vars,
+          "std::unique_ptr< ::grpc::ClientReaderInterface< $Response$>>"
+          " $Method$(::grpc::ClientContext* context, const $Request$& request)"
+          " {\n");
+      printer->Indent();
+      printer->Print(
+          *vars,
+          "return std::unique_ptr< ::grpc::ClientReaderInterface< $Response$>>"
+          "($Method$Raw(context, request));\n");
+      printer->Outdent();
+      printer->Print("}\n");
+      for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
+        auto& async_prefix = async_prefixes[i];
+        (*vars)["AsyncPrefix"] = async_prefix.prefix;
+        (*vars)["AsyncMethodParams"] = async_prefix.method_params;
+        (*vars)["AsyncRawArgs"] = async_prefix.raw_args;
+        printer->Print(
+            *vars,
+            "std::unique_ptr< ::grpc::ClientAsyncReaderInterface< $Response$>> "
+            "$AsyncPrefix$$Method$("
+            "::grpc::ClientContext* context, const $Request$& request, "
+            "::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n");
+        printer->Indent();
+        printer->Print(
+            *vars,
+            "return std::unique_ptr< "
+            "::grpc::ClientAsyncReaderInterface< $Response$>>("
+            "$AsyncPrefix$$Method$Raw(context, request, cq$AsyncRawArgs$));\n");
+        printer->Outdent();
+        printer->Print("}\n");
+      }
+    } else if (method->BidiStreaming()) {
+      printer->Print(*vars,
+                     "std::unique_ptr< ::grpc::ClientReaderWriterInterface< "
+                     "$Request$, $Response$>> "
+                     "$Method$(::grpc::ClientContext* context) {\n");
+      printer->Indent();
+      printer->Print(
+          *vars,
+          "return std::unique_ptr< "
+          "::grpc::ClientReaderWriterInterface< $Request$, $Response$>>("
+          "$Method$Raw(context));\n");
+      printer->Outdent();
+      printer->Print("}\n");
+      for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
+        auto& async_prefix = async_prefixes[i];
+        (*vars)["AsyncPrefix"] = async_prefix.prefix;
+        (*vars)["AsyncMethodParams"] = async_prefix.method_params;
+        (*vars)["AsyncRawArgs"] = async_prefix.raw_args;
+        printer->Print(
+            *vars,
+            "std::unique_ptr< "
+            "::grpc::ClientAsyncReaderWriterInterface< $Request$, $Response$>> "
+            "$AsyncPrefix$$Method$(::grpc::ClientContext* context, "
+            "::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n");
+        printer->Indent();
+        printer->Print(
+            *vars,
+            "return std::unique_ptr< "
+            "::grpc::ClientAsyncReaderWriterInterface< $Request$, $Response$>>("
+            "$AsyncPrefix$$Method$Raw(context, cq$AsyncRawArgs$));\n");
+        printer->Outdent();
+        printer->Print("}\n");
+      }
+    }
+  } else {
+    if (method->NoStreaming()) {
+      for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
+        auto& async_prefix = async_prefixes[i];
+        (*vars)["AsyncPrefix"] = async_prefix.prefix;
+        printer->Print(
+            *vars,
+            "virtual ::grpc::ClientAsyncResponseReaderInterface< $Response$>* "
+            "$AsyncPrefix$$Method$Raw(::grpc::ClientContext* context, "
+            "const $Request$& request, "
+            "::grpc::CompletionQueue* cq) = 0;\n");
+      }
+    } else if (ClientOnlyStreaming(method)) {
+      printer->Print(
+          *vars,
+          "virtual ::grpc::ClientWriterInterface< $Request$>*"
+          " $Method$Raw("
+          "::grpc::ClientContext* context, $Response$* response) = 0;\n");
+      for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
+        auto& async_prefix = async_prefixes[i];
+        (*vars)["AsyncPrefix"] = async_prefix.prefix;
+        (*vars)["AsyncMethodParams"] = async_prefix.method_params;
+        printer->Print(
+            *vars,
+            "virtual ::grpc::ClientAsyncWriterInterface< $Request$>*"
+            " $AsyncPrefix$$Method$Raw(::grpc::ClientContext* context, "
+            "$Response$* response, "
+            "::grpc::CompletionQueue* cq$AsyncMethodParams$) = 0;\n");
+      }
+    } else if (ServerOnlyStreaming(method)) {
+      printer->Print(
+          *vars,
+          "virtual ::grpc::ClientReaderInterface< $Response$>* "
+          "$Method$Raw("
+          "::grpc::ClientContext* context, const $Request$& request) = 0;\n");
+      for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
+        auto& async_prefix = async_prefixes[i];
+        (*vars)["AsyncPrefix"] = async_prefix.prefix;
+        (*vars)["AsyncMethodParams"] = async_prefix.method_params;
+        printer->Print(
+            *vars,
+            "virtual ::grpc::ClientAsyncReaderInterface< $Response$>* "
+            "$AsyncPrefix$$Method$Raw("
+            "::grpc::ClientContext* context, const $Request$& request, "
+            "::grpc::CompletionQueue* cq$AsyncMethodParams$) = 0;\n");
+      }
+    } else if (method->BidiStreaming()) {
+      printer->Print(*vars,
+                     "virtual ::grpc::ClientReaderWriterInterface< $Request$, "
+                     "$Response$>* "
+                     "$Method$Raw(::grpc::ClientContext* context) = 0;\n");
+      for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
+        auto& async_prefix = async_prefixes[i];
+        (*vars)["AsyncPrefix"] = async_prefix.prefix;
+        (*vars)["AsyncMethodParams"] = async_prefix.method_params;
+        printer->Print(
+            *vars,
+            "virtual ::grpc::ClientAsyncReaderWriterInterface< "
+            "$Request$, $Response$>* "
+            "$AsyncPrefix$$Method$Raw(::grpc::ClientContext* context, "
+            "::grpc::CompletionQueue* cq$AsyncMethodParams$) = 0;\n");
+      }
+    }
+  }
+}
+
+void PrintHeaderClientMethod(grpc_generator::Printer *printer,
+                             const grpc_generator::Method *method,
+                             std::map<grpc::string, grpc::string> *vars,
+                             bool is_public) {
+  (*vars)["Method"] = method->name();
+  (*vars)["Request"] = method->input_type_name();
+  (*vars)["Response"] = method->output_type_name();
+  struct {
+    grpc::string prefix;
+    grpc::string method_params;  // extra arguments to method
+    grpc::string raw_args;       // extra arguments to raw version of method
+  } async_prefixes[] = {{"Async", ", void* tag", ", tag"},
+                        {"PrepareAsync", "", ""}};
+
+  if (is_public) {
+    if (method->NoStreaming()) {
+      printer->Print(
+          *vars,
+          "::grpc::Status $Method$(::grpc::ClientContext* context, "
+          "const $Request$& request, $Response$* response) override;\n");
+    for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
+        auto& async_prefix = async_prefixes[i];
+        (*vars)["AsyncPrefix"] = async_prefix.prefix;
+        printer->Print(
+            *vars,
+            "std::unique_ptr< ::grpc::ClientAsyncResponseReader< $Response$>> "
+            "$AsyncPrefix$$Method$(::grpc::ClientContext* context, "
+            "const $Request$& request, "
+            "::grpc::CompletionQueue* cq) {\n");
+        printer->Indent();
+        printer->Print(*vars,
+                       "return std::unique_ptr< "
+                       "::grpc::ClientAsyncResponseReader< $Response$>>("
+                       "$AsyncPrefix$$Method$Raw(context, request, cq));\n");
+        printer->Outdent();
+        printer->Print("}\n");
+      }
+    } else if (ClientOnlyStreaming(method)) {
+      printer->Print(
+          *vars,
+          "std::unique_ptr< ::grpc::ClientWriter< $Request$>>"
+          " $Method$("
+          "::grpc::ClientContext* context, $Response$* response) {\n");
+      printer->Indent();
+      printer->Print(*vars,
+                     "return std::unique_ptr< ::grpc::ClientWriter< $Request$>>"
+                     "($Method$Raw(context, response));\n");
+      printer->Outdent();
+      printer->Print("}\n");
+      for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
+        auto& async_prefix = async_prefixes[i];
+        (*vars)["AsyncPrefix"] = async_prefix.prefix;
+        (*vars)["AsyncMethodParams"] = async_prefix.method_params;
+        (*vars)["AsyncRawArgs"] = async_prefix.raw_args;
+        printer->Print(*vars,
+                       "std::unique_ptr< ::grpc::ClientAsyncWriter< $Request$>>"
+                       " $AsyncPrefix$$Method$(::grpc::ClientContext* context, "
+                       "$Response$* response, "
+                       "::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n");
+        printer->Indent();
+        printer->Print(
+            *vars,
+            "return std::unique_ptr< ::grpc::ClientAsyncWriter< $Request$>>("
+            "$AsyncPrefix$$Method$Raw(context, response, "
+            "cq$AsyncRawArgs$));\n");
+        printer->Outdent();
+        printer->Print("}\n");
+      }
+    } else if (ServerOnlyStreaming(method)) {
+      printer->Print(
+          *vars,
+          "std::unique_ptr< ::grpc::ClientReader< $Response$>>"
+          " $Method$(::grpc::ClientContext* context, const $Request$& request)"
+          " {\n");
+      printer->Indent();
+      printer->Print(
+          *vars,
+          "return std::unique_ptr< ::grpc::ClientReader< $Response$>>"
+          "($Method$Raw(context, request));\n");
+      printer->Outdent();
+      printer->Print("}\n");
+      for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
+        auto& async_prefix = async_prefixes[i];
+        (*vars)["AsyncPrefix"] = async_prefix.prefix;
+        (*vars)["AsyncMethodParams"] = async_prefix.method_params;
+        (*vars)["AsyncRawArgs"] = async_prefix.raw_args;
+        printer->Print(
+            *vars,
+            "std::unique_ptr< ::grpc::ClientAsyncReader< $Response$>> "
+            "$AsyncPrefix$$Method$("
+            "::grpc::ClientContext* context, const $Request$& request, "
+            "::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n");
+        printer->Indent();
+        printer->Print(
+            *vars,
+            "return std::unique_ptr< ::grpc::ClientAsyncReader< $Response$>>("
+            "$AsyncPrefix$$Method$Raw(context, request, cq$AsyncRawArgs$));\n");
+        printer->Outdent();
+        printer->Print("}\n");
+      }
+    } else if (method->BidiStreaming()) {
+      printer->Print(
+          *vars,
+          "std::unique_ptr< ::grpc::ClientReaderWriter< $Request$, $Response$>>"
+          " $Method$(::grpc::ClientContext* context) {\n");
+      printer->Indent();
+      printer->Print(*vars,
+                     "return std::unique_ptr< "
+                     "::grpc::ClientReaderWriter< $Request$, $Response$>>("
+                     "$Method$Raw(context));\n");
+      printer->Outdent();
+      printer->Print("}\n");
+      for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
+        auto& async_prefix = async_prefixes[i];
+        (*vars)["AsyncPrefix"] = async_prefix.prefix;
+        (*vars)["AsyncMethodParams"] = async_prefix.method_params;
+        (*vars)["AsyncRawArgs"] = async_prefix.raw_args;
+        printer->Print(*vars,
+                       "std::unique_ptr<  ::grpc::ClientAsyncReaderWriter< "
+                       "$Request$, $Response$>> "
+                       "$AsyncPrefix$$Method$(::grpc::ClientContext* context, "
+                       "::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n");
+        printer->Indent();
+        printer->Print(
+            *vars,
+            "return std::unique_ptr< "
+            "::grpc::ClientAsyncReaderWriter< $Request$, $Response$>>("
+            "$AsyncPrefix$$Method$Raw(context, cq$AsyncRawArgs$));\n");
+        printer->Outdent();
+        printer->Print("}\n");
+      }
+    }
+  } else {
+    if (method->NoStreaming()) {
+      for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
+        auto& async_prefix = async_prefixes[i];
+        (*vars)["AsyncPrefix"] = async_prefix.prefix;
+        printer->Print(
+            *vars,
+            "::grpc::ClientAsyncResponseReader< $Response$>* "
+            "$AsyncPrefix$$Method$Raw(::grpc::ClientContext* context, "
+            "const $Request$& request, "
+            "::grpc::CompletionQueue* cq) override;\n");
+      }
+    } else if (ClientOnlyStreaming(method)) {
+      printer->Print(*vars,
+                     "::grpc::ClientWriter< $Request$>* $Method$Raw("
+                     "::grpc::ClientContext* context, $Response$* response) "
+                     "override;\n");
+    for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
+        auto& async_prefix = async_prefixes[i];
+        (*vars)["AsyncPrefix"] = async_prefix.prefix;
+        (*vars)["AsyncMethodParams"] = async_prefix.method_params;
+        (*vars)["AsyncRawArgs"] = async_prefix.raw_args;
+        printer->Print(
+            *vars,
+            "::grpc::ClientAsyncWriter< $Request$>* $AsyncPrefix$$Method$Raw("
+            "::grpc::ClientContext* context, $Response$* response, "
+            "::grpc::CompletionQueue* cq$AsyncMethodParams$) override;\n");
+      }
+    } else if (ServerOnlyStreaming(method)) {
+      printer->Print(*vars,
+                     "::grpc::ClientReader< $Response$>* $Method$Raw("
+                     "::grpc::ClientContext* context, const $Request$& request)"
+                     " override;\n");
+    for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
+        auto& async_prefix = async_prefixes[i];
+        (*vars)["AsyncPrefix"] = async_prefix.prefix;
+        (*vars)["AsyncMethodParams"] = async_prefix.method_params;
+        (*vars)["AsyncRawArgs"] = async_prefix.raw_args;
+        printer->Print(
+            *vars,
+            "::grpc::ClientAsyncReader< $Response$>* $AsyncPrefix$$Method$Raw("
+            "::grpc::ClientContext* context, const $Request$& request, "
+            "::grpc::CompletionQueue* cq$AsyncMethodParams$) override;\n");
+      }
+    } else if (method->BidiStreaming()) {
+      printer->Print(*vars,
+                     "::grpc::ClientReaderWriter< $Request$, $Response$>* "
+                     "$Method$Raw(::grpc::ClientContext* context) override;\n");
+      for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
+        auto& async_prefix = async_prefixes[i];
+        (*vars)["AsyncPrefix"] = async_prefix.prefix;
+        (*vars)["AsyncMethodParams"] = async_prefix.method_params;
+        (*vars)["AsyncRawArgs"] = async_prefix.raw_args;
+        printer->Print(
+            *vars,
+            "::grpc::ClientAsyncReaderWriter< $Request$, $Response$>* "
+            "$AsyncPrefix$$Method$Raw(::grpc::ClientContext* context, "
+            "::grpc::CompletionQueue* cq$AsyncMethodParams$) override;\n");
+      }
+    }
+  }
+}
+
+void PrintHeaderClientMethodData(grpc_generator::Printer *printer,
+                                 const grpc_generator::Method *method,
+                                 std::map<grpc::string, grpc::string> *vars) {
+  (*vars)["Method"] = method->name();
+  printer->Print(*vars,
+                 "const ::grpc::internal::RpcMethod rpcmethod_$Method$_;\n");
+}
+
+void PrintHeaderServerMethodSync(grpc_generator::Printer *printer,
+                                 const grpc_generator::Method *method,
+                                 std::map<grpc::string, grpc::string> *vars) {
+  (*vars)["Method"] = method->name();
+  (*vars)["Request"] = method->input_type_name();
+  (*vars)["Response"] = method->output_type_name();
+  printer->Print(method->GetLeadingComments("//").c_str());
+  if (method->NoStreaming()) {
+    printer->Print(*vars,
+                   "virtual ::grpc::Status $Method$("
+                   "::grpc::ServerContext* context, const $Request$* request, "
+                   "$Response$* response);\n");
+  } else if (ClientOnlyStreaming(method)) {
+    printer->Print(*vars,
+                   "virtual ::grpc::Status $Method$("
+                   "::grpc::ServerContext* context, "
+                   "::grpc::ServerReader< $Request$>* reader, "
+                   "$Response$* response);\n");
+  } else if (ServerOnlyStreaming(method)) {
+    printer->Print(*vars,
+                   "virtual ::grpc::Status $Method$("
+                   "::grpc::ServerContext* context, const $Request$* request, "
+                   "::grpc::ServerWriter< $Response$>* writer);\n");
+  } else if (method->BidiStreaming()) {
+    printer->Print(
+        *vars,
+        "virtual ::grpc::Status $Method$("
+        "::grpc::ServerContext* context, "
+        "::grpc::ServerReaderWriter< $Response$, $Request$>* stream);"
+        "\n");
+  }
+  printer->Print(method->GetTrailingComments("//").c_str());
+}
+
+void PrintHeaderServerMethodAsync(grpc_generator::Printer *printer,
+                                  const grpc_generator::Method *method,
+                                  std::map<grpc::string, grpc::string> *vars) {
+  (*vars)["Method"] = method->name();
+  (*vars)["Request"] = method->input_type_name();
+  (*vars)["Response"] = method->output_type_name();
+  printer->Print(*vars, "template <class BaseClass>\n");
+  printer->Print(*vars,
+                 "class WithAsyncMethod_$Method$ : public BaseClass {\n");
+  printer->Print(
+      " private:\n"
+      "  void BaseClassMustBeDerivedFromService(const Service *service) {}\n");
+  printer->Print(" public:\n");
+  printer->Indent();
+  printer->Print(*vars,
+                 "WithAsyncMethod_$Method$() {\n"
+                 "  ::grpc::Service::MarkMethodAsync($Idx$);\n"
+                 "}\n");
+  printer->Print(*vars,
+                 "~WithAsyncMethod_$Method$() override {\n"
+                 "  BaseClassMustBeDerivedFromService(this);\n"
+                 "}\n");
+  if (method->NoStreaming()) {
+    printer->Print(
+        *vars,
+        "// disable synchronous version of this method\n"
+        "::grpc::Status $Method$("
+        "::grpc::ServerContext* context, const $Request$* request, "
+        "$Response$* response) final override {\n"
+        "  abort();\n"
+        "  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
+        "}\n");
+    printer->Print(
+        *vars,
+        "void Request$Method$("
+        "::grpc::ServerContext* context, $Request$* request, "
+        "::grpc::ServerAsyncResponseWriter< $Response$>* response, "
+        "::grpc::CompletionQueue* new_call_cq, "
+        "::grpc::ServerCompletionQueue* notification_cq, void *tag) {\n");
+    printer->Print(*vars,
+                   "  ::grpc::Service::RequestAsyncUnary($Idx$, context, "
+                   "request, response, new_call_cq, notification_cq, tag);\n");
+    printer->Print("}\n");
+  } else if (ClientOnlyStreaming(method)) {
+    printer->Print(
+        *vars,
+        "// disable synchronous version of this method\n"
+        "::grpc::Status $Method$("
+        "::grpc::ServerContext* context, "
+        "::grpc::ServerReader< $Request$>* reader, "
+        "$Response$* response) final override {\n"
+        "  abort();\n"
+        "  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
+        "}\n");
+    printer->Print(
+        *vars,
+        "void Request$Method$("
+        "::grpc::ServerContext* context, "
+        "::grpc::ServerAsyncReader< $Response$, $Request$>* reader, "
+        "::grpc::CompletionQueue* new_call_cq, "
+        "::grpc::ServerCompletionQueue* notification_cq, void *tag) {\n");
+    printer->Print(*vars,
+                   "  ::grpc::Service::RequestAsyncClientStreaming($Idx$, "
+                   "context, reader, new_call_cq, notification_cq, tag);\n");
+    printer->Print("}\n");
+  } else if (ServerOnlyStreaming(method)) {
+    printer->Print(
+        *vars,
+        "// disable synchronous version of this method\n"
+        "::grpc::Status $Method$("
+        "::grpc::ServerContext* context, const $Request$* request, "
+        "::grpc::ServerWriter< $Response$>* writer) final override "
+        "{\n"
+        "  abort();\n"
+        "  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
+        "}\n");
+    printer->Print(
+        *vars,
+        "void Request$Method$("
+        "::grpc::ServerContext* context, $Request$* request, "
+        "::grpc::ServerAsyncWriter< $Response$>* writer, "
+        "::grpc::CompletionQueue* new_call_cq, "
+        "::grpc::ServerCompletionQueue* notification_cq, void *tag) {\n");
+    printer->Print(
+        *vars,
+        "  ::grpc::Service::RequestAsyncServerStreaming($Idx$, "
+        "context, request, writer, new_call_cq, notification_cq, tag);\n");
+    printer->Print("}\n");
+  } else if (method->BidiStreaming()) {
+    printer->Print(
+        *vars,
+        "// disable synchronous version of this method\n"
+        "::grpc::Status $Method$("
+        "::grpc::ServerContext* context, "
+        "::grpc::ServerReaderWriter< $Response$, $Request$>* stream) "
+        "final override {\n"
+        "  abort();\n"
+        "  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
+        "}\n");
+    printer->Print(
+        *vars,
+        "void Request$Method$("
+        "::grpc::ServerContext* context, "
+        "::grpc::ServerAsyncReaderWriter< $Response$, $Request$>* stream, "
+        "::grpc::CompletionQueue* new_call_cq, "
+        "::grpc::ServerCompletionQueue* notification_cq, void *tag) {\n");
+    printer->Print(*vars,
+                   "  ::grpc::Service::RequestAsyncBidiStreaming($Idx$, "
+                   "context, stream, new_call_cq, notification_cq, tag);\n");
+    printer->Print("}\n");
+  }
+  printer->Outdent();
+  printer->Print(*vars, "};\n");
+}
+
+void PrintHeaderServerMethodStreamedUnary(
+    grpc_generator::Printer *printer, const grpc_generator::Method *method,
+    std::map<grpc::string, grpc::string> *vars) {
+  (*vars)["Method"] = method->name();
+  (*vars)["Request"] = method->input_type_name();
+  (*vars)["Response"] = method->output_type_name();
+  if (method->NoStreaming()) {
+    printer->Print(*vars, "template <class BaseClass>\n");
+    printer->Print(*vars,
+                   "class WithStreamedUnaryMethod_$Method$ : "
+                   "public BaseClass {\n");
+    printer->Print(
+        " private:\n"
+        "  void BaseClassMustBeDerivedFromService(const Service *service) "
+        "{}\n");
+    printer->Print(" public:\n");
+    printer->Indent();
+    printer->Print(*vars,
+                   "WithStreamedUnaryMethod_$Method$() {\n"
+                   "  ::grpc::Service::MarkMethodStreamed($Idx$,\n"
+                   "    new ::grpc::internal::StreamedUnaryHandler< $Request$, "
+                   "$Response$>(std::bind"
+                   "(&WithStreamedUnaryMethod_$Method$<BaseClass>::"
+                   "Streamed$Method$, this, std::placeholders::_1, "
+                   "std::placeholders::_2)));\n"
+                   "}\n");
+    printer->Print(*vars,
+                   "~WithStreamedUnaryMethod_$Method$() override {\n"
+                   "  BaseClassMustBeDerivedFromService(this);\n"
+                   "}\n");
+    printer->Print(
+        *vars,
+        "// disable regular version of this method\n"
+        "::grpc::Status $Method$("
+        "::grpc::ServerContext* context, const $Request$* request, "
+        "$Response$* response) final override {\n"
+        "  abort();\n"
+        "  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
+        "}\n");
+    printer->Print(*vars,
+                   "// replace default version of method with streamed unary\n"
+                   "virtual ::grpc::Status Streamed$Method$("
+                   "::grpc::ServerContext* context, "
+                   "::grpc::ServerUnaryStreamer< "
+                   "$Request$,$Response$>* server_unary_streamer)"
+                   " = 0;\n");
+    printer->Outdent();
+    printer->Print(*vars, "};\n");
+  }
+}
+
+void PrintHeaderServerMethodSplitStreaming(
+    grpc_generator::Printer *printer, const grpc_generator::Method *method,
+    std::map<grpc::string, grpc::string> *vars) {
+  (*vars)["Method"] = method->name();
+  (*vars)["Request"] = method->input_type_name();
+  (*vars)["Response"] = method->output_type_name();
+  if (ServerOnlyStreaming(method)) {
+    printer->Print(*vars, "template <class BaseClass>\n");
+    printer->Print(*vars,
+                   "class WithSplitStreamingMethod_$Method$ : "
+                   "public BaseClass {\n");
+    printer->Print(
+        " private:\n"
+        "  void BaseClassMustBeDerivedFromService(const Service *service) "
+        "{}\n");
+    printer->Print(" public:\n");
+    printer->Indent();
+    printer->Print(
+        *vars,
+        "WithSplitStreamingMethod_$Method$() {\n"
+        "  ::grpc::Service::MarkMethodStreamed($Idx$,\n"
+        "    new ::grpc::internal::SplitServerStreamingHandler< $Request$, "
+        "$Response$>(std::bind"
+        "(&WithSplitStreamingMethod_$Method$<BaseClass>::"
+        "Streamed$Method$, this, std::placeholders::_1, "
+        "std::placeholders::_2)));\n"
+        "}\n");
+    printer->Print(*vars,
+                   "~WithSplitStreamingMethod_$Method$() override {\n"
+                   "  BaseClassMustBeDerivedFromService(this);\n"
+                   "}\n");
+    printer->Print(
+        *vars,
+        "// disable regular version of this method\n"
+        "::grpc::Status $Method$("
+        "::grpc::ServerContext* context, const $Request$* request, "
+        "::grpc::ServerWriter< $Response$>* writer) final override "
+        "{\n"
+        "  abort();\n"
+        "  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
+        "}\n");
+    printer->Print(*vars,
+                   "// replace default version of method with split streamed\n"
+                   "virtual ::grpc::Status Streamed$Method$("
+                   "::grpc::ServerContext* context, "
+                   "::grpc::ServerSplitStreamer< "
+                   "$Request$,$Response$>* server_split_streamer)"
+                   " = 0;\n");
+    printer->Outdent();
+    printer->Print(*vars, "};\n");
+  }
+}
+
+void PrintHeaderServerMethodGeneric(
+    grpc_generator::Printer *printer, const grpc_generator::Method *method,
+    std::map<grpc::string, grpc::string> *vars) {
+  (*vars)["Method"] = method->name();
+  (*vars)["Request"] = method->input_type_name();
+  (*vars)["Response"] = method->output_type_name();
+  printer->Print(*vars, "template <class BaseClass>\n");
+  printer->Print(*vars,
+                 "class WithGenericMethod_$Method$ : public BaseClass {\n");
+  printer->Print(
+      " private:\n"
+      "  void BaseClassMustBeDerivedFromService(const Service *service) {}\n");
+  printer->Print(" public:\n");
+  printer->Indent();
+  printer->Print(*vars,
+                 "WithGenericMethod_$Method$() {\n"
+                 "  ::grpc::Service::MarkMethodGeneric($Idx$);\n"
+                 "}\n");
+  printer->Print(*vars,
+                 "~WithGenericMethod_$Method$() override {\n"
+                 "  BaseClassMustBeDerivedFromService(this);\n"
+                 "}\n");
+  if (method->NoStreaming()) {
+    printer->Print(
+        *vars,
+        "// disable synchronous version of this method\n"
+        "::grpc::Status $Method$("
+        "::grpc::ServerContext* context, const $Request$* request, "
+        "$Response$* response) final override {\n"
+        "  abort();\n"
+        "  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
+        "}\n");
+  } else if (ClientOnlyStreaming(method)) {
+    printer->Print(
+        *vars,
+        "// disable synchronous version of this method\n"
+        "::grpc::Status $Method$("
+        "::grpc::ServerContext* context, "
+        "::grpc::ServerReader< $Request$>* reader, "
+        "$Response$* response) final override {\n"
+        "  abort();\n"
+        "  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
+        "}\n");
+  } else if (ServerOnlyStreaming(method)) {
+    printer->Print(
+        *vars,
+        "// disable synchronous version of this method\n"
+        "::grpc::Status $Method$("
+        "::grpc::ServerContext* context, const $Request$* request, "
+        "::grpc::ServerWriter< $Response$>* writer) final override "
+        "{\n"
+        "  abort();\n"
+        "  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
+        "}\n");
+  } else if (method->BidiStreaming()) {
+    printer->Print(
+        *vars,
+        "// disable synchronous version of this method\n"
+        "::grpc::Status $Method$("
+        "::grpc::ServerContext* context, "
+        "::grpc::ServerReaderWriter< $Response$, $Request$>* stream) "
+        "final override {\n"
+        "  abort();\n"
+        "  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
+        "}\n");
+  }
+  printer->Outdent();
+  printer->Print(*vars, "};\n");
+}
+
+void PrintHeaderService(grpc_generator::Printer *printer,
+                        const grpc_generator::Service *service,
+                        std::map<grpc::string, grpc::string> *vars) {
+  (*vars)["Service"] = service->name();
+
+  printer->Print(service->GetLeadingComments("//").c_str());
+  printer->Print(*vars,
+                 "class $Service$ final {\n"
+                 " public:\n");
+  printer->Indent();
+
+  // Service metadata
+  printer->Print(*vars,
+                 "static constexpr char const* service_full_name() {\n"
+                 "  return \"$Package$$Service$\";\n"
+                 "}\n");
+
+  // Client side
+  printer->Print(
+      "class StubInterface {\n"
+      " public:\n");
+  printer->Indent();
+  printer->Print("virtual ~StubInterface() {}\n");
+  for (int i = 0; i < service->method_count(); ++i) {
+    printer->Print(service->method(i)->GetLeadingComments("//").c_str());
+    PrintHeaderClientMethodInterfaces(printer, service->method(i).get(), vars,
+                                      true);
+    printer->Print(service->method(i)->GetTrailingComments("//").c_str());
+  }
+  printer->Outdent();
+  printer->Print("private:\n");
+  printer->Indent();
+  for (int i = 0; i < service->method_count(); ++i) {
+    PrintHeaderClientMethodInterfaces(printer, service->method(i).get(), vars,
+                                      false);
+  }
+  printer->Outdent();
+  printer->Print("};\n");
+  printer->Print(
+      "class Stub final : public StubInterface"
+      " {\n public:\n");
+  printer->Indent();
+  printer->Print(
+      "Stub(const std::shared_ptr< ::grpc::ChannelInterface>& "
+      "channel);\n");
+  for (int i = 0; i < service->method_count(); ++i) {
+    PrintHeaderClientMethod(printer, service->method(i).get(), vars, true);
+  }
+  printer->Outdent();
+  printer->Print("\n private:\n");
+  printer->Indent();
+  printer->Print("std::shared_ptr< ::grpc::ChannelInterface> channel_;\n");
+  for (int i = 0; i < service->method_count(); ++i) {
+    PrintHeaderClientMethod(printer, service->method(i).get(), vars, false);
+  }
+  for (int i = 0; i < service->method_count(); ++i) {
+    PrintHeaderClientMethodData(printer, service->method(i).get(), vars);
+  }
+  printer->Outdent();
+  printer->Print("};\n");
+  printer->Print(
+      "static std::unique_ptr<Stub> NewStub(const std::shared_ptr< "
+      "::grpc::ChannelInterface>& channel, "
+      "const ::grpc::StubOptions& options = ::grpc::StubOptions());\n");
+
+  printer->Print("\n");
+
+  // Server side - base
+  printer->Print(
+      "class Service : public ::grpc::Service {\n"
+      " public:\n");
+  printer->Indent();
+  printer->Print("Service();\n");
+  printer->Print("virtual ~Service();\n");
+  for (int i = 0; i < service->method_count(); ++i) {
+    PrintHeaderServerMethodSync(printer, service->method(i).get(), vars);
+  }
+  printer->Outdent();
+  printer->Print("};\n");
+
+  // Server side - Asynchronous
+  for (int i = 0; i < service->method_count(); ++i) {
+    (*vars)["Idx"] = as_string(i);
+    PrintHeaderServerMethodAsync(printer, service->method(i).get(), vars);
+  }
+
+  printer->Print("typedef ");
+
+  for (int i = 0; i < service->method_count(); ++i) {
+    (*vars)["method_name"] = service->method(i).get()->name();
+    printer->Print(*vars, "WithAsyncMethod_$method_name$<");
+  }
+  printer->Print("Service");
+  for (int i = 0; i < service->method_count(); ++i) {
+    printer->Print(" >");
+  }
+  printer->Print(" AsyncService;\n");
+
+  // Server side - Generic
+  for (int i = 0; i < service->method_count(); ++i) {
+    (*vars)["Idx"] = as_string(i);
+    PrintHeaderServerMethodGeneric(printer, service->method(i).get(), vars);
+  }
+
+  // Server side - Streamed Unary
+  for (int i = 0; i < service->method_count(); ++i) {
+    (*vars)["Idx"] = as_string(i);
+    PrintHeaderServerMethodStreamedUnary(printer, service->method(i).get(),
+                                         vars);
+  }
+
+  printer->Print("typedef ");
+  for (int i = 0; i < service->method_count(); ++i) {
+    (*vars)["method_name"] = service->method(i).get()->name();
+    if (service->method(i)->NoStreaming()) {
+      printer->Print(*vars, "WithStreamedUnaryMethod_$method_name$<");
+    }
+  }
+  printer->Print("Service");
+  for (int i = 0; i < service->method_count(); ++i) {
+    if (service->method(i)->NoStreaming()) {
+      printer->Print(" >");
+    }
+  }
+  printer->Print(" StreamedUnaryService;\n");
+
+  // Server side - controlled server-side streaming
+  for (int i = 0; i < service->method_count(); ++i) {
+    (*vars)["Idx"] = as_string(i);
+    PrintHeaderServerMethodSplitStreaming(printer, service->method(i).get(),
+                                          vars);
+  }
+
+  printer->Print("typedef ");
+  for (int i = 0; i < service->method_count(); ++i) {
+    (*vars)["method_name"] = service->method(i).get()->name();
+    auto method = service->method(i);
+    if (ServerOnlyStreaming(method.get())) {
+      printer->Print(*vars, "WithSplitStreamingMethod_$method_name$<");
+    }
+  }
+  printer->Print("Service");
+  for (int i = 0; i < service->method_count(); ++i) {
+    auto method = service->method(i);
+    if (ServerOnlyStreaming(method.get())) {
+      printer->Print(" >");
+    }
+  }
+  printer->Print(" SplitStreamedService;\n");
+
+  // Server side - typedef for controlled both unary and server-side streaming
+  printer->Print("typedef ");
+  for (int i = 0; i < service->method_count(); ++i) {
+    (*vars)["method_name"] = service->method(i).get()->name();
+    auto method = service->method(i);
+    if (ServerOnlyStreaming(method.get())) {
+      printer->Print(*vars, "WithSplitStreamingMethod_$method_name$<");
+    }
+    if (service->method(i)->NoStreaming()) {
+      printer->Print(*vars, "WithStreamedUnaryMethod_$method_name$<");
+    }
+  }
+  printer->Print("Service");
+  for (int i = 0; i < service->method_count(); ++i) {
+    auto method = service->method(i);
+    if (service->method(i)->NoStreaming() ||
+        ServerOnlyStreaming(method.get())) {
+      printer->Print(" >");
+    }
+  }
+  printer->Print(" StreamedService;\n");
+
+  printer->Outdent();
+  printer->Print("};\n");
+  printer->Print(service->GetTrailingComments("//").c_str());
+}
+
+grpc::string GetHeaderServices(grpc_generator::File *file,
+                               const Parameters &params) {
+  grpc::string output;
+  {
+    // Scope the output stream so it closes and finalizes output to the string.
+    auto printer = file->CreatePrinter(&output);
+    std::map<grpc::string, grpc::string> vars;
+    // Package string is empty or ends with a dot. It is used to fully qualify
+    // method names.
+    vars["Package"] = file->package();
+    if (!file->package().empty()) {
+      vars["Package"].append(".");
+    }
+
+    if (!params.services_namespace.empty()) {
+      vars["services_namespace"] = params.services_namespace;
+      printer->Print(vars, "\nnamespace $services_namespace$ {\n\n");
+    }
+
+    for (int i = 0; i < file->service_count(); ++i) {
+      PrintHeaderService(printer.get(), file->service(i).get(), &vars);
+      printer->Print("\n");
+    }
+
+    if (!params.services_namespace.empty()) {
+      printer->Print(vars, "}  // namespace $services_namespace$\n\n");
+    }
+  }
+  return output;
+}
+
+grpc::string GetHeaderEpilogue(grpc_generator::File *file,
+                               const Parameters & /*params*/) {
+  grpc::string output;
+  {
+    // Scope the output stream so it closes and finalizes output to the string.
+    auto printer = file->CreatePrinter(&output);
+    std::map<grpc::string, grpc::string> vars;
+
+    vars["filename"] = file->filename();
+    vars["filename_identifier"] = FilenameIdentifier(file->filename());
+
+    if (!file->package().empty()) {
+      std::vector<grpc::string> parts = file->package_parts();
+
+      for (auto part = parts.rbegin(); part != parts.rend(); part++) {
+        vars["part"] = *part;
+        printer->Print(vars, "}  // namespace $part$\n");
+      }
+      printer->Print(vars, "\n");
+    }
+
+    printer->Print(vars, "\n");
+    printer->Print(vars, "#endif  // GRPC_$filename_identifier$__INCLUDED\n");
+
+    printer->Print(file->GetTrailingComments("//").c_str());
+  }
+  return output;
+}
+
+grpc::string GetSourcePrologue(grpc_generator::File *file,
+                               const Parameters & /*params*/) {
+  grpc::string output;
+  {
+    // Scope the output stream so it closes and finalizes output to the string.
+    auto printer = file->CreatePrinter(&output);
+    std::map<grpc::string, grpc::string> vars;
+
+    vars["filename"] = file->filename();
+    vars["filename_base"] = file->filename_without_ext();
+    vars["message_header_ext"] = message_header_ext();
+    vars["service_header_ext"] = service_header_ext();
+
+    printer->Print(vars, "// Generated by the gRPC C++ plugin.\n");
+    printer->Print(vars,
+                   "// If you make any local change, they will be lost.\n");
+    printer->Print(vars, "// source: $filename$\n\n");
+
+    printer->Print(vars, "#include \"$filename_base$$message_header_ext$\"\n");
+    printer->Print(vars, "#include \"$filename_base$$service_header_ext$\"\n");
+    printer->Print(vars, "\n");
+  }
+  return output;
+}
+
+grpc::string GetSourceIncludes(grpc_generator::File *file,
+                               const Parameters &params) {
+  grpc::string output;
+  {
+    // Scope the output stream so it closes and finalizes output to the string.
+    auto printer = file->CreatePrinter(&output);
+    std::map<grpc::string, grpc::string> vars;
+
+    static const char *headers_strs[] = {
+        "grpc++/impl/codegen/async_stream.h",
+        "grpc++/impl/codegen/async_unary_call.h",
+        "grpc++/impl/codegen/channel_interface.h",
+        "grpc++/impl/codegen/client_unary_call.h",
+        "grpc++/impl/codegen/method_handler_impl.h",
+        "grpc++/impl/codegen/rpc_service_method.h",
+        "grpc++/impl/codegen/service_type.h",
+        "grpc++/impl/codegen/sync_stream.h"};
+    std::vector<grpc::string> headers(headers_strs, array_end(headers_strs));
+    PrintIncludes(printer.get(), headers, params);
+
+    if (!file->package().empty()) {
+      std::vector<grpc::string> parts = file->package_parts();
+
+      for (auto part = parts.begin(); part != parts.end(); part++) {
+        vars["part"] = *part;
+        printer->Print(vars, "namespace $part$ {\n");
+      }
+    }
+
+    printer->Print(vars, "\n");
+  }
+  return output;
+}
+
+void PrintSourceClientMethod(grpc_generator::Printer *printer,
+                             const grpc_generator::Method *method,
+                             std::map<grpc::string, grpc::string> *vars) {
+  (*vars)["Method"] = method->name();
+  (*vars)["Request"] = method->input_type_name();
+  (*vars)["Response"] = method->output_type_name();
+  struct {
+    grpc::string prefix;
+    grpc::string start;          // bool literal expressed as string
+    grpc::string method_params;  // extra arguments to method
+    grpc::string create_args;    // extra arguments to creator
+  } async_prefixes[] = {{"Async", "true", ", void* tag", ", tag"},
+                        {"PrepareAsync", "false", "", ", nullptr"}};
+  if (method->NoStreaming()) {
+    printer->Print(*vars,
+                   "::grpc::Status $ns$$Service$::Stub::$Method$("
+                   "::grpc::ClientContext* context, "
+                   "const $Request$& request, $Response$* response) {\n");
+    printer->Print(*vars,
+                   "  return ::grpc::internal::BlockingUnaryCall"
+                   "(channel_.get(), rpcmethod_$Method$_, "
+                   "context, request, response);\n}\n\n");
+    for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
+      auto& async_prefix = async_prefixes[i];
+      (*vars)["AsyncPrefix"] = async_prefix.prefix;
+      (*vars)["AsyncStart"] = async_prefix.start;
+      printer->Print(*vars,
+                     "::grpc::ClientAsyncResponseReader< $Response$>* "
+                     "$ns$$Service$::Stub::$AsyncPrefix$$Method$Raw(::grpc::"
+                     "ClientContext* context, "
+                     "const $Request$& request, "
+                     "::grpc::CompletionQueue* cq) {\n");
+      printer->Print(
+          *vars,
+          "  return "
+          "::grpc::internal::ClientAsyncResponseReaderFactory< $Response$>"
+          "::Create(channel_.get(), cq, "
+          "rpcmethod_$Method$_, "
+          "context, request, $AsyncStart$);\n"
+          "}\n\n");
+    }
+  } else if (ClientOnlyStreaming(method)) {
+    printer->Print(*vars,
+                   "::grpc::ClientWriter< $Request$>* "
+                   "$ns$$Service$::Stub::$Method$Raw("
+                   "::grpc::ClientContext* context, $Response$* response) {\n");
+    printer->Print(
+        *vars,
+        "  return ::grpc::internal::ClientWriterFactory< $Request$>::Create("
+        "channel_.get(), "
+        "rpcmethod_$Method$_, "
+        "context, response);\n"
+        "}\n\n");
+    for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
+      auto& async_prefix = async_prefixes[i];
+      (*vars)["AsyncPrefix"] = async_prefix.prefix;
+      (*vars)["AsyncStart"] = async_prefix.start;
+      (*vars)["AsyncMethodParams"] = async_prefix.method_params;
+      (*vars)["AsyncCreateArgs"] = async_prefix.create_args;
+      printer->Print(*vars,
+                     "::grpc::ClientAsyncWriter< $Request$>* "
+                     "$ns$$Service$::Stub::$AsyncPrefix$$Method$Raw("
+                     "::grpc::ClientContext* context, $Response$* response, "
+                     "::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n");
+      printer->Print(
+          *vars,
+          "  return ::grpc::internal::ClientAsyncWriterFactory< $Request$>"
+          "::Create(channel_.get(), cq, "
+          "rpcmethod_$Method$_, "
+          "context, response, $AsyncStart$$AsyncCreateArgs$);\n"
+          "}\n\n");
+    }
+  } else if (ServerOnlyStreaming(method)) {
+    printer->Print(
+        *vars,
+        "::grpc::ClientReader< $Response$>* "
+        "$ns$$Service$::Stub::$Method$Raw("
+        "::grpc::ClientContext* context, const $Request$& request) {\n");
+    printer->Print(
+        *vars,
+        "  return ::grpc::internal::ClientReaderFactory< $Response$>::Create("
+        "channel_.get(), "
+        "rpcmethod_$Method$_, "
+        "context, request);\n"
+        "}\n\n");
+    for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
+      auto& async_prefix = async_prefixes[i];
+      (*vars)["AsyncPrefix"] = async_prefix.prefix;
+      (*vars)["AsyncStart"] = async_prefix.start;
+      (*vars)["AsyncMethodParams"] = async_prefix.method_params;
+      (*vars)["AsyncCreateArgs"] = async_prefix.create_args;
+      printer->Print(
+          *vars,
+          "::grpc::ClientAsyncReader< $Response$>* "
+          "$ns$$Service$::Stub::$AsyncPrefix$$Method$Raw("
+          "::grpc::ClientContext* context, const $Request$& request, "
+          "::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n");
+      printer->Print(
+          *vars,
+          "  return ::grpc::internal::ClientAsyncReaderFactory< $Response$>"
+          "::Create(channel_.get(), cq, "
+          "rpcmethod_$Method$_, "
+          "context, request, $AsyncStart$$AsyncCreateArgs$);\n"
+          "}\n\n");
+    }
+  } else if (method->BidiStreaming()) {
+    printer->Print(
+        *vars,
+        "::grpc::ClientReaderWriter< $Request$, $Response$>* "
+        "$ns$$Service$::Stub::$Method$Raw(::grpc::ClientContext* context) {\n");
+    printer->Print(*vars,
+                   "  return ::grpc::internal::ClientReaderWriterFactory< "
+                   "$Request$, $Response$>::Create("
+                   "channel_.get(), "
+                   "rpcmethod_$Method$_, "
+                   "context);\n"
+                   "}\n\n");
+    for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
+      auto& async_prefix = async_prefixes[i];
+      (*vars)["AsyncPrefix"] = async_prefix.prefix;
+      (*vars)["AsyncStart"] = async_prefix.start;
+      (*vars)["AsyncMethodParams"] = async_prefix.method_params;
+      (*vars)["AsyncCreateArgs"] = async_prefix.create_args;
+      printer->Print(*vars,
+                     "::grpc::ClientAsyncReaderWriter< $Request$, $Response$>* "
+                     "$ns$$Service$::Stub::$AsyncPrefix$$Method$Raw(::grpc::"
+                     "ClientContext* context, "
+                     "::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n");
+      printer->Print(*vars,
+                     "  return "
+                     "::grpc::internal::ClientAsyncReaderWriterFactory< "
+                     "$Request$, $Response$>::Create("
+                     "channel_.get(), cq, "
+                     "rpcmethod_$Method$_, "
+                     "context, $AsyncStart$$AsyncCreateArgs$);\n"
+                     "}\n\n");
+    }
+  }
+}
+
+void PrintSourceServerMethod(grpc_generator::Printer *printer,
+                             const grpc_generator::Method *method,
+                             std::map<grpc::string, grpc::string> *vars) {
+  (*vars)["Method"] = method->name();
+  (*vars)["Request"] = method->input_type_name();
+  (*vars)["Response"] = method->output_type_name();
+  if (method->NoStreaming()) {
+    printer->Print(*vars,
+                   "::grpc::Status $ns$$Service$::Service::$Method$("
+                   "::grpc::ServerContext* context, "
+                   "const $Request$* request, $Response$* response) {\n");
+    printer->Print("  (void) context;\n");
+    printer->Print("  (void) request;\n");
+    printer->Print("  (void) response;\n");
+    printer->Print(
+        "  return ::grpc::Status("
+        "::grpc::StatusCode::UNIMPLEMENTED, \"\");\n");
+    printer->Print("}\n\n");
+  } else if (ClientOnlyStreaming(method)) {
+    printer->Print(*vars,
+                   "::grpc::Status $ns$$Service$::Service::$Method$("
+                   "::grpc::ServerContext* context, "
+                   "::grpc::ServerReader< $Request$>* reader, "
+                   "$Response$* response) {\n");
+    printer->Print("  (void) context;\n");
+    printer->Print("  (void) reader;\n");
+    printer->Print("  (void) response;\n");
+    printer->Print(
+        "  return ::grpc::Status("
+        "::grpc::StatusCode::UNIMPLEMENTED, \"\");\n");
+    printer->Print("}\n\n");
+  } else if (ServerOnlyStreaming(method)) {
+    printer->Print(*vars,
+                   "::grpc::Status $ns$$Service$::Service::$Method$("
+                   "::grpc::ServerContext* context, "
+                   "const $Request$* request, "
+                   "::grpc::ServerWriter< $Response$>* writer) {\n");
+    printer->Print("  (void) context;\n");
+    printer->Print("  (void) request;\n");
+    printer->Print("  (void) writer;\n");
+    printer->Print(
+        "  return ::grpc::Status("
+        "::grpc::StatusCode::UNIMPLEMENTED, \"\");\n");
+    printer->Print("}\n\n");
+  } else if (method->BidiStreaming()) {
+    printer->Print(*vars,
+                   "::grpc::Status $ns$$Service$::Service::$Method$("
+                   "::grpc::ServerContext* context, "
+                   "::grpc::ServerReaderWriter< $Response$, $Request$>* "
+                   "stream) {\n");
+    printer->Print("  (void) context;\n");
+    printer->Print("  (void) stream;\n");
+    printer->Print(
+        "  return ::grpc::Status("
+        "::grpc::StatusCode::UNIMPLEMENTED, \"\");\n");
+    printer->Print("}\n\n");
+  }
+}
+
+void PrintSourceService(grpc_generator::Printer *printer,
+                        const grpc_generator::Service *service,
+                        std::map<grpc::string, grpc::string> *vars) {
+  (*vars)["Service"] = service->name();
+
+  if (service->method_count() > 0) {
+    printer->Print(*vars,
+                   "static const char* $prefix$$Service$_method_names[] = {\n");
+    for (int i = 0; i < service->method_count(); ++i) {
+      (*vars)["Method"] = service->method(i).get()->name();
+      printer->Print(*vars, "  \"/$Package$$Service$/$Method$\",\n");
+    }
+    printer->Print(*vars, "};\n\n");
+  }
+
+  printer->Print(*vars,
+                 "std::unique_ptr< $ns$$Service$::Stub> $ns$$Service$::NewStub("
+                 "const std::shared_ptr< ::grpc::ChannelInterface>& channel, "
+                 "const ::grpc::StubOptions& options) {\n"
+                 "  std::unique_ptr< $ns$$Service$::Stub> stub(new "
+                 "$ns$$Service$::Stub(channel));\n"
+                 "  return stub;\n"
+                 "}\n\n");
+  printer->Print(*vars,
+                 "$ns$$Service$::Stub::Stub(const std::shared_ptr< "
+                 "::grpc::ChannelInterface>& channel)\n");
+  printer->Indent();
+  printer->Print(": channel_(channel)");
+  for (int i = 0; i < service->method_count(); ++i) {
+    auto method = service->method(i);
+    (*vars)["Method"] = method->name();
+    (*vars)["Idx"] = as_string(i);
+    if (method->NoStreaming()) {
+      (*vars)["StreamingType"] = "NORMAL_RPC";
+      // NOTE: There is no reason to consider streamed-unary as a separate
+      // category here since this part is setting up the client-side stub
+      // and this appears as a NORMAL_RPC from the client-side.
+    } else if (ClientOnlyStreaming(method.get())) {
+      (*vars)["StreamingType"] = "CLIENT_STREAMING";
+    } else if (ServerOnlyStreaming(method.get())) {
+      (*vars)["StreamingType"] = "SERVER_STREAMING";
+    } else {
+      (*vars)["StreamingType"] = "BIDI_STREAMING";
+    }
+    printer->Print(*vars,
+                   ", rpcmethod_$Method$_("
+                   "$prefix$$Service$_method_names[$Idx$], "
+                   "::grpc::internal::RpcMethod::$StreamingType$, "
+                   "channel"
+                   ")\n");
+  }
+  printer->Print("{}\n\n");
+  printer->Outdent();
+
+  for (int i = 0; i < service->method_count(); ++i) {
+    (*vars)["Idx"] = as_string(i);
+    PrintSourceClientMethod(printer, service->method(i).get(), vars);
+  }
+
+  printer->Print(*vars, "$ns$$Service$::Service::Service() {\n");
+  printer->Indent();
+  for (int i = 0; i < service->method_count(); ++i) {
+    auto method = service->method(i);
+    (*vars)["Idx"] = as_string(i);
+    (*vars)["Method"] = method->name();
+    (*vars)["Request"] = method->input_type_name();
+    (*vars)["Response"] = method->output_type_name();
+    if (method->NoStreaming()) {
+      printer->Print(
+          *vars,
+          "AddMethod(new ::grpc::internal::RpcServiceMethod(\n"
+          "    $prefix$$Service$_method_names[$Idx$],\n"
+          "    ::grpc::internal::RpcMethod::NORMAL_RPC,\n"
+          "    new ::grpc::internal::RpcMethodHandler< $ns$$Service$::Service, "
+          "$Request$, "
+          "$Response$>(\n"
+          "        std::mem_fn(&$ns$$Service$::Service::$Method$), this)));\n");
+    } else if (ClientOnlyStreaming(method.get())) {
+      printer->Print(
+          *vars,
+          "AddMethod(new ::grpc::internal::RpcServiceMethod(\n"
+          "    $prefix$$Service$_method_names[$Idx$],\n"
+          "    ::grpc::internal::RpcMethod::CLIENT_STREAMING,\n"
+          "    new ::grpc::internal::ClientStreamingHandler< "
+          "$ns$$Service$::Service, $Request$, $Response$>(\n"
+          "        std::mem_fn(&$ns$$Service$::Service::$Method$), this)));\n");
+    } else if (ServerOnlyStreaming(method.get())) {
+      printer->Print(
+          *vars,
+          "AddMethod(new ::grpc::internal::RpcServiceMethod(\n"
+          "    $prefix$$Service$_method_names[$Idx$],\n"
+          "    ::grpc::internal::RpcMethod::SERVER_STREAMING,\n"
+          "    new ::grpc::internal::ServerStreamingHandler< "
+          "$ns$$Service$::Service, $Request$, $Response$>(\n"
+          "        std::mem_fn(&$ns$$Service$::Service::$Method$), this)));\n");
+    } else if (method->BidiStreaming()) {
+      printer->Print(
+          *vars,
+          "AddMethod(new ::grpc::internal::RpcServiceMethod(\n"
+          "    $prefix$$Service$_method_names[$Idx$],\n"
+          "    ::grpc::internal::RpcMethod::BIDI_STREAMING,\n"
+          "    new ::grpc::internal::BidiStreamingHandler< "
+          "$ns$$Service$::Service, $Request$, $Response$>(\n"
+          "        std::mem_fn(&$ns$$Service$::Service::$Method$), this)));\n");
+    }
+  }
+  printer->Outdent();
+  printer->Print(*vars, "}\n\n");
+  printer->Print(*vars,
+                 "$ns$$Service$::Service::~Service() {\n"
+                 "}\n\n");
+  for (int i = 0; i < service->method_count(); ++i) {
+    (*vars)["Idx"] = as_string(i);
+    PrintSourceServerMethod(printer, service->method(i).get(), vars);
+  }
+}
+
+grpc::string GetSourceServices(grpc_generator::File *file,
+                               const Parameters &params) {
+  grpc::string output;
+  {
+    // Scope the output stream so it closes and finalizes output to the string.
+    auto printer = file->CreatePrinter(&output);
+    std::map<grpc::string, grpc::string> vars;
+    // Package string is empty or ends with a dot. It is used to fully qualify
+    // method names.
+    vars["Package"] = file->package();
+    if (!file->package().empty()) {
+      vars["Package"].append(".");
+    }
+    if (!params.services_namespace.empty()) {
+      vars["ns"] = params.services_namespace + "::";
+      vars["prefix"] = params.services_namespace;
+    } else {
+      vars["ns"] = "";
+      vars["prefix"] = "";
+    }
+
+    for (int i = 0; i < file->service_count(); ++i) {
+      PrintSourceService(printer.get(), file->service(i).get(), &vars);
+      printer->Print("\n");
+    }
+  }
+  return output;
+}
+
+grpc::string GetSourceEpilogue(grpc_generator::File *file,
+                               const Parameters & /*params*/) {
+  grpc::string temp;
+
+  if (!file->package().empty()) {
+    std::vector<grpc::string> parts = file->package_parts();
+
+    for (auto part = parts.begin(); part != parts.end(); part++) {
+      temp.append("}  // namespace ");
+      temp.append(*part);
+      temp.append("\n");
+    }
+    temp.append("\n");
+  }
+
+  return temp;
+}
+
+// TODO(mmukhi): Make sure we need parameters or not.
+grpc::string GetMockPrologue(grpc_generator::File *file,
+                             const Parameters & /*params*/) {
+  grpc::string output;
+  {
+    // Scope the output stream so it closes and finalizes output to the string.
+    auto printer = file->CreatePrinter(&output);
+    std::map<grpc::string, grpc::string> vars;
+
+    vars["filename"] = file->filename();
+    vars["filename_base"] = file->filename_without_ext();
+    vars["message_header_ext"] = message_header_ext();
+    vars["service_header_ext"] = service_header_ext();
+
+    printer->Print(vars, "// Generated by the gRPC C++ plugin.\n");
+    printer->Print(vars,
+                   "// If you make any local change, they will be lost.\n");
+    printer->Print(vars, "// source: $filename$\n\n");
+
+    printer->Print(vars, "#include \"$filename_base$$message_header_ext$\"\n");
+    printer->Print(vars, "#include \"$filename_base$$service_header_ext$\"\n");
+    printer->Print(vars, file->additional_headers().c_str());
+    printer->Print(vars, "\n");
+  }
+  return output;
+}
+
+// TODO(mmukhi): Add client-stream and completion-queue headers.
+grpc::string GetMockIncludes(grpc_generator::File *file,
+                             const Parameters &params) {
+  grpc::string output;
+  {
+    // Scope the output stream so it closes and finalizes output to the string.
+    auto printer = file->CreatePrinter(&output);
+    std::map<grpc::string, grpc::string> vars;
+
+    static const char *headers_strs[] = {
+        "grpc++/impl/codegen/async_stream.h",
+        "grpc++/impl/codegen/sync_stream.h",
+        "gmock/gmock.h",
+    };
+    std::vector<grpc::string> headers(headers_strs, array_end(headers_strs));
+    PrintIncludes(printer.get(), headers, params);
+
+    if (!file->package().empty()) {
+      std::vector<grpc::string> parts = file->package_parts();
+
+      for (auto part = parts.begin(); part != parts.end(); part++) {
+        vars["part"] = *part;
+        printer->Print(vars, "namespace $part$ {\n");
+      }
+    }
+
+    printer->Print(vars, "\n");
+  }
+  return output;
+}
+
+void PrintMockClientMethods(grpc_generator::Printer *printer,
+                            const grpc_generator::Method *method,
+                            std::map<grpc::string, grpc::string> *vars) {
+  (*vars)["Method"] = method->name();
+  (*vars)["Request"] = method->input_type_name();
+  (*vars)["Response"] = method->output_type_name();
+
+  struct {
+    grpc::string prefix;
+    grpc::string method_params;  // extra arguments to method
+    int extra_method_param_count;
+  } async_prefixes[] = {{"Async", ", void* tag", 1}, {"PrepareAsync", "", 0}};
+
+  if (method->NoStreaming()) {
+    printer->Print(
+        *vars,
+        "MOCK_METHOD3($Method$, ::grpc::Status(::grpc::ClientContext* context, "
+        "const $Request$& request, $Response$* response));\n");
+    for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
+      auto& async_prefix = async_prefixes[i];
+      (*vars)["AsyncPrefix"] = async_prefix.prefix;
+      printer->Print(
+          *vars,
+          "MOCK_METHOD3($AsyncPrefix$$Method$Raw, "
+          "::grpc::ClientAsyncResponseReaderInterface< $Response$>*"
+          "(::grpc::ClientContext* context, const $Request$& request, "
+          "::grpc::CompletionQueue* cq));\n");
+    }
+  } else if (ClientOnlyStreaming(method)) {
+    printer->Print(
+        *vars,
+        "MOCK_METHOD2($Method$Raw, "
+        "::grpc::ClientWriterInterface< $Request$>*"
+        "(::grpc::ClientContext* context, $Response$* response));\n");
+    for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
+      auto& async_prefix = async_prefixes[i];
+      (*vars)["AsyncPrefix"] = async_prefix.prefix;
+      (*vars)["AsyncMethodParams"] = async_prefix.method_params;
+      (*vars)["MockArgs"] =
+        flatbuffers::NumToString(3 + async_prefix.extra_method_param_count);
+      printer->Print(*vars,
+                     "MOCK_METHOD$MockArgs$($AsyncPrefix$$Method$Raw, "
+                     "::grpc::ClientAsyncWriterInterface< $Request$>*"
+                     "(::grpc::ClientContext* context, $Response$* response, "
+                     "::grpc::CompletionQueue* cq$AsyncMethodParams$));\n");
+    }
+  } else if (ServerOnlyStreaming(method)) {
+    printer->Print(
+        *vars,
+        "MOCK_METHOD2($Method$Raw, "
+        "::grpc::ClientReaderInterface< $Response$>*"
+        "(::grpc::ClientContext* context, const $Request$& request));\n");
+    for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
+      auto& async_prefix = async_prefixes[i];
+      (*vars)["AsyncPrefix"] = async_prefix.prefix;
+      (*vars)["AsyncMethodParams"] = async_prefix.method_params;
+      (*vars)["MockArgs"] =
+          flatbuffers::NumToString(3 + async_prefix.extra_method_param_count);
+      printer->Print(
+          *vars,
+          "MOCK_METHOD$MockArgs$($AsyncPrefix$$Method$Raw, "
+          "::grpc::ClientAsyncReaderInterface< $Response$>*"
+          "(::grpc::ClientContext* context, const $Request$& request, "
+          "::grpc::CompletionQueue* cq$AsyncMethodParams$));\n");
+    }
+  } else if (method->BidiStreaming()) {
+    printer->Print(
+        *vars,
+        "MOCK_METHOD1($Method$Raw, "
+        "::grpc::ClientReaderWriterInterface< $Request$, $Response$>*"
+        "(::grpc::ClientContext* context));\n");
+    for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
+      auto& async_prefix = async_prefixes[i];
+      (*vars)["AsyncPrefix"] = async_prefix.prefix;
+      (*vars)["AsyncMethodParams"] = async_prefix.method_params;
+      (*vars)["MockArgs"] =
+          flatbuffers::NumToString(2 + async_prefix.extra_method_param_count);
+      printer->Print(
+          *vars,
+          "MOCK_METHOD$MockArgs$($AsyncPrefix$$Method$Raw, "
+          "::grpc::ClientAsyncReaderWriterInterface<$Request$, $Response$>*"
+          "(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq"
+          "$AsyncMethodParams$));\n");
+    }
+  }
+}
+
+void PrintMockService(grpc_generator::Printer *printer,
+                      const grpc_generator::Service *service,
+                      std::map<grpc::string, grpc::string> *vars) {
+  (*vars)["Service"] = service->name();
+
+  printer->Print(*vars,
+                 "class Mock$Service$Stub : public $Service$::StubInterface {\n"
+                 " public:\n");
+  printer->Indent();
+  for (int i = 0; i < service->method_count(); ++i) {
+    PrintMockClientMethods(printer, service->method(i).get(), vars);
+  }
+  printer->Outdent();
+  printer->Print("};\n");
+}
+
+grpc::string GetMockServices(grpc_generator::File *file,
+                             const Parameters &params) {
+  grpc::string output;
+  {
+    // Scope the output stream so it closes and finalizes output to the string.
+    auto printer = file->CreatePrinter(&output);
+    std::map<grpc::string, grpc::string> vars;
+    // Package string is empty or ends with a dot. It is used to fully qualify
+    // method names.
+    vars["Package"] = file->package();
+    if (!file->package().empty()) {
+      vars["Package"].append(".");
+    }
+
+    if (!params.services_namespace.empty()) {
+      vars["services_namespace"] = params.services_namespace;
+      printer->Print(vars, "\nnamespace $services_namespace$ {\n\n");
+    }
+
+    for (int i = 0; i < file->service_count(); i++) {
+      PrintMockService(printer.get(), file->service(i).get(), &vars);
+      printer->Print("\n");
+    }
+
+    if (!params.services_namespace.empty()) {
+      printer->Print(vars, "} // namespace $services_namespace$\n\n");
+    }
+  }
+  return output;
+}
+
+grpc::string GetMockEpilogue(grpc_generator::File *file,
+                             const Parameters & /*params*/) {
+  grpc::string temp;
+
+  if (!file->package().empty()) {
+    std::vector<grpc::string> parts = file->package_parts();
+
+    for (auto part = parts.begin(); part != parts.end(); part++) {
+      temp.append("} // namespace ");
+      temp.append(*part);
+      temp.append("\n");
+    }
+    temp.append("\n");
+  }
+
+  return temp;
+}
+
+}  // namespace grpc_cpp_generator
diff --git a/grpc/src/compiler/cpp_generator.h b/grpc/src/compiler/cpp_generator.h
new file mode 100644
index 0000000..6119ebe
--- /dev/null
+++ b/grpc/src/compiler/cpp_generator.h
@@ -0,0 +1,138 @@
+/*
+ *
+ * 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_INTERNAL_COMPILER_CPP_GENERATOR_H
+#define GRPC_INTERNAL_COMPILER_CPP_GENERATOR_H
+
+// cpp_generator.h/.cc do not directly depend on GRPC/ProtoBuf, such that they
+// can be used to generate code for other serialization systems, such as
+// FlatBuffers.
+
+#include <memory>
+#include <vector>
+
+#include "src/compiler/config.h"
+#include "src/compiler/schema_interface.h"
+
+#ifndef GRPC_CUSTOM_STRING
+#include <string>
+#define GRPC_CUSTOM_STRING std::string
+#endif
+
+namespace grpc {
+
+typedef GRPC_CUSTOM_STRING string;
+
+}  // namespace grpc
+
+namespace grpc_cpp_generator {
+
+// Contains all the parameters that are parsed from the command line.
+struct Parameters {
+  // Puts the service into a namespace
+  grpc::string services_namespace;
+  // Use system includes (<>) or local includes ("")
+  bool use_system_headers;
+  // Prefix to any grpc include
+  grpc::string grpc_search_path;
+  // Generate GMOCK code to facilitate unit testing.
+  bool generate_mock_code;
+};
+
+// Return the prologue of the generated header file.
+grpc::string GetHeaderPrologue(grpc_generator::File *file,
+                               const Parameters &params);
+
+// Return the includes needed for generated header file.
+grpc::string GetHeaderIncludes(grpc_generator::File *file,
+                               const Parameters &params);
+
+// Return the includes needed for generated source file.
+grpc::string GetSourceIncludes(grpc_generator::File *file,
+                               const Parameters &params);
+
+// Return the epilogue of the generated header file.
+grpc::string GetHeaderEpilogue(grpc_generator::File *file,
+                               const Parameters &params);
+
+// Return the prologue of the generated source file.
+grpc::string GetSourcePrologue(grpc_generator::File *file,
+                               const Parameters &params);
+
+// Return the services for generated header file.
+grpc::string GetHeaderServices(grpc_generator::File *file,
+                               const Parameters &params);
+
+// Return the services for generated source file.
+grpc::string GetSourceServices(grpc_generator::File *file,
+                               const Parameters &params);
+
+// Return the epilogue of the generated source file.
+grpc::string GetSourceEpilogue(grpc_generator::File *file,
+                               const Parameters &params);
+
+// Return the prologue of the generated mock file.
+grpc::string GetMockPrologue(grpc_generator::File *file,
+                             const Parameters &params);
+
+// Return the includes needed for generated mock file.
+grpc::string GetMockIncludes(grpc_generator::File *file,
+                             const Parameters &params);
+
+// Return the services for generated mock file.
+grpc::string GetMockServices(grpc_generator::File *file,
+                             const Parameters &params);
+
+// Return the epilogue of generated mock file.
+grpc::string GetMockEpilogue(grpc_generator::File *file,
+                             const Parameters &params);
+
+// Return the prologue of the generated mock file.
+grpc::string GetMockPrologue(grpc_generator::File *file,
+                             const Parameters &params);
+
+// Return the includes needed for generated mock file.
+grpc::string GetMockIncludes(grpc_generator::File *file,
+                             const Parameters &params);
+
+// Return the services for generated mock file.
+grpc::string GetMockServices(grpc_generator::File *file,
+                             const Parameters &params);
+
+// Return the epilogue of generated mock file.
+grpc::string GetMockEpilogue(grpc_generator::File *file,
+                             const Parameters &params);
+
+}  // namespace grpc_cpp_generator
+
+#endif  // GRPC_INTERNAL_COMPILER_CPP_GENERATOR_H
diff --git a/grpc/src/compiler/go_generator.cc b/grpc/src/compiler/go_generator.cc
new file mode 100644
index 0000000..604828d
--- /dev/null
+++ b/grpc/src/compiler/go_generator.cc
@@ -0,0 +1,446 @@
+/*
+ *
+ * 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 AN/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 <map>
+#include <cctype>
+#include <sstream>
+
+#include "src/compiler/go_generator.h"
+
+template <class T>
+grpc::string as_string(T x) {
+	std::ostringstream out;
+	out << x;
+	return out.str();
+}
+
+inline bool ClientOnlyStreaming(const grpc_generator::Method *method) {
+  return method->ClientStreaming() && !method->ServerStreaming();
+}
+
+inline bool ServerOnlyStreaming(const grpc_generator::Method *method) {
+  return !method->ClientStreaming() && method->ServerStreaming();
+}
+
+namespace grpc_go_generator {
+
+// Returns string with first letter to lowerCase
+grpc::string unexportName(grpc::string s) {
+	if (s.empty())
+		return s;
+	s[0] = static_cast<char>(std::tolower(s[0]));
+	return s;
+}
+
+// Returns string with first letter to uppercase
+grpc::string exportName(grpc::string s) {
+	if (s.empty())
+		return s;
+	s[0] = static_cast<char>(std::toupper(s[0]));
+	return s;
+}
+
+// Generates imports for the service
+void GenerateImports(grpc_generator::File *file, grpc_generator::Printer *printer,
+                     std::map<grpc::string, grpc::string> vars) {
+	vars["filename"] = file->filename();
+	printer->Print("//Generated by gRPC Go plugin\n");
+	printer->Print("//If you make any local changes, they will be lost\n");
+	printer->Print(vars, "//source: $filename$\n\n");
+	printer->Print(vars, "package $Package$\n\n");
+	if (file->additional_headers() != "") {
+		printer->Print(file->additional_headers().c_str());
+		printer->Print("\n\n");
+	}
+	printer->Print("import (\n");
+	printer->Indent();
+	printer->Print(vars, "$context$ \"context\"\n");
+	printer->Print(vars, "$grpc$ \"google.golang.org/grpc\"\n");
+	printer->Outdent();
+	printer->Print(")\n\n");
+}
+
+// Generates Server method signature source
+void GenerateServerMethodSignature(const grpc_generator::Method *method, grpc_generator::Printer *printer,
+                                   std::map<grpc::string, grpc::string> vars) {
+	vars["Method"] = exportName(method->name());
+	vars["Request"] = method->get_input_type_name();
+	vars["Response"] = (vars["CustomMethodIO"] == "") ? method->get_output_type_name() : vars["CustomMethodIO"];
+	if (method->NoStreaming()) {
+		printer->Print(vars, "$Method$($context$.Context, *$Request$) (*$Response$, error)");
+	} else if (ServerOnlyStreaming(method)) {
+		printer->Print(vars, "$Method$(*$Request$, $Service$_$Method$Server) error");
+	} else {
+		printer->Print(vars, "$Method$($Service$_$Method$Server) error");
+	}
+}
+
+void GenerateServerMethod(const grpc_generator::Method *method, grpc_generator::Printer *printer,
+                          std::map<grpc::string, grpc::string> vars) {
+	vars["Method"] = exportName(method->name());
+	vars["Request"] = method->get_input_type_name();
+	vars["Response"] = (vars["CustomMethodIO"] == "") ? method->get_output_type_name() : vars["CustomMethodIO"];
+	vars["FullMethodName"] = "/" + vars["ServicePrefix"] + "." + vars["Service"] + "/" + vars["Method"];
+	vars["Handler"] = "_" + vars["Service"] + "_" + vars["Method"] + "_Handler";
+	if (method->NoStreaming()) {
+		printer->Print(vars, "func $Handler$(srv interface{}, ctx $context$.Context,\n\tdec func(interface{}) error, interceptor $grpc$.UnaryServerInterceptor) (interface{}, error) {\n");
+		printer->Indent();
+		printer->Print(vars, "in := new($Request$)\n");
+		printer->Print("if err := dec(in); err != nil { return nil, err }\n");
+		printer->Print(vars, "if interceptor == nil { return srv.($Service$Server).$Method$(ctx, in) }\n");
+		printer->Print(vars, "info := &$grpc$.UnaryServerInfo{\n");
+		printer->Indent();
+		printer->Print("Server: srv,\n");
+		printer->Print(vars, "FullMethod: \"$FullMethodName$\",\n");
+		printer->Outdent();
+		printer->Print("}\n\n");
+		printer->Print(vars, "handler := func(ctx $context$.Context, req interface{}) (interface{}, error) {\n");
+		printer->Indent();
+		printer->Print(vars, "return srv.($Service$Server).$Method$(ctx, req.(* $Request$))\n");
+		printer->Outdent();
+		printer->Print("}\n");
+		printer->Print("return interceptor(ctx, in, info, handler)\n");
+		printer->Outdent();
+		printer->Print("}\n\n");
+		return;
+	}
+	vars["StreamType"] = vars["ServiceUnexported"] + vars["Method"] + "Server";
+	printer->Print(vars, "func $Handler$(srv interface{}, stream $grpc$.ServerStream) error {\n");
+	printer->Indent();
+	if (ServerOnlyStreaming(method)) {
+		printer->Print(vars, "m := new($Request$)\n");
+		printer->Print(vars, "if err := stream.RecvMsg(m); err != nil { return err }\n");
+		printer->Print(vars, "return srv.($Service$Server).$Method$(m, &$StreamType${stream})\n");
+	} else {
+		printer->Print(vars, "return srv.($Service$Server).$Method$(&$StreamType${stream})\n");
+	}
+	printer->Outdent();
+	printer->Print("}\n\n");
+
+	bool genSend = method->BidiStreaming() || ServerOnlyStreaming(method);
+	bool genRecv = method->BidiStreaming() || ClientOnlyStreaming(method);
+	bool genSendAndClose = ClientOnlyStreaming(method);
+
+	printer->Print(vars, "type $Service$_$Method$Server interface { \n");
+	printer->Indent();
+	if (genSend) {
+		printer->Print(vars, "Send(* $Response$) error\n");
+	}
+	if (genRecv) {
+		printer->Print(vars, "Recv() (* $Request$, error)\n");
+	}
+	if (genSendAndClose) {
+		printer->Print(vars, "SendAndClose(* $Response$) error\n");
+	}
+	printer->Print(vars, "$grpc$.ServerStream\n");
+	printer->Outdent();
+	printer->Print("}\n\n");
+
+	printer->Print(vars, "type $StreamType$ struct {\n");
+	printer->Indent();
+	printer->Print(vars, "$grpc$.ServerStream\n");
+	printer->Outdent();
+	printer->Print("}\n\n");
+
+	if (genSend) {
+		printer->Print(vars, "func (x *$StreamType$) Send(m *$Response$) error {\n");
+		printer->Indent();
+		printer->Print("return x.ServerStream.SendMsg(m)\n");
+		printer->Outdent();
+		printer->Print("}\n\n");
+	}
+	if (genRecv) {
+		printer->Print(vars, "func (x *$StreamType$) Recv() (*$Request$, error) {\n");
+		printer->Indent();
+		printer->Print(vars, "m := new($Request$)\n");
+		printer->Print("if err := x.ServerStream.RecvMsg(m); err != nil { return nil, err }\n");
+		printer->Print("return m, nil\n");
+		printer->Outdent();
+		printer->Print("}\n\n");
+	}
+	if (genSendAndClose) {
+		printer->Print(vars, "func (x *$StreamType$) SendAndClose(m *$Response$) error {\n");
+		printer->Indent();
+		printer->Print("return x.ServerStream.SendMsg(m)\n");
+		printer->Outdent();
+		printer->Print("}\n\n");
+	}
+
+}
+
+// Generates Client method signature source
+void GenerateClientMethodSignature(const grpc_generator::Method *method, grpc_generator::Printer *printer,
+                                   std::map<grpc::string, grpc::string> vars) {
+	vars["Method"] = exportName(method->name());
+	vars["Request"] = ", in *" + ((vars["CustomMethodIO"] == "") ? method->get_input_type_name() : vars["CustomMethodIO"]);
+	if (ClientOnlyStreaming(method) || method->BidiStreaming()) {
+		vars["Request"] = "";
+	}
+	vars["Response"] = "* " + method->get_output_type_name();
+	if (ClientOnlyStreaming(method) || method->BidiStreaming() || ServerOnlyStreaming(method)) {
+		vars["Response"] = vars["Service"] + "_" + vars["Method"] + "Client" ;
+	}
+	printer->Print(vars, "$Method$(ctx $context$.Context$Request$, \n\topts... $grpc$.CallOption) ($Response$, error)");
+}
+
+// Generates Client method source
+void GenerateClientMethod(const grpc_generator::Method *method, grpc_generator::Printer *printer,
+                          std::map<grpc::string, grpc::string> vars) {
+	printer->Print(vars, "func (c *$ServiceUnexported$Client) ");
+	GenerateClientMethodSignature(method, printer, vars);
+	printer->Print(" {\n");
+	printer->Indent();
+	vars["Method"] = exportName(method->name());
+	vars["Request"] = (vars["CustomMethodIO"] == "") ? method->get_input_type_name() : vars["CustomMethodIO"];
+	vars["Response"] = method->get_output_type_name();
+	vars["FullMethodName"] = "/" + vars["ServicePrefix"] + "." + vars["Service"] + "/" + vars["Method"];
+	if (method->NoStreaming()) {
+		printer->Print(vars, "out := new($Response$)\n");
+		printer->Print(vars, "err := $grpc$.Invoke(ctx, \"$FullMethodName$\", in, out, c.cc, opts...)\n");
+		printer->Print("if err != nil { return nil, err }\n");
+		printer->Print("return out, nil\n");
+		printer->Outdent();
+		printer->Print("}\n\n");
+		return;
+	}
+	vars["StreamType"] = vars["ServiceUnexported"] + vars["Method"] + "Client";
+	printer->Print(vars, "stream, err := $grpc$.NewClientStream(ctx, &$MethodDesc$, c.cc, \"$FullMethodName$\", opts...)\n");
+	printer->Print("if err != nil { return nil, err }\n");
+
+	printer->Print(vars, "x := &$StreamType${stream}\n");
+	if (ServerOnlyStreaming(method)) {
+		printer->Print("if err := x.ClientStream.SendMsg(in); err != nil { return nil, err }\n");
+		printer->Print("if err := x.ClientStream.CloseSend(); err != nil { return nil, err }\n");
+	}
+	printer->Print("return x,nil\n");
+	printer->Outdent();
+	printer->Print("}\n\n");
+
+	bool genSend = method->BidiStreaming() || ClientOnlyStreaming(method);
+	bool genRecv = method->BidiStreaming() || ServerOnlyStreaming(method);
+	bool genCloseAndRecv = ClientOnlyStreaming(method);
+
+	//Stream interface
+	printer->Print(vars, "type $Service$_$Method$Client interface {\n");
+	printer->Indent();
+	if (genSend) {
+		printer->Print(vars, "Send(*$Request$) error\n");
+	}
+	if (genRecv) {
+		printer->Print(vars, "Recv() (*$Response$, error)\n");
+	}
+	if (genCloseAndRecv) {
+		printer->Print(vars, "CloseAndRecv() (*$Response$, error)\n");
+	}
+	printer->Print(vars, "$grpc$.ClientStream\n");
+	printer->Outdent();
+	printer->Print("}\n\n");
+
+	//Stream Client
+	printer->Print(vars, "type $StreamType$ struct{\n");
+	printer->Indent();
+	printer->Print(vars, "$grpc$.ClientStream\n");
+	printer->Outdent();
+	printer->Print("}\n\n");
+
+	if (genSend) {
+		printer->Print(vars, "func (x *$StreamType$) Send(m *$Request$) error {\n");
+		printer->Indent();
+		printer->Print("return x.ClientStream.SendMsg(m)\n");
+		printer->Outdent();
+		printer->Print("}\n\n");
+	}
+
+	if (genRecv) {
+		printer->Print(vars, "func (x *$StreamType$) Recv() (*$Response$, error) {\n");
+		printer->Indent();
+		printer->Print(vars, "m := new($Response$)\n");
+		printer->Print("if err := x.ClientStream.RecvMsg(m); err != nil { return nil, err }\n");
+		printer->Print("return m, nil\n");
+		printer->Outdent();
+		printer->Print("}\n\n");
+	}
+
+	if (genCloseAndRecv) {
+		printer->Print(vars, "func (x *$StreamType$) CloseAndRecv() (*$Response$, error) {\n");
+		printer->Indent();
+		printer->Print("if err := x.ClientStream.CloseSend(); err != nil { return nil, err }\n");
+		printer->Print(vars, "m := new ($Response$)\n");
+		printer->Print("if err := x.ClientStream.RecvMsg(m); err != nil { return nil, err }\n");
+		printer->Print("return m, nil\n");
+		printer->Outdent();
+		printer->Print("}\n\n");
+	}
+}
+
+// Generates client API for the service
+void GenerateService(const grpc_generator::Service *service, grpc_generator::Printer* printer,
+                     std::map<grpc::string, grpc::string> vars) {
+	vars["Service"] = exportName(service->name());
+	// Client Interface
+	printer->Print(vars, "// Client API for $Service$ service\n");
+	printer->Print(vars, "type $Service$Client interface{\n");
+	printer->Indent();
+	for (int i = 0; i < service->method_count(); i++) {
+		GenerateClientMethodSignature(service->method(i).get(), printer, vars);
+		printer->Print("\n");
+	}
+	printer->Outdent();
+	printer->Print("}\n\n");
+
+	// Client structure
+	vars["ServiceUnexported"] = unexportName(vars["Service"]);
+	printer->Print(vars, "type $ServiceUnexported$Client struct {\n");
+	printer->Indent();
+	printer->Print(vars, "cc *$grpc$.ClientConn\n");
+	printer->Outdent();
+	printer->Print("}\n\n");
+
+	// NewClient
+	printer->Print(vars, "func New$Service$Client(cc *$grpc$.ClientConn) $Service$Client {\n");
+	printer->Indent();
+	printer->Print(vars, "return &$ServiceUnexported$Client{cc}");
+	printer->Outdent();
+	printer->Print("\n}\n\n");
+
+	int unary_methods = 0, streaming_methods = 0;
+	vars["ServiceDesc"] = "_" + vars["Service"] + "_serviceDesc";
+	for (int i = 0; i < service->method_count(); i++) {
+		auto method = service->method(i);
+		if (method->NoStreaming()) {
+			vars["MethodDesc"] = vars["ServiceDesc"] + ".Method[" + as_string(unary_methods) + "]";
+			unary_methods++;
+		} else {
+			vars["MethodDesc"] = vars["ServiceDesc"] + ".Streams[" + as_string(streaming_methods) + "]";
+			streaming_methods++;
+		}
+		GenerateClientMethod(method.get(), printer, vars);
+	}
+
+	//Server Interface
+	printer->Print(vars, "// Server API for $Service$ service\n");
+	printer->Print(vars, "type $Service$Server interface {\n");
+	printer->Indent();
+	for (int i = 0; i < service->method_count(); i++) {
+		GenerateServerMethodSignature(service->method(i).get(), printer, vars);
+		printer->Print("\n");
+	}
+	printer->Outdent();
+	printer->Print("}\n\n");
+
+	// Server registration.
+	printer->Print(vars, "func Register$Service$Server(s *$grpc$.Server, srv $Service$Server) {\n");
+	printer->Indent();
+	printer->Print(vars, "s.RegisterService(&$ServiceDesc$, srv)\n");
+	printer->Outdent();
+	printer->Print("}\n\n");
+
+	for (int i = 0; i < service->method_count(); i++) {
+		GenerateServerMethod(service->method(i).get(), printer, vars);
+		printer->Print("\n");
+	}
+
+
+	//Service Descriptor
+	printer->Print(vars, "var $ServiceDesc$ = $grpc$.ServiceDesc{\n");
+	printer->Indent();
+	printer->Print(vars, "ServiceName: \"$ServicePrefix$.$Service$\",\n");
+	printer->Print(vars, "HandlerType: (*$Service$Server)(nil),\n");
+	printer->Print(vars, "Methods: []$grpc$.MethodDesc{\n");
+	printer->Indent();
+	for (int i = 0; i < service->method_count(); i++) {
+		auto method = service->method(i);
+		vars["Method"] = method->name();
+		vars["Handler"] = "_" + vars["Service"] + "_" + vars["Method"] + "_Handler";
+		if (method->NoStreaming()) {
+			printer->Print("{\n");
+			printer->Indent();
+			printer->Print(vars, "MethodName: \"$Method$\",\n");
+			printer->Print(vars, "Handler: $Handler$, \n");
+			printer->Outdent();
+			printer->Print("},\n");
+		}
+	}
+	printer->Outdent();
+	printer->Print("},\n");
+	printer->Print(vars, "Streams: []$grpc$.StreamDesc{\n");
+	printer->Indent();
+	for (int i = 0; i < service->method_count(); i++) {
+		auto method = service->method(i);
+		vars["Method"] = method->name();
+		vars["Handler"] = "_" + vars["Service"] + "_" + vars["Method"] + "_Handler";
+		if (!method->NoStreaming()) {
+			printer->Print("{\n");
+			printer->Indent();
+			printer->Print(vars, "StreamName: \"$Method$\",\n");
+			printer->Print(vars, "Handler: $Handler$, \n");
+			if (ClientOnlyStreaming(method.get())) {
+				printer->Print("ClientStreams: true,\n");
+			} else if (ServerOnlyStreaming(method.get())) {
+				printer->Print("ServerStreams: true,\n");
+			} else {
+				printer->Print("ServerStreams: true,\n");
+				printer->Print("ClientStreams: true,\n");
+			}
+			printer->Outdent();
+			printer->Print("},\n");
+		}
+	}
+	printer->Outdent();
+	printer->Print("},\n");
+	printer->Outdent();
+	printer->Print("}\n\n");
+
+}
+
+
+// Returns source for the service
+grpc::string GenerateServiceSource(grpc_generator::File *file,
+                                   const grpc_generator::Service *service,
+                                   grpc_go_generator::Parameters *parameters) {
+	grpc::string out;
+	auto p = file->CreatePrinter(&out);
+	auto printer = p.get();
+	std::map<grpc::string, grpc::string> vars;
+	vars["Package"] = parameters->package_name;
+	vars["ServicePrefix"] = parameters->service_prefix;
+	vars["grpc"] = "grpc";
+	vars["context"] = "context";
+	GenerateImports(file, printer, vars);
+	if (parameters->custom_method_io_type != "") {
+		vars["CustomMethodIO"] = parameters->custom_method_io_type;
+	}
+	GenerateService(service, printer, vars);
+	return out;
+}
+}// Namespace grpc_go_generator
diff --git a/grpc/src/compiler/go_generator.h b/grpc/src/compiler/go_generator.h
new file mode 100644
index 0000000..baa94e0
--- /dev/null
+++ b/grpc/src/compiler/go_generator.h
@@ -0,0 +1,64 @@
+/*
+ *
+ * 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_INTERNAL_COMPILER_GO_GENERATOR_H
+#define GRPC_INTERNAL_COMPILER_GO_GENERATOR_H
+
+//go generator is used to generate GRPC code for serialization system, such as flatbuffers
+#include <memory>
+#include <vector>
+
+#include "src/compiler/schema_interface.h"
+
+namespace grpc_go_generator {
+
+struct Parameters {
+  //Defines the custom parameter types for methods
+  //eg: flatbuffers uses flatbuffers.Builder as input for the client and output for the server
+  grpc::string custom_method_io_type;
+
+  //Package name for the service
+  grpc::string package_name;
+
+  //Prefix for RPC Calls
+  grpc::string service_prefix;
+};
+
+// Return the source of the generated service file.
+grpc::string GenerateServiceSource(grpc_generator::File *file,
+                                   const grpc_generator::Service *service,
+                                   grpc_go_generator::Parameters *parameters);
+
+}
+
+#endif  // GRPC_INTERNAL_COMPILER_GO_GENERATOR_H
diff --git a/grpc/src/compiler/java_generator.cc b/grpc/src/compiler/java_generator.cc
new file mode 100644
index 0000000..661c9ee
--- /dev/null
+++ b/grpc/src/compiler/java_generator.cc
@@ -0,0 +1,1135 @@
+/*
+ * Copyright 2016 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "java_generator.h"
+
+#include <algorithm>
+#include <iostream>
+#include <iterator>
+#include <map>
+#include <utility>
+#include <vector>
+
+// just to get flatbuffer_version_string()
+#include <flatbuffers/flatbuffers.h>
+#include <flatbuffers/util.h>
+#define to_string flatbuffers::NumToString
+
+// Stringify helpers used solely to cast GRPC_VERSION
+#ifndef STR
+#define STR(s) #s
+#endif
+
+#ifndef XSTR
+#define XSTR(s) STR(s)
+#endif
+
+
+typedef grpc_generator::Printer Printer;
+typedef std::map<grpc::string, grpc::string> VARS;
+typedef grpc_generator::Service ServiceDescriptor;
+typedef grpc_generator::CommentHolder
+    DescriptorType;  // base class of all 'descriptors'
+typedef grpc_generator::Method MethodDescriptor;
+
+namespace grpc_java_generator {
+typedef std::string string;
+// Generates imports for the service
+void GenerateImports(grpc_generator::File* file,
+                     grpc_generator::Printer* printer, VARS& vars) {
+  vars["filename"] = file->filename();
+  printer->Print(
+      vars,
+      "//Generated by flatc compiler (version $flatc_version$)\n");
+  printer->Print("//If you make any local changes, they will be lost\n");
+  printer->Print(vars, "//source: $filename$.fbs\n\n");
+  printer->Print(vars, "package $Package$;\n\n");
+  vars["Package"] = vars["Package"] + ".";
+  if (!file->additional_headers().empty()) {
+    printer->Print(file->additional_headers().c_str());
+    printer->Print("\n\n");
+  }
+}
+
+// Adjust a method name prefix identifier to follow the JavaBean spec:
+//   - decapitalize the first letter
+//   - remove embedded underscores & capitalize the following letter
+static string MixedLower(const string& word) {
+  string w;
+  w += static_cast<string::value_type>(tolower(word[0]));
+  bool after_underscore = false;
+  for (size_t i = 1; i < word.length(); ++i) {
+    if (word[i] == '_') {
+      after_underscore = true;
+    } else {
+      w += after_underscore ? static_cast<string::value_type>(toupper(word[i]))
+                            : word[i];
+      after_underscore = false;
+    }
+  }
+  return w;
+}
+
+// Converts to the identifier to the ALL_UPPER_CASE format.
+//   - An underscore is inserted where a lower case letter is followed by an
+//     upper case letter.
+//   - All letters are converted to upper case
+static string ToAllUpperCase(const string& word) {
+  string w;
+  for (size_t i = 0; i < word.length(); ++i) {
+    w += static_cast<string::value_type>(toupper(word[i]));
+    if ((i < word.length() - 1) && islower(word[i]) && isupper(word[i + 1])) {
+      w += '_';
+    }
+  }
+  return w;
+}
+
+static inline string LowerMethodName(const MethodDescriptor* method) {
+  return MixedLower(method->name());
+}
+
+static inline string MethodPropertiesFieldName(const MethodDescriptor* method) {
+  return "METHOD_" + ToAllUpperCase(method->name());
+}
+
+static inline string MethodPropertiesGetterName(
+    const MethodDescriptor* method) {
+  return MixedLower("get_" + method->name() + "_method");
+}
+
+static inline string MethodIdFieldName(const MethodDescriptor* method) {
+  return "METHODID_" + ToAllUpperCase(method->name());
+}
+
+static inline string JavaClassName(VARS& vars, const string& name) {
+  // string name = google::protobuf::compiler::java::ClassName(desc);
+  return vars["Package"] + name;
+}
+
+static inline string ServiceClassName(const string& service_name) {
+  return service_name + "Grpc";
+}
+
+// TODO(nmittler): Remove once protobuf includes javadoc methods in
+// distribution.
+template <typename ITR>
+static void GrpcSplitStringToIteratorUsing(const string& full,
+                                           const char* delim, ITR& result) {
+  // Optimize the common case where delim is a single character.
+  if (delim[0] != '\0' && delim[1] == '\0') {
+    char c = delim[0];
+    const char* p = full.data();
+    const char* end = p + full.size();
+    while (p != end) {
+      if (*p == c) {
+        ++p;
+      } else {
+        const char* start = p;
+        while (++p != end && *p != c)
+          ;
+        *result++ = string(start, p - start);
+      }
+    }
+    return;
+  }
+
+  string::size_type begin_index, end_index;
+  begin_index = full.find_first_not_of(delim);
+  while (begin_index != string::npos) {
+    end_index = full.find_first_of(delim, begin_index);
+    if (end_index == string::npos) {
+      *result++ = full.substr(begin_index);
+      return;
+    }
+    *result++ = full.substr(begin_index, (end_index - begin_index));
+    begin_index = full.find_first_not_of(delim, end_index);
+  }
+}
+
+static void GrpcSplitStringUsing(const string& full, const char* delim,
+                                 std::vector<string>* result) {
+  std::back_insert_iterator<std::vector<string>> it(*result);
+  GrpcSplitStringToIteratorUsing(full, delim, it);
+}
+
+static std::vector<string> GrpcSplit(const string& full, const char* delim) {
+  std::vector<string> result;
+  GrpcSplitStringUsing(full, delim, &result);
+  return result;
+}
+
+// TODO(nmittler): Remove once protobuf includes javadoc methods in
+// distribution.
+static string GrpcEscapeJavadoc(const string& input) {
+  string result;
+  result.reserve(input.size() * 2);
+
+  char prev = '*';
+
+  for (string::size_type i = 0; i < input.size(); i++) {
+    char c = input[i];
+    switch (c) {
+      case '*':
+        // Avoid "/*".
+        if (prev == '/') {
+          result.append("&#42;");
+        } else {
+          result.push_back(c);
+        }
+        break;
+      case '/':
+        // Avoid "*/".
+        if (prev == '*') {
+          result.append("&#47;");
+        } else {
+          result.push_back(c);
+        }
+        break;
+      case '@':
+        // '@' starts javadoc tags including the @deprecated tag, which will
+        // cause a compile-time error if inserted before a declaration that
+        // does not have a corresponding @Deprecated annotation.
+        result.append("&#64;");
+        break;
+      case '<':
+        // Avoid interpretation as HTML.
+        result.append("&lt;");
+        break;
+      case '>':
+        // Avoid interpretation as HTML.
+        result.append("&gt;");
+        break;
+      case '&':
+        // Avoid interpretation as HTML.
+        result.append("&amp;");
+        break;
+      case '\\':
+        // Java interprets Unicode escape sequences anywhere!
+        result.append("&#92;");
+        break;
+      default:
+        result.push_back(c);
+        break;
+    }
+
+    prev = c;
+  }
+
+  return result;
+}
+
+static std::vector<string> GrpcGetDocLines(const string& comments) {
+  if (!comments.empty()) {
+    // TODO(kenton):  Ideally we should parse the comment text as Markdown and
+    //   write it back as HTML, but this requires a Markdown parser.  For now
+    //   we just use <pre> to get fixed-width text formatting.
+
+    // If the comment itself contains block comment start or end markers,
+    // HTML-escape them so that they don't accidentally close the doc comment.
+    string escapedComments = GrpcEscapeJavadoc(comments);
+
+    std::vector<string> lines = GrpcSplit(escapedComments, "\n");
+    while (!lines.empty() && lines.back().empty()) {
+      lines.pop_back();
+    }
+    return lines;
+  }
+  return std::vector<string>();
+}
+
+static std::vector<string> GrpcGetDocLinesForDescriptor(
+    const DescriptorType* descriptor) {
+  return descriptor->GetAllComments();
+  // return GrpcGetDocLines(descriptor->GetLeadingComments("///"));
+}
+
+static void GrpcWriteDocCommentBody(Printer* printer, VARS& vars,
+                                    const std::vector<string>& lines,
+                                    bool surroundWithPreTag) {
+  if (!lines.empty()) {
+    if (surroundWithPreTag) {
+      printer->Print(" * <pre>\n");
+    }
+
+    for (size_t i = 0; i < lines.size(); i++) {
+      // Most lines should start with a space.  Watch out for lines that start
+      // with a /, since putting that right after the leading asterisk will
+      // close the comment.
+      vars["line"] = lines[i];
+      if (!lines[i].empty() && lines[i][0] == '/') {
+        printer->Print(vars, " * $line$\n");
+      } else {
+        printer->Print(vars, " *$line$\n");
+      }
+    }
+
+    if (surroundWithPreTag) {
+      printer->Print(" * </pre>\n");
+    }
+  }
+}
+
+static void GrpcWriteDocComment(Printer* printer, VARS& vars,
+                                const string& comments) {
+  printer->Print("/**\n");
+  std::vector<string> lines = GrpcGetDocLines(comments);
+  GrpcWriteDocCommentBody(printer, vars, lines, false);
+  printer->Print(" */\n");
+}
+
+static void GrpcWriteServiceDocComment(Printer* printer, VARS& vars,
+                                       const ServiceDescriptor* service) {
+  printer->Print("/**\n");
+  std::vector<string> lines = GrpcGetDocLinesForDescriptor(service);
+  GrpcWriteDocCommentBody(printer, vars, lines, true);
+  printer->Print(" */\n");
+}
+
+void GrpcWriteMethodDocComment(Printer* printer, VARS& vars,
+                               const MethodDescriptor* method) {
+  printer->Print("/**\n");
+  std::vector<string> lines = GrpcGetDocLinesForDescriptor(method);
+  GrpcWriteDocCommentBody(printer, vars, lines, true);
+  printer->Print(" */\n");
+}
+
+//outputs static singleton extractor for type stored in "extr_type" and "extr_type_name" vars
+static void PrintTypeExtractor(Printer* p, VARS& vars) {
+  p->Print(
+    vars,
+    "private static volatile FlatbuffersUtils.FBExtactor<$extr_type$> "
+    "extractorOf$extr_type_name$;\n"
+    "private static FlatbuffersUtils.FBExtactor<$extr_type$> "
+    "getExtractorOf$extr_type_name$() {\n"
+    "    if (extractorOf$extr_type_name$ != null) return "
+    "extractorOf$extr_type_name$;\n"
+    "    synchronized ($service_class_name$.class) {\n"
+    "        if (extractorOf$extr_type_name$ != null) return "
+    "extractorOf$extr_type_name$;\n"
+    "        extractorOf$extr_type_name$ = new "
+    "FlatbuffersUtils.FBExtactor<$extr_type$>() {\n"
+    "            public $extr_type$ extract (ByteBuffer buffer) {\n"
+    "                return "
+    "$extr_type$.getRootAs$extr_type_name$(buffer);\n"
+    "            }\n"
+    "        };\n"
+    "        return extractorOf$extr_type_name$;\n"
+    "    }\n"
+    "}\n\n");
+}
+static void PrintMethodFields(Printer* p, VARS& vars,
+                              const ServiceDescriptor* service) {
+  p->Print("// Static method descriptors that strictly reflect the proto.\n");
+  vars["service_name"] = service->name();
+
+  //set of names of rpc input- and output- types that were already encountered.
+  //this is needed to avoid duplicating type extractor since it's possible that
+  //the same type is used as an input or output type of more than a single RPC method
+  std::set<std::string> encounteredTypes;
+
+  for (int i = 0; i < service->method_count(); ++i) {
+    auto method = service->method(i);
+    vars["arg_in_id"] = to_string(2L * i); //trying to make msvc 10 happy
+    vars["arg_out_id"] = to_string(2L * i + 1);
+    vars["method_name"] = method->name();
+    vars["input_type_name"] = method->get_input_type_name();
+    vars["output_type_name"] = method->get_output_type_name();
+    vars["input_type"] = JavaClassName(vars, method->get_input_type_name());
+    vars["output_type"] = JavaClassName(vars, method->get_output_type_name());
+    vars["method_field_name"] = MethodPropertiesFieldName(method.get());
+    vars["method_new_field_name"] = MethodPropertiesGetterName(method.get());
+    vars["method_method_name"] = MethodPropertiesGetterName(method.get());
+    bool client_streaming = method->ClientStreaming() || method->BidiStreaming();
+    bool server_streaming = method->ServerStreaming() || method->BidiStreaming();
+    if (client_streaming) {
+      if (server_streaming) {
+        vars["method_type"] = "BIDI_STREAMING";
+      } else {
+        vars["method_type"] = "CLIENT_STREAMING";
+      }
+    } else {
+      if (server_streaming) {
+        vars["method_type"] = "SERVER_STREAMING";
+      } else {
+        vars["method_type"] = "UNARY";
+      }
+    }
+
+    p->Print(
+        vars,
+        "@$ExperimentalApi$(\"https://github.com/grpc/grpc-java/issues/"
+        "1901\")\n"
+        "@$Deprecated$ // Use {@link #$method_method_name$()} instead. \n"
+        "public static final $MethodDescriptor$<$input_type$,\n"
+        "    $output_type$> $method_field_name$ = $method_method_name$();\n"
+        "\n"
+        "private static volatile $MethodDescriptor$<$input_type$,\n"
+        "    $output_type$> $method_new_field_name$;\n"
+        "\n");
+
+    if (encounteredTypes.insert(vars["input_type_name"]).second) {
+      vars["extr_type"] = vars["input_type"];
+      vars["extr_type_name"] = vars["input_type_name"];
+      PrintTypeExtractor(p, vars);
+    }
+
+    if (encounteredTypes.insert(vars["output_type_name"]).second) {
+      vars["extr_type"] = vars["output_type"];
+      vars["extr_type_name"] = vars["output_type_name"];
+      PrintTypeExtractor(p, vars);
+    }
+
+    p->Print(
+      vars,
+      "@$ExperimentalApi$(\"https://github.com/grpc/grpc-java/issues/"
+      "1901\")\n"
+      "public static $MethodDescriptor$<$input_type$,\n"
+      "    $output_type$> $method_method_name$() {\n"
+      "  $MethodDescriptor$<$input_type$, $output_type$> "
+      "$method_new_field_name$;\n"
+      "  if (($method_new_field_name$ = "
+      "$service_class_name$.$method_new_field_name$) == null) {\n"
+      "    synchronized ($service_class_name$.class) {\n"
+      "      if (($method_new_field_name$ = "
+      "$service_class_name$.$method_new_field_name$) == null) {\n"
+      "        $service_class_name$.$method_new_field_name$ = "
+      "$method_new_field_name$ = \n"
+      "            $MethodDescriptor$.<$input_type$, "
+      "$output_type$>newBuilder()\n"
+      "            .setType($MethodType$.$method_type$)\n"
+      "            .setFullMethodName(generateFullMethodName(\n"
+      "                \"$Package$$service_name$\", \"$method_name$\"))\n"
+      "            .setSampledToLocalTracing(true)\n"
+      "            .setRequestMarshaller(FlatbuffersUtils.marshaller(\n"
+      "                $input_type$.class, "
+      "getExtractorOf$input_type_name$()))\n"
+      "            .setResponseMarshaller(FlatbuffersUtils.marshaller(\n"
+      "                $output_type$.class, "
+      "getExtractorOf$output_type_name$()))\n");
+
+    //            vars["proto_method_descriptor_supplier"] = service->name() +
+    //            "MethodDescriptorSupplier";
+    p->Print(vars, "                .setSchemaDescriptor(null)\n");
+    //"                .setSchemaDescriptor(new
+    //$proto_method_descriptor_supplier$(\"$method_name$\"))\n");
+
+    p->Print(vars, "                .build();\n");
+    p->Print(vars,
+             "        }\n"
+             "      }\n"
+             "   }\n"
+             "   return $method_new_field_name$;\n"
+             "}\n");
+
+    p->Print("\n");
+  }
+}
+enum StubType {
+  ASYNC_INTERFACE = 0,
+  BLOCKING_CLIENT_INTERFACE = 1,
+  FUTURE_CLIENT_INTERFACE = 2,
+  BLOCKING_SERVER_INTERFACE = 3,
+  ASYNC_CLIENT_IMPL = 4,
+  BLOCKING_CLIENT_IMPL = 5,
+  FUTURE_CLIENT_IMPL = 6,
+  ABSTRACT_CLASS = 7,
+};
+
+enum CallType { ASYNC_CALL = 0, BLOCKING_CALL = 1, FUTURE_CALL = 2 };
+
+static void PrintBindServiceMethodBody(Printer* p, VARS& vars,
+                                       const ServiceDescriptor* service);
+
+// Prints a client interface or implementation class, or a server interface.
+static void PrintStub(Printer* p, VARS& vars, const ServiceDescriptor* service,
+                      StubType type) {
+  const string service_name = service->name();
+  vars["service_name"] = service_name;
+  vars["abstract_name"] = service_name + "ImplBase";
+  string stub_name = service_name;
+  string client_name = service_name;
+  CallType call_type = ASYNC_CALL;
+  bool impl_base = false;
+  bool interface = false;
+  switch (type) {
+    case ABSTRACT_CLASS:
+      call_type = ASYNC_CALL;
+      impl_base = true;
+      break;
+    case ASYNC_CLIENT_IMPL:
+      call_type = ASYNC_CALL;
+      stub_name += "Stub";
+      break;
+    case BLOCKING_CLIENT_INTERFACE:
+      interface = true;
+      FLATBUFFERS_FALLTHROUGH(); // fall thru
+    case BLOCKING_CLIENT_IMPL:
+      call_type = BLOCKING_CALL;
+      stub_name += "BlockingStub";
+      client_name += "BlockingClient";
+      break;
+    case FUTURE_CLIENT_INTERFACE:
+      interface = true;
+      FLATBUFFERS_FALLTHROUGH(); // fall thru
+    case FUTURE_CLIENT_IMPL:
+      call_type = FUTURE_CALL;
+      stub_name += "FutureStub";
+      client_name += "FutureClient";
+      break;
+    case ASYNC_INTERFACE:
+      call_type = ASYNC_CALL;
+      interface = true;
+      break;
+    default:
+      GRPC_CODEGEN_FAIL << "Cannot determine class name for StubType: " << type;
+  }
+  vars["stub_name"] = stub_name;
+  vars["client_name"] = client_name;
+
+  // Class head
+  if (!interface) {
+    GrpcWriteServiceDocComment(p, vars, service);
+  }
+  if (impl_base) {
+    p->Print(vars,
+             "public static abstract class $abstract_name$ implements "
+             "$BindableService$ {\n");
+  } else {
+    p->Print(vars,
+             "public static final class $stub_name$ extends "
+             "$AbstractStub$<$stub_name$> {\n");
+  }
+  p->Indent();
+
+  // Constructor and build() method
+  if (!impl_base && !interface) {
+    p->Print(vars, "private $stub_name$($Channel$ channel) {\n");
+    p->Indent();
+    p->Print("super(channel);\n");
+    p->Outdent();
+    p->Print("}\n\n");
+    p->Print(vars,
+             "private $stub_name$($Channel$ channel,\n"
+             "    $CallOptions$ callOptions) {\n");
+    p->Indent();
+    p->Print("super(channel, callOptions);\n");
+    p->Outdent();
+    p->Print("}\n\n");
+    p->Print(vars,
+             "@$Override$\n"
+             "protected $stub_name$ build($Channel$ channel,\n"
+             "    $CallOptions$ callOptions) {\n");
+    p->Indent();
+    p->Print(vars, "return new $stub_name$(channel, callOptions);\n");
+    p->Outdent();
+    p->Print("}\n");
+  }
+
+  // RPC methods
+  for (int i = 0; i < service->method_count(); ++i) {
+    auto method = service->method(i);
+    vars["input_type"] = JavaClassName(vars, method->get_input_type_name());
+    vars["output_type"] = JavaClassName(vars, method->get_output_type_name());
+    vars["lower_method_name"] = LowerMethodName(&*method);
+    vars["method_method_name"] = MethodPropertiesGetterName(&*method);
+    bool client_streaming = method->ClientStreaming() || method->BidiStreaming();
+    bool server_streaming = method->ServerStreaming() || method->BidiStreaming();
+
+    if (call_type == BLOCKING_CALL && client_streaming) {
+      // Blocking client interface with client streaming is not available
+      continue;
+    }
+
+    if (call_type == FUTURE_CALL && (client_streaming || server_streaming)) {
+      // Future interface doesn't support streaming.
+      continue;
+    }
+
+    // Method signature
+    p->Print("\n");
+    // TODO(nmittler): Replace with WriteMethodDocComment once included by the
+    // protobuf distro.
+    if (!interface) {
+      GrpcWriteMethodDocComment(p, vars, &*method);
+    }
+    p->Print("public ");
+    switch (call_type) {
+      case BLOCKING_CALL:
+        GRPC_CODEGEN_CHECK(!client_streaming)
+            << "Blocking client interface with client streaming is unavailable";
+        if (server_streaming) {
+          // Server streaming
+          p->Print(vars,
+                   "$Iterator$<$output_type$> $lower_method_name$(\n"
+                   "    $input_type$ request)");
+        } else {
+          // Simple RPC
+          p->Print(vars,
+                   "$output_type$ $lower_method_name$($input_type$ request)");
+        }
+        break;
+      case ASYNC_CALL:
+        if (client_streaming) {
+          // Bidirectional streaming or client streaming
+          p->Print(vars,
+                   "$StreamObserver$<$input_type$> $lower_method_name$(\n"
+                   "    $StreamObserver$<$output_type$> responseObserver)");
+        } else {
+          // Server streaming or simple RPC
+          p->Print(vars,
+                   "void $lower_method_name$($input_type$ request,\n"
+                   "    $StreamObserver$<$output_type$> responseObserver)");
+        }
+        break;
+      case FUTURE_CALL:
+        GRPC_CODEGEN_CHECK(!client_streaming && !server_streaming)
+            << "Future interface doesn't support streaming. "
+            << "client_streaming=" << client_streaming << ", "
+            << "server_streaming=" << server_streaming;
+        p->Print(vars,
+                 "$ListenableFuture$<$output_type$> $lower_method_name$(\n"
+                 "    $input_type$ request)");
+        break;
+    }
+
+    if (interface) {
+      p->Print(";\n");
+      continue;
+    }
+    // Method body.
+    p->Print(" {\n");
+    p->Indent();
+    if (impl_base) {
+      switch (call_type) {
+          // NB: Skipping validation of service methods. If something is wrong,
+          // we wouldn't get to this point as compiler would return errors when
+          // generating service interface.
+        case ASYNC_CALL:
+          if (client_streaming) {
+            p->Print(vars,
+                     "return "
+                     "asyncUnimplementedStreamingCall($method_method_name$(), "
+                     "responseObserver);\n");
+          } else {
+            p->Print(vars,
+                     "asyncUnimplementedUnaryCall($method_method_name$(), "
+                     "responseObserver);\n");
+          }
+          break;
+        default:
+          break;
+      }
+    } else if (!interface) {
+      switch (call_type) {
+        case BLOCKING_CALL:
+          GRPC_CODEGEN_CHECK(!client_streaming)
+              << "Blocking client streaming interface is not available";
+          if (server_streaming) {
+            vars["calls_method"] = "blockingServerStreamingCall";
+            vars["params"] = "request";
+          } else {
+            vars["calls_method"] = "blockingUnaryCall";
+            vars["params"] = "request";
+          }
+          p->Print(vars,
+                   "return $calls_method$(\n"
+                   "    getChannel(), $method_method_name$(), "
+                   "getCallOptions(), $params$);\n");
+          break;
+        case ASYNC_CALL:
+          if (server_streaming) {
+            if (client_streaming) {
+              vars["calls_method"] = "asyncBidiStreamingCall";
+              vars["params"] = "responseObserver";
+            } else {
+              vars["calls_method"] = "asyncServerStreamingCall";
+              vars["params"] = "request, responseObserver";
+            }
+          } else {
+            if (client_streaming) {
+              vars["calls_method"] = "asyncClientStreamingCall";
+              vars["params"] = "responseObserver";
+            } else {
+              vars["calls_method"] = "asyncUnaryCall";
+              vars["params"] = "request, responseObserver";
+            }
+          }
+          vars["last_line_prefix"] = client_streaming ? "return " : "";
+          p->Print(vars,
+                   "$last_line_prefix$$calls_method$(\n"
+                   "    getChannel().newCall($method_method_name$(), "
+                   "getCallOptions()), $params$);\n");
+          break;
+        case FUTURE_CALL:
+          GRPC_CODEGEN_CHECK(!client_streaming && !server_streaming)
+              << "Future interface doesn't support streaming. "
+              << "client_streaming=" << client_streaming << ", "
+              << "server_streaming=" << server_streaming;
+          vars["calls_method"] = "futureUnaryCall";
+          p->Print(vars,
+                   "return $calls_method$(\n"
+                   "    getChannel().newCall($method_method_name$(), "
+                   "getCallOptions()), request);\n");
+          break;
+      }
+    }
+    p->Outdent();
+    p->Print("}\n");
+  }
+
+  if (impl_base) {
+    p->Print("\n");
+    p->Print(
+        vars,
+        "@$Override$ public final $ServerServiceDefinition$ bindService() {\n");
+    vars["instance"] = "this";
+    PrintBindServiceMethodBody(p, vars, service);
+    p->Print("}\n");
+  }
+
+  p->Outdent();
+  p->Print("}\n\n");
+}
+
+static bool CompareMethodClientStreaming(
+    const std::unique_ptr<const grpc_generator::Method>& method1,
+    const std::unique_ptr<const grpc_generator::Method>& method2) {
+  return method1->ClientStreaming() < method2->ClientStreaming();
+}
+
+// Place all method invocations into a single class to reduce memory footprint
+// on Android.
+static void PrintMethodHandlerClass(Printer* p, VARS& vars,
+                                    const ServiceDescriptor* service) {
+  // Sort method ids based on ClientStreaming() so switch tables are compact.
+  std::vector<std::unique_ptr<const grpc_generator::Method>> sorted_methods(
+      service->method_count());
+  for (int i = 0; i < service->method_count(); ++i) {
+    sorted_methods[i] = service->method(i);
+  }
+  stable_sort(sorted_methods.begin(), sorted_methods.end(),
+              CompareMethodClientStreaming);
+  for (size_t i = 0; i < sorted_methods.size(); i++) {
+    auto& method = sorted_methods[i];
+    vars["method_id"] = to_string(i);
+    vars["method_id_name"] = MethodIdFieldName(&*method);
+    p->Print(vars,
+             "private static final int $method_id_name$ = $method_id$;\n");
+  }
+  p->Print("\n");
+  vars["service_name"] = service->name() + "ImplBase";
+  p->Print(vars,
+           "private static final class MethodHandlers<Req, Resp> implements\n"
+           "    io.grpc.stub.ServerCalls.UnaryMethod<Req, Resp>,\n"
+           "    io.grpc.stub.ServerCalls.ServerStreamingMethod<Req, Resp>,\n"
+           "    io.grpc.stub.ServerCalls.ClientStreamingMethod<Req, Resp>,\n"
+           "    io.grpc.stub.ServerCalls.BidiStreamingMethod<Req, Resp> {\n"
+           "  private final $service_name$ serviceImpl;\n"
+           "  private final int methodId;\n"
+           "\n"
+           "  MethodHandlers($service_name$ serviceImpl, int methodId) {\n"
+           "    this.serviceImpl = serviceImpl;\n"
+           "    this.methodId = methodId;\n"
+           "  }\n\n");
+  p->Indent();
+  p->Print(vars,
+           "@$Override$\n"
+           "@java.lang.SuppressWarnings(\"unchecked\")\n"
+           "public void invoke(Req request, $StreamObserver$<Resp> "
+           "responseObserver) {\n"
+           "  switch (methodId) {\n");
+  p->Indent();
+  p->Indent();
+
+  for (int i = 0; i < service->method_count(); ++i) {
+    auto method = service->method(i);
+    if (method->ClientStreaming() || method->BidiStreaming()) {
+      continue;
+    }
+    vars["method_id_name"] = MethodIdFieldName(&*method);
+    vars["lower_method_name"] = LowerMethodName(&*method);
+    vars["input_type"] = JavaClassName(vars, method->get_input_type_name());
+    vars["output_type"] = JavaClassName(vars, method->get_output_type_name());
+    p->Print(vars,
+             "case $method_id_name$:\n"
+             "  serviceImpl.$lower_method_name$(($input_type$) request,\n"
+             "      ($StreamObserver$<$output_type$>) responseObserver);\n"
+             "  break;\n");
+  }
+  p->Print(
+      "default:\n"
+      "  throw new AssertionError();\n");
+
+  p->Outdent();
+  p->Outdent();
+  p->Print(
+      "  }\n"
+      "}\n\n");
+
+  p->Print(vars,
+           "@$Override$\n"
+           "@java.lang.SuppressWarnings(\"unchecked\")\n"
+           "public $StreamObserver$<Req> invoke(\n"
+           "    $StreamObserver$<Resp> responseObserver) {\n"
+           "  switch (methodId) {\n");
+  p->Indent();
+  p->Indent();
+
+  for (int i = 0; i < service->method_count(); ++i) {
+    auto method = service->method(i);
+    if (!(method->ClientStreaming() || method->BidiStreaming())) {
+      continue;
+    }
+    vars["method_id_name"] = MethodIdFieldName(&*method);
+    vars["lower_method_name"] = LowerMethodName(&*method);
+    vars["input_type"] = JavaClassName(vars, method->get_input_type_name());
+    vars["output_type"] = JavaClassName(vars, method->get_output_type_name());
+    p->Print(
+        vars,
+        "case $method_id_name$:\n"
+        "  return ($StreamObserver$<Req>) serviceImpl.$lower_method_name$(\n"
+        "      ($StreamObserver$<$output_type$>) responseObserver);\n");
+  }
+  p->Print(
+      "default:\n"
+      "  throw new AssertionError();\n");
+
+  p->Outdent();
+  p->Outdent();
+  p->Print(
+      "  }\n"
+      "}\n");
+
+  p->Outdent();
+  p->Print("}\n\n");
+}
+
+static void PrintGetServiceDescriptorMethod(Printer* p, VARS& vars,
+                                            const ServiceDescriptor* service) {
+  vars["service_name"] = service->name();
+  //        vars["proto_base_descriptor_supplier"] = service->name() +
+  //        "BaseDescriptorSupplier"; vars["proto_file_descriptor_supplier"] =
+  //        service->name() + "FileDescriptorSupplier";
+  //        vars["proto_method_descriptor_supplier"] = service->name() +
+  //        "MethodDescriptorSupplier"; vars["proto_class_name"] =
+  //        google::protobuf::compiler::java::ClassName(service->file());
+  //        p->Print(
+  //                 vars,
+  //                 "private static abstract class
+  //                 $proto_base_descriptor_supplier$\n" "    implements
+  //                 $ProtoFileDescriptorSupplier$,
+  //                 $ProtoServiceDescriptorSupplier$ {\n" "
+  //                 $proto_base_descriptor_supplier$() {}\n"
+  //                 "\n"
+  //                 "  @$Override$\n"
+  //                 "  public com.google.protobuf.Descriptors.FileDescriptor
+  //                 getFileDescriptor() {\n" "    return
+  //                 $proto_class_name$.getDescriptor();\n" "  }\n"
+  //                 "\n"
+  //                 "  @$Override$\n"
+  //                 "  public com.google.protobuf.Descriptors.ServiceDescriptor
+  //                 getServiceDescriptor() {\n" "    return
+  //                 getFileDescriptor().findServiceByName(\"$service_name$\");\n"
+  //                 "  }\n"
+  //                 "}\n"
+  //                 "\n"
+  //                 "private static final class
+  //                 $proto_file_descriptor_supplier$\n" "    extends
+  //                 $proto_base_descriptor_supplier$ {\n" "
+  //                 $proto_file_descriptor_supplier$() {}\n"
+  //                 "}\n"
+  //                 "\n"
+  //                 "private static final class
+  //                 $proto_method_descriptor_supplier$\n" "    extends
+  //                 $proto_base_descriptor_supplier$\n" "    implements
+  //                 $ProtoMethodDescriptorSupplier$ {\n" "  private final
+  //                 String methodName;\n"
+  //                 "\n"
+  //                 "  $proto_method_descriptor_supplier$(String methodName)
+  //                 {\n" "    this.methodName = methodName;\n" "  }\n"
+  //                 "\n"
+  //                 "  @$Override$\n"
+  //                 "  public com.google.protobuf.Descriptors.MethodDescriptor
+  //                 getMethodDescriptor() {\n" "    return
+  //                 getServiceDescriptor().findMethodByName(methodName);\n" "
+  //                 }\n"
+  //                 "}\n\n");
+
+  p->Print(
+      vars,
+      "private static volatile $ServiceDescriptor$ serviceDescriptor;\n\n");
+
+  p->Print(vars,
+           "public static $ServiceDescriptor$ getServiceDescriptor() {\n");
+  p->Indent();
+  p->Print(vars, "$ServiceDescriptor$ result = serviceDescriptor;\n");
+  p->Print("if (result == null) {\n");
+  p->Indent();
+  p->Print(vars, "synchronized ($service_class_name$.class) {\n");
+  p->Indent();
+  p->Print("result = serviceDescriptor;\n");
+  p->Print("if (result == null) {\n");
+  p->Indent();
+
+  p->Print(vars,
+           "serviceDescriptor = result = "
+           "$ServiceDescriptor$.newBuilder(SERVICE_NAME)");
+  p->Indent();
+  p->Indent();
+  p->Print(vars, "\n.setSchemaDescriptor(null)");
+  for (int i = 0; i < service->method_count(); ++i) {
+    auto method = service->method(i);
+    vars["method_method_name"] = MethodPropertiesGetterName(&*method);
+    p->Print(vars, "\n.addMethod($method_method_name$())");
+  }
+  p->Print("\n.build();\n");
+  p->Outdent();
+  p->Outdent();
+
+  p->Outdent();
+  p->Print("}\n");
+  p->Outdent();
+  p->Print("}\n");
+  p->Outdent();
+  p->Print("}\n");
+  p->Print("return result;\n");
+  p->Outdent();
+  p->Print("}\n");
+}
+
+static void PrintBindServiceMethodBody(Printer* p, VARS& vars,
+                                       const ServiceDescriptor* service) {
+  vars["service_name"] = service->name();
+  p->Indent();
+  p->Print(vars,
+           "return "
+           "$ServerServiceDefinition$.builder(getServiceDescriptor())\n");
+  p->Indent();
+  p->Indent();
+  for (int i = 0; i < service->method_count(); ++i) {
+    auto method = service->method(i);
+    vars["lower_method_name"] = LowerMethodName(&*method);
+    vars["method_method_name"] = MethodPropertiesGetterName(&*method);
+    vars["input_type"] = JavaClassName(vars, method->get_input_type_name());
+    vars["output_type"] = JavaClassName(vars, method->get_output_type_name());
+    vars["method_id_name"] = MethodIdFieldName(&*method);
+    bool client_streaming = method->ClientStreaming() || method->BidiStreaming();
+    bool server_streaming = method->ServerStreaming() || method->BidiStreaming();
+    if (client_streaming) {
+      if (server_streaming) {
+        vars["calls_method"] = "asyncBidiStreamingCall";
+      } else {
+        vars["calls_method"] = "asyncClientStreamingCall";
+      }
+    } else {
+      if (server_streaming) {
+        vars["calls_method"] = "asyncServerStreamingCall";
+      } else {
+        vars["calls_method"] = "asyncUnaryCall";
+      }
+    }
+    p->Print(vars, ".addMethod(\n");
+    p->Indent();
+    p->Print(vars,
+             "$method_method_name$(),\n"
+             "$calls_method$(\n");
+    p->Indent();
+    p->Print(vars,
+             "new MethodHandlers<\n"
+             "  $input_type$,\n"
+             "  $output_type$>(\n"
+             "    $instance$, $method_id_name$)))\n");
+    p->Outdent();
+    p->Outdent();
+  }
+  p->Print(".build();\n");
+  p->Outdent();
+  p->Outdent();
+  p->Outdent();
+}
+
+static void PrintService(Printer* p, VARS& vars,
+                         const ServiceDescriptor* service,
+                         bool disable_version) {
+  vars["service_name"] = service->name();
+  vars["service_class_name"] = ServiceClassName(service->name());
+  vars["grpc_version"] = "";
+#ifdef GRPC_VERSION
+  if (!disable_version) {
+    vars["grpc_version"] = " (version " XSTR(GRPC_VERSION) ")";
+  }
+#else
+  (void)disable_version;
+#endif
+  // TODO(nmittler): Replace with WriteServiceDocComment once included by
+  // protobuf distro.
+  GrpcWriteServiceDocComment(p, vars, service);
+  p->Print(vars,
+           "@$Generated$(\n"
+           "    value = \"by gRPC proto compiler$grpc_version$\",\n"
+           "    comments = \"Source: $file_name$.fbs\")\n"
+           "public final class $service_class_name$ {\n\n");
+  p->Indent();
+  p->Print(vars, "private $service_class_name$() {}\n\n");
+
+  p->Print(vars,
+           "public static final String SERVICE_NAME = "
+           "\"$Package$$service_name$\";\n\n");
+
+  PrintMethodFields(p, vars, service);
+
+  // TODO(nmittler): Replace with WriteDocComment once included by protobuf
+  // distro.
+  GrpcWriteDocComment(
+      p, vars,
+      " Creates a new async stub that supports all call types for the service");
+  p->Print(vars,
+           "public static $service_name$Stub newStub($Channel$ channel) {\n");
+  p->Indent();
+  p->Print(vars, "return new $service_name$Stub(channel);\n");
+  p->Outdent();
+  p->Print("}\n\n");
+
+  // TODO(nmittler): Replace with WriteDocComment once included by protobuf
+  // distro.
+  GrpcWriteDocComment(
+      p, vars,
+      " Creates a new blocking-style stub that supports unary and streaming "
+      "output calls on the service");
+  p->Print(vars,
+           "public static $service_name$BlockingStub newBlockingStub(\n"
+           "    $Channel$ channel) {\n");
+  p->Indent();
+  p->Print(vars, "return new $service_name$BlockingStub(channel);\n");
+  p->Outdent();
+  p->Print("}\n\n");
+
+  // TODO(nmittler): Replace with WriteDocComment once included by protobuf
+  // distro.
+  GrpcWriteDocComment(
+      p, vars,
+      " Creates a new ListenableFuture-style stub that supports unary calls "
+      "on the service");
+  p->Print(vars,
+           "public static $service_name$FutureStub newFutureStub(\n"
+           "    $Channel$ channel) {\n");
+  p->Indent();
+  p->Print(vars, "return new $service_name$FutureStub(channel);\n");
+  p->Outdent();
+  p->Print("}\n\n");
+
+  PrintStub(p, vars, service, ABSTRACT_CLASS);
+  PrintStub(p, vars, service, ASYNC_CLIENT_IMPL);
+  PrintStub(p, vars, service, BLOCKING_CLIENT_IMPL);
+  PrintStub(p, vars, service, FUTURE_CLIENT_IMPL);
+
+  PrintMethodHandlerClass(p, vars, service);
+  PrintGetServiceDescriptorMethod(p, vars, service);
+  p->Outdent();
+  p->Print("}\n");
+}
+
+void PrintStaticImports(Printer* p) {
+  p->Print(
+      "import java.nio.ByteBuffer;\n"
+      "import static "
+      "io.grpc.MethodDescriptor.generateFullMethodName;\n"
+      "import static "
+      "io.grpc.stub.ClientCalls.asyncBidiStreamingCall;\n"
+      "import static "
+      "io.grpc.stub.ClientCalls.asyncClientStreamingCall;\n"
+      "import static "
+      "io.grpc.stub.ClientCalls.asyncServerStreamingCall;\n"
+      "import static "
+      "io.grpc.stub.ClientCalls.asyncUnaryCall;\n"
+      "import static "
+      "io.grpc.stub.ClientCalls.blockingServerStreamingCall;\n"
+      "import static "
+      "io.grpc.stub.ClientCalls.blockingUnaryCall;\n"
+      "import static "
+      "io.grpc.stub.ClientCalls.futureUnaryCall;\n"
+      "import static "
+      "io.grpc.stub.ServerCalls.asyncBidiStreamingCall;\n"
+      "import static "
+      "io.grpc.stub.ServerCalls.asyncClientStreamingCall;\n"
+      "import static "
+      "io.grpc.stub.ServerCalls.asyncServerStreamingCall;\n"
+      "import static "
+      "io.grpc.stub.ServerCalls.asyncUnaryCall;\n"
+      "import static "
+      "io.grpc.stub.ServerCalls.asyncUnimplementedStreamingCall;\n"
+      "import static "
+      "io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall;\n\n");
+}
+
+void GenerateService(const grpc_generator::Service* service,
+                     grpc_generator::Printer* printer, VARS& vars,
+                     bool disable_version) {
+  // All non-generated classes must be referred by fully qualified names to
+  // avoid collision with generated classes.
+  vars["String"] = "java.lang.String";
+  vars["Deprecated"] = "java.lang.Deprecated";
+  vars["Override"] = "java.lang.Override";
+  vars["Channel"] = "io.grpc.Channel";
+  vars["CallOptions"] = "io.grpc.CallOptions";
+  vars["MethodType"] = "io.grpc.MethodDescriptor.MethodType";
+  vars["ServerMethodDefinition"] = "io.grpc.ServerMethodDefinition";
+  vars["BindableService"] = "io.grpc.BindableService";
+  vars["ServerServiceDefinition"] = "io.grpc.ServerServiceDefinition";
+  vars["ServiceDescriptor"] = "io.grpc.ServiceDescriptor";
+  vars["ProtoFileDescriptorSupplier"] =
+      "io.grpc.protobuf.ProtoFileDescriptorSupplier";
+  vars["ProtoServiceDescriptorSupplier"] =
+      "io.grpc.protobuf.ProtoServiceDescriptorSupplier";
+  vars["ProtoMethodDescriptorSupplier"] =
+      "io.grpc.protobuf.ProtoMethodDescriptorSupplier";
+  vars["AbstractStub"] = "io.grpc.stub.AbstractStub";
+  vars["MethodDescriptor"] = "io.grpc.MethodDescriptor";
+  vars["NanoUtils"] = "io.grpc.protobuf.nano.NanoUtils";
+  vars["StreamObserver"] = "io.grpc.stub.StreamObserver";
+  vars["Iterator"] = "java.util.Iterator";
+  vars["Generated"] = "javax.annotation.Generated";
+  vars["ListenableFuture"] =
+      "com.google.common.util.concurrent.ListenableFuture";
+  vars["ExperimentalApi"] = "io.grpc.ExperimentalApi";
+
+  PrintStaticImports(printer);
+
+  PrintService(printer, vars, service, disable_version);
+}
+
+grpc::string GenerateServiceSource(
+    grpc_generator::File* file, const grpc_generator::Service* service,
+    grpc_java_generator::Parameters* parameters) {
+  grpc::string out;
+  auto printer = file->CreatePrinter(&out);
+  VARS vars;
+  vars["flatc_version"] = grpc::string(
+      FLATBUFFERS_STRING(FLATBUFFERS_VERSION_MAJOR) "." FLATBUFFERS_STRING(
+          FLATBUFFERS_VERSION_MINOR) "." FLATBUFFERS_STRING(FLATBUFFERS_VERSION_REVISION));
+
+  vars["file_name"] = file->filename();
+
+  if (!parameters->package_name.empty()) {
+    vars["Package"] = parameters->package_name;  // ServiceJavaPackage(service);
+  }
+  GenerateImports(file, &*printer, vars);
+  GenerateService(service, &*printer, vars, false);
+  return out;
+}
+
+}  // namespace grpc_java_generator
diff --git a/grpc/src/compiler/java_generator.h b/grpc/src/compiler/java_generator.h
new file mode 100644
index 0000000..b101fbf
--- /dev/null
+++ b/grpc/src/compiler/java_generator.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2016 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef NET_GRPC_COMPILER_JAVA_GENERATOR_H_
+#define NET_GRPC_COMPILER_JAVA_GENERATOR_H_
+
+#include <stdlib.h>  // for abort()
+#include <iostream>
+#include <map>
+#include <string>
+
+#include "src/compiler/schema_interface.h"
+
+class LogMessageVoidify {
+ public:
+  LogMessageVoidify() {}
+  // This has to be an operator with a precedence lower than << but
+  // higher than ?:
+  void operator&(std::ostream&) {}
+};
+
+class LogHelper {
+  std::ostream* os_;
+
+ public:
+  LogHelper(std::ostream* os) : os_(os) {}
+#if defined(_MSC_VER)
+#pragma warning(push)
+#pragma warning( \
+    disable : 4722)  // the flow of control terminates in a destructor
+  // (needed to compile ~LogHelper where destructor emits abort intentionally -
+  // inherited from grpc/java code generator).
+#endif
+  ~LogHelper() {
+    *os_ << std::endl;
+    ::abort();
+  }
+#if defined(_MSC_VER)
+#pragma warning(pop)
+#endif
+  std::ostream& get_os() const { return *os_; }
+};
+
+// Abort the program after logging the mesage if the given condition is not
+// true. Otherwise, do nothing.
+#define GRPC_CODEGEN_CHECK(x)                                            \
+  (x) ? (void)0                                                          \
+      : LogMessageVoidify() & LogHelper(&std::cerr).get_os()             \
+                                  << "CHECK FAILED: " << __FILE__ << ":" \
+                                  << __LINE__ << ": "
+
+// Abort the program after logging the mesage.
+#define GRPC_CODEGEN_FAIL GRPC_CODEGEN_CHECK(false)
+
+namespace grpc_java_generator {
+struct Parameters {
+  //        //Defines the custom parameter types for methods
+  //        //eg: flatbuffers uses flatbuffers.Builder as input for the client
+  //        and output for the server grpc::string custom_method_io_type;
+
+  // Package name for the service
+  grpc::string package_name;
+};
+
+// Return the source of the generated service file.
+grpc::string GenerateServiceSource(grpc_generator::File* file,
+                                   const grpc_generator::Service* service,
+                                   grpc_java_generator::Parameters* parameters);
+
+}  // namespace grpc_java_generator
+
+#endif  // NET_GRPC_COMPILER_JAVA_GENERATOR_H_
diff --git a/grpc/src/compiler/schema_interface.h b/grpc/src/compiler/schema_interface.h
new file mode 100644
index 0000000..2be2ed7
--- /dev/null
+++ b/grpc/src/compiler/schema_interface.h
@@ -0,0 +1,126 @@
+/*
+ *
+ * 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_INTERNAL_COMPILER_SCHEMA_INTERFACE_H
+#define GRPC_INTERNAL_COMPILER_SCHEMA_INTERFACE_H
+
+#include "src/compiler/config.h"
+
+#include <memory>
+#include <vector>
+
+#ifndef GRPC_CUSTOM_STRING
+#  include <string>
+#  define GRPC_CUSTOM_STRING std::string
+#endif
+
+namespace grpc {
+
+typedef GRPC_CUSTOM_STRING string;
+
+}  // namespace grpc
+
+namespace grpc_generator {
+
+// A common interface for objects having comments in the source.
+// Return formatted comments to be inserted in generated code.
+struct CommentHolder {
+  virtual ~CommentHolder() {}
+  virtual grpc::string GetLeadingComments(const grpc::string prefix) const = 0;
+  virtual grpc::string GetTrailingComments(const grpc::string prefix) const = 0;
+  virtual std::vector<grpc::string> GetAllComments() const = 0;
+};
+
+// An abstract interface representing a method.
+struct Method : public CommentHolder {
+  virtual ~Method() {}
+
+  virtual grpc::string name() const = 0;
+
+  virtual grpc::string input_type_name() const = 0;
+  virtual grpc::string output_type_name() const = 0;
+
+  virtual bool get_module_and_message_path_input(
+      grpc::string *str, grpc::string generator_file_name,
+      bool generate_in_pb2_grpc, grpc::string import_prefix) const = 0;
+  virtual bool get_module_and_message_path_output(
+      grpc::string *str, grpc::string generator_file_name,
+      bool generate_in_pb2_grpc, grpc::string import_prefix) const = 0;
+
+  virtual grpc::string get_input_type_name() const = 0;
+  virtual grpc::string get_output_type_name() const = 0;
+  virtual bool NoStreaming() const = 0;
+  virtual bool ClientStreaming() const = 0;
+  virtual bool ServerStreaming() const = 0;
+  virtual bool BidiStreaming() const = 0;
+};
+
+// An abstract interface representing a service.
+struct Service : public CommentHolder {
+  virtual ~Service() {}
+
+  virtual grpc::string name() const = 0;
+
+  virtual int method_count() const = 0;
+  virtual std::unique_ptr<const Method> method(int i) const = 0;
+};
+
+struct Printer {
+  virtual ~Printer() {}
+
+  virtual void Print(const std::map<grpc::string, grpc::string> &vars,
+                     const char *template_string) = 0;
+  virtual void Print(const char *string) = 0;
+  virtual void Indent() = 0;
+  virtual void Outdent() = 0;
+};
+
+// An interface that allows the source generated to be output using various
+// libraries/idls/serializers.
+struct File : public CommentHolder {
+  virtual ~File() {}
+
+  virtual grpc::string filename() const = 0;
+  virtual grpc::string filename_without_ext() const = 0;
+  virtual grpc::string package() const = 0;
+  virtual std::vector<grpc::string> package_parts() const = 0;
+  virtual grpc::string additional_headers() const = 0;
+
+  virtual int service_count() const = 0;
+  virtual std::unique_ptr<const Service> service(int i) const = 0;
+
+  virtual std::unique_ptr<Printer> CreatePrinter(grpc::string *str) const = 0;
+};
+}  // namespace grpc_generator
+
+#endif  // GRPC_INTERNAL_COMPILER_SCHEMA_INTERFACE_H
