forked from BigfootDev/flatbuffers
Added GRPC code generator to flatc.
Also added simple (in-process) test. Change-Id: I38580d554dd52f590e3396ec4846e07546dcf07d Tested: on Linux.
This commit is contained in:
@@ -9,6 +9,7 @@ option(FLATBUFFERS_INSTALL "Enable the installation of targets." ON)
|
||||
option(FLATBUFFERS_BUILD_FLATLIB "Enable the build of the flatbuffers library" ON)
|
||||
option(FLATBUFFERS_BUILD_FLATC "Enable the build of the flatbuffers compiler" ON)
|
||||
option(FLATBUFFERS_BUILD_FLATHASH "Enable the build of flathash" ON)
|
||||
option(FLATBUFFERS_BUILD_GRPCTEST "Enable the build of grpctest" OFF)
|
||||
|
||||
if(NOT FLATBUFFERS_BUILD_FLATC AND FLATBUFFERS_BUILD_TESTS)
|
||||
message(WARNING
|
||||
@@ -39,7 +40,10 @@ set(FlatBuffers_Compiler_SRCS
|
||||
src/idl_gen_php.cpp
|
||||
src/idl_gen_python.cpp
|
||||
src/idl_gen_fbs.cpp
|
||||
src/idl_gen_grpc.cpp
|
||||
src/flatc.cpp
|
||||
grpc/src/compiler/cpp_generator.h
|
||||
grpc/src/compiler/cpp_generator.cc
|
||||
)
|
||||
|
||||
set(FlatHash_SRCS
|
||||
@@ -76,6 +80,16 @@ set(FlatBuffers_Sample_Text_SRCS
|
||||
${CMAKE_CURRENT_BINARY_DIR}/samples/monster_generated.h
|
||||
)
|
||||
|
||||
set(FlatBuffers_GRPCTest_SRCS
|
||||
include/flatbuffers/flatbuffers.h
|
||||
include/flatbuffers/grpc.h
|
||||
tests/monster_test.grpc.fb.h
|
||||
tests/monster_test.grpc.fb.cc
|
||||
grpc/tests/grpctest.cpp
|
||||
# file generated by running compiler on samples/monster.fbs
|
||||
${CMAKE_CURRENT_BINARY_DIR}/samples/monster_generated.h
|
||||
)
|
||||
|
||||
# source_group(Compiler FILES ${FlatBuffers_Compiler_SRCS})
|
||||
# source_group(Tests FILES ${FlatBuffers_Tests_SRCS})
|
||||
|
||||
@@ -129,6 +143,7 @@ if(BIICODE)
|
||||
endif()
|
||||
|
||||
include_directories(include)
|
||||
include_directories(grpc)
|
||||
|
||||
if(FLATBUFFERS_BUILD_FLATLIB)
|
||||
add_library(flatbuffers STATIC ${FlatBuffers_Library_SRCS})
|
||||
@@ -174,6 +189,14 @@ if(FLATBUFFERS_BUILD_TESTS)
|
||||
add_executable(flatsampletext ${FlatBuffers_Sample_Text_SRCS})
|
||||
endif()
|
||||
|
||||
if(FLATBUFFERS_BUILD_GRPCTEST)
|
||||
if(CMAKE_COMPILER_IS_GNUCXX)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unused-parameter")
|
||||
endif()
|
||||
add_executable(grpctest ${FlatBuffers_GRPCTest_SRCS})
|
||||
target_link_libraries(grpctest grpc++_unsecure grpc pthread dl)
|
||||
endif()
|
||||
|
||||
if(FLATBUFFERS_INSTALL)
|
||||
install(DIRECTORY include/flatbuffers DESTINATION include)
|
||||
if(FLATBUFFERS_BUILD_FLATLIB)
|
||||
|
||||
@@ -33,6 +33,8 @@ For any schema input files, one or more generators can be specified:
|
||||
|
||||
- `--php`: Generate PHP code.
|
||||
|
||||
- `--grpc`: Generate RPC stub code for GRPC.
|
||||
|
||||
For any data input files:
|
||||
|
||||
- `--binary`, `-b` : If data is contained in this file, generate a
|
||||
|
||||
@@ -237,7 +237,8 @@ as the response (both of which must be table types):
|
||||
}
|
||||
|
||||
What code this produces and how it is used depends on language and RPC system
|
||||
used, FlatBuffers itself does not offer this functionality.
|
||||
used, there is preliminary support for GRPC through the `--grpc` code generator,
|
||||
see `grpc/tests` for an example.
|
||||
|
||||
### Comments & documentation
|
||||
|
||||
|
||||
11
grpc/README.md
Normal file
11
grpc/README.md
Normal file
@@ -0,0 +1,11 @@
|
||||
GRPC implementation and test
|
||||
============================
|
||||
|
||||
NOTE: files in `src/` are shared with the GRPC project, and maintained there
|
||||
(any changes should be submitted to GRPC instead). These files are copied
|
||||
from GRPC, and work with both the Protobuf and FlatBuffers code generator.
|
||||
|
||||
`tests/` contains a GRPC specific test, you need to have built and installed
|
||||
the GRPC libraries for this to compile. This test will build using the
|
||||
`FLATBUFFERS_BUILD_GRPCTEST` option to the main FlatBuffers CMake project.
|
||||
|
||||
1202
grpc/src/compiler/cpp_generator.cc
Normal file
1202
grpc/src/compiler/cpp_generator.cc
Normal file
File diff suppressed because it is too large
Load Diff
147
grpc/src/compiler/cpp_generator.h
Normal file
147
grpc/src/compiler/cpp_generator.h
Normal file
@@ -0,0 +1,147 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2015, 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 GRPC_INTERNAL_COMPILER_CPP_GENERATOR_H
|
||||
#define GRPC_INTERNAL_COMPILER_CPP_GENERATOR_H
|
||||
|
||||
// cpp_generator.h/.cc do not directly depend on GRPC/ProtoBuf, such that they
|
||||
// can be used to generate code for other serialization systems, such as
|
||||
// FlatBuffers.
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#ifndef GRPC_CUSTOM_STRING
|
||||
#include <string>
|
||||
#define GRPC_CUSTOM_STRING std::string
|
||||
#endif
|
||||
|
||||
namespace grpc {
|
||||
|
||||
typedef GRPC_CUSTOM_STRING string;
|
||||
|
||||
} // namespace grpc
|
||||
|
||||
namespace grpc_cpp_generator {
|
||||
|
||||
// Contains all the parameters that are parsed from the command line.
|
||||
struct Parameters {
|
||||
// Puts the service into a namespace
|
||||
grpc::string services_namespace;
|
||||
// Use system includes (<>) or local includes ("")
|
||||
bool use_system_headers;
|
||||
// Prefix to any grpc include
|
||||
grpc::string grpc_search_path;
|
||||
};
|
||||
|
||||
// An abstract interface representing a method.
|
||||
struct Method {
|
||||
virtual ~Method() {}
|
||||
|
||||
virtual grpc::string name() const = 0;
|
||||
|
||||
virtual grpc::string input_type_name() const = 0;
|
||||
virtual grpc::string output_type_name() const = 0;
|
||||
|
||||
virtual bool NoStreaming() const = 0;
|
||||
virtual bool ClientOnlyStreaming() const = 0;
|
||||
virtual bool ServerOnlyStreaming() const = 0;
|
||||
virtual bool BidiStreaming() const = 0;
|
||||
};
|
||||
|
||||
// An abstract interface representing a service.
|
||||
struct Service {
|
||||
virtual ~Service() {}
|
||||
|
||||
virtual grpc::string name() const = 0;
|
||||
|
||||
virtual int method_count() const = 0;
|
||||
virtual std::unique_ptr<const Method> method(int i) const = 0;
|
||||
};
|
||||
|
||||
struct Printer {
|
||||
virtual ~Printer() {}
|
||||
|
||||
virtual void Print(const std::map<grpc::string, grpc::string> &vars,
|
||||
const char *template_string) = 0;
|
||||
virtual void Print(const char *string) = 0;
|
||||
virtual void Indent() = 0;
|
||||
virtual void Outdent() = 0;
|
||||
};
|
||||
|
||||
// An interface that allows the source generated to be output using various
|
||||
// libraries/idls/serializers.
|
||||
struct File {
|
||||
virtual ~File() {}
|
||||
|
||||
virtual grpc::string filename() const = 0;
|
||||
virtual grpc::string filename_without_ext() const = 0;
|
||||
virtual grpc::string message_header_ext() const = 0;
|
||||
virtual grpc::string service_header_ext() const = 0;
|
||||
virtual grpc::string package() const = 0;
|
||||
virtual std::vector<grpc::string> package_parts() const = 0;
|
||||
virtual grpc::string additional_headers() const = 0;
|
||||
|
||||
virtual int service_count() const = 0;
|
||||
virtual std::unique_ptr<const Service> service(int i) const = 0;
|
||||
|
||||
virtual std::unique_ptr<Printer> CreatePrinter(grpc::string *str) const = 0;
|
||||
};
|
||||
|
||||
// Return the prologue of the generated header file.
|
||||
grpc::string GetHeaderPrologue(File *file, const Parameters ¶ms);
|
||||
|
||||
// Return the includes needed for generated header file.
|
||||
grpc::string GetHeaderIncludes(File *file, const Parameters ¶ms);
|
||||
|
||||
// Return the includes needed for generated source file.
|
||||
grpc::string GetSourceIncludes(File *file, const Parameters ¶ms);
|
||||
|
||||
// Return the epilogue of the generated header file.
|
||||
grpc::string GetHeaderEpilogue(File *file, const Parameters ¶ms);
|
||||
|
||||
// Return the prologue of the generated source file.
|
||||
grpc::string GetSourcePrologue(File *file, const Parameters ¶ms);
|
||||
|
||||
// Return the services for generated header file.
|
||||
grpc::string GetHeaderServices(File *file, const Parameters ¶ms);
|
||||
|
||||
// Return the services for generated source file.
|
||||
grpc::string GetSourceServices(File *file, const Parameters ¶ms);
|
||||
|
||||
// Return the epilogue of the generated source file.
|
||||
grpc::string GetSourceEpilogue(File *file, const Parameters ¶ms);
|
||||
|
||||
} // namespace grpc_cpp_generator
|
||||
|
||||
#endif // GRPC_INTERNAL_COMPILER_CPP_GENERATOR_H
|
||||
124
grpc/tests/grpctest.cpp
Normal file
124
grpc/tests/grpctest.cpp
Normal file
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <thread>
|
||||
|
||||
#include <grpc++/grpc++.h>
|
||||
|
||||
#include "monster_test_generated.h"
|
||||
#include "monster_test.grpc.fb.h"
|
||||
|
||||
using namespace MyGame::Example;
|
||||
|
||||
// The callback implementation of our server, that derives from the generated
|
||||
// code. It implements all rpcs specified in the FlatBuffers schema.
|
||||
class ServiceImpl final : public MyGame::Example::MonsterStorage::Service {
|
||||
virtual ::grpc::Status Store(::grpc::ServerContext* context,
|
||||
const flatbuffers::BufferRef<Monster> *request,
|
||||
flatbuffers::BufferRef<Stat> *response)
|
||||
override {
|
||||
// Create a response from the incoming request name.
|
||||
fbb_.Clear();
|
||||
auto stat_offset = CreateStat(fbb_, fbb_.CreateString("Hello, " +
|
||||
request->GetRoot()->name()->str()));
|
||||
fbb_.Finish(stat_offset);
|
||||
// Since we keep reusing the same FlatBufferBuilder, the memory it owns
|
||||
// remains valid until the next call (this BufferRef doesn't own the
|
||||
// memory it points to).
|
||||
*response = flatbuffers::BufferRef<Stat>(fbb_.GetBufferPointer(),
|
||||
fbb_.GetSize());
|
||||
return grpc::Status::OK;
|
||||
}
|
||||
virtual ::grpc::Status Retrieve(::grpc::ServerContext *context,
|
||||
const flatbuffers::BufferRef<Stat> *request,
|
||||
flatbuffers::BufferRef<Monster> *response)
|
||||
override {
|
||||
assert(false); // We're not actually using this RPC.
|
||||
return grpc::Status::CANCELLED;
|
||||
}
|
||||
|
||||
private:
|
||||
flatbuffers::FlatBufferBuilder fbb_;
|
||||
};
|
||||
|
||||
// Track the server instance, so we can terminate it later.
|
||||
grpc::Server *server_instance = nullptr;
|
||||
// Mutex to protec this variable.
|
||||
std::mutex wait_for_server;
|
||||
std::condition_variable server_instance_cv;
|
||||
|
||||
// This function implements the server thread.
|
||||
void RunServer() {
|
||||
auto server_address = "0.0.0.0:50051";
|
||||
// Callback interface we implemented above.
|
||||
ServiceImpl service;
|
||||
grpc::ServerBuilder builder;
|
||||
builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
|
||||
builder.RegisterService(&service);
|
||||
|
||||
// Start the server. Lock to change the variable we're changing.
|
||||
wait_for_server.lock();
|
||||
server_instance = builder.BuildAndStart().release();
|
||||
wait_for_server.unlock();
|
||||
server_instance_cv.notify_one();
|
||||
|
||||
std::cout << "Server listening on " << server_address << std::endl;
|
||||
// This will block the thread and serve requests.
|
||||
server_instance->Wait();
|
||||
}
|
||||
|
||||
int main(int /*argc*/, const char * /*argv*/[]) {
|
||||
// Launch server.
|
||||
std::thread server_thread(RunServer);
|
||||
|
||||
// wait for server to spin up.
|
||||
std::unique_lock<std::mutex> lock(wait_for_server);
|
||||
while (!server_instance) server_instance_cv.wait(lock);
|
||||
|
||||
// Now connect the client.
|
||||
auto channel = grpc::CreateChannel("localhost:50051",
|
||||
grpc::InsecureChannelCredentials());
|
||||
auto stub = MyGame::Example::MonsterStorage::NewStub(channel);
|
||||
|
||||
grpc::ClientContext context;
|
||||
|
||||
// Build a request with the name set.
|
||||
flatbuffers::FlatBufferBuilder fbb;
|
||||
auto monster_offset = CreateMonster(fbb, 0, 0, 0, fbb.CreateString("Fred"));
|
||||
fbb.Finish(monster_offset);
|
||||
auto request = flatbuffers::BufferRef<Monster>(fbb.GetBufferPointer(),
|
||||
fbb.GetSize());
|
||||
flatbuffers::BufferRef<Stat> response;
|
||||
|
||||
// The actual RPC.
|
||||
auto status = stub->Store(&context, request, &response);
|
||||
|
||||
if (status.ok()) {
|
||||
auto resp = response.GetRoot()->id();
|
||||
std::cout << "RPC response: " << resp->str() << std::endl;
|
||||
} else {
|
||||
std::cout << "RPC failed" << std::endl;
|
||||
}
|
||||
|
||||
server_instance->Shutdown();
|
||||
|
||||
server_thread.join();
|
||||
|
||||
delete server_instance;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1334,6 +1334,29 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
|
||||
size_t max_tables_;
|
||||
};
|
||||
|
||||
// Convenient way to bundle a buffer and its length, to pass it around
|
||||
// typed by its root.
|
||||
// A BufferRef does not own its buffer.
|
||||
struct BufferRefBase {}; // for std::is_base_of
|
||||
template<typename T> struct BufferRef : BufferRefBase {
|
||||
BufferRef() : buf(nullptr), len(0), must_free(false) {}
|
||||
BufferRef(uint8_t *_buf, uoffset_t _len)
|
||||
: buf(_buf), len(_len), must_free(false) {}
|
||||
|
||||
~BufferRef() { if (must_free) free(buf); }
|
||||
|
||||
const T *GetRoot() const { return flatbuffers::GetRoot<T>(buf); }
|
||||
|
||||
bool Verify() {
|
||||
Verifier verifier(buf, len);
|
||||
return verifier.VerifyBuffer<T>();
|
||||
}
|
||||
|
||||
uint8_t *buf;
|
||||
uoffset_t len;
|
||||
bool must_free;
|
||||
};
|
||||
|
||||
// "structs" are flat structures that do not have an offset table, thus
|
||||
// always have all members present and do not support forwards/backwards
|
||||
// compatible extensions.
|
||||
|
||||
72
include/flatbuffers/grpc.h
Normal file
72
include/flatbuffers/grpc.h
Normal file
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef FLATBUFFERS_GRPC_H_
|
||||
#define FLATBUFFERS_GRPC_H_
|
||||
|
||||
// Helper functionality to glue FlatBuffers and GRPC.
|
||||
|
||||
#include "grpc++/support/byte_buffer.h"
|
||||
#include "grpc/byte_buffer_reader.h"
|
||||
|
||||
namespace grpc {
|
||||
|
||||
template <class T>
|
||||
class SerializationTraits<T, typename std::enable_if<std::is_base_of<
|
||||
flatbuffers::BufferRefBase, T>::value>::type> {
|
||||
public:
|
||||
// The type we're passing here is a BufferRef, which is already serialized
|
||||
// FlatBuffer data, which then gets passed to GRPC.
|
||||
static grpc::Status Serialize(const T& msg,
|
||||
grpc_byte_buffer **buffer,
|
||||
bool *own_buffer) {
|
||||
// TODO(wvo): make this work without copying.
|
||||
auto slice = gpr_slice_from_copied_buffer(
|
||||
reinterpret_cast<const char *>(msg.buf), msg.len);
|
||||
*buffer = grpc_raw_byte_buffer_create(&slice, 1);
|
||||
*own_buffer = true;
|
||||
return grpc::Status();
|
||||
}
|
||||
|
||||
// There is no de-serialization step in FlatBuffers, so we just receive
|
||||
// the data from GRPC.
|
||||
static grpc::Status Deserialize(grpc_byte_buffer *buffer,
|
||||
T *msg,
|
||||
int max_message_size) {
|
||||
// TODO(wvo): make this more efficient / zero copy when possible.
|
||||
auto len = grpc_byte_buffer_length(buffer);
|
||||
msg->buf = reinterpret_cast<uint8_t *>(malloc(len));
|
||||
msg->len = static_cast<flatbuffers::uoffset_t>(len);
|
||||
msg->must_free = true;
|
||||
uint8_t *current = msg->buf;
|
||||
grpc_byte_buffer_reader reader;
|
||||
grpc_byte_buffer_reader_init(&reader, buffer);
|
||||
gpr_slice slice;
|
||||
while (grpc_byte_buffer_reader_next(&reader, &slice)) {
|
||||
memcpy(current, GPR_SLICE_START_PTR(slice), GPR_SLICE_LENGTH(slice));
|
||||
current += GPR_SLICE_LENGTH(slice);
|
||||
gpr_slice_unref(slice);
|
||||
}
|
||||
GPR_ASSERT(current == msg->buf + msg->len);
|
||||
grpc_byte_buffer_reader_destroy(&reader);
|
||||
grpc_byte_buffer_destroy(buffer);
|
||||
return grpc::Status();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace grpc;
|
||||
|
||||
#endif // FLATBUFFERS_GRPC_H_
|
||||
@@ -432,7 +432,7 @@ class Parser : public ParserState {
|
||||
known_attributes_["original_order"] = true;
|
||||
known_attributes_["nested_flatbuffer"] = true;
|
||||
known_attributes_["csharp_partial"] = true;
|
||||
known_attributes_["stream"] = true;
|
||||
known_attributes_["streaming"] = true;
|
||||
known_attributes_["idempotent"] = true;
|
||||
}
|
||||
|
||||
@@ -679,6 +679,12 @@ extern std::string BinaryMakeRule(const Parser &parser,
|
||||
const std::string &path,
|
||||
const std::string &file_name);
|
||||
|
||||
// Generate GRPC interfaces.
|
||||
// See idl_gen_grpc.cpp.
|
||||
bool GenerateGRPC(const Parser &parser,
|
||||
const std::string &path,
|
||||
const std::string &file_name);
|
||||
|
||||
} // namespace flatbuffers
|
||||
|
||||
#endif // FLATBUFFERS_IDL_H_
|
||||
|
||||
@@ -74,10 +74,14 @@ const Generator generators[] = {
|
||||
flatbuffers::IDLOptions::kMAX,
|
||||
"Generate Python files for tables/structs",
|
||||
flatbuffers::GeneralMakeRule },
|
||||
{ flatbuffers::GeneratePhp, nullptr, "--php", "PHP",
|
||||
{ flatbuffers::GeneratePhp, nullptr, "--php", "PHP",
|
||||
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 *program_name = nullptr;
|
||||
|
||||
216
src/idl_gen_grpc.cpp
Normal file
216
src/idl_gen_grpc.cpp
Normal file
@@ -0,0 +1,216 @@
|
||||
/*
|
||||
* 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/flatbuffers.h"
|
||||
#include "flatbuffers/idl.h"
|
||||
#include "flatbuffers/util.h"
|
||||
|
||||
#include "src/compiler/cpp_generator.h"
|
||||
|
||||
namespace flatbuffers {
|
||||
|
||||
class FlatBufMethod : public grpc_cpp_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;
|
||||
}
|
||||
}
|
||||
|
||||
std::string name() const { return method_->name; }
|
||||
|
||||
std::string GRPCType(const StructDef &sd) const {
|
||||
return "flatbuffers::BufferRef<" + sd.name + ">";
|
||||
}
|
||||
|
||||
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 ClientOnlyStreaming() const { return streaming_ == kClient; }
|
||||
bool ServerOnlyStreaming() const { return streaming_ == kServer; }
|
||||
bool BidiStreaming() const { return streaming_ == kBiDi; }
|
||||
|
||||
private:
|
||||
const RPCCall *method_;
|
||||
Streaming streaming_;
|
||||
};
|
||||
|
||||
class FlatBufService : public grpc_cpp_generator::Service {
|
||||
public:
|
||||
FlatBufService(const ServiceDef *service) : service_(service) {}
|
||||
|
||||
std::string name() const { return service_->name; }
|
||||
|
||||
int method_count() const {
|
||||
return static_cast<int>(service_->calls.vec.size());
|
||||
};
|
||||
|
||||
std::unique_ptr<const grpc_cpp_generator::Method> method(int i) const {
|
||||
return std::unique_ptr<const grpc_cpp_generator::Method>(
|
||||
new FlatBufMethod(service_->calls.vec[i]));
|
||||
};
|
||||
|
||||
private:
|
||||
const ServiceDef *service_;
|
||||
};
|
||||
|
||||
class FlatBufPrinter : public grpc_cpp_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) {
|
||||
// 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.
|
||||
auto 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_--; assert(indent_ >= 0); }
|
||||
|
||||
private:
|
||||
std::string *str_;
|
||||
char escape_char_;
|
||||
int indent_;
|
||||
};
|
||||
|
||||
class FlatBufFile : public grpc_cpp_generator::File {
|
||||
public:
|
||||
FlatBufFile(const Parser &parser, const std::string &file_name)
|
||||
: parser_(parser), file_name_(file_name) {}
|
||||
|
||||
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_.namespaces_.back()->GetFullyQualifiedName("");
|
||||
}
|
||||
|
||||
std::vector<std::string> package_parts() const {
|
||||
return parser_.namespaces_.back()->components;
|
||||
}
|
||||
|
||||
std::string additional_headers() const {
|
||||
return "#include \"flatbuffers/grpc.h\"\n";
|
||||
}
|
||||
|
||||
int service_count() const {
|
||||
return static_cast<int>(parser_.services_.vec.size());
|
||||
};
|
||||
|
||||
std::unique_ptr<const grpc_cpp_generator::Service> service(int i) const {
|
||||
return std::unique_ptr<const grpc_cpp_generator::Service> (
|
||||
new FlatBufService(parser_.services_.vec[i]));
|
||||
}
|
||||
|
||||
std::unique_ptr<grpc_cpp_generator::Printer> CreatePrinter(std::string *str) const {
|
||||
return std::unique_ptr<grpc_cpp_generator::Printer>(
|
||||
new FlatBufPrinter(str));
|
||||
}
|
||||
|
||||
private:
|
||||
const Parser &parser_;
|
||||
const std::string &file_name_;
|
||||
};
|
||||
|
||||
bool GenerateGRPC(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);
|
||||
|
||||
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((file_name + ".grpc.fb.h").c_str(),
|
||||
header_code, false) &&
|
||||
flatbuffers::SaveFile((file_name + ".grpc.fb.cc").c_str(),
|
||||
source_code, false);
|
||||
}
|
||||
|
||||
} // namespace flatbuffers
|
||||
|
||||
@@ -1423,6 +1423,10 @@ void Parser::MarkGenerated() {
|
||||
it != structs_.vec.end(); ++it) {
|
||||
(*it)->generated = true;
|
||||
}
|
||||
for (auto it = services_.vec.begin();
|
||||
it != services_.vec.end(); ++it) {
|
||||
(*it)->generated = true;
|
||||
}
|
||||
}
|
||||
|
||||
CheckedError Parser::ParseNamespace() {
|
||||
|
||||
@@ -12,6 +12,6 @@
|
||||
:: See the License for the specific language governing permissions and
|
||||
:: limitations under the License.
|
||||
|
||||
..\flatc.exe --cpp --java --csharp --go --binary --python --js --php --gen-mutable --no-includes monster_test.fbs monsterdata_test.json
|
||||
..\flatc.exe --cpp --java --csharp --go --binary --python --js --php --grpc --gen-mutable --no-includes monster_test.fbs monsterdata_test.json
|
||||
..\flatc.exe --cpp --java --csharp --go --binary --python --js --php --gen-mutable -o namespace_test namespace_test\namespace_test1.fbs namespace_test\namespace_test2.fbs
|
||||
..\flatc.exe --binary --schema monster_test.fbs
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
../flatc --cpp --java --csharp --go --binary --python --js --php --gen-mutable --no-includes monster_test.fbs monsterdata_test.json
|
||||
../flatc --cpp --java --csharp --go --binary --python --js --php --grpc --gen-mutable --no-includes monster_test.fbs monsterdata_test.json
|
||||
../flatc --cpp --java --csharp --go --binary --python --js --php --gen-mutable -o namespace_test namespace_test/namespace_test1.fbs namespace_test/namespace_test2.fbs
|
||||
../flatc --binary --schema monster_test.fbs
|
||||
|
||||
|
||||
@@ -70,7 +70,7 @@ table Monster {
|
||||
}
|
||||
|
||||
rpc_service MonsterStorage {
|
||||
Store(Monster):Stat (stream);
|
||||
Store(Monster):Stat (streaming: "none");
|
||||
Retrieve(Stat):Monster (idempotent);
|
||||
}
|
||||
|
||||
|
||||
85
tests/monster_test.grpc.fb.cc
Normal file
85
tests/monster_test.grpc.fb.cc
Normal file
@@ -0,0 +1,85 @@
|
||||
// Generated by the gRPC protobuf plugin.
|
||||
// If you make any local change, they will be lost.
|
||||
// source: monster_test
|
||||
|
||||
#include "monster_test_generated.h"
|
||||
#include "monster_test.grpc.fb.h"
|
||||
#include "flatbuffers/grpc.h"
|
||||
|
||||
#include <grpc++/impl/codegen/async_stream.h>
|
||||
#include <grpc++/impl/codegen/async_unary_call.h>
|
||||
#include <grpc++/impl/codegen/channel_interface.h>
|
||||
#include <grpc++/impl/codegen/client_unary_call.h>
|
||||
#include <grpc++/impl/codegen/method_handler_impl.h>
|
||||
#include <grpc++/impl/codegen/rpc_service_method.h>
|
||||
#include <grpc++/impl/codegen/service_type.h>
|
||||
#include <grpc++/impl/codegen/sync_stream.h>
|
||||
namespace MyGame {
|
||||
namespace Example {
|
||||
|
||||
static const char* MonsterStorage_method_names[] = {
|
||||
"/MyGame.Example..MonsterStorage/Store",
|
||||
"/MyGame.Example..MonsterStorage/Retrieve",
|
||||
};
|
||||
|
||||
std::unique_ptr< MonsterStorage::Stub> MonsterStorage::NewStub(const std::shared_ptr< ::grpc::ChannelInterface>& channel, const ::grpc::StubOptions& options) {
|
||||
std::unique_ptr< MonsterStorage::Stub> stub(new MonsterStorage::Stub(channel));
|
||||
return stub;
|
||||
}
|
||||
|
||||
MonsterStorage::Stub::Stub(const std::shared_ptr< ::grpc::ChannelInterface>& channel)
|
||||
: channel_(channel) , rpcmethod_Store_(MonsterStorage_method_names[0], ::grpc::RpcMethod::NORMAL_RPC, channel)
|
||||
, rpcmethod_Retrieve_(MonsterStorage_method_names[1], ::grpc::RpcMethod::NORMAL_RPC, channel)
|
||||
{}
|
||||
|
||||
::grpc::Status MonsterStorage::Stub::Store(::grpc::ClientContext* context, const flatbuffers::BufferRef<Monster>& request, flatbuffers::BufferRef<Stat>* response) {
|
||||
return ::grpc::BlockingUnaryCall(channel_.get(), rpcmethod_Store_, context, request, response);
|
||||
}
|
||||
|
||||
::grpc::ClientAsyncResponseReader< flatbuffers::BufferRef<Stat>>* MonsterStorage::Stub::AsyncStoreRaw(::grpc::ClientContext* context, const flatbuffers::BufferRef<Monster>& request, ::grpc::CompletionQueue* cq) {
|
||||
return new ::grpc::ClientAsyncResponseReader< flatbuffers::BufferRef<Stat>>(channel_.get(), cq, rpcmethod_Store_, context, request);
|
||||
}
|
||||
|
||||
::grpc::Status MonsterStorage::Stub::Retrieve(::grpc::ClientContext* context, const flatbuffers::BufferRef<Stat>& request, flatbuffers::BufferRef<Monster>* response) {
|
||||
return ::grpc::BlockingUnaryCall(channel_.get(), rpcmethod_Retrieve_, context, request, response);
|
||||
}
|
||||
|
||||
::grpc::ClientAsyncResponseReader< flatbuffers::BufferRef<Monster>>* MonsterStorage::Stub::AsyncRetrieveRaw(::grpc::ClientContext* context, const flatbuffers::BufferRef<Stat>& request, ::grpc::CompletionQueue* cq) {
|
||||
return new ::grpc::ClientAsyncResponseReader< flatbuffers::BufferRef<Monster>>(channel_.get(), cq, rpcmethod_Retrieve_, context, request);
|
||||
}
|
||||
|
||||
MonsterStorage::Service::Service() {
|
||||
(void)MonsterStorage_method_names;
|
||||
AddMethod(new ::grpc::RpcServiceMethod(
|
||||
MonsterStorage_method_names[0],
|
||||
::grpc::RpcMethod::NORMAL_RPC,
|
||||
new ::grpc::RpcMethodHandler< MonsterStorage::Service, flatbuffers::BufferRef<Monster>, flatbuffers::BufferRef<Stat>>(
|
||||
std::mem_fn(&MonsterStorage::Service::Store), this)));
|
||||
AddMethod(new ::grpc::RpcServiceMethod(
|
||||
MonsterStorage_method_names[1],
|
||||
::grpc::RpcMethod::NORMAL_RPC,
|
||||
new ::grpc::RpcMethodHandler< MonsterStorage::Service, flatbuffers::BufferRef<Stat>, flatbuffers::BufferRef<Monster>>(
|
||||
std::mem_fn(&MonsterStorage::Service::Retrieve), this)));
|
||||
}
|
||||
|
||||
MonsterStorage::Service::~Service() {
|
||||
}
|
||||
|
||||
::grpc::Status MonsterStorage::Service::Store(::grpc::ServerContext* context, const flatbuffers::BufferRef<Monster>* request, flatbuffers::BufferRef<Stat>* response) {
|
||||
(void) context;
|
||||
(void) request;
|
||||
(void) response;
|
||||
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
|
||||
}
|
||||
|
||||
::grpc::Status MonsterStorage::Service::Retrieve(::grpc::ServerContext* context, const flatbuffers::BufferRef<Stat>* request, flatbuffers::BufferRef<Monster>* response) {
|
||||
(void) context;
|
||||
(void) request;
|
||||
(void) response;
|
||||
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
|
||||
}
|
||||
|
||||
|
||||
} // namespace MyGame
|
||||
} // namespace Example
|
||||
|
||||
155
tests/monster_test.grpc.fb.h
Normal file
155
tests/monster_test.grpc.fb.h
Normal file
@@ -0,0 +1,155 @@
|
||||
// Generated by the gRPC protobuf plugin.
|
||||
// If you make any local change, they will be lost.
|
||||
// source: monster_test
|
||||
#ifndef GRPC_monster_5ftest__INCLUDED
|
||||
#define GRPC_monster_5ftest__INCLUDED
|
||||
|
||||
#include "monster_test_generated.h"
|
||||
|
||||
#include <grpc++/impl/codegen/async_stream.h>
|
||||
#include <grpc++/impl/codegen/async_unary_call.h>
|
||||
#include <grpc++/impl/codegen/proto_utils.h>
|
||||
#include <grpc++/impl/codegen/rpc_method.h>
|
||||
#include <grpc++/impl/codegen/service_type.h>
|
||||
#include <grpc++/impl/codegen/status.h>
|
||||
#include <grpc++/impl/codegen/stub_options.h>
|
||||
#include <grpc++/impl/codegen/sync_stream.h>
|
||||
|
||||
namespace grpc {
|
||||
class CompletionQueue;
|
||||
class Channel;
|
||||
class RpcService;
|
||||
class ServerCompletionQueue;
|
||||
class ServerContext;
|
||||
} // namespace grpc
|
||||
|
||||
namespace MyGame {
|
||||
namespace Example {
|
||||
|
||||
class MonsterStorage GRPC_FINAL {
|
||||
public:
|
||||
class StubInterface {
|
||||
public:
|
||||
virtual ~StubInterface() {}
|
||||
virtual ::grpc::Status Store(::grpc::ClientContext* context, const flatbuffers::BufferRef<Monster>& request, flatbuffers::BufferRef<Stat>* response) = 0;
|
||||
std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< flatbuffers::BufferRef<Stat>>> AsyncStore(::grpc::ClientContext* context, const flatbuffers::BufferRef<Monster>& request, ::grpc::CompletionQueue* cq) {
|
||||
return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< flatbuffers::BufferRef<Stat>>>(AsyncStoreRaw(context, request, cq));
|
||||
}
|
||||
virtual ::grpc::Status Retrieve(::grpc::ClientContext* context, const flatbuffers::BufferRef<Stat>& request, flatbuffers::BufferRef<Monster>* response) = 0;
|
||||
std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< flatbuffers::BufferRef<Monster>>> AsyncRetrieve(::grpc::ClientContext* context, const flatbuffers::BufferRef<Stat>& request, ::grpc::CompletionQueue* cq) {
|
||||
return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< flatbuffers::BufferRef<Monster>>>(AsyncRetrieveRaw(context, request, cq));
|
||||
}
|
||||
private:
|
||||
virtual ::grpc::ClientAsyncResponseReaderInterface< flatbuffers::BufferRef<Stat>>* AsyncStoreRaw(::grpc::ClientContext* context, const flatbuffers::BufferRef<Monster>& request, ::grpc::CompletionQueue* cq) = 0;
|
||||
virtual ::grpc::ClientAsyncResponseReaderInterface< flatbuffers::BufferRef<Monster>>* AsyncRetrieveRaw(::grpc::ClientContext* context, const flatbuffers::BufferRef<Stat>& request, ::grpc::CompletionQueue* cq) = 0;
|
||||
};
|
||||
class Stub GRPC_FINAL : public StubInterface {
|
||||
public:
|
||||
Stub(const std::shared_ptr< ::grpc::ChannelInterface>& channel);
|
||||
::grpc::Status Store(::grpc::ClientContext* context, const flatbuffers::BufferRef<Monster>& request, flatbuffers::BufferRef<Stat>* response) GRPC_OVERRIDE;
|
||||
std::unique_ptr< ::grpc::ClientAsyncResponseReader< flatbuffers::BufferRef<Stat>>> AsyncStore(::grpc::ClientContext* context, const flatbuffers::BufferRef<Monster>& request, ::grpc::CompletionQueue* cq) {
|
||||
return std::unique_ptr< ::grpc::ClientAsyncResponseReader< flatbuffers::BufferRef<Stat>>>(AsyncStoreRaw(context, request, cq));
|
||||
}
|
||||
::grpc::Status Retrieve(::grpc::ClientContext* context, const flatbuffers::BufferRef<Stat>& request, flatbuffers::BufferRef<Monster>* response) GRPC_OVERRIDE;
|
||||
std::unique_ptr< ::grpc::ClientAsyncResponseReader< flatbuffers::BufferRef<Monster>>> AsyncRetrieve(::grpc::ClientContext* context, const flatbuffers::BufferRef<Stat>& request, ::grpc::CompletionQueue* cq) {
|
||||
return std::unique_ptr< ::grpc::ClientAsyncResponseReader< flatbuffers::BufferRef<Monster>>>(AsyncRetrieveRaw(context, request, cq));
|
||||
}
|
||||
|
||||
private:
|
||||
std::shared_ptr< ::grpc::ChannelInterface> channel_;
|
||||
::grpc::ClientAsyncResponseReader< flatbuffers::BufferRef<Stat>>* AsyncStoreRaw(::grpc::ClientContext* context, const flatbuffers::BufferRef<Monster>& request, ::grpc::CompletionQueue* cq) GRPC_OVERRIDE;
|
||||
::grpc::ClientAsyncResponseReader< flatbuffers::BufferRef<Monster>>* AsyncRetrieveRaw(::grpc::ClientContext* context, const flatbuffers::BufferRef<Stat>& request, ::grpc::CompletionQueue* cq) GRPC_OVERRIDE;
|
||||
const ::grpc::RpcMethod rpcmethod_Store_;
|
||||
const ::grpc::RpcMethod rpcmethod_Retrieve_;
|
||||
};
|
||||
static std::unique_ptr<Stub> 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 Store(::grpc::ServerContext* context, const flatbuffers::BufferRef<Monster>* request, flatbuffers::BufferRef<Stat>* response);
|
||||
virtual ::grpc::Status Retrieve(::grpc::ServerContext* context, const flatbuffers::BufferRef<Stat>* request, flatbuffers::BufferRef<Monster>* response);
|
||||
};
|
||||
template <class BaseClass>
|
||||
class WithAsyncMethod_Store : public BaseClass {
|
||||
private:
|
||||
void BaseClassMustBeDerivedFromService(const Service *service) {}
|
||||
public:
|
||||
WithAsyncMethod_Store() {
|
||||
::grpc::Service::MarkMethodAsync(0);
|
||||
}
|
||||
~WithAsyncMethod_Store() GRPC_OVERRIDE {
|
||||
BaseClassMustBeDerivedFromService(this);
|
||||
}
|
||||
// disable synchronous version of this method
|
||||
::grpc::Status Store(::grpc::ServerContext* context, const flatbuffers::BufferRef<Monster>* request, flatbuffers::BufferRef<Stat>* response) GRPC_FINAL GRPC_OVERRIDE {
|
||||
abort();
|
||||
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
|
||||
}
|
||||
void RequestStore(::grpc::ServerContext* context, flatbuffers::BufferRef<Monster>* request, ::grpc::ServerAsyncResponseWriter< flatbuffers::BufferRef<Stat>>* 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);
|
||||
}
|
||||
};
|
||||
template <class BaseClass>
|
||||
class WithAsyncMethod_Retrieve : public BaseClass {
|
||||
private:
|
||||
void BaseClassMustBeDerivedFromService(const Service *service) {}
|
||||
public:
|
||||
WithAsyncMethod_Retrieve() {
|
||||
::grpc::Service::MarkMethodAsync(1);
|
||||
}
|
||||
~WithAsyncMethod_Retrieve() GRPC_OVERRIDE {
|
||||
BaseClassMustBeDerivedFromService(this);
|
||||
}
|
||||
// disable synchronous version of this method
|
||||
::grpc::Status Retrieve(::grpc::ServerContext* context, const flatbuffers::BufferRef<Stat>* request, flatbuffers::BufferRef<Monster>* response) GRPC_FINAL GRPC_OVERRIDE {
|
||||
abort();
|
||||
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
|
||||
}
|
||||
void RequestRetrieve(::grpc::ServerContext* context, flatbuffers::BufferRef<Stat>* request, ::grpc::ServerAsyncResponseWriter< flatbuffers::BufferRef<Monster>>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
|
||||
::grpc::Service::RequestAsyncUnary(1, context, request, response, new_call_cq, notification_cq, tag);
|
||||
}
|
||||
};
|
||||
typedef WithAsyncMethod_Store< WithAsyncMethod_Retrieve< Service > > AsyncService;
|
||||
template <class BaseClass>
|
||||
class WithGenericMethod_Store : public BaseClass {
|
||||
private:
|
||||
void BaseClassMustBeDerivedFromService(const Service *service) {}
|
||||
public:
|
||||
WithGenericMethod_Store() {
|
||||
::grpc::Service::MarkMethodGeneric(0);
|
||||
}
|
||||
~WithGenericMethod_Store() GRPC_OVERRIDE {
|
||||
BaseClassMustBeDerivedFromService(this);
|
||||
}
|
||||
// disable synchronous version of this method
|
||||
::grpc::Status Store(::grpc::ServerContext* context, const flatbuffers::BufferRef<Monster>* request, flatbuffers::BufferRef<Stat>* response) GRPC_FINAL GRPC_OVERRIDE {
|
||||
abort();
|
||||
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
|
||||
}
|
||||
};
|
||||
template <class BaseClass>
|
||||
class WithGenericMethod_Retrieve : public BaseClass {
|
||||
private:
|
||||
void BaseClassMustBeDerivedFromService(const Service *service) {}
|
||||
public:
|
||||
WithGenericMethod_Retrieve() {
|
||||
::grpc::Service::MarkMethodGeneric(1);
|
||||
}
|
||||
~WithGenericMethod_Retrieve() GRPC_OVERRIDE {
|
||||
BaseClassMustBeDerivedFromService(this);
|
||||
}
|
||||
// disable synchronous version of this method
|
||||
::grpc::Status Retrieve(::grpc::ServerContext* context, const flatbuffers::BufferRef<Stat>* request, flatbuffers::BufferRef<Monster>* response) GRPC_FINAL GRPC_OVERRIDE {
|
||||
abort();
|
||||
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace Example
|
||||
} // namespace MyGame
|
||||
|
||||
|
||||
#endif // GRPC_monster_5ftest__INCLUDED
|
||||
Reference in New Issue
Block a user