diff --git a/src/idl_gen_grpc.cpp b/src/idl_gen_grpc.cpp
new file mode 100644
index 0000000..1d5e8e5
--- /dev/null
+++ b/src/idl_gen_grpc.cpp
@@ -0,0 +1,371 @@
+/*
+ * Copyright 2014 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.
+ */
+
+// independent from idl_parser, since this code is not needed for most clients
+
+#include "flatbuffers/code_generators.h"
+#include "flatbuffers/flatbuffers.h"
+#include "flatbuffers/idl.h"
+#include "flatbuffers/util.h"
+
+#include "src/compiler/cpp_generator.h"
+#include "src/compiler/go_generator.h"
+#include "src/compiler/java_generator.h"
+
+#if defined(_MSC_VER)
+#  pragma warning(push)
+#  pragma warning(disable : 4512)  // C4512: 'class' : assignment operator could
+// not be generated
+#endif
+
+namespace flatbuffers {
+
+class FlatBufMethod : public grpc_generator::Method {
+ public:
+  enum Streaming {
+    kNone, kClient, kServer, kBiDi
+  };
+
+  FlatBufMethod(const RPCCall *method) : method_(method) {
+    streaming_ = kNone;
+    auto val = method_->attributes.Lookup("streaming");
+    if (val) {
+      if (val->constant == "client") streaming_ = kClient;
+      if (val->constant == "server") streaming_ = kServer;
+      if (val->constant == "bidi") streaming_ = kBiDi;
+    }
+  }
+
+  grpc::string GetLeadingComments(const grpc::string) const { return ""; }
+
+  grpc::string GetTrailingComments(const grpc::string) const { return ""; }
+
+  std::vector<grpc::string> GetAllComments() const {
+    return method_->doc_comment;
+  }
+
+  std::string name() const { return method_->name; }
+
+  std::string GRPCType(const StructDef &sd) const {
+    return "flatbuffers::grpc::Message<" + sd.name + ">";
+  }
+
+  std::string get_input_type_name() const { return (*method_->request).name; }
+
+  std::string get_output_type_name() const { return (*method_->response).name; }
+
+  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 {
+    return true;
+  }
+
+  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 {
+    return true;
+  }
+
+  std::string input_type_name() const { return GRPCType(*method_->request); }
+
+  std::string output_type_name() const { return GRPCType(*method_->response); }
+
+  bool NoStreaming() const { return streaming_ == kNone; }
+
+  bool ClientStreaming() const { return streaming_ == kClient; }
+
+  bool ServerStreaming() const { return streaming_ == kServer; }
+
+  bool BidiStreaming() const { return streaming_ == kBiDi; }
+
+ private:
+  const RPCCall *method_;
+  Streaming streaming_;
+};
+
+class FlatBufService : public grpc_generator::Service {
+ public:
+  FlatBufService(const ServiceDef *service) : service_(service) {}
+
+  grpc::string GetLeadingComments(const grpc::string) const { return ""; }
+
+  grpc::string GetTrailingComments(const grpc::string) const { return ""; }
+
+  std::vector<grpc::string> GetAllComments() const {
+    return service_->doc_comment;
+  }
+
+  std::string name() const { return service_->name; }
+
+  int method_count() const {
+    return static_cast<int>(service_->calls.vec.size());
+  }
+
+  std::unique_ptr<const grpc_generator::Method> method(int i) const {
+    return std::unique_ptr<const grpc_generator::Method>(
+        new FlatBufMethod(service_->calls.vec[i]));
+  }
+
+ private:
+  const ServiceDef *service_;
+};
+
+class FlatBufPrinter : public grpc_generator::Printer {
+ public:
+  FlatBufPrinter(std::string *str) : str_(str), escape_char_('$'), indent_(0) {}
+
+  void Print(const std::map<std::string, std::string> &vars,
+             const char *string_template) {
+    std::string s = string_template;
+    // Replace any occurrences of strings in "vars" that are surrounded
+    // by the escape character by what they're mapped to.
+    size_t pos;
+    while ((pos = s.find(escape_char_)) != std::string::npos) {
+      // Found an escape char, must also find the closing one.
+      size_t pos2 = s.find(escape_char_, pos + 1);
+      // If placeholder not closed, ignore.
+      if (pos2 == std::string::npos) break;
+      auto it = vars.find(s.substr(pos + 1, pos2 - pos - 1));
+      // If unknown placeholder, ignore.
+      if (it == vars.end()) break;
+      // Subtitute placeholder.
+      s.replace(pos, pos2 - pos + 1, it->second);
+    }
+    Print(s.c_str());
+  }
+
+  void Print(const char *s) {
+    if (s == nullptr || *s == '\0') { return; }
+    // Add this string, but for each part separated by \n, add indentation.
+    for (;;) {
+      // Current indentation.
+      str_->insert(str_->end(), indent_ * 2, ' ');
+      // See if this contains more than one line.
+      const char *lf = strchr(s, '\n');
+      if (lf) {
+        (*str_) += std::string(s, lf + 1);
+        s = lf + 1;
+        if (!*s) break;  // Only continue if there's more lines.
+      } else {
+        (*str_) += s;
+        break;
+      }
+    }
+  }
+
+  void Indent() { indent_++; }
+
+  void Outdent() {
+    indent_--;
+        FLATBUFFERS_ASSERT(indent_ >= 0);
+  }
+
+ private:
+  std::string *str_;
+  char escape_char_;
+  int indent_;
+};
+
+class FlatBufFile : public grpc_generator::File {
+ public:
+  enum Language {
+    kLanguageGo, kLanguageCpp, kLanguageJava
+  };
+
+  FlatBufFile(const Parser &parser, const std::string &file_name,
+              Language language)
+      : parser_(parser), file_name_(file_name), language_(language) {}
+
+  FlatBufFile &operator=(const FlatBufFile &);
+
+  grpc::string GetLeadingComments(const grpc::string) const { return ""; }
+
+  grpc::string GetTrailingComments(const grpc::string) const { return ""; }
+
+  std::vector<grpc::string> GetAllComments() const {
+    return std::vector<grpc::string>();
+  }
+
+  std::string filename() const { return file_name_; }
+
+  std::string filename_without_ext() const {
+    return StripExtension(file_name_);
+  }
+
+  std::string message_header_ext() const { return "_generated.h"; }
+
+  std::string service_header_ext() const { return ".grpc.fb.h"; }
+
+  std::string package() const {
+    return parser_.current_namespace_->GetFullyQualifiedName("");
+  }
+
+  std::vector<std::string> package_parts() const {
+    return parser_.current_namespace_->components;
+  }
+
+  std::string additional_headers() const {
+    switch (language_) {
+      case kLanguageCpp: {
+        return "#include \"flatbuffers/grpc.h\"\n";
+      }
+      case kLanguageGo: {
+        return "import \"github.com/google/flatbuffers/go\"";
+      }
+      case kLanguageJava: {
+        return "import com.google.flatbuffers.grpc.FlatbuffersUtils;";
+      }
+    }
+    return "";
+  }
+
+  int service_count() const {
+    return static_cast<int>(parser_.services_.vec.size());
+  }
+
+  std::unique_ptr<const grpc_generator::Service> service(int i) const {
+    return std::unique_ptr<const grpc_generator::Service>(
+        new FlatBufService(parser_.services_.vec[i]));
+  }
+
+  std::unique_ptr<grpc_generator::Printer> CreatePrinter(
+      std::string *str) const {
+    return std::unique_ptr<grpc_generator::Printer>(new FlatBufPrinter(str));
+  }
+
+ private:
+  const Parser &parser_;
+  const std::string &file_name_;
+  const Language language_;
+};
+
+class GoGRPCGenerator : public flatbuffers::BaseGenerator {
+ public:
+  GoGRPCGenerator(const Parser &parser, const std::string &path,
+                  const std::string &file_name)
+      : BaseGenerator(parser, path, file_name, "", "" /*Unused*/),
+        parser_(parser),
+        path_(path),
+        file_name_(file_name) {}
+
+  bool generate() {
+    FlatBufFile file(parser_, file_name_, FlatBufFile::kLanguageGo);
+    grpc_go_generator::Parameters p;
+    p.custom_method_io_type = "flatbuffers.Builder";
+    for (int i = 0; i < file.service_count(); i++) {
+      auto service = file.service(i);
+      const Definition *def = parser_.services_.vec[i];
+      p.package_name = LastNamespacePart(*(def->defined_namespace));
+      p.service_prefix = def->defined_namespace->GetFullyQualifiedName(""); // file.package();
+      std::string output =
+          grpc_go_generator::GenerateServiceSource(&file, service.get(), &p);
+      std::string filename =
+          NamespaceDir(*def->defined_namespace) + def->name + "_grpc.go";
+      if (!flatbuffers::SaveFile(filename.c_str(), output, false)) return false;
+    }
+    return true;
+  }
+
+ protected:
+  const Parser &parser_;
+  const std::string &path_, &file_name_;
+};
+
+bool GenerateGoGRPC(const Parser &parser, const std::string &path,
+                    const std::string &file_name) {
+  int nservices = 0;
+  for (auto it = parser.services_.vec.begin(); it != parser.services_.vec.end();
+       ++it) {
+    if (!(*it)->generated) nservices++;
+  }
+  if (!nservices) return true;
+  return GoGRPCGenerator(parser, path, file_name).generate();
+}
+
+bool GenerateCppGRPC(const Parser &parser, const std::string &path,
+                     const std::string &file_name) {
+  int nservices = 0;
+  for (auto it = parser.services_.vec.begin(); it != parser.services_.vec.end();
+       ++it) {
+    if (!(*it)->generated) nservices++;
+  }
+  if (!nservices) return true;
+
+  grpc_cpp_generator::Parameters generator_parameters;
+  // TODO(wvo): make the other parameters in this struct configurable.
+  generator_parameters.use_system_headers = true;
+
+  FlatBufFile fbfile(parser, file_name, FlatBufFile::kLanguageCpp);
+
+  std::string header_code =
+      grpc_cpp_generator::GetHeaderPrologue(&fbfile, generator_parameters) +
+          grpc_cpp_generator::GetHeaderIncludes(&fbfile, generator_parameters) +
+          grpc_cpp_generator::GetHeaderServices(&fbfile, generator_parameters) +
+          grpc_cpp_generator::GetHeaderEpilogue(&fbfile, generator_parameters);
+
+  std::string source_code =
+      grpc_cpp_generator::GetSourcePrologue(&fbfile, generator_parameters) +
+          grpc_cpp_generator::GetSourceIncludes(&fbfile, generator_parameters) +
+          grpc_cpp_generator::GetSourceServices(&fbfile, generator_parameters) +
+          grpc_cpp_generator::GetSourceEpilogue(&fbfile, generator_parameters);
+
+  return flatbuffers::SaveFile((path + file_name + ".grpc.fb.h").c_str(),
+                               header_code, false) &&
+      flatbuffers::SaveFile((path + file_name + ".grpc.fb.cc").c_str(),
+                            source_code, false);
+}
+
+class JavaGRPCGenerator : public flatbuffers::BaseGenerator {
+ public:
+  JavaGRPCGenerator(const Parser &parser, const std::string &path,
+                    const std::string &file_name)
+      : BaseGenerator(parser, path, file_name, "", "." /*separator*/) {}
+
+  bool generate() {
+    FlatBufFile file(parser_, file_name_, FlatBufFile::kLanguageJava);
+    grpc_java_generator::Parameters p;
+    for (int i = 0; i < file.service_count(); i++) {
+      auto service = file.service(i);
+      const Definition *def = parser_.services_.vec[i];
+      p.package_name =
+          def->defined_namespace->GetFullyQualifiedName("");  // file.package();
+      std::string output =
+          grpc_java_generator::GenerateServiceSource(&file, service.get(), &p);
+      std::string filename =
+          NamespaceDir(*def->defined_namespace) + def->name + "Grpc.java";
+      if (!flatbuffers::SaveFile(filename.c_str(), output, false)) return false;
+    }
+    return true;
+  }
+};
+
+bool GenerateJavaGRPC(const Parser &parser, const std::string &path,
+                      const std::string &file_name) {
+  int nservices = 0;
+  for (auto it = parser.services_.vec.begin(); it != parser.services_.vec.end();
+       ++it) {
+    if (!(*it)->generated) nservices++;
+  }
+  if (!nservices) return true;
+  return JavaGRPCGenerator(parser, path, file_name).generate();
+}
+
+}  // namespace flatbuffers
+
+#if defined(_MSC_VER)
+#  pragma warning(pop)
+#endif
