From 4dcf223c8e0e6fe5ba9881b8cea0ead7c88bd2d9 Mon Sep 17 00:00:00 2001 From: Jared Harper Date: Sat, 22 Jul 2017 06:20:55 -0700 Subject: [PATCH] Support for C++ files generated by protobuf/grpc (#3640) * Support for C++ files generated by protobuf/grpc This changeset includes a sample generated file. [grpc](http://grpc.io) is a high performance, open-source universal RPC framework. * Account for older gRPC protobuf plugin message --- lib/linguist/generated.rb | 16 ++++- samples/C++/grpc.pb.cc | 2 + samples/C++/hello.grpc.pb.h | 125 ++++++++++++++++++++++++++++++++++++ test/test_blob.rb | 4 ++ 4 files changed, 146 insertions(+), 1 deletion(-) create mode 100644 samples/C++/grpc.pb.cc create mode 100644 samples/C++/hello.grpc.pb.h diff --git a/lib/linguist/generated.rb b/lib/linguist/generated.rb index 2d096a04..91fdb974 100644 --- a/lib/linguist/generated.rb +++ b/lib/linguist/generated.rb @@ -81,7 +81,8 @@ module Linguist generated_grammarkit? || generated_roxygen2? || generated_jison? || - generated_yarn_lock? + generated_yarn_lock? || + generated_grpc_cpp? end # Internal: Is the blob an Xcode file? @@ -489,5 +490,18 @@ module Linguist return false unless lines.count > 0 return lines[0].include?("# THIS IS AN AUTOGENERATED FILE") end + + # Internal: Is this a protobuf/grpc-generated C++ file? + # + # A generated file contains: + # // Generated by the gRPC C++ plugin. + # on the first line. + # + # Return true or false + def generated_grpc_cpp? + return false unless %w{.cpp .hpp .h .cc}.include? extname + return false unless lines.count > 1 + return lines[0].start_with?("// Generated by the gRPC") + end end end diff --git a/samples/C++/grpc.pb.cc b/samples/C++/grpc.pb.cc new file mode 100644 index 00000000..e90c96ad --- /dev/null +++ b/samples/C++/grpc.pb.cc @@ -0,0 +1,2 @@ +// Generated by the gRPC protobuf plugin. +// If you make any local change, they will be lost. diff --git a/samples/C++/hello.grpc.pb.h b/samples/C++/hello.grpc.pb.h new file mode 100644 index 00000000..dfc60bfd --- /dev/null +++ b/samples/C++/hello.grpc.pb.h @@ -0,0 +1,125 @@ +// Generated by the gRPC C++ plugin. +// If you make any local change, they will be lost. +// source: hello.proto +#ifndef GRPC_hello_2eproto__INCLUDED +#define GRPC_hello_2eproto__INCLUDED + +#include "hello.pb.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace grpc { +class CompletionQueue; +class Channel; +class RpcService; +class ServerCompletionQueue; +class ServerContext; +} // namespace grpc + +class HelloService final { + public: + class StubInterface { + public: + virtual ~StubInterface() {} + virtual ::grpc::Status SayHello(::grpc::ClientContext* context, const ::HelloRequest& request, ::HelloResponse* response) = 0; + std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::HelloResponse>> AsyncSayHello(::grpc::ClientContext* context, const ::HelloRequest& request, ::grpc::CompletionQueue* cq) { + return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::HelloResponse>>(AsyncSayHelloRaw(context, request, cq)); + } + private: + virtual ::grpc::ClientAsyncResponseReaderInterface< ::HelloResponse>* AsyncSayHelloRaw(::grpc::ClientContext* context, const ::HelloRequest& request, ::grpc::CompletionQueue* cq) = 0; + }; + class Stub final : public StubInterface { + public: + Stub(const std::shared_ptr< ::grpc::ChannelInterface>& channel); + ::grpc::Status SayHello(::grpc::ClientContext* context, const ::HelloRequest& request, ::HelloResponse* response) override; + std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::HelloResponse>> AsyncSayHello(::grpc::ClientContext* context, const ::HelloRequest& request, ::grpc::CompletionQueue* cq) { + return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::HelloResponse>>(AsyncSayHelloRaw(context, request, cq)); + } + + private: + std::shared_ptr< ::grpc::ChannelInterface> channel_; + ::grpc::ClientAsyncResponseReader< ::HelloResponse>* AsyncSayHelloRaw(::grpc::ClientContext* context, const ::HelloRequest& request, ::grpc::CompletionQueue* cq) override; + const ::grpc::RpcMethod rpcmethod_SayHello_; + }; + static std::unique_ptr NewStub(const std::shared_ptr< ::grpc::ChannelInterface>& channel, const ::grpc::StubOptions& options = ::grpc::StubOptions()); + + class Service : public ::grpc::Service { + public: + Service(); + virtual ~Service(); + virtual ::grpc::Status SayHello(::grpc::ServerContext* context, const ::HelloRequest* request, ::HelloResponse* response); + }; + template + class WithAsyncMethod_SayHello : public BaseClass { + private: + void BaseClassMustBeDerivedFromService(const Service *service) {} + public: + WithAsyncMethod_SayHello() { + ::grpc::Service::MarkMethodAsync(0); + } + ~WithAsyncMethod_SayHello() override { + BaseClassMustBeDerivedFromService(this); + } + // disable synchronous version of this method + ::grpc::Status SayHello(::grpc::ServerContext* context, const ::HelloRequest* request, ::HelloResponse* response) final override { + abort(); + return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); + } + void RequestSayHello(::grpc::ServerContext* context, ::HelloRequest* request, ::grpc::ServerAsyncResponseWriter< ::HelloResponse>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { + ::grpc::Service::RequestAsyncUnary(0, context, request, response, new_call_cq, notification_cq, tag); + } + }; + typedef WithAsyncMethod_SayHello AsyncService; + template + class WithGenericMethod_SayHello : public BaseClass { + private: + void BaseClassMustBeDerivedFromService(const Service *service) {} + public: + WithGenericMethod_SayHello() { + ::grpc::Service::MarkMethodGeneric(0); + } + ~WithGenericMethod_SayHello() override { + BaseClassMustBeDerivedFromService(this); + } + // disable synchronous version of this method + ::grpc::Status SayHello(::grpc::ServerContext* context, const ::HelloRequest* request, ::HelloResponse* response) final override { + abort(); + return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); + } + }; + template + class WithStreamedUnaryMethod_SayHello : public BaseClass { + private: + void BaseClassMustBeDerivedFromService(const Service *service) {} + public: + WithStreamedUnaryMethod_SayHello() { + ::grpc::Service::MarkMethodStreamed(0, + new ::grpc::StreamedUnaryHandler< ::HelloRequest, ::HelloResponse>(std::bind(&WithStreamedUnaryMethod_SayHello::StreamedSayHello, this, std::placeholders::_1, std::placeholders::_2))); + } + ~WithStreamedUnaryMethod_SayHello() override { + BaseClassMustBeDerivedFromService(this); + } + // disable regular version of this method + ::grpc::Status SayHello(::grpc::ServerContext* context, const ::HelloRequest* request, ::HelloResponse* response) final override { + abort(); + return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); + } + // replace default version of method with streamed unary + virtual ::grpc::Status StreamedSayHello(::grpc::ServerContext* context, ::grpc::ServerUnaryStreamer< ::HelloRequest,::HelloResponse>* server_unary_streamer) = 0; + }; + typedef WithStreamedUnaryMethod_SayHello StreamedUnaryService; + typedef Service SplitStreamedService; + typedef WithStreamedUnaryMethod_SayHello StreamedService; +}; + + +#endif // GRPC_hello_2eproto__INCLUDED + diff --git a/test/test_blob.rb b/test/test_blob.rb index 1f640916..844f0d2d 100644 --- a/test/test_blob.rb +++ b/test/test_blob.rb @@ -235,6 +235,10 @@ class TestBlob < Minitest::Test # Racc-generated Ruby assert sample_blob_memory("Ruby/racc.rb").generated? + + # protobuf/grpc-plugin C++ + assert sample_blob_memory("C++/hello.grpc.pb.h").generated? + assert sample_blob_memory("C++/grpc.pb.cc").generated? end def test_vendored