Commit 8518b3fb authored by Yuri Finkelstein's avatar Yuri Finkelstein Committed by Wouter van Oortmerssen

grpc bindings generator for Java and a few minor supporting changes i… (#4553)

* grpc bindings generator for Java and a few minor supporting changes in improvements

* restored formatting before my previous changes for ease of review

* Fixed grpc java code generation bug resulting in duplicate extractor declarations in case the same is used in more than a single RPC method
parent 61f4a46c
...@@ -60,6 +60,8 @@ set(FlatBuffers_Compiler_SRCS ...@@ -60,6 +60,8 @@ set(FlatBuffers_Compiler_SRCS
grpc/src/compiler/cpp_generator.cc grpc/src/compiler/cpp_generator.cc
grpc/src/compiler/go_generator.h grpc/src/compiler/go_generator.h
grpc/src/compiler/go_generator.cc grpc/src/compiler/go_generator.cc
grpc/src/compiler/java_generator.h
grpc/src/compiler/java_generator.cc
) )
set(FlatHash_SRCS set(FlatHash_SRCS
......
This diff is collapsed.
/*
* 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)
using namespace std;
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_
...@@ -346,6 +346,7 @@ struct RPCCall { ...@@ -346,6 +346,7 @@ struct RPCCall {
std::string name; std::string name;
SymbolTable<Value> attributes; SymbolTable<Value> attributes;
StructDef *request, *response; StructDef *request, *response;
std::vector<std::string> rpc_comment;
}; };
struct ServiceDef : public Definition { struct ServiceDef : public Definition {
...@@ -844,6 +845,12 @@ bool GenerateGoGRPC(const Parser &parser, ...@@ -844,6 +845,12 @@ bool GenerateGoGRPC(const Parser &parser,
const std::string &path, const std::string &path,
const std::string &file_name); const std::string &file_name);
// Generate GRPC Java classes.
// See idl_gen_grpc.cpp
bool GenerateJavaGRPC(const Parser &parser,
const std::string &path,
const std::string &file_name);
} // namespace flatbuffers } // namespace flatbuffers
#endif // FLATBUFFERS_IDL_H_ #endif // FLATBUFFERS_IDL_H_
...@@ -18,7 +18,8 @@ ...@@ -18,7 +18,8 @@
#include <list> #include <list>
#define FLATC_VERSION "1.8.0 (" __DATE__ ")" #define FLATC_VERSION "1.8.0 (" __DATE__ " " __TIME__ ")"
namespace flatbuffers { namespace flatbuffers {
......
...@@ -67,7 +67,7 @@ int main(int argc, const char *argv[]) { ...@@ -67,7 +67,7 @@ int main(int argc, const char *argv[]) {
"Generate Go files for tables/structs", "Generate Go files for tables/structs",
flatbuffers::GeneralMakeRule }, flatbuffers::GeneralMakeRule },
{ flatbuffers::GenerateGeneral, "-j", "--java", "Java", true, { flatbuffers::GenerateGeneral, "-j", "--java", "Java", true,
nullptr, flatbuffers::GenerateJavaGRPC,
flatbuffers::IDLOptions::kJava, flatbuffers::IDLOptions::kJava,
"Generate Java classes for tables/structs", "Generate Java classes for tables/structs",
flatbuffers::GeneralMakeRule }, flatbuffers::GeneralMakeRule },
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include "src/compiler/cpp_generator.h" #include "src/compiler/cpp_generator.h"
#include "src/compiler/go_generator.h" #include "src/compiler/go_generator.h"
#include "src/compiler/java_generator.h"
#if defined(_MSC_VER) #if defined(_MSC_VER)
#pragma warning(push) #pragma warning(push)
...@@ -53,7 +54,7 @@ class FlatBufMethod : public grpc_generator::Method { ...@@ -53,7 +54,7 @@ class FlatBufMethod : public grpc_generator::Method {
return ""; return "";
} }
std::vector<grpc::string> GetAllComments() const { std::vector<grpc::string> GetAllComments() const {
return std::vector<grpc::string>(); return method_->rpc_comment;
} }
std::string name() const { return method_->name; } std::string name() const { return method_->name; }
...@@ -110,7 +111,7 @@ class FlatBufService : public grpc_generator::Service { ...@@ -110,7 +111,7 @@ class FlatBufService : public grpc_generator::Service {
return ""; return "";
} }
std::vector<grpc::string> GetAllComments() const { std::vector<grpc::string> GetAllComments() const {
return std::vector<grpc::string>(); return service_->doc_comment;
} }
std::string name() const { return service_->name; } std::string name() const { return service_->name; }
...@@ -187,7 +188,8 @@ class FlatBufFile : public grpc_generator::File { ...@@ -187,7 +188,8 @@ class FlatBufFile : public grpc_generator::File {
public: public:
enum Language { enum Language {
kLanguageGo, kLanguageGo,
kLanguageCpp kLanguageCpp,
kLanguageJava
}; };
FlatBufFile( FlatBufFile(
...@@ -229,6 +231,9 @@ class FlatBufFile : public grpc_generator::File { ...@@ -229,6 +231,9 @@ class FlatBufFile : public grpc_generator::File {
case kLanguageGo: { case kLanguageGo: {
return "import \"github.com/google/flatbuffers/go\""; return "import \"github.com/google/flatbuffers/go\"";
} }
case kLanguageJava: {
return "import com.google.flatbuffers.grpc.FlatbuffersUtils;";
}
} }
return ""; return "";
} }
...@@ -328,9 +333,50 @@ bool GenerateCppGRPC(const Parser &parser, ...@@ -328,9 +333,50 @@ bool GenerateCppGRPC(const Parser &parser,
source_code, false); 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*/),
parser_(parser),
path_(path),
file_name_(file_name) {}
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;
}
protected:
const Parser& parser_;
const std::string &path_, &file_name_;
};
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 } // namespace flatbuffers
#if defined(_MSC_VER) #if defined(_MSC_VER)
#pragma warning(pop) #pragma warning(pop)
#endif #endif
...@@ -1645,6 +1645,7 @@ CheckedError Parser::ParseService() { ...@@ -1645,6 +1645,7 @@ CheckedError Parser::ParseService() {
ECHECK(ParseMetaData(&service_def.attributes)); ECHECK(ParseMetaData(&service_def.attributes));
EXPECT('{'); EXPECT('{');
do { do {
std::vector<std::string> rpc_comment = doc_comment_;
auto rpc_name = attribute_; auto rpc_name = attribute_;
EXPECT(kTokenIdentifier); EXPECT(kTokenIdentifier);
EXPECT('('); EXPECT('(');
...@@ -1660,6 +1661,7 @@ CheckedError Parser::ParseService() { ...@@ -1660,6 +1661,7 @@ CheckedError Parser::ParseService() {
rpc.name = rpc_name; rpc.name = rpc_name;
rpc.request = reqtype.struct_def; rpc.request = reqtype.struct_def;
rpc.response = resptype.struct_def; rpc.response = resptype.struct_def;
rpc.rpc_comment = rpc_comment;
if (service_def.calls.Add(rpc_name, &rpc)) if (service_def.calls.Add(rpc_name, &rpc))
return Error("rpc already exists: " + rpc_name); return Error("rpc already exists: " + rpc_name);
ECHECK(ParseMetaData(&rpc.attributes)); ECHECK(ParseMetaData(&rpc.attributes));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment