From 4d8283f93bed3b9d35362cad2c4fb38474b547d6 Mon Sep 17 00:00:00 2001 From: chedeti Date: Sun, 31 Jul 2016 15:11:49 -0700 Subject: [PATCH 01/12] Add thrift module --- .gitmodules | 3 +++ third_party/thrift | 1 + 2 files changed, 4 insertions(+) create mode 160000 third_party/thrift diff --git a/.gitmodules b/.gitmodules index ce647f3c455..3bfd3c9ce10 100644 --- a/.gitmodules +++ b/.gitmodules @@ -17,3 +17,6 @@ [submodule "third_party/nanopb"] path = third_party/nanopb url = https://github.com/nanopb/nanopb.git +[submodule "third_party/thrift"] + path = third_party/thrift + url = https://github.com/apache/thrift.git diff --git a/third_party/thrift b/third_party/thrift new file mode 160000 index 00000000000..bcad91771b7 --- /dev/null +++ b/third_party/thrift @@ -0,0 +1 @@ +Subproject commit bcad91771b7f0bff28a1cac1981d7ef2b9bcef3c From bc618eed71f1c2a2b69351a6aa60e8bb460773b9 Mon Sep 17 00:00:00 2001 From: chedeti Date: Sun, 31 Jul 2016 15:35:51 -0700 Subject: [PATCH 02/12] thrift serializer --- Makefile | 3 + build.yaml | 9 + .../grpc++/impl/codegen/thrift_serializer.h | 148 +++++++++++++++ .../impl/codegen/thrift_serializer_inl.h | 169 ++++++++++++++++++ include/grpc++/impl/codegen/thrift_utils.h | 90 ++++++++++ tools/run_tests/sources_and_headers.json | 22 ++- .../grpc++_test_util/grpc++_test_util.vcxproj | 3 + .../grpc++_test_util.vcxproj.filters | 9 + 8 files changed, 452 insertions(+), 1 deletion(-) create mode 100644 include/grpc++/impl/codegen/thrift_serializer.h create mode 100644 include/grpc++/impl/codegen/thrift_serializer_inl.h create mode 100644 include/grpc++/impl/codegen/thrift_utils.h diff --git a/Makefile b/Makefile index 8b6114bd7f9..986c25780f2 100644 --- a/Makefile +++ b/Makefile @@ -3923,6 +3923,9 @@ PUBLIC_HEADERS_CXX += \ include/grpc/impl/codegen/time.h \ include/grpc++/impl/codegen/proto_utils.h \ include/grpc++/impl/codegen/config_protobuf.h \ + include/grpc++/impl/codegen/thrift_serializer.h \ + include/grpc++/impl/codegen/thrift_serializer_inl.h \ + include/grpc++/impl/codegen/thrift_utils.h \ LIBGRPC++_TEST_UTIL_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC++_TEST_UTIL_SRC)))) diff --git a/build.yaml b/build.yaml index 37c95ccdc0a..35af7a6c7a5 100644 --- a/build.yaml +++ b/build.yaml @@ -780,6 +780,14 @@ filegroups: - src/cpp/ext/reflection.pb.cc uses: - grpc++_codegen_proto +- name: thrift_util + language: c++ + public_headers: + - include/grpc++/impl/codegen/thrift_serializer.h + - include/grpc++/impl/codegen/thrift_serializer_inl.h + - include/grpc++/impl/codegen/thrift_utils.h + uses: + - grpc++_codegen_base libs: - name: gpr build: all @@ -1021,6 +1029,7 @@ libs: - grpc++_codegen_base_src - grpc++_codegen_proto - grpc++_config_proto + - thrift_util - name: grpc++_unsecure build: all language: c++ diff --git a/include/grpc++/impl/codegen/thrift_serializer.h b/include/grpc++/impl/codegen/thrift_serializer.h new file mode 100644 index 00000000000..315d76cf2a5 --- /dev/null +++ b/include/grpc++/impl/codegen/thrift_serializer.h @@ -0,0 +1,148 @@ +/* + * + * Copyright 2016, 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 GRPCXX_IMPL_CODEGEN_THRIFT_SERIALIZER_H + #define GRPCXX_IMPL_CODEGEN_THRIFT_SERIALIZER_H + +#include +#include + +#include +#include +#include +#include +#include + +namespace apache { +namespace thrift { +namespace util { + +using apache::thrift::protocol::TBinaryProtocolT; +using apache::thrift::protocol::TCompactProtocolT; +using apache::thrift::protocol::TNetworkBigEndian; +using apache::thrift::transport::TMemoryBuffer; +using apache::thrift::transport::TBufferBase; +using apache::thrift::transport::TTransport; +using std::shared_ptr; + + +template +class ThriftSerializer { +public: + ThriftSerializer() + : prepared_ (false) + , lastDeserialized_ (false) + , serializeVersion_ (false) {} + + /** + * Serialize the passed type into the internal buffer + * and returns a pointer to internal buffer and its size + * + */ + template + void serialize(const T& fields, const uint8_t** serializedBuffer, + size_t* serializedLen); + + /** + * Serialize the passed type into the byte buffer + */ + template + void serialize(const T& fields, grpc_byte_buffer** bp); + + /** + * Deserialize the passed char array into the passed type, returns the number + * of bytes that have been consumed from the passed string. + */ + template + uint32_t deserialize(const uint8_t* serializedBuffer, size_t length, + T* fields); + + /** + * Deserialize the passed byte buffer to passed type, returns the number + * of bytes consumed from byte buffer + */ + template + uint32_t deserialize(grpc_byte_buffer* buffer, T* msg); + + void setSerializeVersion(bool value); + + virtual ~ThriftSerializer() {} + + + /** + * Set the container size limit to deserialize + * This function should be called after buffer_ is initialized + */ + void setContainerSizeLimit(int32_t container_limit) { + if (!prepared_) { + prepare(); + } + protocol_->setContainerSizeLimit(container_limit); + } + + /** + * Set the string size limit to deserialize + * This function should be called after buffer_ is initialized + */ + void setStringSizeLimit(int32_t string_limit) { + if (!prepared_) { + prepare(); + } + protocol_->setStringSizeLimit(string_limit); + } + + + private: + void prepare(); + + private: + typedef P Protocol; + bool prepared_; + bool lastDeserialized_; + boost::shared_ptr buffer_; + shared_ptr protocol_; + bool serializeVersion_; +}; // ThriftSerializer + +template +struct ThriftSerializerBinary : public ThriftSerializer > {}; + + +template +struct ThriftSerializerCompact : public ThriftSerializer >{ }; + +}}} // namespace apache::thrift::util + +#include + +#endif diff --git a/include/grpc++/impl/codegen/thrift_serializer_inl.h b/include/grpc++/impl/codegen/thrift_serializer_inl.h new file mode 100644 index 00000000000..866ecf6312d --- /dev/null +++ b/include/grpc++/impl/codegen/thrift_serializer_inl.h @@ -0,0 +1,169 @@ +/* + * + * Copyright 2016, 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 GRPCXX_IMPL_CODEGEN_THRIFT_SERIALIZER_INL_H + #define GRPCXX_IMPL_CODEGEN_THRIFT_SERIALIZER_INL_H + +#include +#include +#include +#include +#include +#include +#include + +namespace apache { +namespace thrift { +namespace util { + +using apache::thrift::protocol::TMessageType; + +template +template +void ThriftSerializer::serialize(const T& fields, + const uint8_t** serializedBuffer, size_t* serializedLen) { + + // prepare or reset buffer + if (!prepared_ || lastDeserialized_) { + prepare(); + } else { + buffer_->resetBuffer(); + } + lastDeserialized_ = false; + + // if required serialize protocol version + if (serializeVersion_) { + protocol_->writeMessageBegin("", TMessageType(0), 0); + } + + // serilaize fields into buffer + fields.write(protocol_.get()); + + // write the end of message + if (serializeVersion_) { + protocol_->writeMessageEnd(); + } + + // assign buffer to string + uint8_t* byteBuffer; + uint32_t byteBufferSize; + buffer_->getBuffer(&byteBuffer, &byteBufferSize); + *serializedBuffer = byteBuffer; + *serializedLen = byteBufferSize; +} + +template +template +void ThriftSerializer::serialize(const T& fields, grpc_byte_buffer** bp) { + + const uint8_t* byteBuffer; + size_t byteBufferSize; + serialize(fields, &byteBuffer, &byteBufferSize); + + gpr_slice slice = gpr_slice_from_copied_buffer((char*)byteBuffer,byteBufferSize); + + *bp = grpc_raw_byte_buffer_create(&slice, 1); + + gpr_slice_unref(slice); +} + +template +template +uint32_t ThriftSerializer::deserialize(const uint8_t* serializedBuffer, + size_t length, T* fields) { + // prepare buffer if necessary + if (!prepared_) { + prepare(); + } + lastDeserialized_ = true; + + //reset buffer transport + buffer_->resetBuffer((uint8_t*)serializedBuffer, length); + + // read the protocol version if necessary + if (serializeVersion_) { + std::string name = ""; + TMessageType mt = (TMessageType) 0; + int32_t seq_id = 0; + protocol_->readMessageBegin(name, mt, seq_id); + } + + // deserialize buffer into fields + uint32_t len = fields->read(protocol_.get()); + + // read the end of message + if (serializeVersion_) { + protocol_->readMessageEnd(); + } + + return len; +} + +template +template +uint32_t ThriftSerializer::deserialize(grpc_byte_buffer* bp, T* fields) { + grpc_byte_buffer_reader reader; + grpc_byte_buffer_reader_init(&reader, bp); + + gpr_slice slice = grpc_byte_buffer_reader_readall(&reader); + + uint32_t len = deserialize(GPR_SLICE_START_PTR(slice), GPR_SLICE_LENGTH(slice), fields); + + gpr_slice_unref(slice); + + grpc_byte_buffer_reader_destroy(&reader); + + return len; +} + +template +void ThriftSerializer::setSerializeVersion(bool value) { + serializeVersion_ = value; +} + +template +void +ThriftSerializer::prepare() +{ + + buffer_.reset(new TMemoryBuffer()); + + // create a protocol for the memory buffer transport + protocol_.reset(new Protocol(buffer_)); + + prepared_ = true; +} + +}}} // namespace apache::thrift::util + +#endif diff --git a/include/grpc++/impl/codegen/thrift_utils.h b/include/grpc++/impl/codegen/thrift_utils.h new file mode 100644 index 00000000000..629441149fd --- /dev/null +++ b/include/grpc++/impl/codegen/thrift_utils.h @@ -0,0 +1,90 @@ +/* + * + * Copyright 2016, 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 GRPCXX_IMPL_CODEGEN_THRIFT_UTILS_H +#define GRPCXX_IMPL_CODEGEN_THRIFT_UTILS_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace grpc { + +using apache::thrift::util::ThriftSerializerCompact; + +template +class SerializationTraits::value>::type> { + public: + + static Status Serialize(const T& msg, + grpc_byte_buffer** bp, bool* own_buffer) { + + *own_buffer = true; + + ThriftSerializerCompact serializer; + + serializer.serialize(msg, bp); + + return Status(StatusCode::OK, "ok"); + } + + static Status Deserialize(grpc_byte_buffer* buffer, + T* msg, + int max_message_size) { + if (!buffer) { + return Status(StatusCode::INTERNAL, "No payload"); + } + + ThriftSerializerCompact deserializer; + deserializer.deserialize(buffer, msg); + + grpc_byte_buffer_destroy(buffer); + + return Status(StatusCode::OK, "ok"); + } +}; + +} // namespace grpc + +#endif // GRPCXX_IMPL_CODEGEN_THRIFT_UTILS_H diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json index e85dd2c8200..06ac86fc9c4 100644 --- a/tools/run_tests/sources_and_headers.json +++ b/tools/run_tests/sources_and_headers.json @@ -4411,7 +4411,8 @@ "grpc++_codegen_base_src", "grpc++_codegen_proto", "grpc++_config_proto", - "grpc_test_util" + "grpc_test_util", + "thrift_util" ], "headers": [ "src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.h", @@ -6784,5 +6785,24 @@ ], "third_party": false, "type": "filegroup" + }, + { + "deps": [ + "grpc++_codegen_base" + ], + "headers": [ + "include/grpc++/impl/codegen/thrift_serializer.h", + "include/grpc++/impl/codegen/thrift_serializer_inl.h", + "include/grpc++/impl/codegen/thrift_utils.h" + ], + "language": "c++", + "name": "thrift_util", + "src": [ + "include/grpc++/impl/codegen/thrift_serializer.h", + "include/grpc++/impl/codegen/thrift_serializer_inl.h", + "include/grpc++/impl/codegen/thrift_utils.h" + ], + "third_party": false, + "type": "filegroup" } ] diff --git a/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj b/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj index d0fca9ba65a..96ce3b89164 100644 --- a/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj +++ b/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj @@ -200,6 +200,9 @@ + + + diff --git a/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj.filters b/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj.filters index cc98c604080..2105e672df9 100644 --- a/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj.filters +++ b/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj.filters @@ -192,6 +192,15 @@ include\grpc++\impl\codegen + + include\grpc++\impl\codegen + + + include\grpc++\impl\codegen + + + include\grpc++\impl\codegen + From dd7a2a35e23042413c232ea9f00a4b7dbbce5648 Mon Sep 17 00:00:00 2001 From: chedeti Date: Sun, 31 Jul 2016 21:57:47 -0700 Subject: [PATCH 03/12] gthrift codegen and Dockerfile --- tools/grift/Dockerfile | 63 + tools/grift/grpc_plugins_generator.patch | 2417 ++++++++++++++++++++++ 2 files changed, 2480 insertions(+) create mode 100644 tools/grift/Dockerfile create mode 100644 tools/grift/grpc_plugins_generator.patch diff --git a/tools/grift/Dockerfile b/tools/grift/Dockerfile new file mode 100644 index 00000000000..5238010ea92 --- /dev/null +++ b/tools/grift/Dockerfile @@ -0,0 +1,63 @@ +# Copyright 2016, 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. + +FROM ubuntu:14.04 + +RUN apt-get update && \ + apt-get install -y \ + git build-essential \ + pkg-config flex \ + bison \ + libkrb5-dev \ + libsasl2-dev \ + libnuma-dev \ + pkg-config \ + libssl-dev \ + autoconf libtool \ + cmake \ + libiberty-dev \ + g++ unzip \ + curl make automake libtool + +# Configure git +RUN git config --global user.name " " && \ + git config --global user.email " " + +RUN git clone https://github.com/grpc/grpc + +RUN cd grpc && git submodule update --init + +RUN cd grpc/third_party/thrift && git am --signoff < ../../tools/grift/grpc_plugins_generator.patch + +RUN cd grpc/third_party/protobuf && ./autogen.sh && ./configure && \ + make -j && make check -j && make install && ldconfig + +RUN cd grpc && make -j && make install + +RUN cd grpc/third_party/thrift && ./bootstrap.sh && ./configure && make -j && make install \ No newline at end of file diff --git a/tools/grift/grpc_plugins_generator.patch b/tools/grift/grpc_plugins_generator.patch new file mode 100644 index 00000000000..2779dfb59eb --- /dev/null +++ b/tools/grift/grpc_plugins_generator.patch @@ -0,0 +1,2417 @@ +From 0894590b5020c38106d4ebb2291994668c64f9dd Mon Sep 17 00:00:00 2001 +From: chedeti +Date: Sun, 31 Jul 2016 15:47:47 -0700 +Subject: [PATCH 1/3] don't build tests + +--- + Makefile.am | 7 ++----- + lib/cpp/Makefile.am | 7 ++----- + 2 files changed, 4 insertions(+), 10 deletions(-) + +diff --git a/Makefile.am b/Makefile.am +index 10fe49a..d49caac 100755 +--- a/Makefile.am ++++ b/Makefile.am +@@ -21,10 +21,6 @@ ACLOCAL_AMFLAGS = -I ./aclocal + + SUBDIRS = compiler/cpp lib + +-if WITH_TESTS +-SUBDIRS += test +-endif +- + if WITH_TUTORIAL + SUBDIRS += tutorial + endif +@@ -117,4 +113,5 @@ EXTRA_DIST = \ + CHANGES \ + NOTICE \ + README.md \ +- Thrift.podspec ++ Thrift.podspec \ ++ test +diff --git a/lib/cpp/Makefile.am b/lib/cpp/Makefile.am +index 6fd15d2..7de1fad 100755 +--- a/lib/cpp/Makefile.am ++++ b/lib/cpp/Makefile.am +@@ -27,10 +27,6 @@ moc__%.cpp: %.h + + SUBDIRS = . + +-if WITH_TESTS +-SUBDIRS += test +-endif +- + pkgconfigdir = $(libdir)/pkgconfig + + lib_LTLIBRARIES = libthrift.la +@@ -277,7 +273,8 @@ EXTRA_DIST = \ + thrift-qt.pc.in \ + thrift-qt5.pc.in \ + src/thrift/qt/CMakeLists.txt \ +- $(WINDOWS_DIST) ++ $(WINDOWS_DIST) \ ++ test + + style-local: + $(CPPSTYLE_CMD) +-- +2.8.0.rc3.226.g39d4020 + + +From 04244fa7805740761db757e4c44251f723d85839 Mon Sep 17 00:00:00 2001 +From: chedeti +Date: Sun, 31 Jul 2016 16:16:40 -0700 +Subject: [PATCH 2/3] grpc cpp plugins generator with example + +--- + compiler/cpp/src/generate/t_cpp_generator.cc | 476 +++++++++++++++++++++++---- + tutorial/cpp/CMakeLists.txt | 53 --- + tutorial/cpp/CppClient.cpp | 134 ++++---- + tutorial/cpp/CppServer.cpp | 226 ++++--------- + tutorial/cpp/Makefile.am | 58 ++-- + tutorial/cpp/test.thrift | 13 + + 6 files changed, 590 insertions(+), 370 deletions(-) + delete mode 100644 tutorial/cpp/CMakeLists.txt + create mode 100644 tutorial/cpp/test.thrift + +diff --git a/compiler/cpp/src/generate/t_cpp_generator.cc b/compiler/cpp/src/generate/t_cpp_generator.cc +index 6c04899..9c3399b 100644 +--- a/compiler/cpp/src/generate/t_cpp_generator.cc ++++ b/compiler/cpp/src/generate/t_cpp_generator.cc +@@ -162,6 +162,8 @@ public: + bool specialized = false); + void generate_function_helpers(t_service* tservice, t_function* tfunction); + void generate_service_async_skeleton(t_service* tservice); ++ void generate_service_stub_interface(t_service* tservice); ++ void generate_service_stub(t_service* tservice); + + /** + * Serialization constructs +@@ -883,10 +885,10 @@ void t_cpp_generator::generate_struct_declaration(ofstream& out, + bool is_user_struct) { + string extends = ""; + if (is_exception) { +- extends = " : public ::apache::thrift::TException"; ++ extends = " : public apache::thrift::TException"; + } else { +- if (is_user_struct && !gen_templates_) { +- extends = " : public virtual ::apache::thrift::TBase"; ++ if (!gen_templates_) { ++ extends = " : public virtual apache::thrift::TBase"; + } + } + +@@ -1130,9 +1132,15 @@ void t_cpp_generator::generate_struct_definition(ofstream& out, + vector::const_iterator m_iter; + const vector& members = tstruct->get_members(); + ++ string method_prefix = ""; ++ if (service_name_ != "") { ++ method_prefix = service_name_ + "::"; ++ } ++ + // Destructor + if (tstruct->annotations_.find("final") == tstruct->annotations_.end()) { +- force_cpp_out << endl << indent() << tstruct->get_name() << "::~" << tstruct->get_name() ++ force_cpp_out << endl << indent() << method_prefix << ++ tstruct->get_name() << "::~" << tstruct->get_name() + << "() throw() {" << endl; + indent_up(); + +@@ -1145,12 +1153,14 @@ void t_cpp_generator::generate_struct_definition(ofstream& out, + for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { + if (is_reference((*m_iter))) { + std::string type = type_name((*m_iter)->get_type()); +- out << endl << indent() << "void " << tstruct->get_name() << "::__set_" ++ out << endl << indent() << "void " << method_prefix ++ << tstruct->get_name() << "::__set_" + << (*m_iter)->get_name() << "(boost::shared_ptr<" + << type_name((*m_iter)->get_type(), false, false) << ">"; + out << " val) {" << endl; + } else { +- out << endl << indent() << "void " << tstruct->get_name() << "::__set_" ++ out << endl << indent() << "void " << method_prefix ++ << tstruct->get_name() << "::__set_" + << (*m_iter)->get_name() << "(" << type_name((*m_iter)->get_type(), false, true); + out << " val) {" << endl; + } +@@ -1177,11 +1187,16 @@ void t_cpp_generator::generate_struct_definition(ofstream& out, + * @param tstruct The struct + */ + void t_cpp_generator::generate_struct_reader(ofstream& out, t_struct* tstruct, bool pointers) { ++ string method_prefix = ""; ++ if (service_name_ != "") { ++ method_prefix = service_name_ + "::"; ++ } ++ + if (gen_templates_) { + out << indent() << "template " << endl << indent() << "uint32_t " +- << tstruct->get_name() << "::read(Protocol_* iprot) {" << endl; ++ << method_prefix << tstruct->get_name() << "::read(Protocol_* iprot) {" << endl; + } else { +- indent(out) << "uint32_t " << tstruct->get_name() ++ indent(out) << "uint32_t " << method_prefix << tstruct->get_name() + << "::read(::apache::thrift::protocol::TProtocol* iprot) {" << endl; + } + indent_up(); +@@ -1301,14 +1316,18 @@ void t_cpp_generator::generate_struct_reader(ofstream& out, t_struct* tstruct, b + */ + void t_cpp_generator::generate_struct_writer(ofstream& out, t_struct* tstruct, bool pointers) { + string name = tstruct->get_name(); ++ string method_prefix = ""; ++ if (service_name_ != "") { ++ method_prefix = service_name_ + "::"; ++ } + const vector& fields = tstruct->get_sorted_members(); + vector::const_iterator f_iter; + + if (gen_templates_) { + out << indent() << "template " << endl << indent() << "uint32_t " +- << tstruct->get_name() << "::write(Protocol_* oprot) const {" << endl; ++ << method_prefix << tstruct->get_name() << "::write(Protocol_* oprot) const {" << endl; + } else { +- indent(out) << "uint32_t " << tstruct->get_name() ++ indent(out) << "uint32_t " << method_prefix << tstruct->get_name() + << "::write(::apache::thrift::protocol::TProtocol* oprot) const {" << endl; + } + indent_up(); +@@ -1369,14 +1388,18 @@ void t_cpp_generator::generate_struct_result_writer(ofstream& out, + t_struct* tstruct, + bool pointers) { + string name = tstruct->get_name(); ++ string method_prefix = ""; ++ if (service_name_ != "") { ++ method_prefix = service_name_ + "::"; ++ } + const vector& fields = tstruct->get_sorted_members(); + vector::const_iterator f_iter; + + if (gen_templates_) { + out << indent() << "template " << endl << indent() << "uint32_t " +- << tstruct->get_name() << "::write(Protocol_* oprot) const {" << endl; ++ << method_prefix << tstruct->get_name() << "::write(Protocol_* oprot) const {" << endl; + } else { +- indent(out) << "uint32_t " << tstruct->get_name() ++ indent(out) << "uint32_t " << method_prefix << tstruct->get_name() + << "::write(::apache::thrift::protocol::TProtocol* oprot) const {" << endl; + } + indent_up(); +@@ -1385,18 +1408,7 @@ void t_cpp_generator::generate_struct_result_writer(ofstream& out, + + indent(out) << "xfer += oprot->writeStructBegin(\"" << name << "\");" << endl; + +- bool first = true; + for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { +- if (first) { +- first = false; +- out << endl << indent() << "if "; +- } else { +- out << " else if "; +- } +- +- out << "(this->__isset." << (*f_iter)->get_name() << ") {" << endl; +- +- indent_up(); + + // Write field header + out << indent() << "xfer += oprot->writeFieldBegin(" +@@ -1410,9 +1422,6 @@ void t_cpp_generator::generate_struct_result_writer(ofstream& out, + } + // Write field closer + indent(out) << "xfer += oprot->writeFieldEnd();" << endl; +- +- indent_down(); +- indent(out) << "}"; + } + + // Write the struct map +@@ -1478,9 +1487,13 @@ void t_cpp_generator::generate_struct_ostream_operator(std::ofstream& out, t_str + } + + void t_cpp_generator::generate_struct_print_method_decl(std::ofstream& out, t_struct* tstruct) { ++ string method_prefix = ""; ++ if (service_name_ != "") { ++ method_prefix = service_name_ + "::"; ++ } + out << "void "; + if (tstruct) { +- out << tstruct->get_name() << "::"; ++ out << method_prefix << tstruct->get_name() << "::"; + } + out << "printTo(std::ostream& out) const"; + } +@@ -1601,11 +1614,13 @@ void t_cpp_generator::generate_exception_what_method(std::ofstream& out, t_struc + */ + void t_cpp_generator::generate_service(t_service* tservice) { + string svcname = tservice->get_name(); ++ string ns = tservice->get_program()->get_namespace("cpp"); + + // Make output files +- string f_header_name = get_out_dir() + svcname + ".h"; ++ string f_header_name = get_out_dir() + svcname + ".grpc.thrift.h"; + f_header_.open(f_header_name.c_str()); + ++ + // Print header file includes + f_header_ << autogen_comment(); + f_header_ << "#ifndef " << svcname << "_H" << endl << "#define " << svcname << "_H" << endl +@@ -1621,15 +1636,38 @@ void t_cpp_generator::generate_service(t_service* tservice) { + f_header_ << "#include " << endl; + } + f_header_ << "#include " << endl; ++ + f_header_ << "#include \"" << get_include_prefix(*get_program()) << program_name_ << "_types.h\"" + << endl; + + t_service* extends_service = tservice->get_extends(); +- if (extends_service != NULL) { ++ if (extends_service != nullptr) { + f_header_ << "#include \"" << get_include_prefix(*(extends_service->get_program())) +- << extends_service->get_name() << ".h\"" << endl; ++ << extends_service->get_name() << ".grpc.thrift.h\"" << endl; + } + ++ ++ f_header_ << ++ "#include " << endl << ++ "#include " << endl << ++ "#include " << endl << ++ "#include " << endl << ++ "#include " << endl << ++ "#include " << endl << ++ "#include " << endl << ++ "#include " << endl; ++ ++ ++ f_header_ << ++ endl << ++ "namespace grpc {" << endl << ++ "class CompletionQueue;" << endl << ++ "class Channel;" << endl << ++ "class RpcService;" << endl << ++ "class ServerCompletionQueue;" << endl << ++ "class ServerContext;" << endl << ++ "}" << endl; ++ + f_header_ << endl << ns_open_ << endl << endl; + + f_header_ << "#ifdef _WIN32\n" +@@ -1638,10 +1676,13 @@ void t_cpp_generator::generate_service(t_service* tservice) { + "#endif\n\n"; + + // Service implementation file includes +- string f_service_name = get_out_dir() + svcname + ".cpp"; ++ string f_service_name = get_out_dir() + svcname + ".grpc.thrift.cpp"; + f_service_.open(f_service_name.c_str()); + f_service_ << autogen_comment(); +- f_service_ << "#include \"" << get_include_prefix(*get_program()) << svcname << ".h\"" << endl; ++ ++ f_service_ << "#include \"" << ++ get_include_prefix(*get_program()) << svcname << ".grpc.thrift.h\"" << endl; ++ + if (gen_cob_style_) { + f_service_ << "#include \"thrift/async/TAsyncChannel.h\"" << endl; + } +@@ -1652,7 +1693,7 @@ void t_cpp_generator::generate_service(t_service* tservice) { + string f_service_tcc_name = get_out_dir() + svcname + ".tcc"; + f_service_tcc_.open(f_service_tcc_name.c_str()); + f_service_tcc_ << autogen_comment(); +- f_service_tcc_ << "#include \"" << get_include_prefix(*get_program()) << svcname << ".h\"" ++ f_service_tcc_ << "#include \"" << get_include_prefix(*get_program()) << svcname << ".grpc.thrift.h\"" + << endl; + + f_service_tcc_ << "#ifndef " << svcname << "_TCC" << endl << "#define " << svcname << "_TCC" +@@ -1663,19 +1704,66 @@ void t_cpp_generator::generate_service(t_service* tservice) { + } + } + ++ f_service_ << ++ endl << ++ "#include " << endl << ++ "#include " << endl << ++ "#include " << endl << ++ "#include " << endl << ++ "#include " << endl << ++ "#include " << endl << ++ "#include " << endl << ++ "#include " << endl << ++ endl; ++ + f_service_ << endl << ns_open_ << endl << endl; + f_service_tcc_ << endl << ns_open_ << endl << endl; + ++ vector functions = tservice->get_functions(); ++ vector::iterator f_iter; ++ ++ f_service_ << ++ "static const char* " << service_name_ << "_method_names[] = {" << endl; ++ ++ ++ indent_up(); ++ ++ for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { ++ f_service_ << ++ indent() << "\"/" << ns << "." << service_name_ << "/" << (*f_iter)->get_name() << "\"," << endl; ++ } ++ ++ if (extends_service != nullptr) { ++ vector functions = extends_service->get_functions(); ++ vector::iterator f_iter; ++ ++ for ( f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { ++ f_service_ << ++ indent() << "\"/" << extends_service->get_program()->get_namespace("cpp") << ++ "." << extends_service->get_name() << "/" << (*f_iter)->get_name() << "\"," << endl; ++ } ++ } ++ ++ indent_down(); ++ f_service_ << ++ "};" << endl; ++ ++ // Generate service class ++ if ( extends_service != nullptr ) { ++ f_header_ << "class " << service_name_ << " : public " << ++ extends_service->get_name() << " {" << endl << ++ "public:" << endl; ++ } ++ else { ++ f_header_ << "class " << service_name_ << "{" << endl << ++ "public:" << endl; ++ } ++ + // Generate all the components +- generate_service_interface(tservice, ""); +- generate_service_interface_factory(tservice, ""); +- generate_service_null(tservice, ""); + generate_service_helpers(tservice); +- generate_service_client(tservice, ""); +- generate_service_processor(tservice, ""); +- generate_service_multiface(tservice); +- generate_service_skeleton(tservice); +- generate_service_client(tservice, "Concurrent"); ++ generate_service_interface(tservice, ""); ++ generate_service_stub_interface(tservice); ++ generate_service_stub(tservice); + + // Generate all the cob components + if (gen_cob_style_) { +@@ -1688,10 +1776,14 @@ void t_cpp_generator::generate_service(t_service* tservice) { + generate_service_async_skeleton(tservice); + } + ++ // Close service class ++ f_header_ << "};" << endl; ++ + f_header_ << "#ifdef _WIN32\n" + " #pragma warning( pop )\n" + "#endif\n\n"; + ++ + // Close the namespace + f_service_ << ns_close_ << endl << endl; + f_service_tcc_ << ns_close_ << endl << endl; +@@ -1729,15 +1821,11 @@ void t_cpp_generator::generate_service_helpers(t_service* tservice) { + string name_orig = ts->get_name(); + + // TODO(dreiss): Why is this stuff not in generate_function_helpers? +- ts->set_name(tservice->get_name() + "_" + (*f_iter)->get_name() + "_args"); ++ ts->set_name((*f_iter)->get_name() + "Req"); + generate_struct_declaration(f_header_, ts, false); +- generate_struct_definition(out, f_service_, ts, false); ++ generate_struct_definition(out, f_service_, ts, true); + generate_struct_reader(out, ts); + generate_struct_writer(out, ts); +- ts->set_name(tservice->get_name() + "_" + (*f_iter)->get_name() + "_pargs"); +- generate_struct_declaration(f_header_, ts, false, true, false, true); +- generate_struct_definition(out, f_service_, ts, false); +- generate_struct_writer(out, ts, true); + ts->set_name(name_orig); + + generate_function_helpers(tservice, *f_iter); +@@ -1745,13 +1833,210 @@ void t_cpp_generator::generate_service_helpers(t_service* tservice) { + } + + /** ++ * Generates a service Stub Interface ++ * ++ * @param tservice The service to generate a stub for. ++ * ++ */ ++void t_cpp_generator::generate_service_stub_interface(t_service* tservice) { ++ ++ string extends = ""; ++ if (tservice->get_extends() != nullptr) { ++ extends = " : virtual public " + type_name(tservice->get_extends()) + "::StubInterface"; ++ } ++ ++ f_header_ << ++ endl << ++ "class StubInterface " << extends << " {" << endl; ++ indent_up(); ++ f_header_ << ++ " public:" << endl << ++ indent() << "virtual ~StubInterface() {}" << endl; ++ ++ vector functions = tservice->get_functions(); ++ vector::iterator f_iter; ++ for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { ++ string function_name = (*f_iter)->get_name(); ++ f_header_ << ++ indent() << "virtual ::grpc::Status " << function_name << ++ "(::grpc::ClientContext* context, const " << function_name << ++ "Req& request, " << function_name << "Resp* response) = 0;" << endl; ++ } ++ indent_down(); ++ f_header_ << ++ "};" << endl << endl; ++ ++} ++void t_cpp_generator::generate_service_stub(t_service* tservice) { ++ f_header_ << ++ endl << ++ "class Stub : public StubInterface {" << ++ endl; ++ ++ indent_up(); ++ f_header_ << ++ " public:" << endl << ++ indent() << "Stub(const std::shared_ptr< ::grpc::ChannelInterface>& channel);" << ++ endl; ++ ++ vector functions = tservice->get_functions(); ++ vector::iterator f_iter; ++ for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { ++ string function_name = (*f_iter)->get_name(); ++ f_header_ << ++ indent() << "::grpc::Status " << function_name << ++ "(::grpc::ClientContext* context, const " << function_name << ++ "Req& request, " << function_name << "Resp* response) override;" << endl; ++ } ++ ++ t_service* extends_service = tservice->get_extends(); ++ if (extends_service != nullptr) { ++ // generate inherited methods ++ vector functions = extends_service->get_functions(); ++ vector::iterator f_iter; ++ for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { ++ string function_name = (*f_iter)->get_name(); ++ f_header_ << ++ indent() << "::grpc::Status " << function_name << ++ "(::grpc::ClientContext* context, const " << function_name << ++ "Req& request, " << function_name << "Resp* response) override;" << endl; ++ } ++ } ++ ++ f_header_ << ++ endl << ++ " private:" << endl << ++ indent() << "std::shared_ptr< ::grpc::ChannelInterface> channel_;" << ++ endl; ++ ++ for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { ++ f_header_ << ++ indent() << "const ::grpc::RpcMethod rpcmethod_" << (*f_iter)->get_name() << "_;" << endl; ++ } ++ ++ if (extends_service != nullptr) { ++ // generate inherited methods ++ vector functions = extends_service->get_functions(); ++ vector::iterator f_iter; ++ for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { ++ f_header_ << ++ indent() << "const ::grpc::RpcMethod rpcmethod_" << (*f_iter)->get_name() << "_;" << endl; ++ } ++ } ++ ++ indent_down(); ++ f_header_ << ++ "};" << endl << endl; ++ ++ // generate the implementaion of Stub ++ f_service_ << ++ endl << ++ service_name_ << "::Stub::Stub(const std::shared_ptr< ::grpc::ChannelInterface>& channel)" << endl; ++ ++ indent_up(); ++ f_service_ << ++ indent() << ": channel_(channel)" << endl; ++ int i=0; ++ for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter , ++i) { ++ f_service_ << ++ indent() << ++ ", rpcmethod_" << (*f_iter)->get_name() << "_(" << ++ service_name_ << "_method_names[" << i << "], ::grpc::RpcMethod::NORMAL_RPC, channel)" << endl; ++ } ++ ++ if (extends_service != nullptr) { ++ // generate inherited methods ++ vector functions = extends_service->get_functions(); ++ vector::iterator f_iter; ++ for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter, ++i) { ++ f_service_ << ++ indent() << ++ ", rpcmethod_" << (*f_iter)->get_name() << "_(" << ++ service_name_ << "_method_names[" << i << "], ::grpc::RpcMethod::NORMAL_RPC, channel)" << endl; ++ } ++ } ++ f_service_ << ++ indent() << "{}" << endl; ++ indent_down(); ++ ++ // generate NewStub ++ f_header_ << ++ endl << ++ "static std::unique_ptr NewStub(const std::shared_ptr\ ++ < ::grpc::ChannelInterface>& channel, const ::grpc::StubOptions& options = ::grpc::StubOptions());" << ++ endl; ++ ++ // generate NewStub Implementation ++ f_service_ << ++ endl << ++ "std::unique_ptr< " << service_name_ << "::Stub> " << service_name_ << "::NewStub(const std::shared_ptr\ ++ < ::grpc::ChannelInterface>& channel, const ::grpc::StubOptions& options) {" << endl; ++ ++ indent_up(); ++ f_service_ << ++ indent() << "std::unique_ptr< " << service_name_ << "::Stub> stub(new " << service_name_ << ++ "::Stub(channel));" << endl << ++ indent() << "return stub;" << endl; ++ indent_down(); ++ f_service_ << ++ "}" << endl; ++ ++ // generate stub methods ++ for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { ++ string function_name = (*f_iter)->get_name(); ++ f_service_ << ++ endl << ++ "::grpc::Status " << service_name_ << "::Stub::" << function_name << ++ "(::grpc::ClientContext* context, const " << service_name_ << "::" << ++ function_name << "Req& request, " << service_name_ << "::" << ++ function_name << "Resp* response) {" << endl; ++ ++ indent_up(); ++ f_service_ << ++ indent() << "return ::grpc::BlockingUnaryCall(channel_.get(), rpcmethod_" << ++ function_name << "_, context, request, response);" << endl; ++ indent_down(); ++ ++ f_service_ << ++ "}" << endl; ++ ++ } ++ ++ if (extends_service != nullptr) { ++ vector functions = extends_service->get_functions(); ++ vector::iterator f_iter; ++ for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { ++ string function_name = (*f_iter)->get_name(); ++ f_service_ << ++ endl << ++ "::grpc::Status " << service_name_ << "::Stub::" << function_name << ++ "(::grpc::ClientContext* context, const " << service_name_ << "::" << ++ function_name << "Req& request, " << service_name_ << "::" << ++ function_name << "Resp* response) {" << endl; ++ ++ indent_up(); ++ f_service_ << ++ indent() << "return ::grpc::BlockingUnaryCall(channel_.get(), rpcmethod_" << ++ function_name << "_, context, request, response);" << endl; ++ indent_down(); ++ ++ f_service_ << ++ "}" << endl; ++ ++ } ++ } ++ ++} ++ ++ ++/** + * Generates a service interface definition. + * + * @param tservice The service to generate a header definition for + */ + void t_cpp_generator::generate_service_interface(t_service* tservice, string style) { + +- string service_if_name = service_name_ + style + "If"; ++ string service_if_name = "Service"; + if (style == "CobCl") { + // Forward declare the client. + string client_name = service_name_ + "CobClient"; +@@ -1765,12 +2050,14 @@ void t_cpp_generator::generate_service_interface(t_service* tservice, string sty + + string extends = ""; + if (tservice->get_extends() != NULL) { +- extends = " : virtual public " + type_name(tservice->get_extends()) + style + "If"; ++ extends = " : virtual public " + type_name(tservice->get_extends()) + style + "::Service"; + if (style == "CobCl" && gen_templates_) { + // TODO(simpkins): If gen_templates_ is enabled, we currently assume all + // parent services were also generated with templates enabled. + extends += "T"; + } ++ } else { ++ extends = " : public ::grpc::Service"; + } + + if (style == "CobCl" && gen_templates_) { +@@ -1778,7 +2065,9 @@ void t_cpp_generator::generate_service_interface(t_service* tservice, string sty + } + f_header_ << "class " << service_if_name << extends << " {" << endl << " public:" << endl; + indent_up(); +- f_header_ << indent() << "virtual ~" << service_if_name << "() {}" << endl; ++ ++ f_header_ << indent() << "Service();" << endl; ++ f_header_ << indent() << "virtual ~Service();" << endl; + + vector functions = tservice->get_functions(); + vector::iterator f_iter; +@@ -1786,7 +2075,12 @@ void t_cpp_generator::generate_service_interface(t_service* tservice, string sty + if ((*f_iter)->has_doc()) + f_header_ << endl; + generate_java_doc(f_header_, *f_iter); +- f_header_ << indent() << "virtual " << function_signature(*f_iter, style) << " = 0;" << endl; ++ ++ string function_name = (*f_iter)->get_name(); ++ f_header_ << ++ indent() << "virtual ::grpc::Status " << function_name << ++ "(::grpc::ServerContext* context, const "<< function_name << ++ "Req* request, "<< function_name << "Resp* response);" << endl; + } + indent_down(); + f_header_ << "};" << endl << endl; +@@ -1797,6 +2091,66 @@ void t_cpp_generator::generate_service_interface(t_service* tservice, string sty + f_header_ << "typedef " << service_if_name << "< ::apache::thrift::protocol::TProtocol> " + << service_name_ << style << "If;" << endl << endl; + } ++ ++ // generate the service interface implementations ++ ++ f_service_ << ++ endl << ++ service_name_ << "::Service::Service() {" << endl; ++ indent_up(); ++ f_service_ << ++ indent() << "(void)" << service_name_ << "_method_names;" << endl; ++ uint32_t i=0; ++ for(i=0;iget_name(); ++ f_service_ << ++ endl << ++ indent() << "AddMethod(new ::grpc::RpcServiceMethod(" << endl; ++ indent_up(); ++ ++ f_service_ << ++ indent() << service_name_ << "_method_names[" << i << "]," << endl << ++ indent() << "::grpc::RpcMethod::NORMAL_RPC," << endl << ++ indent() << "new ::grpc::RpcMethodHandler< " << service_name_ << "::Service, " << ++ service_name_ << "::" << function_name << "Req, " << service_name_ << "::" << ++ function_name << "Resp>(" << endl; ++ ++ indent_up(); ++ f_service_ << ++ indent() << "std::mem_fn(&" << service_name_ << "::Service::" << function_name << "), this)));" << endl; ++ ++ indent_down(); ++ indent_down(); ++ } ++ ++ indent_down(); ++ f_service_ << ++ "}" << endl; ++ ++ f_service_ << ++ endl << ++ service_name_ << "::Service::~Service() {" << endl << ++ "}" << endl; ++ ++ for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { ++ string function_name = (*f_iter)->get_name(); ++ f_service_ << ++ endl << ++ "::grpc::Status " << service_name_ << "::Service::" << function_name << ++ "(::grpc::ServerContext* context, const " << service_name_ << "::" << function_name << ++ "Req* request, " << service_name_ << "::" << function_name << "Resp* response) {" << endl; ++ indent_up(); ++ f_service_ << ++ indent() << "(void) context;" << endl << ++ indent() << "(void) request;" << endl << ++ indent() << "(void) response;" << endl << ++ indent() << "return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED,\"\");" << endl; ++ indent_down(); ++ ++ f_service_ << ++ "}" << endl; ++ } ++ + } + + /** +@@ -3095,7 +3449,7 @@ void t_cpp_generator::generate_function_helpers(t_service* tservice, t_function* + + std::ofstream& out = (gen_templates_ ? f_service_tcc_ : f_service_); + +- t_struct result(program_, tservice->get_name() + "_" + tfunction->get_name() + "_result"); ++ t_struct result(program_, tfunction->get_name() + "Resp"); + t_field success(tfunction->get_returntype(), "success", 0); + if (!tfunction->get_returntype()->is_void()) { + result.append(&success); +@@ -3109,17 +3463,9 @@ void t_cpp_generator::generate_function_helpers(t_service* tservice, t_function* + } + + generate_struct_declaration(f_header_, &result, false); +- generate_struct_definition(out, f_service_, &result, false); ++ generate_struct_definition(out, f_service_, &result, true); + generate_struct_reader(out, &result); + generate_struct_result_writer(out, &result); +- +- result.set_name(tservice->get_name() + "_" + tfunction->get_name() + "_presult"); +- generate_struct_declaration(f_header_, &result, false, true, true, gen_cob_style_); +- generate_struct_definition(out, f_service_, &result, false); +- generate_struct_reader(out, &result, true); +- if (gen_cob_style_) { +- generate_struct_writer(out, &result, true); +- } + } + + /** +@@ -3162,8 +3508,8 @@ void t_cpp_generator::generate_process_function(t_service* tservice, + << endl; + scope_up(out); + +- string argsname = tservice->get_name() + "_" + tfunction->get_name() + "_args"; +- string resultname = tservice->get_name() + "_" + tfunction->get_name() + "_result"; ++ string argsname = tfunction->get_name() + "Req"; ++ string resultname = tfunction->get_name() + "Resp"; + + if (tfunction->is_oneway() && !unnamed_oprot_seqid) { + out << indent() << "(void) seqid;" << endl << indent() << "(void) oprot;" << endl; +@@ -3320,7 +3666,7 @@ void t_cpp_generator::generate_process_function(t_service* tservice, + out << indent() << "(void) seqid;" << endl << indent() << "(void) oprot;" << endl; + } + +- out << indent() << tservice->get_name() + "_" + tfunction->get_name() << "_args args;" << endl ++ out << indent() << tfunction->get_name() << "Req args;" << endl + << indent() << "void* ctx = NULL;" << endl << indent() + << "if (this->eventHandler_.get() != NULL) {" << endl << indent() + << " ctx = this->eventHandler_->getContext(" << service_func_name << ", NULL);" << endl +@@ -3487,7 +3833,7 @@ void t_cpp_generator::generate_process_function(t_service* tservice, + << "this->eventHandler_.get(), ctx, " << service_func_name << ");" << endl << endl; + + // Throw the TDelayedException, and catch the result +- out << indent() << tservice->get_name() << "_" << tfunction->get_name() << "_result result;" ++ out << indent() << tfunction->get_name() << "Resp result;" + << endl << endl << indent() << "try {" << endl; + indent_up(); + out << indent() << "_throw->throw_it();" << endl << indent() << "return cob(false);" +diff --git a/tutorial/cpp/CMakeLists.txt b/tutorial/cpp/CMakeLists.txt +deleted file mode 100644 +index 8a3d085..0000000 +--- a/tutorial/cpp/CMakeLists.txt ++++ /dev/null +@@ -1,53 +0,0 @@ +-# +-# Licensed to the Apache Software Foundation (ASF) under one +-# or more contributor license agreements. See the NOTICE file +-# distributed with this work for additional information +-# regarding copyright ownership. The ASF licenses this file +-# to you 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. +-# +- +-find_package(Boost 1.53.0 REQUIRED) +-include_directories(SYSTEM "${Boost_INCLUDE_DIRS}") +- +-#Make sure gen-cpp files can be included +-include_directories("${CMAKE_CURRENT_BINARY_DIR}") +-include_directories("${CMAKE_CURRENT_BINARY_DIR}/gen-cpp") +-include_directories("${PROJECT_SOURCE_DIR}/lib/cpp/src") +- +-include(ThriftMacros) +- +-set(tutorialgencpp_SOURCES +- gen-cpp/Calculator.cpp +- gen-cpp/SharedService.cpp +- gen-cpp/shared_constants.cpp +- gen-cpp/shared_types.cpp +- gen-cpp/tutorial_constants.cpp +- gen-cpp/tutorial_types.cpp +-) +-add_library(tutorialgencpp STATIC ${tutorialgencpp_SOURCES}) +-LINK_AGAINST_THRIFT_LIBRARY(tutorialgencpp thrift) +- +-add_custom_command(OUTPUT gen-cpp/Calculator.cpp gen-cpp/SharedService.cpp gen-cpp/shared_constants.cpp gen-cpp/shared_types.cpp gen-cpp/tutorial_constants.cpp gen-cpp/tutorial_types.cpp +- COMMAND ${THRIFT_COMPILER} --gen cpp -r ${PROJECT_SOURCE_DIR}/tutorial/tutorial.thrift +-) +- +-add_executable(TutorialServer CppServer.cpp) +-target_link_libraries(TutorialServer tutorialgencpp) +-LINK_AGAINST_THRIFT_LIBRARY(TutorialServer thrift) +-target_link_libraries(TutorialServer ${ZLIB_LIBRARIES}) +- +-add_executable(TutorialClient CppClient.cpp) +-target_link_libraries(TutorialClient tutorialgencpp) +-LINK_AGAINST_THRIFT_LIBRARY(TutorialClient thrift) +-target_link_libraries(TutorialClient ${ZLIB_LIBRARIES}) +diff --git a/tutorial/cpp/CppClient.cpp b/tutorial/cpp/CppClient.cpp +index 2763fee..c41604e 100644 +--- a/tutorial/cpp/CppClient.cpp ++++ b/tutorial/cpp/CppClient.cpp +@@ -1,80 +1,94 @@ + /* +- * Licensed to the Apache Software Foundation (ASF) under one +- * or more contributor license agreements. See the NOTICE file +- * distributed with this work for additional information +- * regarding copyright ownership. The ASF licenses this file +- * to you 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 ++ * 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. + * +- * 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 ++#include ++#include + +-#include +-#include +-#include +- +-#include "../gen-cpp/Calculator.h" ++#include + +-using namespace std; +-using namespace apache::thrift; +-using namespace apache::thrift::protocol; +-using namespace apache::thrift::transport; ++#include "gen-cpp/Greeter.grpc.thrift.h" + +-using namespace tutorial; +-using namespace shared; ++using grpc::Channel; ++using grpc::ClientContext; ++using grpc::Status; ++using test::Greeter; ++using namespace test; + +-int main() { +- boost::shared_ptr socket(new TSocket("localhost", 9090)); +- boost::shared_ptr transport(new TBufferedTransport(socket)); +- boost::shared_ptr protocol(new TBinaryProtocol(transport)); +- CalculatorClient client(protocol); ++class GreeterClient { ++ public: ++ GreeterClient(std::shared_ptr channel) ++ : stub_(Greeter::NewStub(channel)) {} + +- try { +- transport->open(); ++ // Assambles the client's payload, sends it and presents the response back ++ // from the server. ++ std::string SayHello(const std::string& user) { ++ // Data we are sending to the server. ++ Greeter::SayHelloReq req; ++ req.request.name = user; + +- client.ping(); +- cout << "ping()" << endl; ++ // Container for the data we expect from the server. ++ Greeter::SayHelloResp reply; + +- cout << "1 + 1 = " << client.add(1, 1) << endl; ++ // Context for the client. It could be used to convey extra information to ++ // the server and/or tweak certain RPC behaviors. ++ ClientContext context; + +- Work work; +- work.op = Operation::DIVIDE; +- work.num1 = 1; +- work.num2 = 0; ++ // The actual RPC. ++ Status status = stub_->SayHello(&context, req, &reply); + +- try { +- client.calculate(1, work); +- cout << "Whoa? We can divide by zero!" << endl; +- } catch (InvalidOperation& io) { +- cout << "InvalidOperation: " << io.why << endl; +- // or using generated operator<<: cout << io << endl; +- // or by using std::exception native method what(): cout << io.what() << endl; ++ // Act upon its status. ++ if (status.ok()) { ++ return reply.success.message; ++ } else { ++ return "RPC failed"; + } ++ } + +- work.op = Operation::SUBTRACT; +- work.num1 = 15; +- work.num2 = 10; +- int32_t diff = client.calculate(1, work); +- cout << "15 - 10 = " << diff << endl; ++ private: ++ std::unique_ptr stub_; ++}; + +- // Note that C++ uses return by reference for complex types to avoid +- // costly copy construction +- SharedStruct ss; +- client.getStruct(ss, 1); +- cout << "Received log: " << ss << endl; ++int main() { ++ // Instantiate the client. It requires a channel, out of which the actual RPCs ++ // are created. This channel models a connection to an endpoint (in this case, ++ // localhost at port 50051). We indicate that the channel isn't authenticated ++ // (use of InsecureChannelCredentials()). ++ GreeterClient greeter(grpc::CreateChannel( ++ "localhost:50051", grpc::InsecureChannelCredentials())); ++ std::string user("world"); ++ std::string reply = greeter.SayHello(user); ++ std::cout << "Greeter received: " << reply << std::endl; + +- transport->close(); +- } catch (TException& tx) { +- cout << "ERROR: " << tx.what() << endl; +- } ++ return 0; + } +diff --git a/tutorial/cpp/CppServer.cpp b/tutorial/cpp/CppServer.cpp +index eafffa9..c838b61 100644 +--- a/tutorial/cpp/CppServer.cpp ++++ b/tutorial/cpp/CppServer.cpp +@@ -1,181 +1,87 @@ + /* +- * Licensed to the Apache Software Foundation (ASF) under one +- * or more contributor license agreements. See the NOTICE file +- * distributed with this work for additional information +- * regarding copyright ownership. The ASF licenses this file +- * to you 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 ++ * 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. + * +- * 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 +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +- +-#include +- + #include +-#include +-#include +- +-#include "../gen-cpp/Calculator.h" ++#include ++#include + +-using namespace std; +-using namespace apache::thrift; +-using namespace apache::thrift::concurrency; +-using namespace apache::thrift::protocol; +-using namespace apache::thrift::transport; +-using namespace apache::thrift::server; ++#include + +-using namespace tutorial; +-using namespace shared; ++#include "gen-cpp/Greeter.grpc.thrift.h" ++#include + +-class CalculatorHandler : public CalculatorIf { +-public: +- CalculatorHandler() {} ++using grpc::Server; ++using grpc::ServerBuilder; ++using grpc::ServerContext; ++using grpc::Status; ++using test::Greeter; + +- void ping() { cout << "ping()" << endl; } ++using namespace grpc; ++using namespace test; + +- int32_t add(const int32_t n1, const int32_t n2) { +- cout << "add(" << n1 << ", " << n2 << ")" << endl; +- return n1 + n2; +- } ++// Logic and data behind the server's behavior. ++class GreeterServiceImpl final : public Greeter::Service { ++ Status SayHello(ServerContext* context,const Greeter::SayHelloReq* request, ++ Greeter::SayHelloResp* reply) override { ++ std::string prefix("Hello "); + +- int32_t calculate(const int32_t logid, const Work& work) { +- cout << "calculate(" << logid << ", " << work << ")" << endl; +- int32_t val; ++ reply->success.message = prefix + request->request.name; + +- switch (work.op) { +- case Operation::ADD: +- val = work.num1 + work.num2; +- break; +- case Operation::SUBTRACT: +- val = work.num1 - work.num2; +- break; +- case Operation::MULTIPLY: +- val = work.num1 * work.num2; +- break; +- case Operation::DIVIDE: +- if (work.num2 == 0) { +- InvalidOperation io; +- io.whatOp = work.op; +- io.why = "Cannot divide by 0"; +- throw io; +- } +- val = work.num1 / work.num2; +- break; +- default: +- InvalidOperation io; +- io.whatOp = work.op; +- io.why = "Invalid Operation"; +- throw io; +- } +- +- SharedStruct ss; +- ss.key = logid; +- ss.value = to_string(val); +- +- log[logid] = ss; +- +- return val; ++ return Status::OK; + } +- +- void getStruct(SharedStruct& ret, const int32_t logid) { +- cout << "getStruct(" << logid << ")" << endl; +- ret = log[logid]; +- } +- +- void zip() { cout << "zip()" << endl; } +- +-protected: +- map log; + }; + +-/* +- CalculatorIfFactory is code generated. +- CalculatorCloneFactory is useful for getting access to the server side of the +- transport. It is also useful for making per-connection state. Without this +- CloneFactory, all connections will end up sharing the same handler instance. +-*/ +-class CalculatorCloneFactory : virtual public CalculatorIfFactory { +- public: +- virtual ~CalculatorCloneFactory() {} +- virtual CalculatorIf* getHandler(const ::apache::thrift::TConnectionInfo& connInfo) +- { +- boost::shared_ptr sock = boost::dynamic_pointer_cast(connInfo.transport); +- cout << "Incoming connection\n"; +- cout << "\tSocketInfo: " << sock->getSocketInfo() << "\n"; +- cout << "\tPeerHost: " << sock->getPeerHost() << "\n"; +- cout << "\tPeerAddress: " << sock->getPeerAddress() << "\n"; +- cout << "\tPeerPort: " << sock->getPeerPort() << "\n"; +- return new CalculatorHandler; +- } +- virtual void releaseHandler( ::shared::SharedServiceIf* handler) { +- delete handler; +- } +-}; ++void RunServer() { ++ std::string server_address("0.0.0.0:50051"); ++ GreeterServiceImpl service; ++ ++ ServerBuilder builder; ++ // Listen on the given address without any authentication mechanism. ++ builder.AddListeningPort(server_address, grpc::InsecureServerCredentials()); ++ // Register "service" as the instance through which we'll communicate with ++ // clients. In this case it corresponds to an *synchronous* service. ++ builder.RegisterService(&service); ++ // Finally assemble the server. ++ std::unique_ptr server(builder.BuildAndStart()); ++ std::cout << "Server listening on " << server_address << std::endl; ++ ++ // Wait for the server to shutdown. Note that some other thread must be ++ // responsible for shutting down the server for this call to ever return. ++ server->Wait(); ++} + + int main() { +- TThreadedServer server( +- boost::make_shared(boost::make_shared()), +- boost::make_shared(9090), //port +- boost::make_shared(), +- boost::make_shared()); +- +- /* +- // if you don't need per-connection state, do the following instead +- TThreadedServer server( +- boost::make_shared(boost::make_shared()), +- boost::make_shared(9090), //port +- boost::make_shared(), +- boost::make_shared()); +- */ +- +- /** +- * Here are some alternate server types... +- +- // This server only allows one connection at a time, but spawns no threads +- TSimpleServer server( +- boost::make_shared(boost::make_shared()), +- boost::make_shared(9090), +- boost::make_shared(), +- boost::make_shared()); +- +- const int workerCount = 4; +- +- boost::shared_ptr threadManager = +- ThreadManager::newSimpleThreadManager(workerCount); +- threadManager->threadFactory( +- boost::make_shared()); +- threadManager->start(); +- +- // This server allows "workerCount" connection at a time, and reuses threads +- TThreadPoolServer server( +- boost::make_shared(boost::make_shared()), +- boost::make_shared(9090), +- boost::make_shared(), +- boost::make_shared(), +- threadManager); +- */ ++ RunServer(); + +- cout << "Starting the server..." << endl; +- server.serve(); +- cout << "Done." << endl; + return 0; + } +diff --git a/tutorial/cpp/Makefile.am b/tutorial/cpp/Makefile.am +index 184a69d..581f75e 100755 +--- a/tutorial/cpp/Makefile.am ++++ b/tutorial/cpp/Makefile.am +@@ -18,44 +18,38 @@ + # + AUTOMAKE_OPTIONS = subdir-objects serial-tests + +-BUILT_SOURCES = gen-cpp/shared_types.cpp \ +- gen-cpp/tutorial_types.cpp ++BUILT_SOURCES = gen-cpp/test_types.cpp + +-noinst_LTLIBRARIES = libtutorialgencpp.la +-nodist_libtutorialgencpp_la_SOURCES = \ +- gen-cpp/Calculator.cpp \ +- gen-cpp/Calculator.h \ +- gen-cpp/SharedService.cpp \ +- gen-cpp/SharedService.h \ +- gen-cpp/shared_constants.cpp \ +- gen-cpp/shared_constants.h \ +- gen-cpp/shared_types.cpp \ +- gen-cpp/shared_types.h \ +- gen-cpp/tutorial_constants.cpp \ +- gen-cpp/tutorial_constants.h \ +- gen-cpp/tutorial_types.cpp \ +- gen-cpp/tutorial_types.h ++#noinst_LTLIBRARIES = libtutorialgencpp.la ++noinst_LTLIBRARIES = libtestgencpp.la ++nodist_libtestgencpp_la_SOURCES = \ ++ gen-cpp/Greeter.grpc.thrift.cpp \ ++ gen-cpp/Greeter.grpc.thrift.h \ ++ gen-cpp/test_constants.cpp \ ++ gen-cpp/test_constants.h \ ++ gen-cpp/test_types.cpp \ ++ gen-cpp/test_types.h + + + +-libtutorialgencpp_la_LIBADD = $(top_builddir)/lib/cpp/libthrift.la ++libtestgencpp_la_LIBADD = $(top_builddir)/lib/cpp/libthrift.la + + noinst_PROGRAMS = \ +- TutorialServer \ +- TutorialClient ++ TestServer \ ++ TestClient + +-TutorialServer_SOURCES = \ ++TestServer_SOURCES = \ + CppServer.cpp + +-TutorialServer_LDADD = \ +- libtutorialgencpp.la \ ++TestServer_LDADD = \ ++ libtestgencpp.la \ + $(top_builddir)/lib/cpp/libthrift.la + +-TutorialClient_SOURCES = \ ++TestClient_SOURCES = \ + CppClient.cpp + +-TutorialClient_LDADD = \ +- libtutorialgencpp.la \ ++TestClient_LDADD = \ ++ libtestgencpp.la \ + $(top_builddir)/lib/cpp/libthrift.la + + # +@@ -63,21 +57,21 @@ TutorialClient_LDADD = \ + # + THRIFT = $(top_builddir)/compiler/cpp/thrift + +-gen-cpp/Calculator.cpp gen-cpp/SharedService.cpp gen-cpp/shared_constants.cpp gen-cpp/shared_types.cpp gen-cpp/tutorial_constants.cpp gen-cpp/tutorial_types.cpp: $(top_srcdir)/tutorial/tutorial.thrift ++gen-cpp/Greeter.grpc.thrift.cpp gen-cpp/test_constants.cpp gen-cpp/test_types.cpp: $(top_srcdir)/tutorial/cpp/test.thrift + $(THRIFT) --gen cpp -r $< + + AM_CPPFLAGS = $(BOOST_CPPFLAGS) $(LIBEVENT_CPPFLAGS) -I$(top_srcdir)/lib/cpp/src -Igen-cpp + AM_CXXFLAGS = -Wall -Wextra -pedantic +-AM_LDFLAGS = $(BOOST_LDFLAGS) $(LIBEVENT_LDFLAGS) ++AM_LDFLAGS = $(BOOST_LDFLAGS) $(LIBEVENT_LDFLAGS) `pkg-config --libs grpc++ grpc` -lpthread -ldl -lgrpc + + clean-local: +- $(RM) gen-cpp/* ++ $(RM) -r gen-cpp + +-tutorialserver: all +- ./TutorialServer ++testserver: all ++ ./TestServer + +-tutorialclient: all +- ./TutorialClient ++testclient: all ++ ./TestClient + + style-local: + $(CPPSTYLE_CMD) +diff --git a/tutorial/cpp/test.thrift b/tutorial/cpp/test.thrift +new file mode 100644 +index 0000000..de3c9a4 +--- /dev/null ++++ b/tutorial/cpp/test.thrift +@@ -0,0 +1,13 @@ ++namespace cpp test ++ ++struct HelloRequest { ++ 1:string name ++} ++ ++struct HelloResponse { ++ 1:string message ++} ++ ++service Greeter { ++ HelloResponse SayHello(1:HelloRequest request); ++} +\ No newline at end of file +-- +2.8.0.rc3.226.g39d4020 + + +From 1d47ed062e62d136c3db9f6fc1dde9e2f794cf22 Mon Sep 17 00:00:00 2001 +From: chedeti +Date: Sun, 31 Jul 2016 16:23:53 -0700 +Subject: [PATCH 3/3] grpc java plugins generator + +for examples refer to https://github.com/grpc/grpc-java/tree/master/examples/thrift +--- + compiler/cpp/src/generate/t_java_generator.cc | 906 +++++++++++++++++++++++++- + tutorial/Makefile.am | 8 +- + 2 files changed, 887 insertions(+), 27 deletions(-) + +diff --git a/compiler/cpp/src/generate/t_java_generator.cc b/compiler/cpp/src/generate/t_java_generator.cc +index 2db8cb8..95e1ca8 100644 +--- a/compiler/cpp/src/generate/t_java_generator.cc ++++ b/compiler/cpp/src/generate/t_java_generator.cc +@@ -97,10 +97,10 @@ public: + } else if(iter->second.compare("suppress") == 0) { + suppress_generated_annotations_ = true; + } else { +- throw "unknown option java:" + iter->first + "=" + iter->second; ++ throw "unknown option java:" + iter->first + "=" + iter->second; + } + } else { +- throw "unknown option java:" + iter->first; ++ throw "unknown option java:" + iter->first; + } + } + +@@ -195,6 +195,17 @@ public: + void generate_service_async_server(t_service* tservice); + void generate_process_function(t_service* tservice, t_function* tfunction); + void generate_process_async_function(t_service* tservice, t_function* tfunction); ++ void generate_service_impl_base(t_service* tservice); ++ void generate_method_descriptors(t_service* tservice); ++ void generate_stub(t_service* tservice); ++ void generate_blocking_stub(t_service* tservice); ++ void generate_future_stub(t_service* tservice); ++ void generate_method_ids(t_service* tservice); ++ void generate_method_handlers(t_service* tservice); ++ void generate_service_descriptors(t_service* tservice); ++ void generate_service_builder(t_service* tservice); ++ void generate_arg_ids(t_service* tservice); ++ void generate_message_factory(t_service* tservice); + + void generate_java_union(t_struct* tstruct); + void generate_union_constructor(ofstream& out, t_struct* tstruct); +@@ -307,6 +318,8 @@ public: + std::string java_package(); + std::string java_type_imports(); + std::string java_suppressions(); ++ std::string grpc_imports(); ++ std::string import_extended_service(t_service* tservice); + std::string type_name(t_type* ttype, + bool in_container = false, + bool in_init = false, +@@ -368,7 +381,7 @@ private: + bool use_option_type_; + bool undated_generated_annotations_; + bool suppress_generated_annotations_; +- ++ + }; + + /** +@@ -456,6 +469,35 @@ string t_java_generator::java_suppressions() { + return "@SuppressWarnings({\"cast\", \"rawtypes\", \"serial\", \"unchecked\", \"unused\"})\n"; + } + ++string t_java_generator::grpc_imports() { ++ return ++ string() + ++ "import static io.grpc.stub.ClientCalls.asyncUnaryCall;\n" + ++ "import static io.grpc.stub.ClientCalls.asyncServerStreamingCall;\n" + ++ "import static io.grpc.stub.ClientCalls.asyncClientStreamingCall;\n" + ++ "import static io.grpc.stub.ClientCalls.asyncBidiStreamingCall;\n" + ++ "import static io.grpc.stub.ClientCalls.blockingUnaryCall;\n" + ++ "import static io.grpc.stub.ClientCalls.blockingServerStreamingCall;\n" + ++ "import static io.grpc.stub.ClientCalls.futureUnaryCall;\n" + ++ "import static io.grpc.MethodDescriptor.generateFullMethodName;\n" + ++ "import static io.grpc.stub.ServerCalls.asyncUnaryCall;\n" + ++ "import static io.grpc.stub.ServerCalls.asyncServerStreamingCall;\n" + ++ "import static io.grpc.stub.ServerCalls.asyncClientStreamingCall;\n" + ++ "import static io.grpc.stub.ServerCalls.asyncBidiStreamingCall;\n" + ++ "import static io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall;\n" + ++ "import static io.grpc.stub.ServerCalls.asyncUnimplementedStreamingCall;\n" + ++ "import io.grpc.thrift.ThriftUtils;\n\n"; ++} ++ ++string t_java_generator::import_extended_service(t_service* tservice) { ++ if (tservice == nullptr) { ++ return string() + "\n"; ++ } ++ string ns = tservice->get_program()->get_namespace("java"); ++ string extend_service_name = tservice->get_name() + "Grpc"; ++ return string() + "import " + ns + "." + extend_service_name + ";\n\n"; ++} ++ + /** + * Nothing in Java + */ +@@ -2772,25 +2814,51 @@ void t_java_generator::generate_field_value_meta_data(std::ofstream& out, t_type + */ + void t_java_generator::generate_service(t_service* tservice) { + // Make output file +- string f_service_name = package_dir_ + "/" + make_valid_java_filename(service_name_) + ".java"; ++ string f_service_name = package_dir_ + "/" + make_valid_java_filename(service_name_) + "Grpc.java"; + f_service_.open(f_service_name.c_str()); + +- f_service_ << autogen_comment() << java_package() << java_type_imports() << java_suppressions(); ++ f_service_ << ++ autogen_comment() << ++ java_package() << ++ java_type_imports() << ++ grpc_imports() << ++ import_extended_service(tservice->get_extends()); ++ java_suppressions(); ++ ++ f_service_ << ++ "public class " << service_name_ << "Grpc {" << endl << ++ endl; + +- if (!suppress_generated_annotations_) { +- generate_javax_generated_annotation(f_service_); +- } +- f_service_ << "public class " << service_name_ << " {" << endl << endl; + indent_up(); + ++ // generate constructor ++ f_service_ << ++ indent() << "private " << service_name_ << ++ "Grpc() {}" << endl << endl; ++ ++ f_service_ << ++ indent() << "public static final String SERVICE_NAME = " << ++ "\"" << package_name_ << "." << service_name_ << "\";" << endl << endl; ++ + // Generate the three main parts of the service + generate_service_interface(tservice); +- generate_service_async_interface(tservice); +- generate_service_client(tservice); +- generate_service_async_client(tservice); +- generate_service_server(tservice); +- generate_service_async_server(tservice); ++ generate_arg_ids(tservice); ++ generate_message_factory(tservice); ++ generate_service_impl_base(tservice); ++ //generate_service_async_interface(tservice); ++ //generate_service_client(tservice); ++ //generate_service_async_client(tservice); ++ //generate_service_server(tservice); ++ //generate_service_async_server(tservice); + generate_service_helpers(tservice); ++ generate_method_descriptors(tservice); ++ generate_stub(tservice); ++ generate_blocking_stub(tservice); ++ generate_future_stub(tservice); ++ generate_method_ids(tservice); ++ generate_method_handlers(tservice); ++ generate_service_descriptors(tservice); ++ generate_service_builder(tservice); + + indent_down(); + f_service_ << "}" << endl; +@@ -2805,24 +2873,820 @@ void t_java_generator::generate_service(t_service* tservice) { + void t_java_generator::generate_service_interface(t_service* tservice) { + string extends = ""; + string extends_iface = ""; +- if (tservice->get_extends() != NULL) { +- extends = type_name(tservice->get_extends()); +- extends_iface = " extends " + extends + ".Iface"; +- } + + generate_java_doc(f_service_, tservice); +- f_service_ << indent() << "public interface Iface" << extends_iface << " {" << endl << endl; ++ f_service_ << indent() << ++ "@java.lang.Deprecated public static interface " << service_name_; ++ ++ if (tservice->get_extends() != nullptr) { ++ f_service_ << " extends " << tservice->get_extends()->get_name() + "Grpc." << ++ tservice->get_extends()->get_name() << endl; ++ } ++ f_service_ << " {" << endl; ++ ++ indent_up(); ++ vector functions = tservice->get_functions(); ++ vector::iterator f_iter; ++ for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { ++ //generate_java_doc(f_service_, *f_iter); ++ f_service_ << ++ indent() << "public void " << (*f_iter)->get_name() << "(" << (*f_iter)->get_name() << ++ "_args request," << endl << ++ indent() << " io.grpc.stub.StreamObserver<" << (*f_iter)->get_name() << ++ "_result> responseObserver);" << endl << endl; ++ } ++ indent_down(); ++ f_service_ << indent() << "}" << endl << endl; ++} ++ ++void t_java_generator::generate_arg_ids(t_service* tservice) { ++ vector functions = tservice->get_functions(); ++ vector::iterator f_iter; ++ int i=0; ++ for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { ++ f_service_ << indent() << ++ "private static final int ARG_IN_METHOD_" << ++ (*f_iter)->get_name() << " = " << ++i << ";" << endl; ++ f_service_ << indent() << ++ "private static final int ARG_OUT_METHOD_" << ++ (*f_iter)->get_name() << " = " << ++i << ";" << endl; ++ } ++ f_service_ << endl; ++ ++ if (tservice->get_extends() != nullptr) { ++ f_service_ << indent() << "// ARG IDs for extended service" << endl; ++ t_service* extend_service = tservice->get_extends(); ++ functions = extend_service->get_functions(); ++ for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { ++ f_service_ << indent() << ++ "private static final int ARG_IN_METHOD_" << ++ (*f_iter)->get_name() << " = " << ++i << ";" << endl; ++ f_service_ << indent() << ++ "private static final int ARG_OUT_METHOD_" << ++ (*f_iter)->get_name() << " = " << ++i << ";" << endl; ++ } ++ f_service_ << endl; ++ } ++} ++ ++void t_java_generator::generate_message_factory(t_service* tservice) { ++ f_service_ << indent() << ++ "private static final class ThriftMessageFactory>" << endl << indent() << ++ " implements io.grpc.thrift.MessageFactory {" << endl; ++ indent_up(); ++ f_service_ << indent() << ++ "private final int id;" << endl << endl; ++ f_service_ << endl; ++ ++ f_service_ << indent() << ++ "ThriftMessageFactory(int id) {" << endl << ++ indent() << " this.id = id;" << endl << ++ indent() << "}" << endl; ++ ++ f_service_ << indent() << ++ "@java.lang.Override" << endl << ++ indent() << "public T newInstance() {" << endl; ++ indent_up(); ++ ++ f_service_ << indent() << ++ "Object o;" << endl << ++ indent() << "switch (id) {" << endl; ++ ++ vector functions = tservice->get_functions(); ++ vector::iterator f_iter; ++ for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { ++ f_service_ << indent() << ++ "case ARG_IN_METHOD_" << (*f_iter)->get_name() << ":" << endl << ++ indent() << " o = new " << (*f_iter)->get_name() << "_args();" << ++ endl << indent() << " break;" << endl; ++ f_service_ << indent() << ++ "case ARG_OUT_METHOD_" << (*f_iter)->get_name() << ":" << endl << ++ indent() << " o = new " << (*f_iter)->get_name() << "_result();" << ++ endl << indent() << " break;" << endl; ++ } ++ ++ if (tservice->get_extends() != nullptr) { ++ t_service* extend_service = tservice->get_extends(); ++ functions = extend_service->get_functions(); ++ string extend_service_name = extend_service->get_name() + "Grpc"; ++ for (f_iter = functions.begin(); f_iter!= functions.end(); ++f_iter) { ++ f_service_ << indent() << ++ "case ARG_IN_METHOD_" << (*f_iter)->get_name() << ":" << endl << ++ indent() << " o = new " << extend_service_name << "." << (*f_iter)->get_name() << "_args();" << ++ endl << indent() << " break;" << endl; ++ f_service_ << indent() << ++ "case ARG_OUT_METHOD_" << (*f_iter)->get_name() << ":" << endl << ++ indent() << " o = new " << extend_service_name << "." << (*f_iter)->get_name() << "_result();" << ++ endl << indent() << " break;" << endl; ++ } ++ } ++ ++ f_service_ << indent() << ++ "default:" << endl << indent() << ++ " throw new AssertionError();" << endl << indent() << ++ "}" << endl; ++ ++ f_service_ << indent() << ++ "@java.lang.SuppressWarnings(\"unchecked\")" << endl << ++ indent() << "T t = (T) o;" << endl << indent() << ++ "return t;" << endl; ++ ++ indent_down(); ++ f_service_ << ++ indent() << "}" << endl; ++ ++ indent_down(); ++ f_service_ << indent() << "}" << endl; ++} ++ ++void t_java_generator::generate_service_impl_base(t_service* tservice) { ++ f_service_ << ++ indent() << "public static abstract class " << service_name_ << ++ "ImplBase implements " << service_name_ << ", io.grpc.BindableService {" << endl; ++ indent_up(); ++ ++ vector functions = tservice->get_functions(); ++ vector::iterator f_iter; ++ for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { ++ f_service_ << ++ indent() << "@java.lang.Override" << endl << ++ indent() << "public void " << (*f_iter)->get_name() << "(" << (*f_iter)->get_name() << ++ "_args request, " << endl << ++ indent() << " io.grpc.stub.StreamObserver<" << (*f_iter)->get_name() << ++ "_result> responseObserver) {" << endl; ++ indent_up(); ++ f_service_ << ++ indent() << "asyncUnimplementedUnaryCall(METHOD_" << (*f_iter)->get_name() << ++ ", responseObserver);" << endl; ++ indent_down(); ++ f_service_ << ++ indent() << "}" << endl << endl; ++ } ++ ++ if (tservice->get_extends() != nullptr) { ++ t_service* extend_service = tservice->get_extends(); ++ functions = extend_service->get_functions(); ++ string extend_service_name = extend_service->get_name() + "Grpc" ; ++ for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { ++ f_service_ << ++ indent() << "@java.lang.Override" << endl << ++ indent() << "public void " << (*f_iter)->get_name() << "(" << ++ extend_service_name << "." << (*f_iter)->get_name() << ++ "_args request, " << endl << ++ indent() << " io.grpc.stub.StreamObserver<" << extend_service_name ++ << "." << (*f_iter)->get_name() << "_result> responseObserver) {" << endl; ++ indent_up(); ++ f_service_ << ++ indent() << "asyncUnimplementedUnaryCall(METHOD_" << (*f_iter)->get_name() << ++ ", responseObserver);" << endl; ++ indent_down(); ++ f_service_ << ++ indent() << "}" << endl << endl; ++ } ++ } ++ ++ f_service_ << ++ indent() << "@java.lang.Override" << ++ " public io.grpc.ServerServiceDefinition bindService() {" << endl; + indent_up(); ++ f_service_ << ++ indent() << "return " << service_name_ << "Grpc.bindService(this);" << endl; ++ indent_down(); ++ f_service_ << ++ indent() << "}" << endl << endl; ++ ++ indent_down(); ++ f_service_ << ++ indent() << "}" << endl << endl; ++ ++ // generate Abstract Service ++ f_service_ << ++ indent() << "@java.lang.Deprecated public static abstract class Abstract" << service_name_ << ++ " extends " << service_name_ << "ImplBase {}" << endl << endl; ++} ++ ++void t_java_generator::generate_method_descriptors(t_service* tservice) { ++ vector functions = tservice->get_functions(); ++ vector::iterator f_iter; ++ for( f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { ++ f_service_ << ++ indent() << "public static final io.grpc.MethodDescriptor<" << ++ (*f_iter)->get_name() << "_args," << endl << ++ indent() << " " << (*f_iter)->get_name() << "_result> METHOD_" << (*f_iter)->get_name() << ++ " = " << endl << indent() << " io.grpc.MethodDescriptor.create(" << endl; ++ indent_up(); ++ f_service_ << ++ indent() << " io.grpc.MethodDescriptor.MethodType.UNARY," << endl << ++ indent() << " generateFullMethodName(" << "\"" << package_name_ << "." << ++ service_name_ << "\" , \"" << (*f_iter)->get_name() << "\")," << endl << ++ indent() << " io.grpc.thrift.ThriftUtils.marshaller(" << endl << ++ indent() << " new ThriftMessageFactory<" << (*f_iter)->get_name() << ++ "_args>( ARG_IN_METHOD_" << (*f_iter)->get_name() << "))," << endl << ++ indent() << " io.grpc.thrift.ThriftUtils.marshaller(" << endl << ++ indent() << " new ThriftMessageFactory<" << (*f_iter)->get_name() << ++ "_result>( ARG_OUT_METHOD_" << (*f_iter)->get_name() << ")));" << endl << endl; ++ indent_down(); ++ } ++ ++ if(tservice->get_extends() != nullptr) { ++ t_service* extends_service = tservice->get_extends(); ++ functions = extends_service->get_functions(); ++ string extend_service_name = extends_service->get_name() + "Grpc"; ++ for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { ++ f_service_ << ++ indent() << "public static final io.grpc.MethodDescriptor<" << extend_service_name << "." << ++ (*f_iter)->get_name() << "_args," << endl << ++ indent() << " " << extend_service_name << "." << (*f_iter)->get_name() << "_result> METHOD_" ++ << (*f_iter)->get_name() << " = " << endl << indent() << ++ " io.grpc.MethodDescriptor.create(" << endl; ++ indent_up(); ++ f_service_ << ++ indent() << " io.grpc.MethodDescriptor.MethodType.UNARY," << endl << ++ indent() << " generateFullMethodName(" << "\"" << package_name_ << "." << ++ service_name_ << "\" , \"" << (*f_iter)->get_name() << "\")," << endl << ++ indent() << " io.grpc.thrift.ThriftUtils.marshaller(" << endl << ++ indent() << " new ThriftMessageFactory<" << extend_service_name << "." << ++ (*f_iter)->get_name() << "_args>( ARG_IN_METHOD_" << (*f_iter)->get_name() << "))," << endl << ++ indent() << " io.grpc.thrift.ThriftUtils.marshaller(" << endl << ++ indent() << " new ThriftMessageFactory<" << extend_service_name << "." << (*f_iter)->get_name() << ++ "_result>( ARG_OUT_METHOD_" << (*f_iter)->get_name() << ")));" << endl << endl; ++ indent_down(); ++ } ++ } ++} ++ ++void t_java_generator::generate_stub(t_service* tservice) { ++ f_service_ << ++ indent() << ++ "public static " << service_name_ << ++ "Stub newStub(io.grpc.Channel channel) {" << ++ endl; ++ ++ indent_up(); ++ f_service_ << ++ indent() << ++ "return new " << service_name_ << "Stub(channel);" << endl; ++ indent_down(); ++ f_service_ << ++ indent() << "}" << endl << endl; ++ ++ // generate Stub impl ++ ++ f_service_ << ++ indent() << "public static class " << ++ service_name_ << "Stub extends io.grpc.stub.AbstractStub<" << ++ service_name_ << "Stub>" << endl << ++ indent() << " implements " << service_name_ << "{" << endl; ++ indent_up(); ++ ++ f_service_ << ++ indent() << "private " << service_name_ << "Stub(io.grpc.Channel channel) {" << endl; ++ indent_up(); ++ f_service_ << ++ indent() << "super(channel);" << endl; ++ indent_down(); ++ f_service_ << ++ indent() << "}" << endl << endl; ++ ++ f_service_ << ++ indent() << "private " << service_name_ << "Stub(io.grpc.Channel channel, " << endl << ++ indent() << " io.grpc.CallOptions callOptions) {" << endl; ++ indent_up(); ++ f_service_ << ++ indent() << "super(channel, callOptions);" << endl; ++ indent_down(); ++ f_service_ << ++ indent() << "}" << endl << endl; ++ ++ f_service_ << ++ indent() << "@java.lang.Override" << endl << ++ indent() << "protected " << service_name_ << "Stub build(io.grpc.Channel channel, " << ++ endl << indent() << " io.grpc.CallOptions callOptions) {" << endl; ++ indent_up(); ++ f_service_ << ++ indent() << "return new " << service_name_ << "Stub(channel, callOptions);" << endl; ++ indent_down(); ++ f_service_ << ++ indent() << "}" << endl << endl; ++ ++ vector functions = tservice->get_functions(); ++ vector::iterator f_iter; ++ for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { ++ f_service_ << ++ indent() << "@java.lang.Override" << endl << ++ indent() << "public void " << (*f_iter)->get_name() << "(" << ++ (*f_iter)->get_name() << "_args request," << endl << indent() << ++ " io.grpc.stub.StreamObserver<" << (*f_iter)->get_name() << ++ "_result> responseObserver) {" << endl; ++ indent_up(); ++ f_service_ << ++ indent() << "asyncUnaryCall(" << endl << ++ indent() << " getChannel().newCall(METHOD_" << (*f_iter)->get_name() << ++ ", getCallOptions()), request, responseObserver);" << endl; ++ indent_down(); ++ f_service_ << ++ indent() << "}" << endl << endl; ++ } ++ ++ if (tservice->get_extends() != nullptr) { ++ t_service* extend_service = tservice->get_extends(); ++ functions = extend_service->get_functions(); ++ string extend_service_name = extend_service->get_name() + "Grpc"; ++ for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { ++ f_service_ << ++ indent() << "@java.lang.Override" << endl << ++ indent() << "public void " << (*f_iter)->get_name() << "(" << ++ extend_service_name << "." << (*f_iter)->get_name() << "_args request," ++ << endl << indent() << " io.grpc.stub.StreamObserver<" << ++ extend_service_name << "." << (*f_iter)->get_name() << ++ "_result> responseObserver) {" << endl; ++ indent_up(); ++ f_service_ << ++ indent() << "asyncUnaryCall(" << endl << ++ indent() << " getChannel().newCall(METHOD_" << (*f_iter)->get_name() << ++ ", getCallOptions()), request, responseObserver);" << endl; ++ indent_down(); ++ f_service_ << ++ indent() << "}" << endl << endl; ++ } ++ } ++ indent_down(); ++ f_service_ << ++ indent() << "}" << endl << endl; ++} ++ ++void t_java_generator::generate_blocking_stub(t_service* tservice) { ++ f_service_ << ++ indent() << "public static " << service_name_ << ++ "BlockingStub newBlockingStub(" << endl << ++ indent() << " io.grpc.Channel channel) {" << endl; ++ indent_up(); ++ f_service_ << ++ indent() << "return new " << service_name_ << "BlockingStub(channel);" << endl; ++ indent_down(); ++ f_service_ << ++ indent() << "}" << endl << endl; ++ ++ // generate Blocking Client ++ f_service_ << ++ indent() << "@java.lang.Deprecated public static interface " << service_name_ << ++ "BlockingClient " ; ++ ++ if (tservice->get_extends() != nullptr) { ++ string extend_service_name = tservice->get_extends()->get_name(); ++ f_service_ << endl << indent() << " extends " << extend_service_name << "Grpc." << ++ extend_service_name << "BlockingClient " ; ++ } ++ ++ f_service_ << "{" << endl; ++ ++ indent_up(); ++ + vector functions = tservice->get_functions(); + vector::iterator f_iter; + for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { +- generate_java_doc(f_service_, *f_iter); +- indent(f_service_) << "public " << function_signature(*f_iter) << ";" << endl << endl; ++ f_service_ << ++ indent() << "public " << (*f_iter)->get_name() << "_result " << ++ (*f_iter)->get_name() << "(" << (*f_iter)->get_name() << "_args request);" << endl << endl; ++ } ++ indent_down(); ++ f_service_ << ++ indent() << "}" << endl << endl; ++ ++ // generate Blocking Stub impl ++ ++ f_service_ << ++ indent() << "public static class " << ++ service_name_ << "BlockingStub extends io.grpc.stub.AbstractStub<" << ++ service_name_ << "BlockingStub>" << endl << ++ indent() << " implements " << service_name_ << "BlockingClient {"; ++ ++ indent_up(); ++ ++ f_service_ << ++ indent() << "private " << service_name_ << "BlockingStub(io.grpc.Channel channel) {" << endl; ++ indent_up(); ++ f_service_ << ++ indent() << "super(channel);" << endl; ++ indent_down(); ++ f_service_ << ++ indent() << "}" << endl << endl; ++ ++ f_service_ << ++ indent() << "private " << service_name_ << "BlockingStub(io.grpc.Channel channel, " << endl << ++ indent() << " io.grpc.CallOptions callOptions) {" << endl; ++ indent_up(); ++ f_service_ << ++ indent() << "super(channel, callOptions);" << endl; ++ indent_down(); ++ f_service_ << ++ indent() << "}" << endl << endl; ++ ++ f_service_ << ++ indent() << "@java.lang.Override" << endl << ++ indent() << "protected " << service_name_ << "BlockingStub build(io.grpc.Channel channel, " << ++ endl << indent() << " io.grpc.CallOptions callOptions) {" << endl; ++ indent_up(); ++ f_service_ << ++ indent() << "return new " << service_name_ << "BlockingStub(channel, callOptions);" << endl; ++ indent_down(); ++ f_service_ << ++ indent() << "}" << endl << endl; ++ ++ for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { ++ f_service_ << ++ indent() << "@java.lang.Override" << endl << ++ indent() << "public " << (*f_iter)->get_name() << "_result " << (*f_iter)->get_name() << "(" << ++ (*f_iter)->get_name() << "_args request) {" << endl; ++ indent_up(); ++ f_service_ << ++ indent() << "return blockingUnaryCall(" << endl << ++ indent() << " getChannel(), METHOD_" << (*f_iter)->get_name() << ++ ", getCallOptions(), request);" << endl; ++ indent_down(); ++ f_service_ << ++ indent() << "}" << endl << endl; ++ } ++ ++ if (tservice->get_extends() != nullptr) { ++ t_service* extend_service = tservice->get_extends(); ++ functions = extend_service->get_functions(); ++ string extend_service_name = extend_service->get_name() + "Grpc"; ++ for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { ++ f_service_ << ++ indent() << "@java.lang.Override" << endl << ++ indent() << "public " << extend_service_name << "." << (*f_iter)->get_name() << ++ "_result " << (*f_iter)->get_name() << "(" << extend_service_name << "." << ++ (*f_iter)->get_name() << "_args request) {" << endl; ++ indent_up(); ++ f_service_ << ++ indent() << "return blockingUnaryCall(" << endl << ++ indent() << " getChannel(), METHOD_" << (*f_iter)->get_name() << ++ ", getCallOptions(), request);" << endl; ++ indent_down(); ++ f_service_ << ++ indent() << "}" << endl << endl; ++ } ++ } ++ indent_down(); ++ f_service_ << ++ indent() << "}" << endl << endl; ++} ++ ++void t_java_generator::generate_future_stub(t_service* tservice) { ++ f_service_ << ++ indent() << "public static " << service_name_ << ++ "FutureStub newFutureStub(" << endl << ++ indent() << " io.grpc.Channel channel) {" << endl; ++ indent_up(); ++ f_service_ << ++ indent() << "return new " << service_name_ << "FutureStub(channel);" << endl; ++ indent_down(); ++ f_service_ << ++ indent() << "}" << endl << endl; ++ ++ // generate Future Client ++ f_service_ << ++ indent() << "@java.lang.Deprecated public static interface " << service_name_ << ++ "FutureClient " ; ++ ++ if (tservice->get_extends() != nullptr) { ++ string extend_service_name = tservice->get_extends()->get_name(); ++ f_service_ << endl << indent() << " extends " << extend_service_name << "Grpc." << ++ extend_service_name << "FutureClient " ; ++ } ++ f_service_ << "{" << endl; ++ ++ indent_up(); ++ ++ vector functions = tservice->get_functions(); ++ vector::iterator f_iter; ++ for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { ++ f_service_ << ++ indent() << "public com.google.common.util.concurrent.ListenableFuture<" << ++ (*f_iter)->get_name() << "_result> " << (*f_iter)->get_name() << "(" << endl << ++ indent() << " " << (*f_iter)->get_name() << "_args request);" << endl << endl; ++ } ++ ++ if (tservice->get_extends() != nullptr) { ++ t_service* extend_service = tservice->get_extends(); ++ functions = extend_service->get_functions(); ++ string extend_service_name = extend_service->get_name() + "Grpc"; ++ for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { ++ f_service_ << ++ indent() << "public com.google.common.util.concurrent.ListenableFuture<" << ++ extend_service_name << "." << (*f_iter)->get_name() << "_result> " << ++ (*f_iter)->get_name() << "(" << endl << ++ indent() << " " << extend_service_name << "." << (*f_iter)->get_name() << ++ "_args request);" << endl << endl; ++ } ++ } ++ indent_down(); ++ f_service_ << ++ indent() << "}" << endl << endl; ++ ++ // generate Stub impl ++ ++ f_service_ << ++ indent() << "public static class " << ++ service_name_ << "FutureStub extends io.grpc.stub.AbstractStub<" << ++ service_name_ << "FutureStub>" << endl << ++ indent() << " implements " << service_name_ << "FutureClient {" << endl; ++ indent_up(); ++ ++ f_service_ << ++ indent() << "private " << service_name_ << "FutureStub(io.grpc.Channel channel) {" << endl; ++ indent_up(); ++ f_service_ << ++ indent() << "super(channel);" << endl; ++ indent_down(); ++ f_service_ << ++ indent() << "}" << endl << endl; ++ ++ f_service_ << ++ indent() << "private " << service_name_ << "FutureStub(io.grpc.Channel channel, " << endl << ++ indent() << " io.grpc.CallOptions callOptions) {" << endl; ++ indent_up(); ++ f_service_ << ++ indent() << "super(channel, callOptions);" << endl; ++ indent_down(); ++ f_service_ << ++ indent() << "}" << endl << endl; ++ ++ f_service_ << ++ indent() << "@java.lang.Override" << endl << ++ indent() << "protected " << service_name_ << "FutureStub build(io.grpc.Channel channel, " << ++ endl << indent() << " io.grpc.CallOptions callOptions) {" << endl; ++ indent_up(); ++ f_service_ << ++ indent() << "return new " << service_name_ << "FutureStub(channel, callOptions);" << endl; ++ indent_down(); ++ f_service_ << ++ indent() << "}" << endl << endl; ++ ++ functions = tservice->get_functions(); ++ for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { ++ f_service_ << ++ indent() << "@java.lang.Override" << endl << ++ indent() << "public com.google.common.util.concurrent.ListenableFuture<" << ++ (*f_iter)->get_name() << "_result> " << (*f_iter)->get_name() << "(" << ++ endl << indent() << " " << (*f_iter)->get_name() << "_args request) {" << endl; ++ indent_up(); ++ f_service_ << ++ indent() << "return futureUnaryCall(" << endl << ++ indent() << " getChannel().newCall(METHOD_" << (*f_iter)->get_name() << ++ ", getCallOptions()), request);" << endl; ++ indent_down(); ++ f_service_ << ++ indent() << "}" << endl << endl; ++ } ++ ++ if (tservice->get_extends() != nullptr) { ++ t_service* extend_service = tservice->get_extends(); ++ functions = extend_service->get_functions(); ++ string extend_service_name = extend_service->get_name() + "Grpc"; ++ for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { ++ f_service_ << ++ indent() << "@java.lang.Override" << endl << ++ indent() << "public com.google.common.util.concurrent.ListenableFuture<" << ++ extend_service_name << "." << (*f_iter)->get_name() << "_result> " << ++ (*f_iter)->get_name() << "(" << endl << indent() << " " << ++ extend_service_name << "." << (*f_iter)->get_name() << "_args request) {" << endl; ++ indent_up(); ++ f_service_ << ++ indent() << "return futureUnaryCall(" << endl << ++ indent() << " getChannel().newCall(METHOD_" << (*f_iter)->get_name() << ++ ", getCallOptions()), request);" << endl; ++ indent_down(); ++ f_service_ << ++ indent() << "}" << endl << endl; ++ } ++ } ++ indent_down(); ++ f_service_ << ++ indent() << "}" << endl << endl; ++} ++ ++void t_java_generator::generate_method_ids(t_service* tservice) { ++ vector functions = tservice->get_functions(); ++ vector::iterator f_iter; ++ int i=0; ++ for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter, ++i) { ++ f_service_ << ++ indent() << "private static final int METHODID_" << ++ (*f_iter)->get_name() << " = " << i << ";" << endl; ++ } ++ if (tservice->get_extends() != nullptr) { ++ t_service* extend_service = tservice->get_extends(); ++ functions = extend_service->get_functions(); ++ string extend_service_name = extend_service->get_name() + "Grpc"; ++ for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter, ++i) { ++ f_service_ << ++ indent() << "private static final int METHODID_" << ++ (*f_iter)->get_name() << " = " << i << ";" << endl; ++ } ++ } ++ f_service_ << endl; ++} ++ ++void t_java_generator::generate_method_handlers(t_service* tservice) { ++ f_service_ << ++ indent() << "private static class MethodHandlers implements" << ++ endl << indent() << " io.grpc.stub.ServerCalls.UnaryMethod," << ++ endl << indent() << " io.grpc.stub.ServerCalls.ServerStreamingMethod," << ++ endl << indent() << " io.grpc.stub.ServerCalls.ClientStreamingMethod," << ++ endl << indent() << " io.grpc.stub.ServerCalls.BidiStreamingMethod {" << ++ endl; ++ indent_up(); ++ f_service_ << ++ indent() << "private final " << service_name_ << " serviceImpl;" << endl << ++ indent() << "private final int methodId;" << endl << endl; ++ ++ f_service_ << ++ indent() << "public MethodHandlers(" << service_name_ << " serviceImpl, int " << ++ "methodId) {" << endl; ++ indent_up(); ++ f_service_ << ++ indent() << "this.serviceImpl = serviceImpl;" << endl << ++ indent() << "this.methodId = methodId;" << endl; ++ indent_down(); ++ f_service_ << ++ indent() << "}" << endl << endl; ++ ++ // invoke ++ f_service_ << ++ indent() << "@java.lang.Override" << endl << ++ indent() << "@java.lang.SuppressWarnings(\"unchecked\")" << endl << ++ indent() << "public void invoke(Req request, io.grpc.stub.StreamObserver responseObserver) {" << ++ endl; ++ indent_up(); ++ f_service_ << ++ indent() << "switch (methodId) {" << endl; ++ indent_up(); ++ ++ vector functions = tservice->get_functions(); ++ vector::iterator f_iter; ++ for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { ++ f_service_ << ++ indent() << "case METHODID_" << (*f_iter)->get_name() << ":" << endl; ++ indent_up(); ++ f_service_ << ++ indent() << "serviceImpl." << (*f_iter)->get_name() << "((" << (*f_iter)->get_name() << ++ "_args) request," << endl << ++ indent() << " (io.grpc.stub.StreamObserver<" << (*f_iter)->get_name() << "_result>)" << ++ " responseObserver);" << endl << ++ indent() << "break;" << endl << endl; ++ indent_down(); ++ } ++ if (tservice->get_extends() != nullptr) { ++ t_service* extend_service = tservice->get_extends(); ++ functions = extend_service->get_functions(); ++ string extend_service_name = extend_service->get_name() + "Grpc"; ++ for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { ++ f_service_ << ++ indent() << "case METHODID_" << (*f_iter)->get_name() << ":" << endl; ++ indent_up(); ++ f_service_ << ++ indent() << "serviceImpl." << (*f_iter)->get_name() << "((" << extend_service_name << ++ "." << (*f_iter)->get_name() << "_args) request," << endl << ++ indent() << " (io.grpc.stub.StreamObserver<" << extend_service_name << "." << ++ (*f_iter)->get_name() << "_result>)" << " responseObserver);" << endl << ++ indent() << "break;" << endl << endl; ++ indent_down(); ++ } + } ++ f_service_ << ++ indent() << "default:" << endl << ++ indent() << " throw new AssertionError();" << endl; ++ indent_down(); ++ f_service_ << ++ indent() << "}" << endl; ++ indent_down(); ++ f_service_ << ++ indent() << "}" << endl << endl; ++ ++ // invoke ++ f_service_ << ++ indent() << "@java.lang.Override" << endl << ++ indent() << "@java.lang.SuppressWarnings(\"unchecked\")" << endl << ++ indent() << "public io.grpc.stub.StreamObserver invoke(" << endl << ++ indent() << " io.grpc.stub.StreamObserver responseObserver) {" << endl; ++ indent_up(); ++ f_service_ << ++ indent() << "switch (methodId) {" << endl; ++ indent_up(); ++ f_service_ << ++ indent() << "default:" << endl; ++ f_service_ << ++ indent() << " throw new AssertionError();" << endl; ++ indent_down(); ++ f_service_ << indent() << "}" << endl; + indent_down(); + f_service_ << indent() << "}" << endl << endl; ++ indent_down(); ++ f_service_ << indent() << "}" << endl << endl; ++ + } + ++void t_java_generator::generate_service_descriptors(t_service* tservice) { ++ // generate service descriptor ++ vector functions = tservice->get_functions(); ++ vector::iterator f_iter; ++ f_service_ << ++ indent() << "public static io.grpc.ServiceDescriptor getServiceDescriptor() {" << ++ endl; ++ indent_up(); ++ f_service_ << ++ indent() << "return new io.grpc.ServiceDescriptor(SERVICE_NAME"; ++ for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { ++ f_service_ << ++ indent() << "," << endl << ++ indent() << " METHOD_" << (*f_iter)->get_name(); ++ } ++ if (tservice->get_extends() != nullptr) { ++ t_service* extend_service = tservice->get_extends(); ++ functions = extend_service->get_functions(); ++ for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { ++ f_service_ << ++ indent() << "," << endl << ++ indent() << " METHOD_" << (*f_iter)->get_name(); ++ } ++ } ++ f_service_ << ");" << endl; ++ indent_down(); ++ f_service_ << indent() << "}" << endl << endl; ++} ++ ++void t_java_generator::generate_service_builder(t_service* tservice) { ++ // bind Service ++ vector functions = tservice->get_functions(); ++ vector::iterator f_iter; ++ f_service_ << ++ indent() << "@java.lang.Deprecated public static io.grpc.ServerServiceDefinition" << ++ " bindService(" << endl << ++ indent() << " final " << service_name_ << " serviceImpl) {" << endl; ++ indent_up(); ++ f_service_ << ++ indent() << "return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor())" << ++ endl; ++ for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { ++ f_service_ << ++ indent() << " .addMethod(" << endl; ++ indent_up(); ++ f_service_ << ++ indent() << " METHOD_" << (*f_iter)->get_name() << "," << endl << ++ indent() << " asyncUnaryCall(" << endl; ++ indent_up(); ++ f_service_ << ++ indent() << " new MethodHandlers<" << endl; ++ indent_up(); ++ f_service_ << ++ indent() << " " << (*f_iter)->get_name() << "_args," << endl << ++ indent() << " " << (*f_iter)->get_name() << "_result>(" << endl; ++ indent_up(); ++ f_service_ << ++ indent() << " serviceImpl, METHODID_" << (*f_iter)->get_name() << ")))" << endl; ++ indent_down(); ++ indent_down(); ++ indent_down(); ++ indent_down(); ++ } ++ ++ if (tservice->get_extends() != nullptr) { ++ t_service* extend_service = tservice->get_extends(); ++ functions = extend_service->get_functions(); ++ string extend_service_name = extend_service->get_name() + "Grpc"; ++ for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { ++ f_service_ << ++ indent() << " .addMethod(" << endl; ++ indent_up(); ++ f_service_ << ++ indent() << " METHOD_" << (*f_iter)->get_name() << "," << endl << ++ indent() << " asyncUnaryCall(" << endl; ++ indent_up(); ++ f_service_ << ++ indent() << " new MethodHandlers<" << endl; ++ indent_up(); ++ f_service_ << ++ indent() << " " << extend_service_name << "." << (*f_iter)->get_name() << "_args," << endl << ++ indent() << " " << extend_service_name << "." << (*f_iter)->get_name() << "_result>(" << endl; ++ indent_up(); ++ f_service_ << ++ indent() << " serviceImpl, METHODID_" << (*f_iter)->get_name() << ")))" << endl; ++ indent_down(); ++ indent_down(); ++ indent_down(); ++ indent_down(); ++ } ++ } ++ f_service_ << ++ indent() << " .build();" << endl; ++ indent_down(); ++ f_service_ << indent() << "}" << endl << endl; ++} ++ ++ + void t_java_generator::generate_service_async_interface(t_service* tservice) { + string extends = ""; + string extends_iface = ""; +diff --git a/tutorial/Makefile.am b/tutorial/Makefile.am +index 5865c54..1cffbe6 100755 +--- a/tutorial/Makefile.am ++++ b/tutorial/Makefile.am +@@ -35,11 +35,6 @@ if WITH_D + SUBDIRS += d + endif + +-if WITH_JAVA +-SUBDIRS += java +-SUBDIRS += js +-endif +- + if WITH_PYTHON + SUBDIRS += py + SUBDIRS += py.twisted +@@ -95,4 +90,5 @@ EXTRA_DIST = \ + php \ + shared.thrift \ + tutorial.thrift \ +- README.md ++ README.md \ ++ java +-- +2.8.0.rc3.226.g39d4020 + From a17039aaa443ac8b4f8d5bad51fd6e8c2777071f Mon Sep 17 00:00:00 2001 From: chedeti Date: Mon, 1 Aug 2016 17:32:06 -0700 Subject: [PATCH 04/12] refine code and add README --- Makefile | 1 - build.yaml | 1 - .../grpc++/impl/codegen/thrift_serializer.h | 207 ++++++++++++------ .../impl/codegen/thrift_serializer_inl.h | 169 -------------- include/grpc++/impl/codegen/thrift_utils.h | 10 +- tools/grift/README.md | 15 ++ tools/grift/grpc_plugins_generator.patch | 187 +++++++++++++++- tools/run_tests/sources_and_headers.json | 2 - .../grpc++_test_util/grpc++_test_util.vcxproj | 1 - .../grpc++_test_util.vcxproj.filters | 3 - 10 files changed, 341 insertions(+), 255 deletions(-) delete mode 100644 include/grpc++/impl/codegen/thrift_serializer_inl.h create mode 100644 tools/grift/README.md diff --git a/Makefile b/Makefile index 986c25780f2..31a8448fff6 100644 --- a/Makefile +++ b/Makefile @@ -3924,7 +3924,6 @@ PUBLIC_HEADERS_CXX += \ include/grpc++/impl/codegen/proto_utils.h \ include/grpc++/impl/codegen/config_protobuf.h \ include/grpc++/impl/codegen/thrift_serializer.h \ - include/grpc++/impl/codegen/thrift_serializer_inl.h \ include/grpc++/impl/codegen/thrift_utils.h \ LIBGRPC++_TEST_UTIL_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC++_TEST_UTIL_SRC)))) diff --git a/build.yaml b/build.yaml index 35af7a6c7a5..02ad6a8842b 100644 --- a/build.yaml +++ b/build.yaml @@ -784,7 +784,6 @@ filegroups: language: c++ public_headers: - include/grpc++/impl/codegen/thrift_serializer.h - - include/grpc++/impl/codegen/thrift_serializer_inl.h - include/grpc++/impl/codegen/thrift_utils.h uses: - grpc++_codegen_base diff --git a/include/grpc++/impl/codegen/thrift_serializer.h b/include/grpc++/impl/codegen/thrift_serializer.h index 315d76cf2a5..46112ee5b23 100644 --- a/include/grpc++/impl/codegen/thrift_serializer.h +++ b/include/grpc++/impl/codegen/thrift_serializer.h @@ -36,12 +36,16 @@ #include #include - +#include +#include +#include +#include +#include #include #include +#include #include #include -#include namespace apache { namespace thrift { @@ -49,100 +53,165 @@ namespace util { using apache::thrift::protocol::TBinaryProtocolT; using apache::thrift::protocol::TCompactProtocolT; +using apache::thrift::protocol::TMessageType; using apache::thrift::protocol::TNetworkBigEndian; using apache::thrift::transport::TMemoryBuffer; using apache::thrift::transport::TBufferBase; using apache::thrift::transport::TTransport; -using std::shared_ptr; - -template -class ThriftSerializer { +template class ThriftSerializer { public: ThriftSerializer() - : prepared_ (false) - , lastDeserialized_ (false) - , serializeVersion_ (false) {} - - /** - * Serialize the passed type into the internal buffer - * and returns a pointer to internal buffer and its size - * - */ - template - void serialize(const T& fields, const uint8_t** serializedBuffer, - size_t* serializedLen); - - /** - * Serialize the passed type into the byte buffer - */ - template - void serialize(const T& fields, grpc_byte_buffer** bp); - - /** - * Deserialize the passed char array into the passed type, returns the number - * of bytes that have been consumed from the passed string. - */ - template - uint32_t deserialize(const uint8_t* serializedBuffer, size_t length, - T* fields); - - /** - * Deserialize the passed byte buffer to passed type, returns the number - * of bytes consumed from byte buffer - */ - template - uint32_t deserialize(grpc_byte_buffer* buffer, T* msg); - - void setSerializeVersion(bool value); + : prepared_ (false) + , last_deserialized_ (false) + , serialize_version_ (false) {} virtual ~ThriftSerializer() {} + // Serialize the passed type into the internal buffer + // and returns a pointer to internal buffer and its size + template void Serialize(const T& fields, const uint8_t** serializedBuffer, + size_t* serializedLen) { + // prepare or reset buffer + if (!prepared_ || last_deserialized_) { + prepare(); + } else { + buffer_->resetBuffer(); + } + last_deserialized_ = false; + + // if required serialize protocol version + if (serialize_version_) { + protocol_->writeMessageBegin("", TMessageType(0), 0); + } + + // serilaize fields into buffer + fields.write(protocol_.get()); + + // write the end of message + if (serialize_version_) { + protocol_->writeMessageEnd(); + } + + uint8_t* byteBuffer; + uint32_t byteBufferSize; + buffer_->getBuffer(&byteBuffer, &byteBufferSize); + *serializedBuffer = byteBuffer; + *serializedLen = byteBufferSize; + } + + // Serialize the passed type into the byte buffer + template void Serialize(const T& fields, grpc_byte_buffer** bp) { + + const uint8_t* byteBuffer; + size_t byteBufferSize; + + Serialize(fields, &byteBuffer, &byteBufferSize); + + gpr_slice slice = gpr_slice_from_copied_buffer((char*)byteBuffer,byteBufferSize); + + *bp = grpc_raw_byte_buffer_create(&slice, 1); - /** - * Set the container size limit to deserialize - * This function should be called after buffer_ is initialized - */ - void setContainerSizeLimit(int32_t container_limit) { + gpr_slice_unref(slice); + } + + // Deserialize the passed char array into the passed type, returns the number + // of bytes that have been consumed from the passed string. + template uint32_t Deserialize(const uint8_t* serializedBuffer, size_t length, + T* fields) { + // prepare buffer if necessary + if (!prepared_) { + prepare(); + } + last_deserialized_ = true; + + //reset buffer transport + buffer_->resetBuffer((uint8_t*)serializedBuffer, length); + + // read the protocol version if necessary + if (serialize_version_) { + std::string name = ""; + TMessageType mt = (TMessageType) 0; + int32_t seq_id = 0; + protocol_->readMessageBegin(name, mt, seq_id); + } + + // deserialize buffer into fields + uint32_t len = fields->read(protocol_.get()); + + // read the end of message + if (serialize_version_) { + protocol_->readMessageEnd(); + } + + return len; + } + + + // Deserialize the passed byte buffer to passed type, returns the number + // of bytes consumed from byte buffer + template uint32_t Deserialize(grpc_byte_buffer* buffer, T* msg) { + + grpc_byte_buffer_reader reader; + grpc_byte_buffer_reader_init(&reader, buffer); + + gpr_slice slice = grpc_byte_buffer_reader_readall(&reader); + + uint32_t len = Deserialize(GPR_SLICE_START_PTR(slice), GPR_SLICE_LENGTH(slice), msg); + + gpr_slice_unref(slice); + + grpc_byte_buffer_reader_destroy(&reader); + + return len; + } + + // set serialization version flag + void SetSerializeVersion(bool value) { + serialize_version_ = value; + } + + // Set the container size limit to deserialize + // This function should be called after buffer_ is initialized + void SetContainerSizeLimit(int32_t container_limit) { if (!prepared_) { prepare(); } protocol_->setContainerSizeLimit(container_limit); } - /** - * Set the string size limit to deserialize - * This function should be called after buffer_ is initialized - */ - void setStringSizeLimit(int32_t string_limit) { + // Set the string size limit to deserialize + // This function should be called after buffer_ is initialized + void SetStringSizeLimit(int32_t string_limit) { if (!prepared_) { prepare(); } protocol_->setStringSizeLimit(string_limit); } +private: + bool prepared_; + bool last_deserialized_; + boost::shared_ptr buffer_; + std::shared_ptr protocol_; + bool serialize_version_; - private: - void prepare(); - - private: - typedef P Protocol; - bool prepared_; - bool lastDeserialized_; - boost::shared_ptr buffer_; - shared_ptr protocol_; - bool serializeVersion_; -}; // ThriftSerializer + void prepare() { + buffer_.reset(new TMemoryBuffer()); -template -struct ThriftSerializerBinary : public ThriftSerializer > {}; + // create a protocol for the memory buffer transport + protocol_.reset(new Protocol(buffer_)); + prepared_ = true; + } -template -struct ThriftSerializerCompact : public ThriftSerializer >{ }; +}; // ThriftSerializer -}}} // namespace apache::thrift::util +typedef ThriftSerializer> ThriftSerializerBinary; +typedef ThriftSerializer> ThriftSerializerCompact; -#include +} // namespace util +} // namespace thrift +} // namespace apache -#endif +#endif \ No newline at end of file diff --git a/include/grpc++/impl/codegen/thrift_serializer_inl.h b/include/grpc++/impl/codegen/thrift_serializer_inl.h deleted file mode 100644 index 866ecf6312d..00000000000 --- a/include/grpc++/impl/codegen/thrift_serializer_inl.h +++ /dev/null @@ -1,169 +0,0 @@ -/* - * - * Copyright 2016, 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 GRPCXX_IMPL_CODEGEN_THRIFT_SERIALIZER_INL_H - #define GRPCXX_IMPL_CODEGEN_THRIFT_SERIALIZER_INL_H - -#include -#include -#include -#include -#include -#include -#include - -namespace apache { -namespace thrift { -namespace util { - -using apache::thrift::protocol::TMessageType; - -template -template -void ThriftSerializer::serialize(const T& fields, - const uint8_t** serializedBuffer, size_t* serializedLen) { - - // prepare or reset buffer - if (!prepared_ || lastDeserialized_) { - prepare(); - } else { - buffer_->resetBuffer(); - } - lastDeserialized_ = false; - - // if required serialize protocol version - if (serializeVersion_) { - protocol_->writeMessageBegin("", TMessageType(0), 0); - } - - // serilaize fields into buffer - fields.write(protocol_.get()); - - // write the end of message - if (serializeVersion_) { - protocol_->writeMessageEnd(); - } - - // assign buffer to string - uint8_t* byteBuffer; - uint32_t byteBufferSize; - buffer_->getBuffer(&byteBuffer, &byteBufferSize); - *serializedBuffer = byteBuffer; - *serializedLen = byteBufferSize; -} - -template -template -void ThriftSerializer::serialize(const T& fields, grpc_byte_buffer** bp) { - - const uint8_t* byteBuffer; - size_t byteBufferSize; - serialize(fields, &byteBuffer, &byteBufferSize); - - gpr_slice slice = gpr_slice_from_copied_buffer((char*)byteBuffer,byteBufferSize); - - *bp = grpc_raw_byte_buffer_create(&slice, 1); - - gpr_slice_unref(slice); -} - -template -template -uint32_t ThriftSerializer::deserialize(const uint8_t* serializedBuffer, - size_t length, T* fields) { - // prepare buffer if necessary - if (!prepared_) { - prepare(); - } - lastDeserialized_ = true; - - //reset buffer transport - buffer_->resetBuffer((uint8_t*)serializedBuffer, length); - - // read the protocol version if necessary - if (serializeVersion_) { - std::string name = ""; - TMessageType mt = (TMessageType) 0; - int32_t seq_id = 0; - protocol_->readMessageBegin(name, mt, seq_id); - } - - // deserialize buffer into fields - uint32_t len = fields->read(protocol_.get()); - - // read the end of message - if (serializeVersion_) { - protocol_->readMessageEnd(); - } - - return len; -} - -template -template -uint32_t ThriftSerializer::deserialize(grpc_byte_buffer* bp, T* fields) { - grpc_byte_buffer_reader reader; - grpc_byte_buffer_reader_init(&reader, bp); - - gpr_slice slice = grpc_byte_buffer_reader_readall(&reader); - - uint32_t len = deserialize(GPR_SLICE_START_PTR(slice), GPR_SLICE_LENGTH(slice), fields); - - gpr_slice_unref(slice); - - grpc_byte_buffer_reader_destroy(&reader); - - return len; -} - -template -void ThriftSerializer::setSerializeVersion(bool value) { - serializeVersion_ = value; -} - -template -void -ThriftSerializer::prepare() -{ - - buffer_.reset(new TMemoryBuffer()); - - // create a protocol for the memory buffer transport - protocol_.reset(new Protocol(buffer_)); - - prepared_ = true; -} - -}}} // namespace apache::thrift::util - -#endif diff --git a/include/grpc++/impl/codegen/thrift_utils.h b/include/grpc++/impl/codegen/thrift_utils.h index 629441149fd..14332c05219 100644 --- a/include/grpc++/impl/codegen/thrift_utils.h +++ b/include/grpc++/impl/codegen/thrift_utils.h @@ -44,9 +44,7 @@ #include #include #include -#include #include -#include #include namespace grpc { @@ -62,9 +60,9 @@ class SerializationTraits serializer; + ThriftSerializerCompact serializer; - serializer.serialize(msg, bp); + serializer.Serialize(msg, bp); return Status(StatusCode::OK, "ok"); } @@ -76,8 +74,8 @@ class SerializationTraits deserializer; - deserializer.deserialize(buffer, msg); + ThriftSerializerCompact deserializer; + deserializer.Deserialize(buffer, msg); grpc_byte_buffer_destroy(buffer); diff --git a/tools/grift/README.md b/tools/grift/README.md new file mode 100644 index 00000000000..a4cb87bff1a --- /dev/null +++ b/tools/grift/README.md @@ -0,0 +1,15 @@ +Copyright 2016 Google Inc. + +#Documentation + +grift is integration of [Apache Thrift](https://github.com/apache/thrift.git) Serializer with GRPC. + +This integration allows you to use grpc to send thrift messages in C++ and java. + +By default grift uses Compact Protocol to serialize thrift messages. + +#Installation + +Before Installing thrift make sure to apply this [patch](grpc_plugins_generate.patch) to third_party/thrift. +Go to third_party/thrift and follow the [INSTALLATION](https://github.com/apache/thrift.git) instructions to +install thrift. \ No newline at end of file diff --git a/tools/grift/grpc_plugins_generator.patch b/tools/grift/grpc_plugins_generator.patch index 2779dfb59eb..9c18db35995 100644 --- a/tools/grift/grpc_plugins_generator.patch +++ b/tools/grift/grpc_plugins_generator.patch @@ -1,7 +1,7 @@ From 0894590b5020c38106d4ebb2291994668c64f9dd Mon Sep 17 00:00:00 2001 From: chedeti Date: Sun, 31 Jul 2016 15:47:47 -0700 -Subject: [PATCH 1/3] don't build tests +Subject: [PATCH 1/5] don't build tests --- Makefile.am | 7 ++----- @@ -62,7 +62,7 @@ index 6fd15d2..7de1fad 100755 From 04244fa7805740761db757e4c44251f723d85839 Mon Sep 17 00:00:00 2001 From: chedeti Date: Sun, 31 Jul 2016 16:16:40 -0700 -Subject: [PATCH 2/3] grpc cpp plugins generator with example +Subject: [PATCH 2/5] grpc cpp plugins generator with example --- compiler/cpp/src/generate/t_cpp_generator.cc | 476 +++++++++++++++++++++++---- @@ -1401,7 +1401,7 @@ index 0000000..de3c9a4 From 1d47ed062e62d136c3db9f6fc1dde9e2f794cf22 Mon Sep 17 00:00:00 2001 From: chedeti Date: Sun, 31 Jul 2016 16:23:53 -0700 -Subject: [PATCH 3/3] grpc java plugins generator +Subject: [PATCH 3/5] grpc java plugins generator for examples refer to https://github.com/grpc/grpc-java/tree/master/examples/thrift --- @@ -2415,3 +2415,184 @@ index 5865c54..1cffbe6 100755 -- 2.8.0.rc3.226.g39d4020 + +From a9769a0fa08f553da76215ca59a8fd797b92a853 Mon Sep 17 00:00:00 2001 +From: chedeti +Date: Mon, 1 Aug 2016 16:56:36 -0700 +Subject: [PATCH 4/5] maintain consistency with grpc + +--- + compiler/cpp/src/generate/t_cpp_generator.cc | 20 ++++++++++---------- + tutorial/cpp/{CppClient.cpp => GrpcClient.cpp} | 0 + tutorial/cpp/{CppServer.cpp => GrpcServer.cpp} | 0 + tutorial/cpp/Makefile.am | 8 ++++---- + 4 files changed, 14 insertions(+), 14 deletions(-) + rename tutorial/cpp/{CppClient.cpp => GrpcClient.cpp} (100%) + rename tutorial/cpp/{CppServer.cpp => GrpcServer.cpp} (100%) + +diff --git a/compiler/cpp/src/generate/t_cpp_generator.cc b/compiler/cpp/src/generate/t_cpp_generator.cc +index 9c3399b..4e00129 100644 +--- a/compiler/cpp/src/generate/t_cpp_generator.cc ++++ b/compiler/cpp/src/generate/t_cpp_generator.cc +@@ -1641,7 +1641,7 @@ void t_cpp_generator::generate_service(t_service* tservice) { + << endl; + + t_service* extends_service = tservice->get_extends(); +- if (extends_service != nullptr) { ++ if (extends_service) { + f_header_ << "#include \"" << get_include_prefix(*(extends_service->get_program())) + << extends_service->get_name() << ".grpc.thrift.h\"" << endl; + } +@@ -1733,7 +1733,7 @@ void t_cpp_generator::generate_service(t_service* tservice) { + indent() << "\"/" << ns << "." << service_name_ << "/" << (*f_iter)->get_name() << "\"," << endl; + } + +- if (extends_service != nullptr) { ++ if (extends_service) { + vector functions = extends_service->get_functions(); + vector::iterator f_iter; + +@@ -1749,9 +1749,9 @@ void t_cpp_generator::generate_service(t_service* tservice) { + "};" << endl; + + // Generate service class +- if ( extends_service != nullptr ) { ++ if ( extends_service) { + f_header_ << "class " << service_name_ << " : public " << +- extends_service->get_name() << " {" << endl << ++ type_name(extends_service) << " {" << endl << + "public:" << endl; + } + else { +@@ -1841,7 +1841,7 @@ void t_cpp_generator::generate_service_helpers(t_service* tservice) { + void t_cpp_generator::generate_service_stub_interface(t_service* tservice) { + + string extends = ""; +- if (tservice->get_extends() != nullptr) { ++ if (tservice->get_extends()) { + extends = " : virtual public " + type_name(tservice->get_extends()) + "::StubInterface"; + } + +@@ -1890,7 +1890,7 @@ void t_cpp_generator::generate_service_stub(t_service* tservice) { + } + + t_service* extends_service = tservice->get_extends(); +- if (extends_service != nullptr) { ++ if (extends_service) { + // generate inherited methods + vector functions = extends_service->get_functions(); + vector::iterator f_iter; +@@ -1914,7 +1914,7 @@ void t_cpp_generator::generate_service_stub(t_service* tservice) { + indent() << "const ::grpc::RpcMethod rpcmethod_" << (*f_iter)->get_name() << "_;" << endl; + } + +- if (extends_service != nullptr) { ++ if (extends_service) { + // generate inherited methods + vector functions = extends_service->get_functions(); + vector::iterator f_iter; +@@ -1944,7 +1944,7 @@ void t_cpp_generator::generate_service_stub(t_service* tservice) { + service_name_ << "_method_names[" << i << "], ::grpc::RpcMethod::NORMAL_RPC, channel)" << endl; + } + +- if (extends_service != nullptr) { ++ if (extends_service) { + // generate inherited methods + vector functions = extends_service->get_functions(); + vector::iterator f_iter; +@@ -2002,7 +2002,7 @@ void t_cpp_generator::generate_service_stub(t_service* tservice) { + + } + +- if (extends_service != nullptr) { ++ if (extends_service) { + vector functions = extends_service->get_functions(); + vector::iterator f_iter; + for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { +@@ -2049,7 +2049,7 @@ void t_cpp_generator::generate_service_interface(t_service* tservice, string sty + } + + string extends = ""; +- if (tservice->get_extends() != NULL) { ++ if (tservice->get_extends()) { + extends = " : virtual public " + type_name(tservice->get_extends()) + style + "::Service"; + if (style == "CobCl" && gen_templates_) { + // TODO(simpkins): If gen_templates_ is enabled, we currently assume all +diff --git a/tutorial/cpp/CppClient.cpp b/tutorial/cpp/GrpcClient.cpp +similarity index 100% +rename from tutorial/cpp/CppClient.cpp +rename to tutorial/cpp/GrpcClient.cpp +diff --git a/tutorial/cpp/CppServer.cpp b/tutorial/cpp/GrpcServer.cpp +similarity index 100% +rename from tutorial/cpp/CppServer.cpp +rename to tutorial/cpp/GrpcServer.cpp +diff --git a/tutorial/cpp/Makefile.am b/tutorial/cpp/Makefile.am +index 581f75e..39d85e1 100755 +--- a/tutorial/cpp/Makefile.am ++++ b/tutorial/cpp/Makefile.am +@@ -39,14 +39,14 @@ noinst_PROGRAMS = \ + TestClient + + TestServer_SOURCES = \ +- CppServer.cpp ++ GrpcServer.cpp + + TestServer_LDADD = \ + libtestgencpp.la \ + $(top_builddir)/lib/cpp/libthrift.la + + TestClient_SOURCES = \ +- CppClient.cpp ++ GrpcClient.cpp + + TestClient_LDADD = \ + libtestgencpp.la \ +@@ -78,5 +78,5 @@ style-local: + + EXTRA_DIST = \ + CMakeLists.txt \ +- CppClient.cpp \ +- CppServer.cpp ++ GrpcClient.cpp \ ++ GrpcServer.cpp +-- +2.8.0.rc3.226.g39d4020 + + +From b4bc0c810f00a1b86516774306ff4017e3d2d252 Mon Sep 17 00:00:00 2001 +From: chedeti +Date: Mon, 1 Aug 2016 17:00:17 -0700 +Subject: [PATCH 5/5] fix typo + +--- + tutorial/cpp/GrpcClient.cpp | 2 +- + tutorial/cpp/GrpcServer.cpp | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/tutorial/cpp/GrpcClient.cpp b/tutorial/cpp/GrpcClient.cpp +index c41604e..41a7acf 100644 +--- a/tutorial/cpp/GrpcClient.cpp ++++ b/tutorial/cpp/GrpcClient.cpp +@@ -1,6 +1,6 @@ + /* + * +- * Copyright 2015, Google Inc. ++ * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without +diff --git a/tutorial/cpp/GrpcServer.cpp b/tutorial/cpp/GrpcServer.cpp +index c838b61..f63db57 100644 +--- a/tutorial/cpp/GrpcServer.cpp ++++ b/tutorial/cpp/GrpcServer.cpp +@@ -1,6 +1,6 @@ + /* + * +- * Copyright 2015, Google Inc. ++ * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without +-- +2.8.0.rc3.226.g39d4020 + diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json index 06ac86fc9c4..82b443a4742 100644 --- a/tools/run_tests/sources_and_headers.json +++ b/tools/run_tests/sources_and_headers.json @@ -6792,14 +6792,12 @@ ], "headers": [ "include/grpc++/impl/codegen/thrift_serializer.h", - "include/grpc++/impl/codegen/thrift_serializer_inl.h", "include/grpc++/impl/codegen/thrift_utils.h" ], "language": "c++", "name": "thrift_util", "src": [ "include/grpc++/impl/codegen/thrift_serializer.h", - "include/grpc++/impl/codegen/thrift_serializer_inl.h", "include/grpc++/impl/codegen/thrift_utils.h" ], "third_party": false, diff --git a/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj b/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj index 96ce3b89164..c2c7d00a6d9 100644 --- a/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj +++ b/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj @@ -201,7 +201,6 @@ - diff --git a/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj.filters b/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj.filters index 2105e672df9..9b8c8ddfada 100644 --- a/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj.filters +++ b/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj.filters @@ -195,9 +195,6 @@ include\grpc++\impl\codegen - - include\grpc++\impl\codegen - include\grpc++\impl\codegen From f5dcc9b5b5d1ade84eb7bac07abbac56f5f86675 Mon Sep 17 00:00:00 2001 From: chedeti Date: Mon, 1 Aug 2016 17:57:24 -0700 Subject: [PATCH 05/12] fix typos --- tools/grift/README.md | 16 ++++++++++++++-- tools/grift/grpc_plugins_generator.patch | 17 +++++++++++++---- 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/tools/grift/README.md b/tools/grift/README.md index a4cb87bff1a..25c67451326 100644 --- a/tools/grift/README.md +++ b/tools/grift/README.md @@ -6,10 +6,22 @@ grift is integration of [Apache Thrift](https://github.com/apache/thrift.git) Se This integration allows you to use grpc to send thrift messages in C++ and java. -By default grift uses Compact Protocol to serialize thrift messages. +grift uses Compact Protocol to serialize thrift messages. + +##generating grpc plugins for thrift services + +###CPP +```sh + $ thrift --gen cpp +``` + +###JAVA +```sh + $ thrift --gen java +``` #Installation -Before Installing thrift make sure to apply this [patch](grpc_plugins_generate.patch) to third_party/thrift. +Before Installing thrift make sure to apply this [patch](grpc_plugins_generator.patch) to third_party/thrift. Go to third_party/thrift and follow the [INSTALLATION](https://github.com/apache/thrift.git) instructions to install thrift. \ No newline at end of file diff --git a/tools/grift/grpc_plugins_generator.patch b/tools/grift/grpc_plugins_generator.patch index 9c18db35995..eeee1612519 100644 --- a/tools/grift/grpc_plugins_generator.patch +++ b/tools/grift/grpc_plugins_generator.patch @@ -2559,18 +2559,18 @@ index 581f75e..39d85e1 100755 2.8.0.rc3.226.g39d4020 -From b4bc0c810f00a1b86516774306ff4017e3d2d252 Mon Sep 17 00:00:00 2001 +From bc74fca1ee73333819724f51d5aaff3546443ed0 Mon Sep 17 00:00:00 2001 From: chedeti Date: Mon, 1 Aug 2016 17:00:17 -0700 Subject: [PATCH 5/5] fix typo --- - tutorial/cpp/GrpcClient.cpp | 2 +- + tutorial/cpp/GrpcClient.cpp | 4 ++-- tutorial/cpp/GrpcServer.cpp | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) + 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tutorial/cpp/GrpcClient.cpp b/tutorial/cpp/GrpcClient.cpp -index c41604e..41a7acf 100644 +index c41604e..ab1fe77 100644 --- a/tutorial/cpp/GrpcClient.cpp +++ b/tutorial/cpp/GrpcClient.cpp @@ -1,6 +1,6 @@ @@ -2581,6 +2581,15 @@ index c41604e..41a7acf 100644 * All rights reserved. * * Redistribution and use in source and binary forms, with or without +@@ -50,7 +50,7 @@ class GreeterClient { + GreeterClient(std::shared_ptr channel) + : stub_(Greeter::NewStub(channel)) {} + +- // Assambles the client's payload, sends it and presents the response back ++ // Assembles the client's payload, sends it and presents the response back + // from the server. + std::string SayHello(const std::string& user) { + // Data we are sending to the server. diff --git a/tutorial/cpp/GrpcServer.cpp b/tutorial/cpp/GrpcServer.cpp index c838b61..f63db57 100644 --- a/tutorial/cpp/GrpcServer.cpp From 00be9de95cf040e2705c137ea213140562f7571d Mon Sep 17 00:00:00 2001 From: chedeti Date: Tue, 2 Aug 2016 10:44:41 -0700 Subject: [PATCH 06/12] fix codegen patch --- tools/grift/grpc_plugins_generator.patch | 880 ++++++++++------------- 1 file changed, 381 insertions(+), 499 deletions(-) diff --git a/tools/grift/grpc_plugins_generator.patch b/tools/grift/grpc_plugins_generator.patch index eeee1612519..3a6710c224e 100644 --- a/tools/grift/grpc_plugins_generator.patch +++ b/tools/grift/grpc_plugins_generator.patch @@ -1,7 +1,7 @@ From 0894590b5020c38106d4ebb2291994668c64f9dd Mon Sep 17 00:00:00 2001 From: chedeti Date: Sun, 31 Jul 2016 15:47:47 -0700 -Subject: [PATCH 1/5] don't build tests +Subject: [PATCH 1/3] don't build tests --- Makefile.am | 7 ++----- @@ -59,24 +59,30 @@ index 6fd15d2..7de1fad 100755 2.8.0.rc3.226.g39d4020 -From 04244fa7805740761db757e4c44251f723d85839 Mon Sep 17 00:00:00 2001 +From c8577ad5513543c57a81ad1bf4927cc8a78baa03 Mon Sep 17 00:00:00 2001 From: chedeti Date: Sun, 31 Jul 2016 16:16:40 -0700 -Subject: [PATCH 2/5] grpc cpp plugins generator with example +Subject: [PATCH 2/3] grpc cpp plugins generator with example --- - compiler/cpp/src/generate/t_cpp_generator.cc | 476 +++++++++++++++++++++++---- + compiler/cpp/src/generate/t_cpp_generator.cc | 478 +++++++++++++++++++++++---- tutorial/cpp/CMakeLists.txt | 53 --- - tutorial/cpp/CppClient.cpp | 134 ++++---- - tutorial/cpp/CppServer.cpp | 226 ++++--------- - tutorial/cpp/Makefile.am | 58 ++-- + tutorial/cpp/CppClient.cpp | 80 ----- + tutorial/cpp/CppServer.cpp | 181 ---------- + tutorial/cpp/GrpcClient.cpp | 94 ++++++ + tutorial/cpp/GrpcServer.cpp | 87 +++++ + tutorial/cpp/Makefile.am | 66 ++-- tutorial/cpp/test.thrift | 13 + - 6 files changed, 590 insertions(+), 370 deletions(-) + 8 files changed, 636 insertions(+), 416 deletions(-) delete mode 100644 tutorial/cpp/CMakeLists.txt + delete mode 100644 tutorial/cpp/CppClient.cpp + delete mode 100644 tutorial/cpp/CppServer.cpp + create mode 100644 tutorial/cpp/GrpcClient.cpp + create mode 100644 tutorial/cpp/GrpcServer.cpp create mode 100644 tutorial/cpp/test.thrift diff --git a/compiler/cpp/src/generate/t_cpp_generator.cc b/compiler/cpp/src/generate/t_cpp_generator.cc -index 6c04899..9c3399b 100644 +index 6c04899..4e00129 100644 --- a/compiler/cpp/src/generate/t_cpp_generator.cc +++ b/compiler/cpp/src/generate/t_cpp_generator.cc @@ -162,6 +162,8 @@ public: @@ -266,7 +272,7 @@ index 6c04899..9c3399b 100644 t_service* extends_service = tservice->get_extends(); - if (extends_service != NULL) { -+ if (extends_service != nullptr) { ++ if (extends_service) { f_header_ << "#include \"" << get_include_prefix(*(extends_service->get_program())) - << extends_service->get_name() << ".h\"" << endl; + << extends_service->get_name() << ".grpc.thrift.h\"" << endl; @@ -355,7 +361,7 @@ index 6c04899..9c3399b 100644 + indent() << "\"/" << ns << "." << service_name_ << "/" << (*f_iter)->get_name() << "\"," << endl; + } + -+ if (extends_service != nullptr) { ++ if (extends_service) { + vector functions = extends_service->get_functions(); + vector::iterator f_iter; + @@ -371,9 +377,9 @@ index 6c04899..9c3399b 100644 + "};" << endl; + + // Generate service class -+ if ( extends_service != nullptr ) { ++ if ( extends_service) { + f_header_ << "class " << service_name_ << " : public " << -+ extends_service->get_name() << " {" << endl << ++ type_name(extends_service) << " {" << endl << + "public:" << endl; + } + else { @@ -442,7 +448,7 @@ index 6c04899..9c3399b 100644 +void t_cpp_generator::generate_service_stub_interface(t_service* tservice) { + + string extends = ""; -+ if (tservice->get_extends() != nullptr) { ++ if (tservice->get_extends()) { + extends = " : virtual public " + type_name(tservice->get_extends()) + "::StubInterface"; + } + @@ -491,7 +497,7 @@ index 6c04899..9c3399b 100644 + } + + t_service* extends_service = tservice->get_extends(); -+ if (extends_service != nullptr) { ++ if (extends_service) { + // generate inherited methods + vector functions = extends_service->get_functions(); + vector::iterator f_iter; @@ -515,7 +521,7 @@ index 6c04899..9c3399b 100644 + indent() << "const ::grpc::RpcMethod rpcmethod_" << (*f_iter)->get_name() << "_;" << endl; + } + -+ if (extends_service != nullptr) { ++ if (extends_service) { + // generate inherited methods + vector functions = extends_service->get_functions(); + vector::iterator f_iter; @@ -545,7 +551,7 @@ index 6c04899..9c3399b 100644 + service_name_ << "_method_names[" << i << "], ::grpc::RpcMethod::NORMAL_RPC, channel)" << endl; + } + -+ if (extends_service != nullptr) { ++ if (extends_service) { + // generate inherited methods + vector functions = extends_service->get_functions(); + vector::iterator f_iter; @@ -603,7 +609,7 @@ index 6c04899..9c3399b 100644 + + } + -+ if (extends_service != nullptr) { ++ if (extends_service) { + vector functions = extends_service->get_functions(); + vector::iterator f_iter; + for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { @@ -642,11 +648,13 @@ index 6c04899..9c3399b 100644 if (style == "CobCl") { // Forward declare the client. string client_name = service_name_ + "CobClient"; -@@ -1765,12 +2050,14 @@ void t_cpp_generator::generate_service_interface(t_service* tservice, string sty +@@ -1764,13 +2049,15 @@ void t_cpp_generator::generate_service_interface(t_service* tservice, string sty + } string extends = ""; - if (tservice->get_extends() != NULL) { +- if (tservice->get_extends() != NULL) { - extends = " : virtual public " + type_name(tservice->get_extends()) + style + "If"; ++ if (tservice->get_extends()) { + extends = " : virtual public " + type_name(tservice->get_extends()) + style + "::Service"; if (style == "CobCl" && gen_templates_) { // TODO(simpkins): If gen_templates_ is enabled, we currently assume all @@ -867,11 +875,12 @@ index 8a3d085..0000000 -LINK_AGAINST_THRIFT_LIBRARY(TutorialClient thrift) -target_link_libraries(TutorialClient ${ZLIB_LIBRARIES}) diff --git a/tutorial/cpp/CppClient.cpp b/tutorial/cpp/CppClient.cpp -index 2763fee..c41604e 100644 +deleted file mode 100644 +index 2763fee..0000000 --- a/tutorial/cpp/CppClient.cpp -+++ b/tutorial/cpp/CppClient.cpp -@@ -1,80 +1,94 @@ - /* ++++ /dev/null +@@ -1,80 +0,0 @@ +-/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information @@ -879,9 +888,274 @@ index 2763fee..c41604e 100644 - * to you 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 -+ * Copyright 2015, Google Inc. +- * +- * 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 +- +-#include +-#include +-#include +- +-#include "../gen-cpp/Calculator.h" +- +-using namespace std; +-using namespace apache::thrift; +-using namespace apache::thrift::protocol; +-using namespace apache::thrift::transport; +- +-using namespace tutorial; +-using namespace shared; +- +-int main() { +- boost::shared_ptr socket(new TSocket("localhost", 9090)); +- boost::shared_ptr transport(new TBufferedTransport(socket)); +- boost::shared_ptr protocol(new TBinaryProtocol(transport)); +- CalculatorClient client(protocol); +- +- try { +- transport->open(); +- +- client.ping(); +- cout << "ping()" << endl; +- +- cout << "1 + 1 = " << client.add(1, 1) << endl; +- +- Work work; +- work.op = Operation::DIVIDE; +- work.num1 = 1; +- work.num2 = 0; +- +- try { +- client.calculate(1, work); +- cout << "Whoa? We can divide by zero!" << endl; +- } catch (InvalidOperation& io) { +- cout << "InvalidOperation: " << io.why << endl; +- // or using generated operator<<: cout << io << endl; +- // or by using std::exception native method what(): cout << io.what() << endl; +- } +- +- work.op = Operation::SUBTRACT; +- work.num1 = 15; +- work.num2 = 10; +- int32_t diff = client.calculate(1, work); +- cout << "15 - 10 = " << diff << endl; +- +- // Note that C++ uses return by reference for complex types to avoid +- // costly copy construction +- SharedStruct ss; +- client.getStruct(ss, 1); +- cout << "Received log: " << ss << endl; +- +- transport->close(); +- } catch (TException& tx) { +- cout << "ERROR: " << tx.what() << endl; +- } +-} +diff --git a/tutorial/cpp/CppServer.cpp b/tutorial/cpp/CppServer.cpp +deleted file mode 100644 +index eafffa9..0000000 +--- a/tutorial/cpp/CppServer.cpp ++++ /dev/null +@@ -1,181 +0,0 @@ +-/* +- * Licensed to the Apache Software Foundation (ASF) under one +- * or more contributor license agreements. See the NOTICE file +- * distributed with this work for additional information +- * regarding copyright ownership. The ASF licenses this file +- * to you 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 +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +- +-#include +- +-#include +-#include +-#include +- +-#include "../gen-cpp/Calculator.h" +- +-using namespace std; +-using namespace apache::thrift; +-using namespace apache::thrift::concurrency; +-using namespace apache::thrift::protocol; +-using namespace apache::thrift::transport; +-using namespace apache::thrift::server; +- +-using namespace tutorial; +-using namespace shared; +- +-class CalculatorHandler : public CalculatorIf { +-public: +- CalculatorHandler() {} +- +- void ping() { cout << "ping()" << endl; } +- +- int32_t add(const int32_t n1, const int32_t n2) { +- cout << "add(" << n1 << ", " << n2 << ")" << endl; +- return n1 + n2; +- } +- +- int32_t calculate(const int32_t logid, const Work& work) { +- cout << "calculate(" << logid << ", " << work << ")" << endl; +- int32_t val; +- +- switch (work.op) { +- case Operation::ADD: +- val = work.num1 + work.num2; +- break; +- case Operation::SUBTRACT: +- val = work.num1 - work.num2; +- break; +- case Operation::MULTIPLY: +- val = work.num1 * work.num2; +- break; +- case Operation::DIVIDE: +- if (work.num2 == 0) { +- InvalidOperation io; +- io.whatOp = work.op; +- io.why = "Cannot divide by 0"; +- throw io; +- } +- val = work.num1 / work.num2; +- break; +- default: +- InvalidOperation io; +- io.whatOp = work.op; +- io.why = "Invalid Operation"; +- throw io; +- } +- +- SharedStruct ss; +- ss.key = logid; +- ss.value = to_string(val); +- +- log[logid] = ss; +- +- return val; +- } +- +- void getStruct(SharedStruct& ret, const int32_t logid) { +- cout << "getStruct(" << logid << ")" << endl; +- ret = log[logid]; +- } +- +- void zip() { cout << "zip()" << endl; } +- +-protected: +- map log; +-}; +- +-/* +- CalculatorIfFactory is code generated. +- CalculatorCloneFactory is useful for getting access to the server side of the +- transport. It is also useful for making per-connection state. Without this +- CloneFactory, all connections will end up sharing the same handler instance. +-*/ +-class CalculatorCloneFactory : virtual public CalculatorIfFactory { +- public: +- virtual ~CalculatorCloneFactory() {} +- virtual CalculatorIf* getHandler(const ::apache::thrift::TConnectionInfo& connInfo) +- { +- boost::shared_ptr sock = boost::dynamic_pointer_cast(connInfo.transport); +- cout << "Incoming connection\n"; +- cout << "\tSocketInfo: " << sock->getSocketInfo() << "\n"; +- cout << "\tPeerHost: " << sock->getPeerHost() << "\n"; +- cout << "\tPeerAddress: " << sock->getPeerAddress() << "\n"; +- cout << "\tPeerPort: " << sock->getPeerPort() << "\n"; +- return new CalculatorHandler; +- } +- virtual void releaseHandler( ::shared::SharedServiceIf* handler) { +- delete handler; +- } +-}; +- +-int main() { +- TThreadedServer server( +- boost::make_shared(boost::make_shared()), +- boost::make_shared(9090), //port +- boost::make_shared(), +- boost::make_shared()); +- +- /* +- // if you don't need per-connection state, do the following instead +- TThreadedServer server( +- boost::make_shared(boost::make_shared()), +- boost::make_shared(9090), //port +- boost::make_shared(), +- boost::make_shared()); +- */ +- +- /** +- * Here are some alternate server types... +- +- // This server only allows one connection at a time, but spawns no threads +- TSimpleServer server( +- boost::make_shared(boost::make_shared()), +- boost::make_shared(9090), +- boost::make_shared(), +- boost::make_shared()); +- +- const int workerCount = 4; +- +- boost::shared_ptr threadManager = +- ThreadManager::newSimpleThreadManager(workerCount); +- threadManager->threadFactory( +- boost::make_shared()); +- threadManager->start(); +- +- // This server allows "workerCount" connection at a time, and reuses threads +- TThreadPoolServer server( +- boost::make_shared(boost::make_shared()), +- boost::make_shared(9090), +- boost::make_shared(), +- boost::make_shared(), +- threadManager); +- */ +- +- cout << "Starting the server..." << endl; +- server.serve(); +- cout << "Done." << endl; +- return 0; +-} +diff --git a/tutorial/cpp/GrpcClient.cpp b/tutorial/cpp/GrpcClient.cpp +new file mode 100644 +index 0000000..ab1fe77 +--- /dev/null ++++ b/tutorial/cpp/GrpcClient.cpp +@@ -0,0 +1,94 @@ ++/* ++ * ++ * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without @@ -909,105 +1183,57 @@ index 2763fee..c41604e 100644 + * 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. - * -- * 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 ++ * ++ */ ++ ++#include +#include +#include - --#include --#include --#include -- --#include "../gen-cpp/Calculator.h" ++ +#include - --using namespace std; --using namespace apache::thrift; --using namespace apache::thrift::protocol; --using namespace apache::thrift::transport; ++ +#include "gen-cpp/Greeter.grpc.thrift.h" - --using namespace tutorial; --using namespace shared; ++ +using grpc::Channel; +using grpc::ClientContext; +using grpc::Status; +using test::Greeter; +using namespace test; - --int main() { -- boost::shared_ptr socket(new TSocket("localhost", 9090)); -- boost::shared_ptr transport(new TBufferedTransport(socket)); -- boost::shared_ptr protocol(new TBinaryProtocol(transport)); -- CalculatorClient client(protocol); ++ +class GreeterClient { + public: + GreeterClient(std::shared_ptr channel) + : stub_(Greeter::NewStub(channel)) {} - -- try { -- transport->open(); -+ // Assambles the client's payload, sends it and presents the response back ++ ++ // Assembles the client's payload, sends it and presents the response back + // from the server. + std::string SayHello(const std::string& user) { + // Data we are sending to the server. + Greeter::SayHelloReq req; + req.request.name = user; - -- client.ping(); -- cout << "ping()" << endl; ++ + // Container for the data we expect from the server. + Greeter::SayHelloResp reply; - -- cout << "1 + 1 = " << client.add(1, 1) << endl; ++ + // Context for the client. It could be used to convey extra information to + // the server and/or tweak certain RPC behaviors. + ClientContext context; - -- Work work; -- work.op = Operation::DIVIDE; -- work.num1 = 1; -- work.num2 = 0; ++ + // The actual RPC. + Status status = stub_->SayHello(&context, req, &reply); - -- try { -- client.calculate(1, work); -- cout << "Whoa? We can divide by zero!" << endl; -- } catch (InvalidOperation& io) { -- cout << "InvalidOperation: " << io.why << endl; -- // or using generated operator<<: cout << io << endl; -- // or by using std::exception native method what(): cout << io.what() << endl; ++ + // Act upon its status. + if (status.ok()) { + return reply.success.message; + } else { + return "RPC failed"; - } ++ } + } - -- work.op = Operation::SUBTRACT; -- work.num1 = 15; -- work.num2 = 10; -- int32_t diff = client.calculate(1, work); -- cout << "15 - 10 = " << diff << endl; ++ + private: + std::unique_ptr stub_; +}; - -- // Note that C++ uses return by reference for complex types to avoid -- // costly copy construction -- SharedStruct ss; -- client.getStruct(ss, 1); -- cout << "Received log: " << ss << endl; ++ +int main() { + // Instantiate the client. It requires a channel, out of which the actual RPCs + // are created. This channel models a connection to an endpoint (in this case, @@ -1018,29 +1244,18 @@ index 2763fee..c41604e 100644 + std::string user("world"); + std::string reply = greeter.SayHello(user); + std::cout << "Greeter received: " << reply << std::endl; - -- transport->close(); -- } catch (TException& tx) { -- cout << "ERROR: " << tx.what() << endl; -- } ++ + return 0; - } -diff --git a/tutorial/cpp/CppServer.cpp b/tutorial/cpp/CppServer.cpp -index eafffa9..c838b61 100644 ---- a/tutorial/cpp/CppServer.cpp -+++ b/tutorial/cpp/CppServer.cpp -@@ -1,181 +1,87 @@ - /* -- * Licensed to the Apache Software Foundation (ASF) under one -- * or more contributor license agreements. See the NOTICE file -- * distributed with this work for additional information -- * regarding copyright ownership. The ASF licenses this file -- * to you 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 -+ * Copyright 2015, Google Inc. ++} +diff --git a/tutorial/cpp/GrpcServer.cpp b/tutorial/cpp/GrpcServer.cpp +new file mode 100644 +index 0000000..f63db57 +--- /dev/null ++++ b/tutorial/cpp/GrpcServer.cpp +@@ -0,0 +1,87 @@ ++/* ++ * ++ * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without @@ -1068,147 +1283,39 @@ index eafffa9..c838b61 100644 + * 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. - * -- * 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 --#include --#include --#include --#include --#include --#include --#include --#include --#include -- --#include -- - #include --#include --#include -- --#include "../gen-cpp/Calculator.h" ++ * ++ */ ++ ++#include +#include +#include - --using namespace std; --using namespace apache::thrift; --using namespace apache::thrift::concurrency; --using namespace apache::thrift::protocol; --using namespace apache::thrift::transport; --using namespace apache::thrift::server; ++ +#include - --using namespace tutorial; --using namespace shared; -+#include "gen-cpp/Greeter.grpc.thrift.h" -+#include - --class CalculatorHandler : public CalculatorIf { --public: -- CalculatorHandler() {} ++ ++#include "gen-cpp/Greeter.grpc.thrift.h" ++#include ++ +using grpc::Server; +using grpc::ServerBuilder; +using grpc::ServerContext; +using grpc::Status; +using test::Greeter; - -- void ping() { cout << "ping()" << endl; } ++ +using namespace grpc; +using namespace test; - -- int32_t add(const int32_t n1, const int32_t n2) { -- cout << "add(" << n1 << ", " << n2 << ")" << endl; -- return n1 + n2; -- } ++ +// Logic and data behind the server's behavior. +class GreeterServiceImpl final : public Greeter::Service { + Status SayHello(ServerContext* context,const Greeter::SayHelloReq* request, + Greeter::SayHelloResp* reply) override { + std::string prefix("Hello "); - -- int32_t calculate(const int32_t logid, const Work& work) { -- cout << "calculate(" << logid << ", " << work << ")" << endl; -- int32_t val; ++ + reply->success.message = prefix + request->request.name; - -- switch (work.op) { -- case Operation::ADD: -- val = work.num1 + work.num2; -- break; -- case Operation::SUBTRACT: -- val = work.num1 - work.num2; -- break; -- case Operation::MULTIPLY: -- val = work.num1 * work.num2; -- break; -- case Operation::DIVIDE: -- if (work.num2 == 0) { -- InvalidOperation io; -- io.whatOp = work.op; -- io.why = "Cannot divide by 0"; -- throw io; -- } -- val = work.num1 / work.num2; -- break; -- default: -- InvalidOperation io; -- io.whatOp = work.op; -- io.why = "Invalid Operation"; -- throw io; -- } -- -- SharedStruct ss; -- ss.key = logid; -- ss.value = to_string(val); -- -- log[logid] = ss; -- -- return val; ++ + return Status::OK; - } -- -- void getStruct(SharedStruct& ret, const int32_t logid) { -- cout << "getStruct(" << logid << ")" << endl; -- ret = log[logid]; -- } -- -- void zip() { cout << "zip()" << endl; } -- --protected: -- map log; - }; - --/* -- CalculatorIfFactory is code generated. -- CalculatorCloneFactory is useful for getting access to the server side of the -- transport. It is also useful for making per-connection state. Without this -- CloneFactory, all connections will end up sharing the same handler instance. --*/ --class CalculatorCloneFactory : virtual public CalculatorIfFactory { -- public: -- virtual ~CalculatorCloneFactory() {} -- virtual CalculatorIf* getHandler(const ::apache::thrift::TConnectionInfo& connInfo) -- { -- boost::shared_ptr sock = boost::dynamic_pointer_cast(connInfo.transport); -- cout << "Incoming connection\n"; -- cout << "\tSocketInfo: " << sock->getSocketInfo() << "\n"; -- cout << "\tPeerHost: " << sock->getPeerHost() << "\n"; -- cout << "\tPeerAddress: " << sock->getPeerAddress() << "\n"; -- cout << "\tPeerPort: " << sock->getPeerPort() << "\n"; -- return new CalculatorHandler; -- } -- virtual void releaseHandler( ::shared::SharedServiceIf* handler) { -- delete handler; -- } --}; ++ } ++}; ++ +void RunServer() { + std::string server_address("0.0.0.0:50051"); + GreeterServiceImpl service; @@ -1227,58 +1334,14 @@ index eafffa9..c838b61 100644 + // responsible for shutting down the server for this call to ever return. + server->Wait(); +} - - int main() { -- TThreadedServer server( -- boost::make_shared(boost::make_shared()), -- boost::make_shared(9090), //port -- boost::make_shared(), -- boost::make_shared()); -- -- /* -- // if you don't need per-connection state, do the following instead -- TThreadedServer server( -- boost::make_shared(boost::make_shared()), -- boost::make_shared(9090), //port -- boost::make_shared(), -- boost::make_shared()); -- */ -- -- /** -- * Here are some alternate server types... -- -- // This server only allows one connection at a time, but spawns no threads -- TSimpleServer server( -- boost::make_shared(boost::make_shared()), -- boost::make_shared(9090), -- boost::make_shared(), -- boost::make_shared()); -- -- const int workerCount = 4; -- -- boost::shared_ptr threadManager = -- ThreadManager::newSimpleThreadManager(workerCount); -- threadManager->threadFactory( -- boost::make_shared()); -- threadManager->start(); -- -- // This server allows "workerCount" connection at a time, and reuses threads -- TThreadPoolServer server( -- boost::make_shared(boost::make_shared()), -- boost::make_shared(9090), -- boost::make_shared(), -- boost::make_shared(), -- threadManager); -- */ ++ ++int main() { + RunServer(); - -- cout << "Starting the server..." << endl; -- server.serve(); -- cout << "Done." << endl; - return 0; - } ++ ++ return 0; ++} diff --git a/tutorial/cpp/Makefile.am b/tutorial/cpp/Makefile.am -index 184a69d..581f75e 100755 +index 184a69d..39d85e1 100755 --- a/tutorial/cpp/Makefile.am +++ b/tutorial/cpp/Makefile.am @@ -18,44 +18,38 @@ @@ -1325,8 +1388,9 @@ index 184a69d..581f75e 100755 + TestClient -TutorialServer_SOURCES = \ +- CppServer.cpp +TestServer_SOURCES = \ - CppServer.cpp ++ GrpcServer.cpp -TutorialServer_LDADD = \ - libtutorialgencpp.la \ @@ -1335,8 +1399,9 @@ index 184a69d..581f75e 100755 $(top_builddir)/lib/cpp/libthrift.la -TutorialClient_SOURCES = \ +- CppClient.cpp +TestClient_SOURCES = \ - CppClient.cpp ++ GrpcClient.cpp -TutorialClient_LDADD = \ - libtutorialgencpp.la \ @@ -1345,7 +1410,7 @@ index 184a69d..581f75e 100755 $(top_builddir)/lib/cpp/libthrift.la # -@@ -63,21 +57,21 @@ TutorialClient_LDADD = \ +@@ -63,26 +57,26 @@ TutorialClient_LDADD = \ # THRIFT = $(top_builddir)/compiler/cpp/thrift @@ -1374,6 +1439,13 @@ index 184a69d..581f75e 100755 style-local: $(CPPSTYLE_CMD) + + EXTRA_DIST = \ + CMakeLists.txt \ +- CppClient.cpp \ +- CppServer.cpp ++ GrpcClient.cpp \ ++ GrpcServer.cpp diff --git a/tutorial/cpp/test.thrift b/tutorial/cpp/test.thrift new file mode 100644 index 0000000..de3c9a4 @@ -1398,10 +1470,10 @@ index 0000000..de3c9a4 2.8.0.rc3.226.g39d4020 -From 1d47ed062e62d136c3db9f6fc1dde9e2f794cf22 Mon Sep 17 00:00:00 2001 +From 096042c132126536870eea118127cf1e608969bc Mon Sep 17 00:00:00 2001 From: chedeti Date: Sun, 31 Jul 2016 16:23:53 -0700 -Subject: [PATCH 3/5] grpc java plugins generator +Subject: [PATCH 3/3] grpc java plugins generator for examples refer to https://github.com/grpc/grpc-java/tree/master/examples/thrift --- @@ -1410,7 +1482,7 @@ for examples refer to https://github.com/grpc/grpc-java/tree/master/examples/thr 2 files changed, 887 insertions(+), 27 deletions(-) diff --git a/compiler/cpp/src/generate/t_java_generator.cc b/compiler/cpp/src/generate/t_java_generator.cc -index 2db8cb8..95e1ca8 100644 +index 2db8cb8..8b28fe2 100644 --- a/compiler/cpp/src/generate/t_java_generator.cc +++ b/compiler/cpp/src/generate/t_java_generator.cc @@ -97,10 +97,10 @@ public: @@ -1487,7 +1559,7 @@ index 2db8cb8..95e1ca8 100644 +} + +string t_java_generator::import_extended_service(t_service* tservice) { -+ if (tservice == nullptr) { ++ if (!tservice) { + return string() + "\n"; + } + string ns = tservice->get_program()->get_namespace("java"); @@ -1575,7 +1647,7 @@ index 2db8cb8..95e1ca8 100644 + f_service_ << indent() << + "@java.lang.Deprecated public static interface " << service_name_; + -+ if (tservice->get_extends() != nullptr) { ++ if (tservice->get_extends()) { + f_service_ << " extends " << tservice->get_extends()->get_name() + "Grpc." << + tservice->get_extends()->get_name() << endl; + } @@ -1610,7 +1682,7 @@ index 2db8cb8..95e1ca8 100644 + } + f_service_ << endl; + -+ if (tservice->get_extends() != nullptr) { ++ if (tservice->get_extends()) { + f_service_ << indent() << "// ARG IDs for extended service" << endl; + t_service* extend_service = tservice->get_extends(); + functions = extend_service->get_functions(); @@ -1663,7 +1735,7 @@ index 2db8cb8..95e1ca8 100644 + endl << indent() << " break;" << endl; + } + -+ if (tservice->get_extends() != nullptr) { ++ if (tservice->get_extends()) { + t_service* extend_service = tservice->get_extends(); + functions = extend_service->get_functions(); + string extend_service_name = extend_service->get_name() + "Grpc"; @@ -1721,7 +1793,7 @@ index 2db8cb8..95e1ca8 100644 + indent() << "}" << endl << endl; + } + -+ if (tservice->get_extends() != nullptr) { ++ if (tservice->get_extends()) { + t_service* extend_service = tservice->get_extends(); + functions = extend_service->get_functions(); + string extend_service_name = extend_service->get_name() + "Grpc" ; @@ -1786,7 +1858,7 @@ index 2db8cb8..95e1ca8 100644 + indent_down(); + } + -+ if(tservice->get_extends() != nullptr) { ++ if(tservice->get_extends()) { + t_service* extends_service = tservice->get_extends(); + functions = extends_service->get_functions(); + string extend_service_name = extends_service->get_name() + "Grpc"; @@ -1886,7 +1958,7 @@ index 2db8cb8..95e1ca8 100644 + indent() << "}" << endl << endl; + } + -+ if (tservice->get_extends() != nullptr) { ++ if (tservice->get_extends()) { + t_service* extend_service = tservice->get_extends(); + functions = extend_service->get_functions(); + string extend_service_name = extend_service->get_name() + "Grpc"; @@ -1930,7 +2002,7 @@ index 2db8cb8..95e1ca8 100644 + indent() << "@java.lang.Deprecated public static interface " << service_name_ << + "BlockingClient " ; + -+ if (tservice->get_extends() != nullptr) { ++ if (tservice->get_extends()) { + string extend_service_name = tservice->get_extends()->get_name(); + f_service_ << endl << indent() << " extends " << extend_service_name << "Grpc." << + extend_service_name << "BlockingClient " ; @@ -2008,7 +2080,7 @@ index 2db8cb8..95e1ca8 100644 + indent() << "}" << endl << endl; + } + -+ if (tservice->get_extends() != nullptr) { ++ if (tservice->get_extends()) { + t_service* extend_service = tservice->get_extends(); + functions = extend_service->get_functions(); + string extend_service_name = extend_service->get_name() + "Grpc"; @@ -2050,7 +2122,7 @@ index 2db8cb8..95e1ca8 100644 + indent() << "@java.lang.Deprecated public static interface " << service_name_ << + "FutureClient " ; + -+ if (tservice->get_extends() != nullptr) { ++ if (tservice->get_extends()) { + string extend_service_name = tservice->get_extends()->get_name(); + f_service_ << endl << indent() << " extends " << extend_service_name << "Grpc." << + extend_service_name << "FutureClient " ; @@ -2068,7 +2140,7 @@ index 2db8cb8..95e1ca8 100644 + indent() << " " << (*f_iter)->get_name() << "_args request);" << endl << endl; + } + -+ if (tservice->get_extends() != nullptr) { ++ if (tservice->get_extends()) { + t_service* extend_service = tservice->get_extends(); + functions = extend_service->get_functions(); + string extend_service_name = extend_service->get_name() + "Grpc"; @@ -2141,7 +2213,7 @@ index 2db8cb8..95e1ca8 100644 + indent() << "}" << endl << endl; + } + -+ if (tservice->get_extends() != nullptr) { ++ if (tservice->get_extends()) { + t_service* extend_service = tservice->get_extends(); + functions = extend_service->get_functions(); + string extend_service_name = extend_service->get_name() + "Grpc"; @@ -2176,7 +2248,7 @@ index 2db8cb8..95e1ca8 100644 + indent() << "private static final int METHODID_" << + (*f_iter)->get_name() << " = " << i << ";" << endl; + } -+ if (tservice->get_extends() != nullptr) { ++ if (tservice->get_extends()) { + t_service* extend_service = tservice->get_extends(); + functions = extend_service->get_functions(); + string extend_service_name = extend_service->get_name() + "Grpc"; @@ -2238,7 +2310,7 @@ index 2db8cb8..95e1ca8 100644 + indent() << "break;" << endl << endl; + indent_down(); + } -+ if (tservice->get_extends() != nullptr) { ++ if (tservice->get_extends()) { + t_service* extend_service = tservice->get_extends(); + functions = extend_service->get_functions(); + string extend_service_name = extend_service->get_name() + "Grpc"; @@ -2303,7 +2375,7 @@ index 2db8cb8..95e1ca8 100644 + indent() << "," << endl << + indent() << " METHOD_" << (*f_iter)->get_name(); + } -+ if (tservice->get_extends() != nullptr) { ++ if (tservice->get_extends()) { + t_service* extend_service = tservice->get_extends(); + functions = extend_service->get_functions(); + for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { @@ -2352,7 +2424,7 @@ index 2db8cb8..95e1ca8 100644 + indent_down(); + } + -+ if (tservice->get_extends() != nullptr) { ++ if (tservice->get_extends()) { + t_service* extend_service = tservice->get_extends(); + functions = extend_service->get_functions(); + string extend_service_name = extend_service->get_name() + "Grpc"; @@ -2415,193 +2487,3 @@ index 5865c54..1cffbe6 100755 -- 2.8.0.rc3.226.g39d4020 - -From a9769a0fa08f553da76215ca59a8fd797b92a853 Mon Sep 17 00:00:00 2001 -From: chedeti -Date: Mon, 1 Aug 2016 16:56:36 -0700 -Subject: [PATCH 4/5] maintain consistency with grpc - ---- - compiler/cpp/src/generate/t_cpp_generator.cc | 20 ++++++++++---------- - tutorial/cpp/{CppClient.cpp => GrpcClient.cpp} | 0 - tutorial/cpp/{CppServer.cpp => GrpcServer.cpp} | 0 - tutorial/cpp/Makefile.am | 8 ++++---- - 4 files changed, 14 insertions(+), 14 deletions(-) - rename tutorial/cpp/{CppClient.cpp => GrpcClient.cpp} (100%) - rename tutorial/cpp/{CppServer.cpp => GrpcServer.cpp} (100%) - -diff --git a/compiler/cpp/src/generate/t_cpp_generator.cc b/compiler/cpp/src/generate/t_cpp_generator.cc -index 9c3399b..4e00129 100644 ---- a/compiler/cpp/src/generate/t_cpp_generator.cc -+++ b/compiler/cpp/src/generate/t_cpp_generator.cc -@@ -1641,7 +1641,7 @@ void t_cpp_generator::generate_service(t_service* tservice) { - << endl; - - t_service* extends_service = tservice->get_extends(); -- if (extends_service != nullptr) { -+ if (extends_service) { - f_header_ << "#include \"" << get_include_prefix(*(extends_service->get_program())) - << extends_service->get_name() << ".grpc.thrift.h\"" << endl; - } -@@ -1733,7 +1733,7 @@ void t_cpp_generator::generate_service(t_service* tservice) { - indent() << "\"/" << ns << "." << service_name_ << "/" << (*f_iter)->get_name() << "\"," << endl; - } - -- if (extends_service != nullptr) { -+ if (extends_service) { - vector functions = extends_service->get_functions(); - vector::iterator f_iter; - -@@ -1749,9 +1749,9 @@ void t_cpp_generator::generate_service(t_service* tservice) { - "};" << endl; - - // Generate service class -- if ( extends_service != nullptr ) { -+ if ( extends_service) { - f_header_ << "class " << service_name_ << " : public " << -- extends_service->get_name() << " {" << endl << -+ type_name(extends_service) << " {" << endl << - "public:" << endl; - } - else { -@@ -1841,7 +1841,7 @@ void t_cpp_generator::generate_service_helpers(t_service* tservice) { - void t_cpp_generator::generate_service_stub_interface(t_service* tservice) { - - string extends = ""; -- if (tservice->get_extends() != nullptr) { -+ if (tservice->get_extends()) { - extends = " : virtual public " + type_name(tservice->get_extends()) + "::StubInterface"; - } - -@@ -1890,7 +1890,7 @@ void t_cpp_generator::generate_service_stub(t_service* tservice) { - } - - t_service* extends_service = tservice->get_extends(); -- if (extends_service != nullptr) { -+ if (extends_service) { - // generate inherited methods - vector functions = extends_service->get_functions(); - vector::iterator f_iter; -@@ -1914,7 +1914,7 @@ void t_cpp_generator::generate_service_stub(t_service* tservice) { - indent() << "const ::grpc::RpcMethod rpcmethod_" << (*f_iter)->get_name() << "_;" << endl; - } - -- if (extends_service != nullptr) { -+ if (extends_service) { - // generate inherited methods - vector functions = extends_service->get_functions(); - vector::iterator f_iter; -@@ -1944,7 +1944,7 @@ void t_cpp_generator::generate_service_stub(t_service* tservice) { - service_name_ << "_method_names[" << i << "], ::grpc::RpcMethod::NORMAL_RPC, channel)" << endl; - } - -- if (extends_service != nullptr) { -+ if (extends_service) { - // generate inherited methods - vector functions = extends_service->get_functions(); - vector::iterator f_iter; -@@ -2002,7 +2002,7 @@ void t_cpp_generator::generate_service_stub(t_service* tservice) { - - } - -- if (extends_service != nullptr) { -+ if (extends_service) { - vector functions = extends_service->get_functions(); - vector::iterator f_iter; - for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { -@@ -2049,7 +2049,7 @@ void t_cpp_generator::generate_service_interface(t_service* tservice, string sty - } - - string extends = ""; -- if (tservice->get_extends() != NULL) { -+ if (tservice->get_extends()) { - extends = " : virtual public " + type_name(tservice->get_extends()) + style + "::Service"; - if (style == "CobCl" && gen_templates_) { - // TODO(simpkins): If gen_templates_ is enabled, we currently assume all -diff --git a/tutorial/cpp/CppClient.cpp b/tutorial/cpp/GrpcClient.cpp -similarity index 100% -rename from tutorial/cpp/CppClient.cpp -rename to tutorial/cpp/GrpcClient.cpp -diff --git a/tutorial/cpp/CppServer.cpp b/tutorial/cpp/GrpcServer.cpp -similarity index 100% -rename from tutorial/cpp/CppServer.cpp -rename to tutorial/cpp/GrpcServer.cpp -diff --git a/tutorial/cpp/Makefile.am b/tutorial/cpp/Makefile.am -index 581f75e..39d85e1 100755 ---- a/tutorial/cpp/Makefile.am -+++ b/tutorial/cpp/Makefile.am -@@ -39,14 +39,14 @@ noinst_PROGRAMS = \ - TestClient - - TestServer_SOURCES = \ -- CppServer.cpp -+ GrpcServer.cpp - - TestServer_LDADD = \ - libtestgencpp.la \ - $(top_builddir)/lib/cpp/libthrift.la - - TestClient_SOURCES = \ -- CppClient.cpp -+ GrpcClient.cpp - - TestClient_LDADD = \ - libtestgencpp.la \ -@@ -78,5 +78,5 @@ style-local: - - EXTRA_DIST = \ - CMakeLists.txt \ -- CppClient.cpp \ -- CppServer.cpp -+ GrpcClient.cpp \ -+ GrpcServer.cpp --- -2.8.0.rc3.226.g39d4020 - - -From bc74fca1ee73333819724f51d5aaff3546443ed0 Mon Sep 17 00:00:00 2001 -From: chedeti -Date: Mon, 1 Aug 2016 17:00:17 -0700 -Subject: [PATCH 5/5] fix typo - ---- - tutorial/cpp/GrpcClient.cpp | 4 ++-- - tutorial/cpp/GrpcServer.cpp | 2 +- - 2 files changed, 3 insertions(+), 3 deletions(-) - -diff --git a/tutorial/cpp/GrpcClient.cpp b/tutorial/cpp/GrpcClient.cpp -index c41604e..ab1fe77 100644 ---- a/tutorial/cpp/GrpcClient.cpp -+++ b/tutorial/cpp/GrpcClient.cpp -@@ -1,6 +1,6 @@ - /* - * -- * Copyright 2015, Google Inc. -+ * Copyright 2016, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without -@@ -50,7 +50,7 @@ class GreeterClient { - GreeterClient(std::shared_ptr channel) - : stub_(Greeter::NewStub(channel)) {} - -- // Assambles the client's payload, sends it and presents the response back -+ // Assembles the client's payload, sends it and presents the response back - // from the server. - std::string SayHello(const std::string& user) { - // Data we are sending to the server. -diff --git a/tutorial/cpp/GrpcServer.cpp b/tutorial/cpp/GrpcServer.cpp -index c838b61..f63db57 100644 ---- a/tutorial/cpp/GrpcServer.cpp -+++ b/tutorial/cpp/GrpcServer.cpp -@@ -1,6 +1,6 @@ - /* - * -- * Copyright 2015, Google Inc. -+ * Copyright 2016, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without --- -2.8.0.rc3.226.g39d4020 - From 82afcaa009e85cba16422b94a23387a3b7a0bd06 Mon Sep 17 00:00:00 2001 From: chedeti Date: Wed, 3 Aug 2016 16:38:05 -0700 Subject: [PATCH 07/12] rename class variables to snake_case --- .../grpc++/impl/codegen/thrift_serializer.h | 94 ++++++++++--------- include/grpc++/impl/codegen/thrift_utils.h | 21 ++--- tools/grift/Dockerfile | 4 +- tools/grift/README.md | 2 +- tools/grift/grpc_plugins_generator.patch | 91 +++++++++--------- 5 files changed, 110 insertions(+), 102 deletions(-) diff --git a/include/grpc++/impl/codegen/thrift_serializer.h b/include/grpc++/impl/codegen/thrift_serializer.h index 46112ee5b23..04dcc699deb 100644 --- a/include/grpc++/impl/codegen/thrift_serializer.h +++ b/include/grpc++/impl/codegen/thrift_serializer.h @@ -31,12 +31,9 @@ * */ - #ifndef GRPCXX_IMPL_CODEGEN_THRIFT_SERIALIZER_H - #define GRPCXX_IMPL_CODEGEN_THRIFT_SERIALIZER_H +#ifndef GRPCXX_IMPL_CODEGEN_THRIFT_SERIALIZER_H +#define GRPCXX_IMPL_CODEGEN_THRIFT_SERIALIZER_H -#include -#include -#include #include #include #include @@ -46,6 +43,10 @@ #include #include #include +#include +#include +#include +#include namespace apache { namespace thrift { @@ -59,20 +60,22 @@ using apache::thrift::transport::TMemoryBuffer; using apache::thrift::transport::TBufferBase; using apache::thrift::transport::TTransport; -template class ThriftSerializer { -public: +template +class ThriftSerializer { + public: ThriftSerializer() - : prepared_ (false) - , last_deserialized_ (false) - , serialize_version_ (false) {} + : prepared_(false), + last_deserialized_(false), + serialize_version_(false) {} virtual ~ThriftSerializer() {} // Serialize the passed type into the internal buffer // and returns a pointer to internal buffer and its size - template void Serialize(const T& fields, const uint8_t** serializedBuffer, - size_t* serializedLen) { - // prepare or reset buffer + template + void Serialize(const T& fields, const uint8_t** serialized_buffer, + size_t* serialized_len) { + // prepare or reset buffer if (!prepared_ || last_deserialized_) { prepare(); } else { @@ -85,7 +88,7 @@ public: protocol_->writeMessageBegin("", TMessageType(0), 0); } - // serilaize fields into buffer + // serialize fields into buffer fields.write(protocol_.get()); // write the end of message @@ -93,22 +96,23 @@ public: protocol_->writeMessageEnd(); } - uint8_t* byteBuffer; - uint32_t byteBufferSize; - buffer_->getBuffer(&byteBuffer, &byteBufferSize); - *serializedBuffer = byteBuffer; - *serializedLen = byteBufferSize; + uint8_t* byte_buffer; + uint32_t byte_buffer_size; + buffer_->getBuffer(&byte_buffer, &byte_buffer_size); + *serialized_buffer = byte_buffer; + *serialized_len = byte_buffer_size; } // Serialize the passed type into the byte buffer - template void Serialize(const T& fields, grpc_byte_buffer** bp) { + template + void Serialize(const T& fields, grpc_byte_buffer** bp) { + const uint8_t* byte_buffer; + size_t byte_buffer_size; - const uint8_t* byteBuffer; - size_t byteBufferSize; + Serialize(fields, &byte_buffer, &byte_buffer_size); - Serialize(fields, &byteBuffer, &byteBufferSize); - - gpr_slice slice = gpr_slice_from_copied_buffer((char*)byteBuffer,byteBufferSize); + gpr_slice slice = + gpr_slice_from_copied_buffer((char*)byte_buffer, byte_buffer_size); *bp = grpc_raw_byte_buffer_create(&slice, 1); @@ -117,21 +121,22 @@ public: // Deserialize the passed char array into the passed type, returns the number // of bytes that have been consumed from the passed string. - template uint32_t Deserialize(const uint8_t* serializedBuffer, size_t length, - T* fields) { + template + uint32_t Deserialize(const uint8_t* serialized_buffer, size_t length, + T* fields) { // prepare buffer if necessary if (!prepared_) { prepare(); } last_deserialized_ = true; - //reset buffer transport - buffer_->resetBuffer((uint8_t*)serializedBuffer, length); + // reset buffer transport + buffer_->resetBuffer((uint8_t*)serialized_buffer, length); // read the protocol version if necessary if (serialize_version_) { std::string name = ""; - TMessageType mt = (TMessageType) 0; + TMessageType mt = (TMessageType)0; int32_t seq_id = 0; protocol_->readMessageBegin(name, mt, seq_id); } @@ -147,17 +152,17 @@ public: return len; } - // Deserialize the passed byte buffer to passed type, returns the number // of bytes consumed from byte buffer - template uint32_t Deserialize(grpc_byte_buffer* buffer, T* msg) { - + template + uint32_t Deserialize(grpc_byte_buffer* buffer, T* msg) { grpc_byte_buffer_reader reader; grpc_byte_buffer_reader_init(&reader, buffer); gpr_slice slice = grpc_byte_buffer_reader_readall(&reader); - uint32_t len = Deserialize(GPR_SLICE_START_PTR(slice), GPR_SLICE_LENGTH(slice), msg); + uint32_t len = + Deserialize(GPR_SLICE_START_PTR(slice), GPR_SLICE_LENGTH(slice), msg); gpr_slice_unref(slice); @@ -167,9 +172,7 @@ public: } // set serialization version flag - void SetSerializeVersion(bool value) { - serialize_version_ = value; - } + void SetSerializeVersion(bool value) { serialize_version_ = value; } // Set the container size limit to deserialize // This function should be called after buffer_ is initialized @@ -189,7 +192,7 @@ public: protocol_->setStringSizeLimit(string_limit); } -private: + private: bool prepared_; bool last_deserialized_; boost::shared_ptr buffer_; @@ -197,6 +200,7 @@ private: bool serialize_version_; void prepare() { + buffer_.reset(new TMemoryBuffer()); // create a protocol for the memory buffer transport @@ -205,13 +209,15 @@ private: prepared_ = true; } -}; // ThriftSerializer +}; // ThriftSerializer -typedef ThriftSerializer> ThriftSerializerBinary; -typedef ThriftSerializer> ThriftSerializerCompact; +typedef ThriftSerializer> + ThriftSerializerBinary; +typedef ThriftSerializer> + ThriftSerializerCompact; -} // namespace util -} // namespace thrift -} // namespace apache +} // namespace util +} // namespace thrift +} // namespace apache #endif \ No newline at end of file diff --git a/include/grpc++/impl/codegen/thrift_utils.h b/include/grpc++/impl/codegen/thrift_utils.h index 14332c05219..7d19b247f4c 100644 --- a/include/grpc++/impl/codegen/thrift_utils.h +++ b/include/grpc++/impl/codegen/thrift_utils.h @@ -34,16 +34,16 @@ #ifndef GRPCXX_IMPL_CODEGEN_THRIFT_UTILS_H #define GRPCXX_IMPL_CODEGEN_THRIFT_UTILS_H -#include -#include -#include -#include #include #include #include #include #include #include +#include +#include +#include +#include #include #include @@ -52,23 +52,20 @@ namespace grpc { using apache::thrift::util::ThriftSerializerCompact; template -class SerializationTraits::value>::type> { +class SerializationTraits::value>::type> { public: - - static Status Serialize(const T& msg, - grpc_byte_buffer** bp, bool* own_buffer) { - + static Status Serialize(const T& msg, grpc_byte_buffer** bp, + bool* own_buffer) { *own_buffer = true; ThriftSerializerCompact serializer; - serializer.Serialize(msg, bp); return Status(StatusCode::OK, "ok"); } - static Status Deserialize(grpc_byte_buffer* buffer, - T* msg, + static Status Deserialize(grpc_byte_buffer* buffer, T* msg, int max_message_size) { if (!buffer) { return Status(StatusCode::INTERNAL, "No payload"); diff --git a/tools/grift/Dockerfile b/tools/grift/Dockerfile index 5238010ea92..954640f0df0 100644 --- a/tools/grift/Dockerfile +++ b/tools/grift/Dockerfile @@ -46,8 +46,8 @@ RUN apt-get update && \ curl make automake libtool # Configure git -RUN git config --global user.name " " && \ - git config --global user.email " " +RUN git config --global user.name "Jenkins" && \ + git config --global user.email "jenkins@grpc" RUN git clone https://github.com/grpc/grpc diff --git a/tools/grift/README.md b/tools/grift/README.md index 25c67451326..2525f9b83dd 100644 --- a/tools/grift/README.md +++ b/tools/grift/README.md @@ -2,7 +2,7 @@ Copyright 2016 Google Inc. #Documentation -grift is integration of [Apache Thrift](https://github.com/apache/thrift.git) Serializer with GRPC. +grift is integration of [Apache Thrift](https://github.com/apache/thrift.git) Serializer with gRPC. This integration allows you to use grpc to send thrift messages in C++ and java. diff --git a/tools/grift/grpc_plugins_generator.patch b/tools/grift/grpc_plugins_generator.patch index 3a6710c224e..a1d4cecde04 100644 --- a/tools/grift/grpc_plugins_generator.patch +++ b/tools/grift/grpc_plugins_generator.patch @@ -59,7 +59,7 @@ index 6fd15d2..7de1fad 100755 2.8.0.rc3.226.g39d4020 -From c8577ad5513543c57a81ad1bf4927cc8a78baa03 Mon Sep 17 00:00:00 2001 +From e724d3abf096278615085bd58217321e32b43fd8 Mon Sep 17 00:00:00 2001 From: chedeti Date: Sun, 31 Jul 2016 16:16:40 -0700 Subject: [PATCH 2/3] grpc cpp plugins generator with example @@ -69,16 +69,16 @@ Subject: [PATCH 2/3] grpc cpp plugins generator with example tutorial/cpp/CMakeLists.txt | 53 --- tutorial/cpp/CppClient.cpp | 80 ----- tutorial/cpp/CppServer.cpp | 181 ---------- - tutorial/cpp/GrpcClient.cpp | 94 ++++++ - tutorial/cpp/GrpcServer.cpp | 87 +++++ + tutorial/cpp/GriftClient.cpp | 93 ++++++ + tutorial/cpp/GriftServer.cpp | 93 ++++++ tutorial/cpp/Makefile.am | 66 ++-- tutorial/cpp/test.thrift | 13 + - 8 files changed, 636 insertions(+), 416 deletions(-) + 8 files changed, 641 insertions(+), 416 deletions(-) delete mode 100644 tutorial/cpp/CMakeLists.txt delete mode 100644 tutorial/cpp/CppClient.cpp delete mode 100644 tutorial/cpp/CppServer.cpp - create mode 100644 tutorial/cpp/GrpcClient.cpp - create mode 100644 tutorial/cpp/GrpcServer.cpp + create mode 100644 tutorial/cpp/GriftClient.cpp + create mode 100644 tutorial/cpp/GriftServer.cpp create mode 100644 tutorial/cpp/test.thrift diff --git a/compiler/cpp/src/generate/t_cpp_generator.cc b/compiler/cpp/src/generate/t_cpp_generator.cc @@ -1147,12 +1147,12 @@ index eafffa9..0000000 - cout << "Done." << endl; - return 0; -} -diff --git a/tutorial/cpp/GrpcClient.cpp b/tutorial/cpp/GrpcClient.cpp +diff --git a/tutorial/cpp/GriftClient.cpp b/tutorial/cpp/GriftClient.cpp new file mode 100644 -index 0000000..ab1fe77 +index 0000000..647a683 --- /dev/null -+++ b/tutorial/cpp/GrpcClient.cpp -@@ -0,0 +1,94 @@ ++++ b/tutorial/cpp/GriftClient.cpp +@@ -0,0 +1,93 @@ +/* + * + * Copyright 2016, Google Inc. @@ -1198,7 +1198,6 @@ index 0000000..ab1fe77 +using grpc::ClientContext; +using grpc::Status; +using test::Greeter; -+using namespace test; + +class GreeterClient { + public: @@ -1247,12 +1246,12 @@ index 0000000..ab1fe77 + + return 0; +} -diff --git a/tutorial/cpp/GrpcServer.cpp b/tutorial/cpp/GrpcServer.cpp +diff --git a/tutorial/cpp/GriftServer.cpp b/tutorial/cpp/GriftServer.cpp new file mode 100644 -index 0000000..f63db57 +index 0000000..7c01606 --- /dev/null -+++ b/tutorial/cpp/GrpcServer.cpp -@@ -0,0 +1,87 @@ ++++ b/tutorial/cpp/GriftServer.cpp +@@ -0,0 +1,93 @@ +/* + * + * Copyright 2016, Google Inc. @@ -1301,11 +1300,14 @@ index 0000000..f63db57 +using grpc::Status; +using test::Greeter; + -+using namespace grpc; -+using namespace test; -+ +// Logic and data behind the server's behavior. +class GreeterServiceImpl final : public Greeter::Service { ++ public: ++ ~GreeterServiceImpl() { ++ // shutdown server ++ server->Shutdown(); ++ } ++ + Status SayHello(ServerContext* context,const Greeter::SayHelloReq* request, + Greeter::SayHelloResp* reply) override { + std::string prefix("Hello "); @@ -1314,34 +1316,37 @@ index 0000000..f63db57 + + return Status::OK; + } -+}; + -+void RunServer() { -+ std::string server_address("0.0.0.0:50051"); -+ GreeterServiceImpl service; ++ void RunServer() { ++ std::string server_address("0.0.0.0:50051"); ++ ++ ServerBuilder builder; ++ // Listen on the given address without any authentication mechanism. ++ builder.AddListeningPort(server_address, grpc::InsecureServerCredentials()); ++ // Register "service" as the instance through which we'll communicate with ++ // clients. In this case it corresponds to an *synchronous* service. ++ builder.RegisterService(this); ++ // Finally assemble the server. ++ server = builder.BuildAndStart(); ++ std::cout << "Server listening on " << server_address << std::endl; ++ ++ // Wait for the server to shutdown. Note that some other thread must be ++ // responsible for shutting down the server for this call to ever return. ++ server->Wait(); ++ } + -+ ServerBuilder builder; -+ // Listen on the given address without any authentication mechanism. -+ builder.AddListeningPort(server_address, grpc::InsecureServerCredentials()); -+ // Register "service" as the instance through which we'll communicate with -+ // clients. In this case it corresponds to an *synchronous* service. -+ builder.RegisterService(&service); -+ // Finally assemble the server. -+ std::unique_ptr server(builder.BuildAndStart()); -+ std::cout << "Server listening on " << server_address << std::endl; -+ -+ // Wait for the server to shutdown. Note that some other thread must be -+ // responsible for shutting down the server for this call to ever return. -+ server->Wait(); -+} ++ private: ++ std::unique_ptr server; ++}; + +int main() { -+ RunServer(); ++ GreeterServiceImpl service; ++ service.RunServer(); + + return 0; +} diff --git a/tutorial/cpp/Makefile.am b/tutorial/cpp/Makefile.am -index 184a69d..39d85e1 100755 +index 184a69d..6f91e28 100755 --- a/tutorial/cpp/Makefile.am +++ b/tutorial/cpp/Makefile.am @@ -18,44 +18,38 @@ @@ -1390,7 +1395,7 @@ index 184a69d..39d85e1 100755 -TutorialServer_SOURCES = \ - CppServer.cpp +TestServer_SOURCES = \ -+ GrpcServer.cpp ++ GriftServer.cpp -TutorialServer_LDADD = \ - libtutorialgencpp.la \ @@ -1401,7 +1406,7 @@ index 184a69d..39d85e1 100755 -TutorialClient_SOURCES = \ - CppClient.cpp +TestClient_SOURCES = \ -+ GrpcClient.cpp ++ GriftClient.cpp -TutorialClient_LDADD = \ - libtutorialgencpp.la \ @@ -1444,8 +1449,8 @@ index 184a69d..39d85e1 100755 CMakeLists.txt \ - CppClient.cpp \ - CppServer.cpp -+ GrpcClient.cpp \ -+ GrpcServer.cpp ++ GriftClient.cpp \ ++ GriftServer.cpp diff --git a/tutorial/cpp/test.thrift b/tutorial/cpp/test.thrift new file mode 100644 index 0000000..de3c9a4 @@ -1470,7 +1475,7 @@ index 0000000..de3c9a4 2.8.0.rc3.226.g39d4020 -From 096042c132126536870eea118127cf1e608969bc Mon Sep 17 00:00:00 2001 +From f991f33dd6461eae197b6ad0e7088b571f2a7b22 Mon Sep 17 00:00:00 2001 From: chedeti Date: Sun, 31 Jul 2016 16:23:53 -0700 Subject: [PATCH 3/3] grpc java plugins generator From 2e698457f370091111d0fe620bad306c743a3548 Mon Sep 17 00:00:00 2001 From: chedeti Date: Wed, 3 Aug 2016 16:45:18 -0700 Subject: [PATCH 08/12] sanity check for thrift --- tools/run_tests/sanity/check_submodules.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/run_tests/sanity/check_submodules.sh b/tools/run_tests/sanity/check_submodules.sh index b602d695649..e2bbd8cabfc 100755 --- a/tools/run_tests/sanity/check_submodules.sh +++ b/tools/run_tests/sanity/check_submodules.sh @@ -47,6 +47,7 @@ cat << EOF | awk '{ print $1 }' | sort > $want_submodules f8ac463766281625ad710900479130c7fcb4d63b third_party/nanopb (nanopb-0.3.4-29-gf8ac463) bdeb215cab2985195325fcd5e70c3fa751f46e0f third_party/protobuf (v3.0.0-beta-3.3) 50893291621658f355bc5b4d450a8d06a563053d third_party/zlib (v1.2.8) + bcad91771b7f0bff28a1cac1981d7ef2b9bcef3c third_party/thrift EOF diff -u $submodules $want_submodules From 76db7f9a7cdf6b5fd6706037c72de1dd131b181e Mon Sep 17 00:00:00 2001 From: chedeti Date: Thu, 4 Aug 2016 11:56:54 -0700 Subject: [PATCH 09/12] use boost::make_shared --- include/grpc++/impl/codegen/thrift_serializer.h | 14 ++++++-------- tools/grift/README.md | 3 +-- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/include/grpc++/impl/codegen/thrift_serializer.h b/include/grpc++/impl/codegen/thrift_serializer.h index 04dcc699deb..fcb0ffaad6e 100644 --- a/include/grpc++/impl/codegen/thrift_serializer.h +++ b/include/grpc++/impl/codegen/thrift_serializer.h @@ -111,8 +111,8 @@ class ThriftSerializer { Serialize(fields, &byte_buffer, &byte_buffer_size); - gpr_slice slice = - gpr_slice_from_copied_buffer((char*)byte_buffer, byte_buffer_size); + gpr_slice slice = gpr_slice_from_copied_buffer( + reinterpret_cast(byte_buffer), byte_buffer_size); *bp = grpc_raw_byte_buffer_create(&slice, 1); @@ -131,12 +131,12 @@ class ThriftSerializer { last_deserialized_ = true; // reset buffer transport - buffer_->resetBuffer((uint8_t*)serialized_buffer, length); + buffer_->resetBuffer(const_cast(serialized_buffer), length); // read the protocol version if necessary if (serialize_version_) { std::string name = ""; - TMessageType mt = (TMessageType)0; + TMessageType mt = static_cast(0); int32_t seq_id = 0; protocol_->readMessageBegin(name, mt, seq_id); } @@ -200,11 +200,9 @@ class ThriftSerializer { bool serialize_version_; void prepare() { - - buffer_.reset(new TMemoryBuffer()); - + buffer_ = boost::make_shared(*(new TMemoryBuffer())); // create a protocol for the memory buffer transport - protocol_.reset(new Protocol(buffer_)); + protocol_ = std::make_shared(*(new Protocol(buffer_))); prepared_ = true; } diff --git a/tools/grift/README.md b/tools/grift/README.md index 2525f9b83dd..7cbbdc567bf 100644 --- a/tools/grift/README.md +++ b/tools/grift/README.md @@ -23,5 +23,4 @@ grift uses Compact Protocol to serialize thrift messages. #Installation Before Installing thrift make sure to apply this [patch](grpc_plugins_generator.patch) to third_party/thrift. -Go to third_party/thrift and follow the [INSTALLATION](https://github.com/apache/thrift.git) instructions to -install thrift. \ No newline at end of file +Go to third_party/thrift and follow the [INSTALLATION](https://github.com/apache/thrift.git) instructions to install thrift with commit id bcad91771b7f0bff28a1cac1981d7ef2b9bcef3c. \ No newline at end of file From a7ee93864a2e822ec510dccec19012e59acdeb7d Mon Sep 17 00:00:00 2001 From: chedeti Date: Thu, 4 Aug 2016 14:42:35 -0700 Subject: [PATCH 10/12] remove const in Deserialize --- include/grpc++/impl/codegen/thrift_serializer.h | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/include/grpc++/impl/codegen/thrift_serializer.h b/include/grpc++/impl/codegen/thrift_serializer.h index fcb0ffaad6e..7308a1577c8 100644 --- a/include/grpc++/impl/codegen/thrift_serializer.h +++ b/include/grpc++/impl/codegen/thrift_serializer.h @@ -122,8 +122,7 @@ class ThriftSerializer { // Deserialize the passed char array into the passed type, returns the number // of bytes that have been consumed from the passed string. template - uint32_t Deserialize(const uint8_t* serialized_buffer, size_t length, - T* fields) { + uint32_t Deserialize(uint8_t* serialized_buffer, size_t length, T* fields) { // prepare buffer if necessary if (!prepared_) { prepare(); @@ -131,7 +130,7 @@ class ThriftSerializer { last_deserialized_ = true; // reset buffer transport - buffer_->resetBuffer(const_cast(serialized_buffer), length); + buffer_->resetBuffer(serialized_buffer, length); // read the protocol version if necessary if (serialize_version_) { @@ -200,10 +199,9 @@ class ThriftSerializer { bool serialize_version_; void prepare() { - buffer_ = boost::make_shared(*(new TMemoryBuffer())); + buffer_ = boost::make_shared(); // create a protocol for the memory buffer transport - protocol_ = std::make_shared(*(new Protocol(buffer_))); - + protocol_ = std::make_shared(buffer_); prepared_ = true; } From d07c17e3430bbf1cc1a802b76cf57175bbb6603c Mon Sep 17 00:00:00 2001 From: chedeti Date: Thu, 4 Aug 2016 17:52:00 -0700 Subject: [PATCH 11/12] fix Dockerfile --- tools/grift/Dockerfile | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/tools/grift/Dockerfile b/tools/grift/Dockerfile index 954640f0df0..223ee939927 100644 --- a/tools/grift/Dockerfile +++ b/tools/grift/Dockerfile @@ -43,21 +43,25 @@ RUN apt-get update && \ cmake \ libiberty-dev \ g++ unzip \ - curl make automake libtool + curl make automake libtool libboost-dev # Configure git RUN git config --global user.name "Jenkins" && \ git config --global user.email "jenkins@grpc" +# Clone gRPC RUN git clone https://github.com/grpc/grpc +# Update Submodules RUN cd grpc && git submodule update --init -RUN cd grpc/third_party/thrift && git am --signoff < ../../tools/grift/grpc_plugins_generator.patch - +# Install protobuf RUN cd grpc/third_party/protobuf && ./autogen.sh && ./configure && \ make -j && make check -j && make install && ldconfig +# Install gRPC RUN cd grpc && make -j && make install -RUN cd grpc/third_party/thrift && ./bootstrap.sh && ./configure && make -j && make install \ No newline at end of file +# Install thrift +RUN cd grpc/third_party/thrift && git am --signoff < ../../tools/grift/grpc_plugins_generator.patch && \ + ./bootstrap.sh && ./configure && make -j && make install \ No newline at end of file From 7e024be839687470bd1343f70f08ec1e703eb9ec Mon Sep 17 00:00:00 2001 From: chedeti Date: Fri, 5 Aug 2016 11:15:37 -0700 Subject: [PATCH 12/12] fix multilevel inheritence codegen --- tools/grift/grpc_plugins_generator.patch | 75 ++++++++++++++---------- 1 file changed, 43 insertions(+), 32 deletions(-) diff --git a/tools/grift/grpc_plugins_generator.patch b/tools/grift/grpc_plugins_generator.patch index a1d4cecde04..de82a01f625 100644 --- a/tools/grift/grpc_plugins_generator.patch +++ b/tools/grift/grpc_plugins_generator.patch @@ -59,21 +59,21 @@ index 6fd15d2..7de1fad 100755 2.8.0.rc3.226.g39d4020 -From e724d3abf096278615085bd58217321e32b43fd8 Mon Sep 17 00:00:00 2001 +From 387e4300bc9d98176a92a7c010621443a538e7f2 Mon Sep 17 00:00:00 2001 From: chedeti Date: Sun, 31 Jul 2016 16:16:40 -0700 Subject: [PATCH 2/3] grpc cpp plugins generator with example --- - compiler/cpp/src/generate/t_cpp_generator.cc | 478 +++++++++++++++++++++++---- + compiler/cpp/src/generate/t_cpp_generator.cc | 489 +++++++++++++++++++++++---- tutorial/cpp/CMakeLists.txt | 53 --- tutorial/cpp/CppClient.cpp | 80 ----- tutorial/cpp/CppServer.cpp | 181 ---------- - tutorial/cpp/GriftClient.cpp | 93 ++++++ - tutorial/cpp/GriftServer.cpp | 93 ++++++ + tutorial/cpp/GriftClient.cpp | 93 +++++ + tutorial/cpp/GriftServer.cpp | 93 +++++ tutorial/cpp/Makefile.am | 66 ++-- tutorial/cpp/test.thrift | 13 + - 8 files changed, 641 insertions(+), 416 deletions(-) + 8 files changed, 652 insertions(+), 416 deletions(-) delete mode 100644 tutorial/cpp/CMakeLists.txt delete mode 100644 tutorial/cpp/CppClient.cpp delete mode 100644 tutorial/cpp/CppServer.cpp @@ -82,7 +82,7 @@ Subject: [PATCH 2/3] grpc cpp plugins generator with example create mode 100644 tutorial/cpp/test.thrift diff --git a/compiler/cpp/src/generate/t_cpp_generator.cc b/compiler/cpp/src/generate/t_cpp_generator.cc -index 6c04899..4e00129 100644 +index 6c04899..1557241 100644 --- a/compiler/cpp/src/generate/t_cpp_generator.cc +++ b/compiler/cpp/src/generate/t_cpp_generator.cc @@ -162,6 +162,8 @@ public: @@ -328,7 +328,7 @@ index 6c04899..4e00129 100644 << endl; f_service_tcc_ << "#ifndef " << svcname << "_TCC" << endl << "#define " << svcname << "_TCC" -@@ -1663,19 +1704,66 @@ void t_cpp_generator::generate_service(t_service* tservice) { +@@ -1663,19 +1704,69 @@ void t_cpp_generator::generate_service(t_service* tservice) { } } @@ -361,15 +361,18 @@ index 6c04899..4e00129 100644 + indent() << "\"/" << ns << "." << service_name_ << "/" << (*f_iter)->get_name() << "\"," << endl; + } + -+ if (extends_service) { -+ vector functions = extends_service->get_functions(); ++ ++ t_service* service_iter = extends_service; ++ while (service_iter) { ++ vector functions = service_iter->get_functions(); + vector::iterator f_iter; + + for ( f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { + f_service_ << -+ indent() << "\"/" << extends_service->get_program()->get_namespace("cpp") << -+ "." << extends_service->get_name() << "/" << (*f_iter)->get_name() << "\"," << endl; ++ indent() << "\"/" << service_iter->get_program()->get_namespace("cpp") << ++ "." << service_iter->get_name() << "/" << (*f_iter)->get_name() << "\"," << endl; + } ++ service_iter = service_iter->get_extends(); + } + + indent_down(); @@ -403,7 +406,7 @@ index 6c04899..4e00129 100644 // Generate all the cob components if (gen_cob_style_) { -@@ -1688,10 +1776,14 @@ void t_cpp_generator::generate_service(t_service* tservice) { +@@ -1688,10 +1779,14 @@ void t_cpp_generator::generate_service(t_service* tservice) { generate_service_async_skeleton(tservice); } @@ -418,7 +421,7 @@ index 6c04899..4e00129 100644 // Close the namespace f_service_ << ns_close_ << endl << endl; f_service_tcc_ << ns_close_ << endl << endl; -@@ -1729,15 +1821,11 @@ void t_cpp_generator::generate_service_helpers(t_service* tservice) { +@@ -1729,15 +1824,11 @@ void t_cpp_generator::generate_service_helpers(t_service* tservice) { string name_orig = ts->get_name(); // TODO(dreiss): Why is this stuff not in generate_function_helpers? @@ -436,7 +439,7 @@ index 6c04899..4e00129 100644 ts->set_name(name_orig); generate_function_helpers(tservice, *f_iter); -@@ -1745,13 +1833,210 @@ void t_cpp_generator::generate_service_helpers(t_service* tservice) { +@@ -1745,13 +1836,218 @@ void t_cpp_generator::generate_service_helpers(t_service* tservice) { } /** @@ -497,9 +500,10 @@ index 6c04899..4e00129 100644 + } + + t_service* extends_service = tservice->get_extends(); -+ if (extends_service) { ++ t_service* service_iter = extends_service; ++ while (service_iter) { + // generate inherited methods -+ vector functions = extends_service->get_functions(); ++ vector functions = service_iter->get_functions(); + vector::iterator f_iter; + for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { + string function_name = (*f_iter)->get_name(); @@ -508,6 +512,7 @@ index 6c04899..4e00129 100644 + "(::grpc::ClientContext* context, const " << function_name << + "Req& request, " << function_name << "Resp* response) override;" << endl; + } ++ service_iter = service_iter->get_extends(); + } + + f_header_ << @@ -521,14 +526,16 @@ index 6c04899..4e00129 100644 + indent() << "const ::grpc::RpcMethod rpcmethod_" << (*f_iter)->get_name() << "_;" << endl; + } + -+ if (extends_service) { ++ service_iter = extends_service; ++ while (service_iter) { + // generate inherited methods -+ vector functions = extends_service->get_functions(); ++ vector functions = service_iter->get_functions(); + vector::iterator f_iter; + for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { + f_header_ << + indent() << "const ::grpc::RpcMethod rpcmethod_" << (*f_iter)->get_name() << "_;" << endl; + } ++ service_iter = service_iter->get_extends(); + } + + indent_down(); @@ -551,9 +558,10 @@ index 6c04899..4e00129 100644 + service_name_ << "_method_names[" << i << "], ::grpc::RpcMethod::NORMAL_RPC, channel)" << endl; + } + -+ if (extends_service) { ++ service_iter = extends_service; ++ while (service_iter) { + // generate inherited methods -+ vector functions = extends_service->get_functions(); ++ vector functions = service_iter->get_functions(); + vector::iterator f_iter; + for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter, ++i) { + f_service_ << @@ -561,6 +569,7 @@ index 6c04899..4e00129 100644 + ", rpcmethod_" << (*f_iter)->get_name() << "_(" << + service_name_ << "_method_names[" << i << "], ::grpc::RpcMethod::NORMAL_RPC, channel)" << endl; + } ++ service_iter = service_iter->get_extends(); + } + f_service_ << + indent() << "{}" << endl; @@ -609,8 +618,9 @@ index 6c04899..4e00129 100644 + + } + -+ if (extends_service) { -+ vector functions = extends_service->get_functions(); ++ service_iter = extends_service; ++ while (service_iter) { ++ vector functions = service_iter->get_functions(); + vector::iterator f_iter; + for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { + string function_name = (*f_iter)->get_name(); @@ -631,6 +641,7 @@ index 6c04899..4e00129 100644 + "}" << endl; + + } ++ service_iter = service_iter->get_extends(); + } + +} @@ -648,7 +659,7 @@ index 6c04899..4e00129 100644 if (style == "CobCl") { // Forward declare the client. string client_name = service_name_ + "CobClient"; -@@ -1764,13 +2049,15 @@ void t_cpp_generator::generate_service_interface(t_service* tservice, string sty +@@ -1764,13 +2060,15 @@ void t_cpp_generator::generate_service_interface(t_service* tservice, string sty } string extends = ""; @@ -666,7 +677,7 @@ index 6c04899..4e00129 100644 } if (style == "CobCl" && gen_templates_) { -@@ -1778,7 +2065,9 @@ void t_cpp_generator::generate_service_interface(t_service* tservice, string sty +@@ -1778,7 +2076,9 @@ void t_cpp_generator::generate_service_interface(t_service* tservice, string sty } f_header_ << "class " << service_if_name << extends << " {" << endl << " public:" << endl; indent_up(); @@ -677,7 +688,7 @@ index 6c04899..4e00129 100644 vector functions = tservice->get_functions(); vector::iterator f_iter; -@@ -1786,7 +2075,12 @@ void t_cpp_generator::generate_service_interface(t_service* tservice, string sty +@@ -1786,7 +2086,12 @@ void t_cpp_generator::generate_service_interface(t_service* tservice, string sty if ((*f_iter)->has_doc()) f_header_ << endl; generate_java_doc(f_header_, *f_iter); @@ -691,7 +702,7 @@ index 6c04899..4e00129 100644 } indent_down(); f_header_ << "};" << endl << endl; -@@ -1797,6 +2091,66 @@ void t_cpp_generator::generate_service_interface(t_service* tservice, string sty +@@ -1797,6 +2102,66 @@ void t_cpp_generator::generate_service_interface(t_service* tservice, string sty f_header_ << "typedef " << service_if_name << "< ::apache::thrift::protocol::TProtocol> " << service_name_ << style << "If;" << endl << endl; } @@ -758,7 +769,7 @@ index 6c04899..4e00129 100644 } /** -@@ -3095,7 +3449,7 @@ void t_cpp_generator::generate_function_helpers(t_service* tservice, t_function* +@@ -3095,7 +3460,7 @@ void t_cpp_generator::generate_function_helpers(t_service* tservice, t_function* std::ofstream& out = (gen_templates_ ? f_service_tcc_ : f_service_); @@ -767,7 +778,7 @@ index 6c04899..4e00129 100644 t_field success(tfunction->get_returntype(), "success", 0); if (!tfunction->get_returntype()->is_void()) { result.append(&success); -@@ -3109,17 +3463,9 @@ void t_cpp_generator::generate_function_helpers(t_service* tservice, t_function* +@@ -3109,17 +3474,9 @@ void t_cpp_generator::generate_function_helpers(t_service* tservice, t_function* } generate_struct_declaration(f_header_, &result, false); @@ -786,7 +797,7 @@ index 6c04899..4e00129 100644 } /** -@@ -3162,8 +3508,8 @@ void t_cpp_generator::generate_process_function(t_service* tservice, +@@ -3162,8 +3519,8 @@ void t_cpp_generator::generate_process_function(t_service* tservice, << endl; scope_up(out); @@ -797,7 +808,7 @@ index 6c04899..4e00129 100644 if (tfunction->is_oneway() && !unnamed_oprot_seqid) { out << indent() << "(void) seqid;" << endl << indent() << "(void) oprot;" << endl; -@@ -3320,7 +3666,7 @@ void t_cpp_generator::generate_process_function(t_service* tservice, +@@ -3320,7 +3677,7 @@ void t_cpp_generator::generate_process_function(t_service* tservice, out << indent() << "(void) seqid;" << endl << indent() << "(void) oprot;" << endl; } @@ -806,7 +817,7 @@ index 6c04899..4e00129 100644 << indent() << "void* ctx = NULL;" << endl << indent() << "if (this->eventHandler_.get() != NULL) {" << endl << indent() << " ctx = this->eventHandler_->getContext(" << service_func_name << ", NULL);" << endl -@@ -3487,7 +3833,7 @@ void t_cpp_generator::generate_process_function(t_service* tservice, +@@ -3487,7 +3844,7 @@ void t_cpp_generator::generate_process_function(t_service* tservice, << "this->eventHandler_.get(), ctx, " << service_func_name << ");" << endl << endl; // Throw the TDelayedException, and catch the result @@ -1475,7 +1486,7 @@ index 0000000..de3c9a4 2.8.0.rc3.226.g39d4020 -From f991f33dd6461eae197b6ad0e7088b571f2a7b22 Mon Sep 17 00:00:00 2001 +From 3e4d75a2e2c474ee7700e7c9acaf89fdb768bedc Mon Sep 17 00:00:00 2001 From: chedeti Date: Sun, 31 Jul 2016 16:23:53 -0700 Subject: [PATCH 3/3] grpc java plugins generator