Support for Golang GRPC (Experimental) (#4082)

* support for grpc golang

* refactored grpc go generator

* added grpc-go test and refactored

* refactored idl_gen_grpc.cpp

* fixed grpc generate method name

* refactored flatc and fixed line length issue

* added codec to go lib and fixed formatting issues

* fixed spacing issues
This commit is contained in:
Ronak Jain
2016-12-06 02:50:38 +05:30
committed by Wouter van Oortmerssen
parent bc2ec7119b
commit a31ddd2bb3
10 changed files with 819 additions and 11 deletions

View File

@@ -33,6 +33,9 @@ struct Generator {
const char *generator_opt_short;
const char *generator_opt_long;
const char *lang_name;
bool (*generateGRPC)(const flatbuffers::Parser &parser,
const std::string &path,
const std::string &file_name);
flatbuffers::IDLOptions::Language lang;
const char *generator_help;
@@ -43,45 +46,50 @@ struct Generator {
const Generator generators[] = {
{ flatbuffers::GenerateBinary, "-b", "--binary", "binary",
nullptr,
flatbuffers::IDLOptions::kMAX,
"Generate wire format binaries for any data definitions",
flatbuffers::BinaryMakeRule },
{ flatbuffers::GenerateTextFile, "-t", "--json", "text",
nullptr,
flatbuffers::IDLOptions::kMAX,
"Generate text output for any data definitions",
flatbuffers::TextMakeRule },
{ flatbuffers::GenerateCPP, "-c", "--cpp", "C++",
flatbuffers::GenerateCppGRPC,
flatbuffers::IDLOptions::kMAX,
"Generate C++ headers for tables/structs",
flatbuffers::CPPMakeRule },
{ flatbuffers::GenerateGo, "-g", "--go", "Go",
flatbuffers::GenerateGoGRPC,
flatbuffers::IDLOptions::kGo,
"Generate Go files for tables/structs",
flatbuffers::GeneralMakeRule },
{ flatbuffers::GenerateGeneral, "-j", "--java", "Java",
nullptr,
flatbuffers::IDLOptions::kJava,
"Generate Java classes for tables/structs",
flatbuffers::GeneralMakeRule },
{ flatbuffers::GenerateJS, "-s", "--js", "JavaScript",
nullptr,
flatbuffers::IDLOptions::kMAX,
"Generate JavaScript code for tables/structs",
flatbuffers::JSMakeRule },
{ flatbuffers::GenerateGeneral, "-n", "--csharp", "C#",
nullptr,
flatbuffers::IDLOptions::kCSharp,
"Generate C# classes for tables/structs",
flatbuffers::GeneralMakeRule },
{ flatbuffers::GeneratePython, "-p", "--python", "Python",
nullptr,
flatbuffers::IDLOptions::kMAX,
"Generate Python files for tables/structs",
flatbuffers::GeneralMakeRule },
{ flatbuffers::GeneratePhp, nullptr, "--php", "PHP",
nullptr,
flatbuffers::IDLOptions::kMAX,
"Generate PHP files for tables/structs",
flatbuffers::GeneralMakeRule },
{ flatbuffers::GenerateGRPC, nullptr, "--grpc", "GRPC",
flatbuffers::IDLOptions::kMAX,
"Generate GRPC interfaces",
flatbuffers::CPPMakeRule },
};
const char *g_program_name = nullptr;
@@ -170,6 +178,7 @@ int main(int argc, const char *argv[]) {
bool print_make_rules = false;
bool raw_binary = false;
bool schema_binary = false;
bool grpc_enabled = false;
std::vector<std::string> filenames;
std::vector<const char *> include_directories;
std::vector<const char *> conform_include_directories;
@@ -243,6 +252,8 @@ int main(int argc, const char *argv[]) {
} else if(arg == "--version") {
printf("flatc version %s\n", FLATC_VERSION);
exit(0);
} else if(arg == "--grpc") {
grpc_enabled = true;
} else {
for (size_t i = 0; i < num_generators; ++i) {
if (arg == generators[i].generator_opt_long ||
@@ -360,6 +371,17 @@ int main(int argc, const char *argv[]) {
printf("%s\n", flatbuffers::WordWrap(
make_rule, 80, " ", " \\").c_str());
}
if (grpc_enabled) {
if (generators[i].generateGRPC != nullptr) {
if (!generators[i].generateGRPC(*g_parser, output_path, filebase)) {
Error(std::string("Unable to generate GRPC interface for") +
generators[i].lang_name);
}
} else {
Error(std::string("GRPC interface generator not implemented for ") +
generators[i].lang_name);
}
}
}
}

View File

@@ -19,8 +19,10 @@
#include "flatbuffers/flatbuffers.h"
#include "flatbuffers/idl.h"
#include "flatbuffers/util.h"
#include "flatbuffers/code_generators.h"
#include "src/compiler/cpp_generator.h"
#include "src/compiler/go_generator.h"
namespace flatbuffers {
@@ -52,6 +54,14 @@ class FlatBufMethod : public grpc_generator::Method {
return GRPCType(*method_->response);
}
std::string input_name() const {
return (*method_->request).name;
}
std::string output_name() const {
return (*method_->response).name;
}
bool NoStreaming() const { return streaming_ == kNone; }
bool ClientOnlyStreaming() const { return streaming_ == kClient; }
bool ServerOnlyStreaming() const { return streaming_ == kServer; }
@@ -159,6 +169,10 @@ class FlatBufFile : public grpc_generator::File {
return "#include \"flatbuffers/grpc.h\"\n";
}
std::string additional_imports() const {
return "import \"github.com/google/flatbuffers/go\"";
}
int service_count() const {
return static_cast<int>(parser_.services_.vec.size());
};
@@ -178,7 +192,47 @@ class FlatBufFile : public grpc_generator::File {
const std::string &file_name_;
};
bool GenerateGRPC(const Parser &parser,
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_);
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));
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) {