First pass at making the compilers open-sourcable.

Change on 2014/12/10 by nnoble <nnoble@google.com>
-------------
Created by MOE: http://code.google.com/p/moe-java
MOE_MIGRATED_REVID=81829127
pull/1/merge
nnoble 10 years ago committed by Jan Tattermusch
parent 0005b778ee
commit ebebb7e21c
  1. 58
      Makefile
  2. 30
      build.json
  3. 451
      src/compiler/cpp_generator.cc
  4. 63
      src/compiler/cpp_generator.h
  5. 106
      src/compiler/cpp_generator_helpers.h
  6. 94
      src/compiler/cpp_plugin.cc
  7. 172
      src/compiler/ruby_generator.cc
  8. 49
      src/compiler/ruby_generator.h
  9. 65
      src/compiler/ruby_generator_helpers-inl.h
  10. 71
      src/compiler/ruby_generator_map-inl.h
  11. 116
      src/compiler/ruby_generator_string-inl.h
  12. 76
      src/compiler/ruby_plugin.cc
  13. 8
      templates/Makefile.template

File diff suppressed because one or more lines are too long

@ -360,6 +360,36 @@
"grpc"
]
},
{
"name": "cpp_plugin",
"build": "protoc",
"src": [
"src/compiler/cpp_plugin.cpp",
"src/compiler/cpp_generator.cpp"
],
"headers": [
"src/compiler/cpp_generator.h",
"src/compiler/cpp_generator_helpers.h"
],
"deps": []
},
{
"name": "ruby_plugin",
"build": "protoc",
"src": [
"src/compiler/ruby_plugin.cpp",
"src/compiler/ruby_generator.cpp"
],
"headers": [
"src/compiler/cpp_generator.h",
"src/compiler/cpp_generator_helpers-inl.h",
"src/compiler/cpp_generator_map-inl.h",
"src/compiler/cpp_generator_string-inl.h"
],
"deps": []
},
{
"name": "grpc_byte_buffer_reader_test",
"build": "test",

@ -0,0 +1,451 @@
/*
*
* Copyright 2014, 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 "src/compiler/cpp_generator.h"
#include "src/compiler/cpp_generator_helpers.h"
#include <google/protobuf/descriptor.h>
#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/io/printer.h>
#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
namespace grpc_cpp_generator {
namespace {
bool NoStreaming(const google::protobuf::MethodDescriptor* method) {
return !method->options().has_client_streaming() &&
!method->options().has_server_streaming();
}
bool ClientOnlyStreaming(const google::protobuf::MethodDescriptor* method) {
return method->options().has_client_streaming() &&
!method->options().has_server_streaming();
}
bool ServerOnlyStreaming(const google::protobuf::MethodDescriptor* method) {
return !method->options().has_client_streaming() &&
method->options().has_server_streaming();
}
bool BidiStreaming(const google::protobuf::MethodDescriptor* method) {
return method->options().has_client_streaming() &&
method->options().has_server_streaming();
}
bool HasClientOnlyStreaming(const google::protobuf::FileDescriptor* file) {
for (int i = 0; i < file->service_count(); i++) {
for (int j = 0; j < file->service(i)->method_count(); j++) {
if (ClientOnlyStreaming(file->service(i)->method(j))) {
return true;
}
}
}
return false;
}
bool HasServerOnlyStreaming(const google::protobuf::FileDescriptor* file) {
for (int i = 0; i < file->service_count(); i++) {
for (int j = 0; j < file->service(i)->method_count(); j++) {
if (ServerOnlyStreaming(file->service(i)->method(j))) {
return true;
}
}
}
return false;
}
bool HasBidiStreaming(const google::protobuf::FileDescriptor* file) {
for (int i = 0; i < file->service_count(); i++) {
for (int j = 0; j < file->service(i)->method_count(); j++) {
if (BidiStreaming(file->service(i)->method(j))) {
return true;
}
}
}
return false;
}
} // namespace
string GetHeaderIncludes(const google::protobuf::FileDescriptor* file) {
string temp =
"#include \"net/grpc/cpp/internal/client/internal_stub.h\"\n"
"#include \"net/grpc/cpp/public/status.h\"\n"
"\n"
"namespace grpc {\n"
"class ChannelInterface;\n"
"class RpcService;\n";
if (HasClientOnlyStreaming(file)) {
temp.append("template <class OutMessage> class ClientWriter;\n");
temp.append("template <class InMessage> class ServerReader;\n");
}
if (HasServerOnlyStreaming(file)) {
temp.append("template <class InMessage> class ClientReader;\n");
temp.append("template <class OutMessage> class ServerWriter;\n");
}
if (HasBidiStreaming(file)) {
temp.append(
"template <class OutMessage, class InMessage>\n"
"class ClientReaderWriter;\n");
temp.append(
"template <class OutMessage, class InMessage>\n"
"class ServerReaderWriter;\n");
}
temp.append("} // namespace grpc\n");
return temp;
}
string GetSourceIncludes() {
return "#include \"net/grpc/cpp/internal/rpc_method.h\"\n"
"#include \"net/grpc/cpp/internal/server/rpc_service_method.h\"\n"
"#include \"net/grpc/cpp/public/channel_interface.h\"\n"
"#include \"net/grpc/cpp/public/stream.h\"\n";
}
void PrintHeaderClientMethod(google::protobuf::io::Printer* printer,
const google::protobuf::MethodDescriptor* method,
map<string, string>* vars) {
(*vars)["Method"] = method->name();
(*vars)["Request"] =
grpc_cpp_generator::ClassName(method->input_type(), true);
(*vars)["Response"] =
grpc_cpp_generator::ClassName(method->output_type(), true);
if (NoStreaming(method)) {
printer->Print(*vars,
"::grpc::Status $Method$(::grpc::ClientContext* context, "
"const $Request$& request, $Response$* response);\n\n");
} else if (ClientOnlyStreaming(method)) {
printer->Print(
*vars,
"::grpc::ClientWriter<$Request$>* $Method$("
"::grpc::ClientContext* context, $Response$* response);\n\n");
} else if (ServerOnlyStreaming(method)) {
printer->Print(
*vars,
"::grpc::ClientReader<$Response$>* $Method$("
"::grpc::ClientContext* context, const $Request$* request);\n\n");
} else if (BidiStreaming(method)) {
printer->Print(*vars,
"::grpc::ClientReaderWriter<$Request$, $Response$>* "
"$Method$(::grpc::ClientContext* context);\n\n");
}
}
void PrintHeaderServerMethod(google::protobuf::io::Printer* printer,
const google::protobuf::MethodDescriptor* method,
map<string, string>* vars) {
(*vars)["Method"] = method->name();
(*vars)["Request"] =
grpc_cpp_generator::ClassName(method->input_type(), true);
(*vars)["Response"] =
grpc_cpp_generator::ClassName(method->output_type(), true);
if (NoStreaming(method)) {
printer->Print(*vars,
"virtual ::grpc::Status $Method$(const $Request$* request, "
"$Response$* response);\n");
} else if (ClientOnlyStreaming(method)) {
printer->Print(*vars,
"virtual ::grpc::Status $Method$("
"::grpc::ServerReader<$Request$>* reader, "
"$Response$* response);\n");
} else if (ServerOnlyStreaming(method)) {
printer->Print(*vars,
"virtual ::grpc::Status $Method$(const $Request$* request, "
"::grpc::ServerWriter<$Response$>* writer);\n");
} else if (BidiStreaming(method)) {
printer->Print(*vars,
"virtual ::grpc::Status $Method$("
"::grpc::ServerReaderWriter<$Response$, $Request$>* stream);"
"\n");
}
}
void PrintHeaderService(google::protobuf::io::Printer* printer,
const google::protobuf::ServiceDescriptor* service,
map<string, string>* vars) {
(*vars)["Service"] = service->name();
printer->Print(*vars,
"class $Service$ {\n"
" public:\n");
printer->Indent();
// Client side
printer->Print("class Stub : public ::grpc::InternalStub {\n"
" public:\n");
printer->Indent();
for (int i = 0; i < service->method_count(); ++i) {
PrintHeaderClientMethod(printer, service->method(i), vars);
}
printer->Outdent();
printer->Print("};\n");
printer->Print(
"static Stub* NewStub(const std::shared_ptr<::grpc::ChannelInterface>& "
"channel);\n");
printer->Print("\n");
// Server side
printer->Print("class Service {\n"
" public:\n");
printer->Indent();
printer->Print("Service() : service_(nullptr) {}\n");
printer->Print("virtual ~Service();\n");
for (int i = 0; i < service->method_count(); ++i) {
PrintHeaderServerMethod(printer, service->method(i), vars);
}
printer->Print("::grpc::RpcService* service();\n");
printer->Outdent();
printer->Print(" private:\n"
" ::grpc::RpcService* service_;\n");
printer->Print("};\n");
printer->Outdent();
printer->Print("};\n");
}
string GetHeaderServices(const google::protobuf::FileDescriptor* file) {
string output;
google::protobuf::io::StringOutputStream output_stream(&output);
google::protobuf::io::Printer printer(&output_stream, '$');
map<string, string> vars;
for (int i = 0; i < file->service_count(); ++i) {
PrintHeaderService(&printer, file->service(0), &vars);
printer.Print("\n");
}
return output;
}
void PrintSourceClientMethod(google::protobuf::io::Printer* printer,
const google::protobuf::MethodDescriptor* method,
map<string, string>* vars) {
(*vars)["Method"] = method->name();
(*vars)["Request"] =
grpc_cpp_generator::ClassName(method->input_type(), true);
(*vars)["Response"] =
grpc_cpp_generator::ClassName(method->output_type(), true);
if (NoStreaming(method)) {
printer->Print(*vars,
"::grpc::Status $Service$::Stub::$Method$("
"::grpc::ClientContext* context, "
"const $Request$& request, $Response$* response) {\n");
printer->Print(*vars,
" return channel()->StartBlockingRpc("
"::grpc::RpcMethod(\"/$Service$/$Method$\"), "
"context, request, response);\n"
"}\n\n");
} else if (ClientOnlyStreaming(method)) {
printer->Print(*vars,
"::grpc::ClientWriter<$Request$>* $Service$::Stub::$Method$("
"::grpc::ClientContext* context, $Response$* response) {\n");
printer->Print(
*vars,
" return new ::grpc::ClientWriter<$Request$>("
"channel()->CreateStream(::grpc::RpcMethod(\"/$Service$/$Method$\", "
"::grpc::RpcMethod::RpcType::CLIENT_STREAMING), "
"context, nullptr, response));\n"
"}\n\n");
} else if (ServerOnlyStreaming(method)) {
printer->Print(
*vars,
"::grpc::ClientReader<$Response$>* $Service$::Stub::$Method$("
"::grpc::ClientContext* context, const $Request$* request) {\n");
printer->Print(
*vars,
" return new ::grpc::ClientReader<$Response$>("
"channel()->CreateStream(::grpc::RpcMethod(\"/$Service$/$Method$\", "
"::grpc::RpcMethod::RpcType::SERVER_STREAMING), "
"context, request, nullptr));\n"
"}\n\n");
} else if (BidiStreaming(method)) {
printer->Print(
*vars,
"::grpc::ClientReaderWriter<$Request$, $Response$>* "
"$Service$::Stub::$Method$(::grpc::ClientContext* context) {\n");
printer->Print(
*vars,
" return new ::grpc::ClientReaderWriter<$Request$, $Response$>("
"channel()->CreateStream(::grpc::RpcMethod(\"/$Service$/$Method$\", "
"::grpc::RpcMethod::RpcType::BIDI_STREAMING), "
"context, nullptr, nullptr));\n"
"}\n\n");
}
}
void PrintSourceServerMethod(google::protobuf::io::Printer* printer,
const google::protobuf::MethodDescriptor* method,
map<string, string>* vars) {
(*vars)["Method"] = method->name();
(*vars)["Request"] =
grpc_cpp_generator::ClassName(method->input_type(), true);
(*vars)["Response"] =
grpc_cpp_generator::ClassName(method->output_type(), true);
if (NoStreaming(method)) {
printer->Print(*vars,
"::grpc::Status $Service$::Service::$Method$("
"const $Request$* request, $Response$* response) {\n");
printer->Print(
" return ::grpc::Status("
"::grpc::StatusCode::UNIMPLEMENTED);\n");
printer->Print("}\n\n");
} else if (ClientOnlyStreaming(method)) {
printer->Print(*vars,
"::grpc::Status $Service$::Service::$Method$("
"::grpc::ServerReader<$Request$>* reader, "
"$Response$* response) {\n");
printer->Print(
" return ::grpc::Status("
"::grpc::StatusCode::UNIMPLEMENTED);\n");
printer->Print("}\n\n");
} else if (ServerOnlyStreaming(method)) {
printer->Print(*vars,
"::grpc::Status $Service$::Service::$Method$("
"const $Request$* request, "
"::grpc::ServerWriter<$Response$>* writer) {\n");
printer->Print(
" return ::grpc::Status("
"::grpc::StatusCode::UNIMPLEMENTED);\n");
printer->Print("}\n\n");
} else if (BidiStreaming(method)) {
printer->Print(*vars,
"::grpc::Status $Service$::Service::$Method$("
"::grpc::ServerReaderWriter<$Response$, $Request$>* "
"stream) {\n");
printer->Print(
" return ::grpc::Status("
"::grpc::StatusCode::UNIMPLEMENTED);\n");
printer->Print("}\n\n");
}
}
void PrintSourceService(google::protobuf::io::Printer* printer,
const google::protobuf::ServiceDescriptor* service,
map<string, string>* vars) {
(*vars)["Service"] = service->name();
printer->Print(*vars,
"$Service$::Stub* $Service$::NewStub("
"const std::shared_ptr<::grpc::ChannelInterface>& channel) {\n"
" $Service$::Stub* stub = new $Service$::Stub();\n"
" stub->set_channel(channel);\n"
" return stub;\n"
"};\n\n");
for (int i = 0; i < service->method_count(); ++i) {
PrintSourceClientMethod(printer, service->method(i), vars);
}
printer->Print(*vars,
"$Service$::Service::~Service() {\n"
" delete service_;\n"
"}\n\n");
for (int i = 0; i < service->method_count(); ++i) {
PrintSourceServerMethod(printer, service->method(i), vars);
}
printer->Print(*vars,
"::grpc::RpcService* $Service$::Service::service() {\n");
printer->Indent();
printer->Print("if (service_ != nullptr) {\n"
" return service_;\n"
"}\n");
printer->Print("service_ = new ::grpc::RpcService();\n");
for (int i = 0; i < service->method_count(); ++i) {
const google::protobuf::MethodDescriptor* method = service->method(i);
(*vars)["Method"] = method->name();
(*vars)["Request"] =
grpc_cpp_generator::ClassName(method->input_type(), true);
(*vars)["Response"] =
grpc_cpp_generator::ClassName(method->output_type(), true);
if (NoStreaming(method)) {
printer->Print(
*vars,
"service_->AddMethod(new ::grpc::RpcServiceMethod(\n"
" \"/$Service$/$Method$\", ::grpc::RpcMethod::NORMAL_RPC,\n"
" new ::grpc::RpcMethodHandler<$Service$::Service, $Request$, "
"$Response$>(\n"
" std::function<::grpc::Status($Service$::Service*, "
"const $Request$*, $Response$*)>("
"&$Service$::Service::$Method$), this),\n"
" new $Request$, new $Response$));\n");
} else if (ClientOnlyStreaming(method)) {
printer->Print(
*vars,
"service_->AddMethod(new ::grpc::RpcServiceMethod(\n"
" \"/$Service$/$Method$\", ::grpc::RpcMethod::CLIENT_STREAMING,\n"
" new ::grpc::ClientStreamingHandler<"
"$Service$::Service, $Request$, $Response$>(\n"
" std::function<::grpc::Status($Service$::Service*, "
"::grpc::ServerReader<$Request$>*, $Response$*)>("
"&$Service$::Service::$Method$), this),\n"
" new $Request$, new $Response$));\n");
} else if (ServerOnlyStreaming(method)) {
printer->Print(
*vars,
"service_->AddMethod(new ::grpc::RpcServiceMethod(\n"
" \"/$Service$/$Method$\", ::grpc::RpcMethod::SERVER_STREAMING,\n"
" new ::grpc::ServerStreamingHandler<"
"$Service$::Service, $Request$, $Response$>(\n"
" std::function<::grpc::Status($Service$::Service*, "
"const $Request$*, ::grpc::ServerWriter<$Response$>*)>("
"&$Service$::Service::$Method$), this),\n"
" new $Request$, new $Response$));\n");
} else if (BidiStreaming(method)) {
printer->Print(
*vars,
"service_->AddMethod(new ::grpc::RpcServiceMethod(\n"
" \"/$Service$/$Method$\", ::grpc::RpcMethod::BIDI_STREAMING,\n"
" new ::grpc::BidiStreamingHandler<"
"$Service$::Service, $Request$, $Response$>(\n"
" std::function<::grpc::Status($Service$::Service*, "
"::grpc::ServerReaderWriter<$Response$, $Request$>*)>("
"&$Service$::Service::$Method$), this),\n"
" new $Request$, new $Response$));\n");
}
}
printer->Print("return service_;\n");
printer->Outdent();
printer->Print("}\n\n");
}
string GetSourceServices(const google::protobuf::FileDescriptor* file) {
string output;
google::protobuf::io::StringOutputStream output_stream(&output);
google::protobuf::io::Printer printer(&output_stream, '$');
map<string, string> vars;
for (int i = 0; i < file->service_count(); ++i) {
PrintSourceService(&printer, file->service(0), &vars);
printer.Print("\n");
}
return output;
}
} // namespace grpc_cpp_generator

@ -0,0 +1,63 @@
/*
*
* Copyright 2014, 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 NET_GRPC_COMPILER_CPP_GENERATOR_H_
#define NET_GRPC_COMPILER_CPP_GENERATOR_H_
#include <string>
namespace google {
namespace protobuf {
class FileDescriptor;
} // namespace protobuf
} // namespace google
using namespace std;
namespace grpc_cpp_generator {
// Return the includes needed for generated header file.
string GetHeaderIncludes(const google::protobuf::FileDescriptor* file);
// Return the includes needed for generated source file.
string GetSourceIncludes();
// Return the services for generated header file.
string GetHeaderServices(const google::protobuf::FileDescriptor* file);
// Return the services for generated source file.
string GetSourceServices(const google::protobuf::FileDescriptor* file);
} // namespace grpc_cpp_generator
#endif // NET_GRPC_COMPILER_CPP_GENERATOR_H_

@ -0,0 +1,106 @@
/*
*
* Copyright 2014, 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 NET_GRPC_COMPILER_CPP_GENERATOR_HELPERS_H__
#define NET_GRPC_COMPILER_CPP_GENERATOR_HELPERS_H__
#include <map>
#include <string>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/descriptor.pb.h>
using namespace std;
namespace grpc_cpp_generator {
inline bool StripSuffix(string* filename, const string& suffix) {
if (filename->length() >= suffix.length()) {
size_t suffix_pos = filename->length() - suffix.length();
if (filename->compare(suffix_pos, string::npos, suffix) == 0) {
filename->resize(filename->size() - suffix.size());
return true;
}
}
return false;
}
inline string StripProto(string filename) {
if (!StripSuffix(&filename, ".protodevel")) {
StripSuffix(&filename, ".proto");
}
return filename;
}
inline string StringReplace(string str, const string& from, const string& to) {
size_t pos = 0;
for (;;) {
pos = str.find(from, pos);
if (pos == string::npos) {
break;
}
str.replace(pos, from.length(), to);
pos += to.length();
}
return str;
}
inline string DotsToColons(const string& name) {
return StringReplace(name, ".", "::");
}
inline string DotsToUnderscores(const string& name) {
return StringReplace(name, ".", "_");
}
inline string ClassName(const google::protobuf::Descriptor* descriptor, bool qualified) {
// Find "outer", the descriptor of the top-level message in which
// "descriptor" is embedded.
const google::protobuf::Descriptor* outer = descriptor;
while (outer->containing_type() != NULL) outer = outer->containing_type();
const string& outer_name = outer->full_name();
string inner_name = descriptor->full_name().substr(outer_name.size());
if (qualified) {
return "::" + DotsToColons(outer_name) + DotsToUnderscores(inner_name);
} else {
return outer->name() + DotsToUnderscores(inner_name);
}
}
} // namespace grpc_cpp_generator
#endif // NET_GRPC_COMPILER_CPP_GENERATOR_HELPERS_H__

@ -0,0 +1,94 @@
/*
*
* Copyright 2014, 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.
*
*/
// Generates cpp gRPC service interface out of Protobuf IDL.
//
#include <memory>
#include "src/compiler/cpp_generator.h"
#include "src/compiler/cpp_generator_helpers.h"
#include <google/protobuf/descriptor.h>
#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/compiler/code_generator.h>
#include <google/protobuf/compiler/plugin.h>
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/io/zero_copy_stream.h>
class CppGrpcGenerator : public google::protobuf::compiler::CodeGenerator {
public:
CppGrpcGenerator() {}
virtual ~CppGrpcGenerator() {}
virtual bool Generate(const google::protobuf::FileDescriptor* file,
const string& parameter,
google::protobuf::compiler::GeneratorContext* context,
string* error) const {
if (file->options().cc_generic_services()) {
*error = "cpp grpc proto compiler plugin does not work with generic "
"services. To generate cpp grpc APIs, please set \""
"cc_generic_service = false\".";
return false;
}
string file_name = grpc_cpp_generator::StripProto(file->name());
// Generate .pb.h
Insert(context, file_name + ".pb.h", "includes",
grpc_cpp_generator::GetHeaderIncludes(file));
Insert(context, file_name + ".pb.h", "namespace_scope",
grpc_cpp_generator::GetHeaderServices(file));
// Generate .pb.cc
Insert(context, file_name + ".pb.cc", "includes",
grpc_cpp_generator::GetSourceIncludes());
Insert(context, file_name + ".pb.cc", "namespace_scope",
grpc_cpp_generator::GetSourceServices(file));
return true;
}
private:
// Insert the given code into the given file at the given insertion point.
void Insert(google::protobuf::compiler::GeneratorContext* context,
const string& filename, const string& insertion_point,
const string& code) const {
std::unique_ptr<google::protobuf::io::ZeroCopyOutputStream> output(
context->OpenForInsert(filename, insertion_point));
google::protobuf::io::CodedOutputStream coded_out(output.get());
coded_out.WriteRaw(code.data(), code.size());
}
};
int main(int argc, char* argv[]) {
CppGrpcGenerator generator;
return google::protobuf::compiler::PluginMain(argc, argv, &generator);
}

@ -0,0 +1,172 @@
/*
*
* Copyright 2014, 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 <cctype>
#include <map>
#include <vector>
#include "src/compiler/ruby_generator.h"
#include "src/compiler/ruby_generator_helpers-inl.h"
#include "src/compiler/ruby_generator_map-inl.h"
#include "src/compiler/ruby_generator_string-inl.h"
#include <google/protobuf/io/printer.h>
#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/descriptor.h>
using google::protobuf::FileDescriptor;
using google::protobuf::ServiceDescriptor;
using google::protobuf::MethodDescriptor;
using google::protobuf::io::Printer;
using google::protobuf::io::StringOutputStream;
using std::map;
using std::vector;
namespace grpc_ruby_generator {
namespace {
// Prints out the method using the ruby gRPC DSL.
void PrintMethod(const MethodDescriptor* method, const string& package,
Printer* out) {
string input_type = RubyTypeOf(method->input_type()->name(), package);
if (method->options().has_client_streaming()) {
input_type = "stream(" + input_type + ")";
}
string output_type = RubyTypeOf(method->output_type()->name(), package);
if (method->options().has_server_streaming()) {
output_type = "stream(" + output_type + ")";
}
map<string, string> method_vars = ListToDict({
"mth.name", method->name(),
"input.type", input_type,
"output.type", output_type,
});
out->Print(method_vars, "rpc :$mth.name$, $input.type$, $output.type$\n");
}
// Prints out the service using the ruby gRPC DSL.
void PrintService(const ServiceDescriptor* service, const string& package,
Printer* out) {
if (service->method_count() == 0) {
return;
}
// Begin the service module
map<string, string> module_vars = ListToDict({
"module.name", CapitalizeString(service->name()),
});
out->Print(module_vars, "module $module.name$\n");
out->Indent();
// TODO(temiola): add documentation
string doc = "TODO: add proto service documentation here";
map<string, string> template_vars = ListToDict({
"Documentation", doc,
});
out->Print("\n");
out->Print(template_vars, "# $Documentation$\n");
out->Print("class Service\n");
// Write the indented class body.
out->Indent();
out->Print("\n");
out->Print("include GRPC::Generic::Service\n");
out->Print("\n");
out->Print("self.marshal_class_method = :encode\n");
out->Print("self.unmarshal_class_method = :decode\n");
out->Print("\n");
for (int i = 0; i < service->method_count(); ++i) {
PrintMethod(service->method(i), package, out);
}
out->Outdent();
out->Print("end\n");
out->Print("\n");
out->Print("Stub = Service.rpc_stub_class\n");
// End the service module
out->Outdent();
out->Print("end\n");
}
} // namespace
string GetServices(const FileDescriptor* file) {
string output;
StringOutputStream output_stream(&output);
Printer out(&output_stream, '$');
// Always write out a file header.
map<string, string> header_comment_vars = ListToDict({
"file.name", file->name(),
"file.package", file->package(),
});
out.Print(header_comment_vars,
"### Generated from $file.name$ for $file.package$\n");
if (file->service_count() == 0) {
return output;
}
out.Print("\n");
out.Print("require 'grpc'\n");
// Write out require statemment to import the separately generated file
// that defines the messages used by the service. This is generated by the
// main ruby plugin.
map<string, string> dep_vars = ListToDict({
"dep.name", MessagesRequireName(file),
});
out.Print(dep_vars, "require '$dep.name$'\n");
// Write out services within the modules
out.Print("\n");
vector<string> modules = Split(file->package(), '.');
for (size_t i = 0; i < modules.size(); ++i) {
map<string, string> module_vars = ListToDict({
"module.name", CapitalizeString(modules[i]),
});
out.Print(module_vars, "module $module.name$\n");
out.Indent();
}
for (int i = 0; i < file->service_count(); ++i) {
auto service = file->service(i);
PrintService(service, file->package(), &out);
}
for (size_t i = 0; i < modules.size(); ++i) {
out.Outdent();
out.Print("end\n");
}
return output;
}
} // namespace grpc_ruby_generator

@ -0,0 +1,49 @@
/*
*
* Copyright 2014, 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 NET_GRPC_COMPILER_RUBY_GENERATOR_H_
#define NET_GRPC_COMPILER_RUBY_GENERATOR_H_
#include <string>
namespace proto2 {
class FileDescriptor;
} // namespace proto2
namespace grpc_ruby_generator {
string GetServices(const google::protobuf::FileDescriptor* file);
} // namespace grpc_ruby_generator
#endif // NET_GRPC_COMPILER_RUBY_GENERATOR_H_

@ -0,0 +1,65 @@
/*
*
* Copyright 2014, 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 NET_GRPC_COMPILER_RUBY_GENERATOR_HELPERS_INL_H_
#define NET_GRPC_COMPILER_RUBY_GENERATOR_HELPERS_INL_H_
#include <string>
#include <google/protobuf/descriptor.h>
#include "src/compiler/ruby_generator_string-inl.h"
namespace grpc_ruby_generator {
inline bool ServicesFilename(const google::protobuf::FileDescriptor* file,
string* file_name_or_error) {
// Get output file name.
static const int proto_suffix_length = 6; // length of ".proto"
if (file->name().size() > proto_suffix_length &&
file->name().find_last_of(".proto") == file->name().size() - 1) {
*file_name_or_error = file->name().substr(
0, file->name().size() - proto_suffix_length) + "_services.rb";
return true;
} else {
*file_name_or_error = "Invalid proto file name: must end with .proto";
return false;
}
}
inline string MessagesRequireName(const google::protobuf::FileDescriptor* file) {
return Replace(file->name(), ".proto", "");
}
} // namespace grpc_ruby_generator
#endif // NET_GRPC_COMPILER_RUBY_GENERATOR_HELPERS_INL_H_

@ -0,0 +1,71 @@
/*
*
* Copyright 2014, 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 NET_GRPC_COMPILER_RUBY_GENERATOR_MAP_INL_H_
#define NET_GRPC_COMPILER_RUBY_GENERATOR_MAP_INL_H_
#include <initializer_list>
#include <map>
#include <ostream> // NOLINT
#include <string>
#include <vector>
#include "base/logging.h"
using std::initializer_list;
using std::map;
using std::vector;
namespace grpc_ruby_generator {
// Converts an initializer list of the form { key0, value0, key1, value1, ... }
// into a map of key* to value*. Is merely a readability helper for later code.
inline map<string, string> ListToDict(const initializer_list<string>& values) {
if (values.size() % 2 != 0) {
LOG(FATAL) << "Not every 'key' has a value in `values`.";
}
map<string, string> value_map;
auto value_iter = values.begin();
for (int i = 0; i < values.size()/2; ++i) {
string key = *value_iter;
++value_iter;
string value = *value_iter;
value_map[key] = value;
++value_iter;
}
return value_map;
}
} // namespace grpc_ruby_generator
#endif // NET_GRPC_COMPILER_RUBY_GENERATOR_MAP_INL_H_

@ -0,0 +1,116 @@
/*
*
* Copyright 2014, 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 NET_GRPC_COMPILER_RUBY_GENERATOR_STRING_INL_H_
#define NET_GRPC_COMPILER_RUBY_GENERATOR_STRING_INL_H_
#include <algorithm>
#include <string>
#include <sstream>
#include <vector>
using std::getline;
using std::transform;
namespace grpc_ruby_generator {
// Split splits a string using char into elems.
inline vector<string> &Split(const string &s, char delim,
vector<string>* elems) {
stringstream ss(s);
string item;
while (getline(ss, item, delim)) {
elems->push_back(item);
}
return *elems;
}
// Split splits a string using char, returning the result in a vector.
inline vector<string> Split(const string &s, char delim) {
vector<string> elems;
Split(s, delim, &elems);
return elems;
}
// Replace replaces from with to in s.
inline string Replace(string s, const string& from, const string& to) {
size_t start_pos = s.find(from);
if (start_pos == string::npos) {
return s;
}
s.replace(start_pos, from.length(), to);
return s;
}
// ReplaceAll replaces all instances of search with replace in s.
inline string ReplaceAll(string s, const string& search,
const string& replace) {
size_t pos = 0;
while ((pos = s.find(search, pos)) != string::npos) {
s.replace(pos, search.length(), replace);
pos += replace.length();
}
return s;
}
// ReplacePrefix replaces from with to in s if search is a prefix of s.
inline bool ReplacePrefix(string* s, const string& from, const string& to) {
size_t start_pos = s->find(from);
if (start_pos == string::npos || start_pos != 0) {
return false;
}
s->replace(start_pos, from.length(), to);
return true;
}
// RubyTypeOf updates a proto type to the required ruby equivalent.
inline string RubyTypeOf(const string& a_type, const string& package) {
string res(a_type);
ReplacePrefix(&res, package, ""); // remove the leading package if present
ReplacePrefix(&res, ".", ""); // remove the leading . (no package)
return ReplaceAll(res, ".", "::"); // switch '.' to the ruby module delimiter
}
// CapitalizeString capitalizes a string.
inline string CapitalizeString(string s) {
if (!s.empty()) {
return s;
}
transform(s.begin(), s.end(), s.begin(), ::tolower);
s[0] = ::toupper(s[0]);
return s;
}
} // namespace grpc_ruby_generator
#endif // NET_GRPC_COMPILER_RUBY_GENERATOR_STRING_INL_H_

@ -0,0 +1,76 @@
/*
*
* Copyright 2014, 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.
*
*/
// Generates Ruby gRPC service interface out of Protobuf IDL.
//
// This is a Proto2 compiler plugin. See net/proto2/compiler/proto/plugin.proto
// and net/proto2/compiler/public/plugin.h for more information on plugins.
#include <memory>
#include "src/compiler/ruby_generator.h"
#include "src/compiler/ruby_generator_helpers-inl.h"
#include <google/protobuf/compiler/code_generator.h>
#include <google/protobuf/compiler/plugin.h>
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/io/zero_copy_stream.h>
#include <google/protobuf/descriptor.h>
class RubyGrpcGenerator : public google::protobuf::compiler::CodeGenerator {
public:
RubyGrpcGenerator() {}
~RubyGrpcGenerator() override {}
bool Generate(const google::protobuf::FileDescriptor* file,
const string& parameter,
google::protobuf::compiler::GeneratorContext* context,
string* error) const override {
// Get output file name.
string file_name;
if (!grpc_ruby_generator::ServicesFilename(file, &file_name)) {
return false;
}
std::unique_ptr<google::protobuf::io::ZeroCopyOutputStream> output(
context->OpenForInsert(file_name, "module_scope"));
google::protobuf::io::CodedOutputStream coded_out(output.get());
string code = grpc_ruby_generator::GetServices(file);
coded_out.WriteRaw(code.data(), code.size());
return true;
}
};
int main(int argc, char* argv[]) {
RubyGrpcGenerator generator;
return google::protobuf::compiler::PluginMain(argc, argv, &generator);
}

@ -220,6 +220,14 @@ tools: privatelibs\
% endfor
protoc_plugins:\
% for tgt in targets:
% if tgt.build == 'protoc':
bins/${tgt.name}\
% endif
% endfor
buildbenchmarks: privatelibs\
% for tgt in targets:
% if tgt.build == 'benchmark':

Loading…
Cancel
Save