blob: de82a01f625fe12f3ca110f784164e5f003c6223 [file] [log] [blame]
chedetidd7a2a32016-07-31 21:57:47 -07001From 0894590b5020c38106d4ebb2291994668c64f9dd Mon Sep 17 00:00:00 2001
2From: chedeti <chedeti@google.com>
3Date: Sun, 31 Jul 2016 15:47:47 -0700
chedeti00be9de2016-08-02 10:44:41 -07004Subject: [PATCH 1/3] don't build tests
chedetidd7a2a32016-07-31 21:57:47 -07005
6---
7 Makefile.am | 7 ++-----
8 lib/cpp/Makefile.am | 7 ++-----
9 2 files changed, 4 insertions(+), 10 deletions(-)
10
11diff --git a/Makefile.am b/Makefile.am
12index 10fe49a..d49caac 100755
13--- a/Makefile.am
14+++ b/Makefile.am
15@@ -21,10 +21,6 @@ ACLOCAL_AMFLAGS = -I ./aclocal
16
17 SUBDIRS = compiler/cpp lib
18
19-if WITH_TESTS
20-SUBDIRS += test
21-endif
22-
23 if WITH_TUTORIAL
24 SUBDIRS += tutorial
25 endif
26@@ -117,4 +113,5 @@ EXTRA_DIST = \
27 CHANGES \
28 NOTICE \
29 README.md \
30- Thrift.podspec
31+ Thrift.podspec \
32+ test
33diff --git a/lib/cpp/Makefile.am b/lib/cpp/Makefile.am
34index 6fd15d2..7de1fad 100755
35--- a/lib/cpp/Makefile.am
36+++ b/lib/cpp/Makefile.am
37@@ -27,10 +27,6 @@ moc__%.cpp: %.h
38
39 SUBDIRS = .
40
41-if WITH_TESTS
42-SUBDIRS += test
43-endif
44-
45 pkgconfigdir = $(libdir)/pkgconfig
46
47 lib_LTLIBRARIES = libthrift.la
48@@ -277,7 +273,8 @@ EXTRA_DIST = \
49 thrift-qt.pc.in \
50 thrift-qt5.pc.in \
51 src/thrift/qt/CMakeLists.txt \
52- $(WINDOWS_DIST)
53+ $(WINDOWS_DIST) \
54+ test
55
56 style-local:
57 $(CPPSTYLE_CMD)
58--
592.8.0.rc3.226.g39d4020
60
61
chedeti7e024be2016-08-05 11:15:37 -070062From 387e4300bc9d98176a92a7c010621443a538e7f2 Mon Sep 17 00:00:00 2001
chedetidd7a2a32016-07-31 21:57:47 -070063From: chedeti <chedeti@google.com>
64Date: Sun, 31 Jul 2016 16:16:40 -0700
chedeti00be9de2016-08-02 10:44:41 -070065Subject: [PATCH 2/3] grpc cpp plugins generator with example
chedetidd7a2a32016-07-31 21:57:47 -070066
67---
chedeti7e024be2016-08-05 11:15:37 -070068 compiler/cpp/src/generate/t_cpp_generator.cc | 489 +++++++++++++++++++++++----
chedetidd7a2a32016-07-31 21:57:47 -070069 tutorial/cpp/CMakeLists.txt | 53 ---
chedeti00be9de2016-08-02 10:44:41 -070070 tutorial/cpp/CppClient.cpp | 80 -----
71 tutorial/cpp/CppServer.cpp | 181 ----------
chedeti7e024be2016-08-05 11:15:37 -070072 tutorial/cpp/GriftClient.cpp | 93 +++++
73 tutorial/cpp/GriftServer.cpp | 93 +++++
chedeti00be9de2016-08-02 10:44:41 -070074 tutorial/cpp/Makefile.am | 66 ++--
chedetidd7a2a32016-07-31 21:57:47 -070075 tutorial/cpp/test.thrift | 13 +
chedeti7e024be2016-08-05 11:15:37 -070076 8 files changed, 652 insertions(+), 416 deletions(-)
chedetidd7a2a32016-07-31 21:57:47 -070077 delete mode 100644 tutorial/cpp/CMakeLists.txt
chedeti00be9de2016-08-02 10:44:41 -070078 delete mode 100644 tutorial/cpp/CppClient.cpp
79 delete mode 100644 tutorial/cpp/CppServer.cpp
chedeti82afcaa2016-08-03 16:38:05 -070080 create mode 100644 tutorial/cpp/GriftClient.cpp
81 create mode 100644 tutorial/cpp/GriftServer.cpp
chedetidd7a2a32016-07-31 21:57:47 -070082 create mode 100644 tutorial/cpp/test.thrift
83
84diff --git a/compiler/cpp/src/generate/t_cpp_generator.cc b/compiler/cpp/src/generate/t_cpp_generator.cc
chedeti7e024be2016-08-05 11:15:37 -070085index 6c04899..1557241 100644
chedetidd7a2a32016-07-31 21:57:47 -070086--- a/compiler/cpp/src/generate/t_cpp_generator.cc
87+++ b/compiler/cpp/src/generate/t_cpp_generator.cc
88@@ -162,6 +162,8 @@ public:
89 bool specialized = false);
90 void generate_function_helpers(t_service* tservice, t_function* tfunction);
91 void generate_service_async_skeleton(t_service* tservice);
92+ void generate_service_stub_interface(t_service* tservice);
93+ void generate_service_stub(t_service* tservice);
94
95 /**
96 * Serialization constructs
97@@ -883,10 +885,10 @@ void t_cpp_generator::generate_struct_declaration(ofstream& out,
98 bool is_user_struct) {
99 string extends = "";
100 if (is_exception) {
101- extends = " : public ::apache::thrift::TException";
102+ extends = " : public apache::thrift::TException";
103 } else {
104- if (is_user_struct && !gen_templates_) {
105- extends = " : public virtual ::apache::thrift::TBase";
106+ if (!gen_templates_) {
107+ extends = " : public virtual apache::thrift::TBase";
108 }
109 }
110
111@@ -1130,9 +1132,15 @@ void t_cpp_generator::generate_struct_definition(ofstream& out,
112 vector<t_field*>::const_iterator m_iter;
113 const vector<t_field*>& members = tstruct->get_members();
114
115+ string method_prefix = "";
116+ if (service_name_ != "") {
117+ method_prefix = service_name_ + "::";
118+ }
119+
120 // Destructor
121 if (tstruct->annotations_.find("final") == tstruct->annotations_.end()) {
122- force_cpp_out << endl << indent() << tstruct->get_name() << "::~" << tstruct->get_name()
123+ force_cpp_out << endl << indent() << method_prefix <<
124+ tstruct->get_name() << "::~" << tstruct->get_name()
125 << "() throw() {" << endl;
126 indent_up();
127
128@@ -1145,12 +1153,14 @@ void t_cpp_generator::generate_struct_definition(ofstream& out,
129 for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
130 if (is_reference((*m_iter))) {
131 std::string type = type_name((*m_iter)->get_type());
132- out << endl << indent() << "void " << tstruct->get_name() << "::__set_"
133+ out << endl << indent() << "void " << method_prefix
134+ << tstruct->get_name() << "::__set_"
135 << (*m_iter)->get_name() << "(boost::shared_ptr<"
136 << type_name((*m_iter)->get_type(), false, false) << ">";
137 out << " val) {" << endl;
138 } else {
139- out << endl << indent() << "void " << tstruct->get_name() << "::__set_"
140+ out << endl << indent() << "void " << method_prefix
141+ << tstruct->get_name() << "::__set_"
142 << (*m_iter)->get_name() << "(" << type_name((*m_iter)->get_type(), false, true);
143 out << " val) {" << endl;
144 }
145@@ -1177,11 +1187,16 @@ void t_cpp_generator::generate_struct_definition(ofstream& out,
146 * @param tstruct The struct
147 */
148 void t_cpp_generator::generate_struct_reader(ofstream& out, t_struct* tstruct, bool pointers) {
149+ string method_prefix = "";
150+ if (service_name_ != "") {
151+ method_prefix = service_name_ + "::";
152+ }
153+
154 if (gen_templates_) {
155 out << indent() << "template <class Protocol_>" << endl << indent() << "uint32_t "
156- << tstruct->get_name() << "::read(Protocol_* iprot) {" << endl;
157+ << method_prefix << tstruct->get_name() << "::read(Protocol_* iprot) {" << endl;
158 } else {
159- indent(out) << "uint32_t " << tstruct->get_name()
160+ indent(out) << "uint32_t " << method_prefix << tstruct->get_name()
161 << "::read(::apache::thrift::protocol::TProtocol* iprot) {" << endl;
162 }
163 indent_up();
164@@ -1301,14 +1316,18 @@ void t_cpp_generator::generate_struct_reader(ofstream& out, t_struct* tstruct, b
165 */
166 void t_cpp_generator::generate_struct_writer(ofstream& out, t_struct* tstruct, bool pointers) {
167 string name = tstruct->get_name();
168+ string method_prefix = "";
169+ if (service_name_ != "") {
170+ method_prefix = service_name_ + "::";
171+ }
172 const vector<t_field*>& fields = tstruct->get_sorted_members();
173 vector<t_field*>::const_iterator f_iter;
174
175 if (gen_templates_) {
176 out << indent() << "template <class Protocol_>" << endl << indent() << "uint32_t "
177- << tstruct->get_name() << "::write(Protocol_* oprot) const {" << endl;
178+ << method_prefix << tstruct->get_name() << "::write(Protocol_* oprot) const {" << endl;
179 } else {
180- indent(out) << "uint32_t " << tstruct->get_name()
181+ indent(out) << "uint32_t " << method_prefix << tstruct->get_name()
182 << "::write(::apache::thrift::protocol::TProtocol* oprot) const {" << endl;
183 }
184 indent_up();
185@@ -1369,14 +1388,18 @@ void t_cpp_generator::generate_struct_result_writer(ofstream& out,
186 t_struct* tstruct,
187 bool pointers) {
188 string name = tstruct->get_name();
189+ string method_prefix = "";
190+ if (service_name_ != "") {
191+ method_prefix = service_name_ + "::";
192+ }
193 const vector<t_field*>& fields = tstruct->get_sorted_members();
194 vector<t_field*>::const_iterator f_iter;
195
196 if (gen_templates_) {
197 out << indent() << "template <class Protocol_>" << endl << indent() << "uint32_t "
198- << tstruct->get_name() << "::write(Protocol_* oprot) const {" << endl;
199+ << method_prefix << tstruct->get_name() << "::write(Protocol_* oprot) const {" << endl;
200 } else {
201- indent(out) << "uint32_t " << tstruct->get_name()
202+ indent(out) << "uint32_t " << method_prefix << tstruct->get_name()
203 << "::write(::apache::thrift::protocol::TProtocol* oprot) const {" << endl;
204 }
205 indent_up();
206@@ -1385,18 +1408,7 @@ void t_cpp_generator::generate_struct_result_writer(ofstream& out,
207
208 indent(out) << "xfer += oprot->writeStructBegin(\"" << name << "\");" << endl;
209
210- bool first = true;
211 for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
212- if (first) {
213- first = false;
214- out << endl << indent() << "if ";
215- } else {
216- out << " else if ";
217- }
218-
219- out << "(this->__isset." << (*f_iter)->get_name() << ") {" << endl;
220-
221- indent_up();
222
223 // Write field header
224 out << indent() << "xfer += oprot->writeFieldBegin("
225@@ -1410,9 +1422,6 @@ void t_cpp_generator::generate_struct_result_writer(ofstream& out,
226 }
227 // Write field closer
228 indent(out) << "xfer += oprot->writeFieldEnd();" << endl;
229-
230- indent_down();
231- indent(out) << "}";
232 }
233
234 // Write the struct map
235@@ -1478,9 +1487,13 @@ void t_cpp_generator::generate_struct_ostream_operator(std::ofstream& out, t_str
236 }
237
238 void t_cpp_generator::generate_struct_print_method_decl(std::ofstream& out, t_struct* tstruct) {
239+ string method_prefix = "";
240+ if (service_name_ != "") {
241+ method_prefix = service_name_ + "::";
242+ }
243 out << "void ";
244 if (tstruct) {
245- out << tstruct->get_name() << "::";
246+ out << method_prefix << tstruct->get_name() << "::";
247 }
248 out << "printTo(std::ostream& out) const";
249 }
250@@ -1601,11 +1614,13 @@ void t_cpp_generator::generate_exception_what_method(std::ofstream& out, t_struc
251 */
252 void t_cpp_generator::generate_service(t_service* tservice) {
253 string svcname = tservice->get_name();
254+ string ns = tservice->get_program()->get_namespace("cpp");
255
256 // Make output files
257- string f_header_name = get_out_dir() + svcname + ".h";
258+ string f_header_name = get_out_dir() + svcname + ".grpc.thrift.h";
259 f_header_.open(f_header_name.c_str());
260
261+
262 // Print header file includes
263 f_header_ << autogen_comment();
264 f_header_ << "#ifndef " << svcname << "_H" << endl << "#define " << svcname << "_H" << endl
265@@ -1621,15 +1636,38 @@ void t_cpp_generator::generate_service(t_service* tservice) {
266 f_header_ << "#include <thrift/async/TAsyncDispatchProcessor.h>" << endl;
267 }
268 f_header_ << "#include <thrift/async/TConcurrentClientSyncInfo.h>" << endl;
269+
270 f_header_ << "#include \"" << get_include_prefix(*get_program()) << program_name_ << "_types.h\""
271 << endl;
272
273 t_service* extends_service = tservice->get_extends();
274- if (extends_service != NULL) {
chedeti00be9de2016-08-02 10:44:41 -0700275+ if (extends_service) {
chedetidd7a2a32016-07-31 21:57:47 -0700276 f_header_ << "#include \"" << get_include_prefix(*(extends_service->get_program()))
277- << extends_service->get_name() << ".h\"" << endl;
278+ << extends_service->get_name() << ".grpc.thrift.h\"" << endl;
279 }
280
281+
282+ f_header_ <<
283+ "#include <grpc++/impl/codegen/async_stream.h>" << endl <<
284+ "#include <grpc++/impl/codegen/async_unary_call.h>" << endl <<
285+ "#include <grpc++/impl/codegen/thrift_utils.h>" << endl <<
286+ "#include <grpc++/impl/codegen/rpc_method.h>" << endl <<
287+ "#include <grpc++/impl/codegen/service_type.h>" << endl <<
288+ "#include <grpc++/impl/codegen/status.h>" << endl <<
289+ "#include <grpc++/impl/codegen/stub_options.h>" << endl <<
290+ "#include <grpc++/impl/codegen/sync_stream.h>" << endl;
291+
292+
293+ f_header_ <<
294+ endl <<
295+ "namespace grpc {" << endl <<
296+ "class CompletionQueue;" << endl <<
297+ "class Channel;" << endl <<
298+ "class RpcService;" << endl <<
299+ "class ServerCompletionQueue;" << endl <<
300+ "class ServerContext;" << endl <<
301+ "}" << endl;
302+
303 f_header_ << endl << ns_open_ << endl << endl;
304
305 f_header_ << "#ifdef _WIN32\n"
306@@ -1638,10 +1676,13 @@ void t_cpp_generator::generate_service(t_service* tservice) {
307 "#endif\n\n";
308
309 // Service implementation file includes
310- string f_service_name = get_out_dir() + svcname + ".cpp";
311+ string f_service_name = get_out_dir() + svcname + ".grpc.thrift.cpp";
312 f_service_.open(f_service_name.c_str());
313 f_service_ << autogen_comment();
314- f_service_ << "#include \"" << get_include_prefix(*get_program()) << svcname << ".h\"" << endl;
315+
316+ f_service_ << "#include \"" <<
317+ get_include_prefix(*get_program()) << svcname << ".grpc.thrift.h\"" << endl;
318+
319 if (gen_cob_style_) {
320 f_service_ << "#include \"thrift/async/TAsyncChannel.h\"" << endl;
321 }
322@@ -1652,7 +1693,7 @@ void t_cpp_generator::generate_service(t_service* tservice) {
323 string f_service_tcc_name = get_out_dir() + svcname + ".tcc";
324 f_service_tcc_.open(f_service_tcc_name.c_str());
325 f_service_tcc_ << autogen_comment();
326- f_service_tcc_ << "#include \"" << get_include_prefix(*get_program()) << svcname << ".h\""
327+ f_service_tcc_ << "#include \"" << get_include_prefix(*get_program()) << svcname << ".grpc.thrift.h\""
328 << endl;
329
330 f_service_tcc_ << "#ifndef " << svcname << "_TCC" << endl << "#define " << svcname << "_TCC"
chedeti7e024be2016-08-05 11:15:37 -0700331@@ -1663,19 +1704,69 @@ void t_cpp_generator::generate_service(t_service* tservice) {
chedetidd7a2a32016-07-31 21:57:47 -0700332 }
333 }
334
335+ f_service_ <<
336+ endl <<
337+ "#include <grpc++/impl/codegen/async_stream.h>" << endl <<
338+ "#include <grpc++/impl/codegen/async_unary_call.h>" << endl <<
339+ "#include <grpc++/impl/codegen/channel_interface.h>" << endl <<
340+ "#include <grpc++/impl/codegen/client_unary_call.h>" << endl <<
341+ "#include <grpc++/impl/codegen/method_handler_impl.h>" << endl <<
342+ "#include <grpc++/impl/codegen/rpc_service_method.h>" << endl <<
343+ "#include <grpc++/impl/codegen/service_type.h>" << endl <<
344+ "#include <grpc++/impl/codegen/sync_stream.h>" << endl <<
345+ endl;
346+
347 f_service_ << endl << ns_open_ << endl << endl;
348 f_service_tcc_ << endl << ns_open_ << endl << endl;
349
350+ vector<t_function*> functions = tservice->get_functions();
351+ vector<t_function*>::iterator f_iter;
352+
353+ f_service_ <<
354+ "static const char* " << service_name_ << "_method_names[] = {" << endl;
355+
356+
357+ indent_up();
358+
359+ for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
360+ f_service_ <<
361+ indent() << "\"/" << ns << "." << service_name_ << "/" << (*f_iter)->get_name() << "\"," << endl;
362+ }
363+
chedeti7e024be2016-08-05 11:15:37 -0700364+
365+ t_service* service_iter = extends_service;
366+ while (service_iter) {
367+ vector<t_function*> functions = service_iter->get_functions();
chedetidd7a2a32016-07-31 21:57:47 -0700368+ vector<t_function*>::iterator f_iter;
369+
370+ for ( f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
371+ f_service_ <<
chedeti7e024be2016-08-05 11:15:37 -0700372+ indent() << "\"/" << service_iter->get_program()->get_namespace("cpp") <<
373+ "." << service_iter->get_name() << "/" << (*f_iter)->get_name() << "\"," << endl;
chedetidd7a2a32016-07-31 21:57:47 -0700374+ }
chedeti7e024be2016-08-05 11:15:37 -0700375+ service_iter = service_iter->get_extends();
chedetidd7a2a32016-07-31 21:57:47 -0700376+ }
377+
378+ indent_down();
379+ f_service_ <<
380+ "};" << endl;
381+
382+ // Generate service class
chedeti00be9de2016-08-02 10:44:41 -0700383+ if ( extends_service) {
chedetidd7a2a32016-07-31 21:57:47 -0700384+ f_header_ << "class " << service_name_ << " : public " <<
chedeti00be9de2016-08-02 10:44:41 -0700385+ type_name(extends_service) << " {" << endl <<
chedetidd7a2a32016-07-31 21:57:47 -0700386+ "public:" << endl;
387+ }
388+ else {
389+ f_header_ << "class " << service_name_ << "{" << endl <<
390+ "public:" << endl;
391+ }
392+
393 // Generate all the components
394- generate_service_interface(tservice, "");
395- generate_service_interface_factory(tservice, "");
396- generate_service_null(tservice, "");
397 generate_service_helpers(tservice);
398- generate_service_client(tservice, "");
399- generate_service_processor(tservice, "");
400- generate_service_multiface(tservice);
401- generate_service_skeleton(tservice);
402- generate_service_client(tservice, "Concurrent");
403+ generate_service_interface(tservice, "");
404+ generate_service_stub_interface(tservice);
405+ generate_service_stub(tservice);
406
407 // Generate all the cob components
408 if (gen_cob_style_) {
chedeti7e024be2016-08-05 11:15:37 -0700409@@ -1688,10 +1779,14 @@ void t_cpp_generator::generate_service(t_service* tservice) {
chedetidd7a2a32016-07-31 21:57:47 -0700410 generate_service_async_skeleton(tservice);
411 }
412
413+ // Close service class
414+ f_header_ << "};" << endl;
415+
416 f_header_ << "#ifdef _WIN32\n"
417 " #pragma warning( pop )\n"
418 "#endif\n\n";
419
420+
421 // Close the namespace
422 f_service_ << ns_close_ << endl << endl;
423 f_service_tcc_ << ns_close_ << endl << endl;
chedeti7e024be2016-08-05 11:15:37 -0700424@@ -1729,15 +1824,11 @@ void t_cpp_generator::generate_service_helpers(t_service* tservice) {
chedetidd7a2a32016-07-31 21:57:47 -0700425 string name_orig = ts->get_name();
426
427 // TODO(dreiss): Why is this stuff not in generate_function_helpers?
428- ts->set_name(tservice->get_name() + "_" + (*f_iter)->get_name() + "_args");
429+ ts->set_name((*f_iter)->get_name() + "Req");
430 generate_struct_declaration(f_header_, ts, false);
431- generate_struct_definition(out, f_service_, ts, false);
432+ generate_struct_definition(out, f_service_, ts, true);
433 generate_struct_reader(out, ts);
434 generate_struct_writer(out, ts);
435- ts->set_name(tservice->get_name() + "_" + (*f_iter)->get_name() + "_pargs");
436- generate_struct_declaration(f_header_, ts, false, true, false, true);
437- generate_struct_definition(out, f_service_, ts, false);
438- generate_struct_writer(out, ts, true);
439 ts->set_name(name_orig);
440
441 generate_function_helpers(tservice, *f_iter);
chedeti7e024be2016-08-05 11:15:37 -0700442@@ -1745,13 +1836,218 @@ void t_cpp_generator::generate_service_helpers(t_service* tservice) {
chedetidd7a2a32016-07-31 21:57:47 -0700443 }
444
445 /**
446+ * Generates a service Stub Interface
447+ *
448+ * @param tservice The service to generate a stub for.
449+ *
450+ */
451+void t_cpp_generator::generate_service_stub_interface(t_service* tservice) {
452+
453+ string extends = "";
chedeti00be9de2016-08-02 10:44:41 -0700454+ if (tservice->get_extends()) {
chedetidd7a2a32016-07-31 21:57:47 -0700455+ extends = " : virtual public " + type_name(tservice->get_extends()) + "::StubInterface";
456+ }
457+
458+ f_header_ <<
459+ endl <<
460+ "class StubInterface " << extends << " {" << endl;
461+ indent_up();
462+ f_header_ <<
463+ " public:" << endl <<
464+ indent() << "virtual ~StubInterface() {}" << endl;
465+
466+ vector<t_function*> functions = tservice->get_functions();
467+ vector<t_function*>::iterator f_iter;
468+ for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
469+ string function_name = (*f_iter)->get_name();
470+ f_header_ <<
471+ indent() << "virtual ::grpc::Status " << function_name <<
472+ "(::grpc::ClientContext* context, const " << function_name <<
473+ "Req& request, " << function_name << "Resp* response) = 0;" << endl;
474+ }
475+ indent_down();
476+ f_header_ <<
477+ "};" << endl << endl;
478+
479+}
480+void t_cpp_generator::generate_service_stub(t_service* tservice) {
481+ f_header_ <<
482+ endl <<
483+ "class Stub : public StubInterface {" <<
484+ endl;
485+
486+ indent_up();
487+ f_header_ <<
488+ " public:" << endl <<
489+ indent() << "Stub(const std::shared_ptr< ::grpc::ChannelInterface>& channel);" <<
490+ endl;
491+
492+ vector<t_function*> functions = tservice->get_functions();
493+ vector<t_function*>::iterator f_iter;
494+ for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
495+ string function_name = (*f_iter)->get_name();
496+ f_header_ <<
497+ indent() << "::grpc::Status " << function_name <<
498+ "(::grpc::ClientContext* context, const " << function_name <<
499+ "Req& request, " << function_name << "Resp* response) override;" << endl;
500+ }
501+
502+ t_service* extends_service = tservice->get_extends();
chedeti7e024be2016-08-05 11:15:37 -0700503+ t_service* service_iter = extends_service;
504+ while (service_iter) {
chedetidd7a2a32016-07-31 21:57:47 -0700505+ // generate inherited methods
chedeti7e024be2016-08-05 11:15:37 -0700506+ vector<t_function*> functions = service_iter->get_functions();
chedetidd7a2a32016-07-31 21:57:47 -0700507+ vector<t_function*>::iterator f_iter;
508+ for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
509+ string function_name = (*f_iter)->get_name();
510+ f_header_ <<
511+ indent() << "::grpc::Status " << function_name <<
512+ "(::grpc::ClientContext* context, const " << function_name <<
513+ "Req& request, " << function_name << "Resp* response) override;" << endl;
514+ }
chedeti7e024be2016-08-05 11:15:37 -0700515+ service_iter = service_iter->get_extends();
chedetidd7a2a32016-07-31 21:57:47 -0700516+ }
517+
518+ f_header_ <<
519+ endl <<
520+ " private:" << endl <<
521+ indent() << "std::shared_ptr< ::grpc::ChannelInterface> channel_;" <<
522+ endl;
523+
524+ for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
525+ f_header_ <<
526+ indent() << "const ::grpc::RpcMethod rpcmethod_" << (*f_iter)->get_name() << "_;" << endl;
527+ }
528+
chedeti7e024be2016-08-05 11:15:37 -0700529+ service_iter = extends_service;
530+ while (service_iter) {
chedetidd7a2a32016-07-31 21:57:47 -0700531+ // generate inherited methods
chedeti7e024be2016-08-05 11:15:37 -0700532+ vector<t_function*> functions = service_iter->get_functions();
chedetidd7a2a32016-07-31 21:57:47 -0700533+ vector<t_function*>::iterator f_iter;
534+ for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
535+ f_header_ <<
536+ indent() << "const ::grpc::RpcMethod rpcmethod_" << (*f_iter)->get_name() << "_;" << endl;
537+ }
chedeti7e024be2016-08-05 11:15:37 -0700538+ service_iter = service_iter->get_extends();
chedetidd7a2a32016-07-31 21:57:47 -0700539+ }
540+
541+ indent_down();
542+ f_header_ <<
543+ "};" << endl << endl;
544+
545+ // generate the implementaion of Stub
546+ f_service_ <<
547+ endl <<
548+ service_name_ << "::Stub::Stub(const std::shared_ptr< ::grpc::ChannelInterface>& channel)" << endl;
549+
550+ indent_up();
551+ f_service_ <<
552+ indent() << ": channel_(channel)" << endl;
553+ int i=0;
554+ for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter , ++i) {
555+ f_service_ <<
556+ indent() <<
557+ ", rpcmethod_" << (*f_iter)->get_name() << "_(" <<
558+ service_name_ << "_method_names[" << i << "], ::grpc::RpcMethod::NORMAL_RPC, channel)" << endl;
559+ }
560+
chedeti7e024be2016-08-05 11:15:37 -0700561+ service_iter = extends_service;
562+ while (service_iter) {
chedetidd7a2a32016-07-31 21:57:47 -0700563+ // generate inherited methods
chedeti7e024be2016-08-05 11:15:37 -0700564+ vector<t_function*> functions = service_iter->get_functions();
chedetidd7a2a32016-07-31 21:57:47 -0700565+ vector<t_function*>::iterator f_iter;
566+ for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter, ++i) {
567+ f_service_ <<
568+ indent() <<
569+ ", rpcmethod_" << (*f_iter)->get_name() << "_(" <<
570+ service_name_ << "_method_names[" << i << "], ::grpc::RpcMethod::NORMAL_RPC, channel)" << endl;
571+ }
chedeti7e024be2016-08-05 11:15:37 -0700572+ service_iter = service_iter->get_extends();
chedetidd7a2a32016-07-31 21:57:47 -0700573+ }
574+ f_service_ <<
575+ indent() << "{}" << endl;
576+ indent_down();
577+
578+ // generate NewStub
579+ f_header_ <<
580+ endl <<
581+ "static std::unique_ptr<Stub> NewStub(const std::shared_ptr\
582+ < ::grpc::ChannelInterface>& channel, const ::grpc::StubOptions& options = ::grpc::StubOptions());" <<
583+ endl;
584+
585+ // generate NewStub Implementation
586+ f_service_ <<
587+ endl <<
588+ "std::unique_ptr< " << service_name_ << "::Stub> " << service_name_ << "::NewStub(const std::shared_ptr\
589+ < ::grpc::ChannelInterface>& channel, const ::grpc::StubOptions& options) {" << endl;
590+
591+ indent_up();
592+ f_service_ <<
593+ indent() << "std::unique_ptr< " << service_name_ << "::Stub> stub(new " << service_name_ <<
594+ "::Stub(channel));" << endl <<
595+ indent() << "return stub;" << endl;
596+ indent_down();
597+ f_service_ <<
598+ "}" << endl;
599+
600+ // generate stub methods
601+ for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
602+ string function_name = (*f_iter)->get_name();
603+ f_service_ <<
604+ endl <<
605+ "::grpc::Status " << service_name_ << "::Stub::" << function_name <<
606+ "(::grpc::ClientContext* context, const " << service_name_ << "::" <<
607+ function_name << "Req& request, " << service_name_ << "::" <<
608+ function_name << "Resp* response) {" << endl;
609+
610+ indent_up();
611+ f_service_ <<
612+ indent() << "return ::grpc::BlockingUnaryCall(channel_.get(), rpcmethod_" <<
613+ function_name << "_, context, request, response);" << endl;
614+ indent_down();
615+
616+ f_service_ <<
617+ "}" << endl;
618+
619+ }
620+
chedeti7e024be2016-08-05 11:15:37 -0700621+ service_iter = extends_service;
622+ while (service_iter) {
623+ vector<t_function*> functions = service_iter->get_functions();
chedetidd7a2a32016-07-31 21:57:47 -0700624+ vector<t_function*>::iterator f_iter;
625+ for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
626+ string function_name = (*f_iter)->get_name();
627+ f_service_ <<
628+ endl <<
629+ "::grpc::Status " << service_name_ << "::Stub::" << function_name <<
630+ "(::grpc::ClientContext* context, const " << service_name_ << "::" <<
631+ function_name << "Req& request, " << service_name_ << "::" <<
632+ function_name << "Resp* response) {" << endl;
633+
634+ indent_up();
635+ f_service_ <<
636+ indent() << "return ::grpc::BlockingUnaryCall(channel_.get(), rpcmethod_" <<
637+ function_name << "_, context, request, response);" << endl;
638+ indent_down();
639+
640+ f_service_ <<
641+ "}" << endl;
642+
643+ }
chedeti7e024be2016-08-05 11:15:37 -0700644+ service_iter = service_iter->get_extends();
chedetidd7a2a32016-07-31 21:57:47 -0700645+ }
646+
647+}
648+
649+
650+/**
651 * Generates a service interface definition.
652 *
653 * @param tservice The service to generate a header definition for
654 */
655 void t_cpp_generator::generate_service_interface(t_service* tservice, string style) {
656
657- string service_if_name = service_name_ + style + "If";
658+ string service_if_name = "Service";
659 if (style == "CobCl") {
660 // Forward declare the client.
661 string client_name = service_name_ + "CobClient";
chedeti7e024be2016-08-05 11:15:37 -0700662@@ -1764,13 +2060,15 @@ void t_cpp_generator::generate_service_interface(t_service* tservice, string sty
chedeti00be9de2016-08-02 10:44:41 -0700663 }
chedetidd7a2a32016-07-31 21:57:47 -0700664
665 string extends = "";
chedeti00be9de2016-08-02 10:44:41 -0700666- if (tservice->get_extends() != NULL) {
chedetidd7a2a32016-07-31 21:57:47 -0700667- extends = " : virtual public " + type_name(tservice->get_extends()) + style + "If";
chedeti00be9de2016-08-02 10:44:41 -0700668+ if (tservice->get_extends()) {
chedetidd7a2a32016-07-31 21:57:47 -0700669+ extends = " : virtual public " + type_name(tservice->get_extends()) + style + "::Service";
670 if (style == "CobCl" && gen_templates_) {
671 // TODO(simpkins): If gen_templates_ is enabled, we currently assume all
672 // parent services were also generated with templates enabled.
673 extends += "T<Protocol_>";
674 }
675+ } else {
676+ extends = " : public ::grpc::Service";
677 }
678
679 if (style == "CobCl" && gen_templates_) {
chedeti7e024be2016-08-05 11:15:37 -0700680@@ -1778,7 +2076,9 @@ void t_cpp_generator::generate_service_interface(t_service* tservice, string sty
chedetidd7a2a32016-07-31 21:57:47 -0700681 }
682 f_header_ << "class " << service_if_name << extends << " {" << endl << " public:" << endl;
683 indent_up();
684- f_header_ << indent() << "virtual ~" << service_if_name << "() {}" << endl;
685+
686+ f_header_ << indent() << "Service();" << endl;
687+ f_header_ << indent() << "virtual ~Service();" << endl;
688
689 vector<t_function*> functions = tservice->get_functions();
690 vector<t_function*>::iterator f_iter;
chedeti7e024be2016-08-05 11:15:37 -0700691@@ -1786,7 +2086,12 @@ void t_cpp_generator::generate_service_interface(t_service* tservice, string sty
chedetidd7a2a32016-07-31 21:57:47 -0700692 if ((*f_iter)->has_doc())
693 f_header_ << endl;
694 generate_java_doc(f_header_, *f_iter);
695- f_header_ << indent() << "virtual " << function_signature(*f_iter, style) << " = 0;" << endl;
696+
697+ string function_name = (*f_iter)->get_name();
698+ f_header_ <<
699+ indent() << "virtual ::grpc::Status " << function_name <<
700+ "(::grpc::ServerContext* context, const "<< function_name <<
701+ "Req* request, "<< function_name << "Resp* response);" << endl;
702 }
703 indent_down();
704 f_header_ << "};" << endl << endl;
chedeti7e024be2016-08-05 11:15:37 -0700705@@ -1797,6 +2102,66 @@ void t_cpp_generator::generate_service_interface(t_service* tservice, string sty
chedetidd7a2a32016-07-31 21:57:47 -0700706 f_header_ << "typedef " << service_if_name << "< ::apache::thrift::protocol::TProtocol> "
707 << service_name_ << style << "If;" << endl << endl;
708 }
709+
710+ // generate the service interface implementations
711+
712+ f_service_ <<
713+ endl <<
714+ service_name_ << "::Service::Service() {" << endl;
715+ indent_up();
716+ f_service_ <<
717+ indent() << "(void)" << service_name_ << "_method_names;" << endl;
718+ uint32_t i=0;
719+ for(i=0;i<functions.size(); i++) {
720+ string function_name = functions[i]->get_name();
721+ f_service_ <<
722+ endl <<
723+ indent() << "AddMethod(new ::grpc::RpcServiceMethod(" << endl;
724+ indent_up();
725+
726+ f_service_ <<
727+ indent() << service_name_ << "_method_names[" << i << "]," << endl <<
728+ indent() << "::grpc::RpcMethod::NORMAL_RPC," << endl <<
729+ indent() << "new ::grpc::RpcMethodHandler< " << service_name_ << "::Service, " <<
730+ service_name_ << "::" << function_name << "Req, " << service_name_ << "::" <<
731+ function_name << "Resp>(" << endl;
732+
733+ indent_up();
734+ f_service_ <<
735+ indent() << "std::mem_fn(&" << service_name_ << "::Service::" << function_name << "), this)));" << endl;
736+
737+ indent_down();
738+ indent_down();
739+ }
740+
741+ indent_down();
742+ f_service_ <<
743+ "}" << endl;
744+
745+ f_service_ <<
746+ endl <<
747+ service_name_ << "::Service::~Service() {" << endl <<
748+ "}" << endl;
749+
750+ for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
751+ string function_name = (*f_iter)->get_name();
752+ f_service_ <<
753+ endl <<
754+ "::grpc::Status " << service_name_ << "::Service::" << function_name <<
755+ "(::grpc::ServerContext* context, const " << service_name_ << "::" << function_name <<
756+ "Req* request, " << service_name_ << "::" << function_name << "Resp* response) {" << endl;
757+ indent_up();
758+ f_service_ <<
759+ indent() << "(void) context;" << endl <<
760+ indent() << "(void) request;" << endl <<
761+ indent() << "(void) response;" << endl <<
762+ indent() << "return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED,\"\");" << endl;
763+ indent_down();
764+
765+ f_service_ <<
766+ "}" << endl;
767+ }
768+
769 }
770
771 /**
chedeti7e024be2016-08-05 11:15:37 -0700772@@ -3095,7 +3460,7 @@ void t_cpp_generator::generate_function_helpers(t_service* tservice, t_function*
chedetidd7a2a32016-07-31 21:57:47 -0700773
774 std::ofstream& out = (gen_templates_ ? f_service_tcc_ : f_service_);
775
776- t_struct result(program_, tservice->get_name() + "_" + tfunction->get_name() + "_result");
777+ t_struct result(program_, tfunction->get_name() + "Resp");
778 t_field success(tfunction->get_returntype(), "success", 0);
779 if (!tfunction->get_returntype()->is_void()) {
780 result.append(&success);
chedeti7e024be2016-08-05 11:15:37 -0700781@@ -3109,17 +3474,9 @@ void t_cpp_generator::generate_function_helpers(t_service* tservice, t_function*
chedetidd7a2a32016-07-31 21:57:47 -0700782 }
783
784 generate_struct_declaration(f_header_, &result, false);
785- generate_struct_definition(out, f_service_, &result, false);
786+ generate_struct_definition(out, f_service_, &result, true);
787 generate_struct_reader(out, &result);
788 generate_struct_result_writer(out, &result);
789-
790- result.set_name(tservice->get_name() + "_" + tfunction->get_name() + "_presult");
791- generate_struct_declaration(f_header_, &result, false, true, true, gen_cob_style_);
792- generate_struct_definition(out, f_service_, &result, false);
793- generate_struct_reader(out, &result, true);
794- if (gen_cob_style_) {
795- generate_struct_writer(out, &result, true);
796- }
797 }
798
799 /**
chedeti7e024be2016-08-05 11:15:37 -0700800@@ -3162,8 +3519,8 @@ void t_cpp_generator::generate_process_function(t_service* tservice,
chedetidd7a2a32016-07-31 21:57:47 -0700801 << endl;
802 scope_up(out);
803
804- string argsname = tservice->get_name() + "_" + tfunction->get_name() + "_args";
805- string resultname = tservice->get_name() + "_" + tfunction->get_name() + "_result";
806+ string argsname = tfunction->get_name() + "Req";
807+ string resultname = tfunction->get_name() + "Resp";
808
809 if (tfunction->is_oneway() && !unnamed_oprot_seqid) {
810 out << indent() << "(void) seqid;" << endl << indent() << "(void) oprot;" << endl;
chedeti7e024be2016-08-05 11:15:37 -0700811@@ -3320,7 +3677,7 @@ void t_cpp_generator::generate_process_function(t_service* tservice,
chedetidd7a2a32016-07-31 21:57:47 -0700812 out << indent() << "(void) seqid;" << endl << indent() << "(void) oprot;" << endl;
813 }
814
815- out << indent() << tservice->get_name() + "_" + tfunction->get_name() << "_args args;" << endl
816+ out << indent() << tfunction->get_name() << "Req args;" << endl
817 << indent() << "void* ctx = NULL;" << endl << indent()
818 << "if (this->eventHandler_.get() != NULL) {" << endl << indent()
819 << " ctx = this->eventHandler_->getContext(" << service_func_name << ", NULL);" << endl
chedeti7e024be2016-08-05 11:15:37 -0700820@@ -3487,7 +3844,7 @@ void t_cpp_generator::generate_process_function(t_service* tservice,
chedetidd7a2a32016-07-31 21:57:47 -0700821 << "this->eventHandler_.get(), ctx, " << service_func_name << ");" << endl << endl;
822
823 // Throw the TDelayedException, and catch the result
824- out << indent() << tservice->get_name() << "_" << tfunction->get_name() << "_result result;"
825+ out << indent() << tfunction->get_name() << "Resp result;"
826 << endl << endl << indent() << "try {" << endl;
827 indent_up();
828 out << indent() << "_throw->throw_it();" << endl << indent() << "return cob(false);"
829diff --git a/tutorial/cpp/CMakeLists.txt b/tutorial/cpp/CMakeLists.txt
830deleted file mode 100644
831index 8a3d085..0000000
832--- a/tutorial/cpp/CMakeLists.txt
833+++ /dev/null
834@@ -1,53 +0,0 @@
835-#
836-# Licensed to the Apache Software Foundation (ASF) under one
837-# or more contributor license agreements. See the NOTICE file
838-# distributed with this work for additional information
839-# regarding copyright ownership. The ASF licenses this file
840-# to you under the Apache License, Version 2.0 (the
841-# "License"); you may not use this file except in compliance
842-# with the License. You may obtain a copy of the License at
843-#
844-# http://www.apache.org/licenses/LICENSE-2.0
845-#
846-# Unless required by applicable law or agreed to in writing,
847-# software distributed under the License is distributed on an
848-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
849-# KIND, either express or implied. See the License for the
850-# specific language governing permissions and limitations
851-# under the License.
852-#
853-
854-find_package(Boost 1.53.0 REQUIRED)
855-include_directories(SYSTEM "${Boost_INCLUDE_DIRS}")
856-
857-#Make sure gen-cpp files can be included
858-include_directories("${CMAKE_CURRENT_BINARY_DIR}")
859-include_directories("${CMAKE_CURRENT_BINARY_DIR}/gen-cpp")
860-include_directories("${PROJECT_SOURCE_DIR}/lib/cpp/src")
861-
862-include(ThriftMacros)
863-
864-set(tutorialgencpp_SOURCES
865- gen-cpp/Calculator.cpp
866- gen-cpp/SharedService.cpp
867- gen-cpp/shared_constants.cpp
868- gen-cpp/shared_types.cpp
869- gen-cpp/tutorial_constants.cpp
870- gen-cpp/tutorial_types.cpp
871-)
872-add_library(tutorialgencpp STATIC ${tutorialgencpp_SOURCES})
873-LINK_AGAINST_THRIFT_LIBRARY(tutorialgencpp thrift)
874-
875-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
876- COMMAND ${THRIFT_COMPILER} --gen cpp -r ${PROJECT_SOURCE_DIR}/tutorial/tutorial.thrift
877-)
878-
879-add_executable(TutorialServer CppServer.cpp)
880-target_link_libraries(TutorialServer tutorialgencpp)
881-LINK_AGAINST_THRIFT_LIBRARY(TutorialServer thrift)
882-target_link_libraries(TutorialServer ${ZLIB_LIBRARIES})
883-
884-add_executable(TutorialClient CppClient.cpp)
885-target_link_libraries(TutorialClient tutorialgencpp)
886-LINK_AGAINST_THRIFT_LIBRARY(TutorialClient thrift)
887-target_link_libraries(TutorialClient ${ZLIB_LIBRARIES})
888diff --git a/tutorial/cpp/CppClient.cpp b/tutorial/cpp/CppClient.cpp
chedeti00be9de2016-08-02 10:44:41 -0700889deleted file mode 100644
890index 2763fee..0000000
chedetidd7a2a32016-07-31 21:57:47 -0700891--- a/tutorial/cpp/CppClient.cpp
chedeti00be9de2016-08-02 10:44:41 -0700892+++ /dev/null
893@@ -1,80 +0,0 @@
894-/*
chedetidd7a2a32016-07-31 21:57:47 -0700895- * Licensed to the Apache Software Foundation (ASF) under one
896- * or more contributor license agreements. See the NOTICE file
897- * distributed with this work for additional information
898- * regarding copyright ownership. The ASF licenses this file
899- * to you under the Apache License, Version 2.0 (the
900- * "License"); you may not use this file except in compliance
901- * with the License. You may obtain a copy of the License at
chedeti00be9de2016-08-02 10:44:41 -0700902- *
chedetidd7a2a32016-07-31 21:57:47 -0700903- * http://www.apache.org/licenses/LICENSE-2.0
chedeti00be9de2016-08-02 10:44:41 -0700904- *
chedetidd7a2a32016-07-31 21:57:47 -0700905- * Unless required by applicable law or agreed to in writing,
906- * software distributed under the License is distributed on an
907- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
908- * KIND, either express or implied. See the License for the
909- * specific language governing permissions and limitations
910- * under the License.
chedeti00be9de2016-08-02 10:44:41 -0700911- */
912-
913-#include <iostream>
914-
chedetidd7a2a32016-07-31 21:57:47 -0700915-#include <thrift/protocol/TBinaryProtocol.h>
916-#include <thrift/transport/TSocket.h>
917-#include <thrift/transport/TTransportUtils.h>
918-
919-#include "../gen-cpp/Calculator.h"
chedeti00be9de2016-08-02 10:44:41 -0700920-
chedetidd7a2a32016-07-31 21:57:47 -0700921-using namespace std;
922-using namespace apache::thrift;
923-using namespace apache::thrift::protocol;
924-using namespace apache::thrift::transport;
chedeti00be9de2016-08-02 10:44:41 -0700925-
chedetidd7a2a32016-07-31 21:57:47 -0700926-using namespace tutorial;
927-using namespace shared;
chedeti00be9de2016-08-02 10:44:41 -0700928-
chedetidd7a2a32016-07-31 21:57:47 -0700929-int main() {
930- boost::shared_ptr<TTransport> socket(new TSocket("localhost", 9090));
931- boost::shared_ptr<TTransport> transport(new TBufferedTransport(socket));
932- boost::shared_ptr<TProtocol> protocol(new TBinaryProtocol(transport));
933- CalculatorClient client(protocol);
chedeti00be9de2016-08-02 10:44:41 -0700934-
chedetidd7a2a32016-07-31 21:57:47 -0700935- try {
936- transport->open();
chedeti00be9de2016-08-02 10:44:41 -0700937-
chedetidd7a2a32016-07-31 21:57:47 -0700938- client.ping();
939- cout << "ping()" << endl;
chedeti00be9de2016-08-02 10:44:41 -0700940-
chedetidd7a2a32016-07-31 21:57:47 -0700941- cout << "1 + 1 = " << client.add(1, 1) << endl;
chedeti00be9de2016-08-02 10:44:41 -0700942-
chedetidd7a2a32016-07-31 21:57:47 -0700943- Work work;
944- work.op = Operation::DIVIDE;
945- work.num1 = 1;
946- work.num2 = 0;
chedeti00be9de2016-08-02 10:44:41 -0700947-
chedetidd7a2a32016-07-31 21:57:47 -0700948- try {
949- client.calculate(1, work);
950- cout << "Whoa? We can divide by zero!" << endl;
951- } catch (InvalidOperation& io) {
952- cout << "InvalidOperation: " << io.why << endl;
953- // or using generated operator<<: cout << io << endl;
954- // or by using std::exception native method what(): cout << io.what() << endl;
chedeti00be9de2016-08-02 10:44:41 -0700955- }
956-
chedetidd7a2a32016-07-31 21:57:47 -0700957- work.op = Operation::SUBTRACT;
958- work.num1 = 15;
959- work.num2 = 10;
960- int32_t diff = client.calculate(1, work);
961- cout << "15 - 10 = " << diff << endl;
chedeti00be9de2016-08-02 10:44:41 -0700962-
chedetidd7a2a32016-07-31 21:57:47 -0700963- // Note that C++ uses return by reference for complex types to avoid
964- // costly copy construction
965- SharedStruct ss;
966- client.getStruct(ss, 1);
967- cout << "Received log: " << ss << endl;
chedeti00be9de2016-08-02 10:44:41 -0700968-
chedetidd7a2a32016-07-31 21:57:47 -0700969- transport->close();
970- } catch (TException& tx) {
971- cout << "ERROR: " << tx.what() << endl;
972- }
chedeti00be9de2016-08-02 10:44:41 -0700973-}
chedetidd7a2a32016-07-31 21:57:47 -0700974diff --git a/tutorial/cpp/CppServer.cpp b/tutorial/cpp/CppServer.cpp
chedeti00be9de2016-08-02 10:44:41 -0700975deleted file mode 100644
976index eafffa9..0000000
chedetidd7a2a32016-07-31 21:57:47 -0700977--- a/tutorial/cpp/CppServer.cpp
chedeti00be9de2016-08-02 10:44:41 -0700978+++ /dev/null
979@@ -1,181 +0,0 @@
980-/*
chedetidd7a2a32016-07-31 21:57:47 -0700981- * Licensed to the Apache Software Foundation (ASF) under one
982- * or more contributor license agreements. See the NOTICE file
983- * distributed with this work for additional information
984- * regarding copyright ownership. The ASF licenses this file
985- * to you under the Apache License, Version 2.0 (the
986- * "License"); you may not use this file except in compliance
987- * with the License. You may obtain a copy of the License at
chedeti00be9de2016-08-02 10:44:41 -0700988- *
chedetidd7a2a32016-07-31 21:57:47 -0700989- * http://www.apache.org/licenses/LICENSE-2.0
chedeti00be9de2016-08-02 10:44:41 -0700990- *
chedetidd7a2a32016-07-31 21:57:47 -0700991- * Unless required by applicable law or agreed to in writing,
992- * software distributed under the License is distributed on an
993- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
994- * KIND, either express or implied. See the License for the
995- * specific language governing permissions and limitations
996- * under the License.
chedeti00be9de2016-08-02 10:44:41 -0700997- */
998-
chedetidd7a2a32016-07-31 21:57:47 -0700999-#include <thrift/concurrency/ThreadManager.h>
1000-#include <thrift/concurrency/PlatformThreadFactory.h>
1001-#include <thrift/protocol/TBinaryProtocol.h>
1002-#include <thrift/server/TSimpleServer.h>
1003-#include <thrift/server/TThreadPoolServer.h>
1004-#include <thrift/server/TThreadedServer.h>
1005-#include <thrift/transport/TServerSocket.h>
1006-#include <thrift/transport/TSocket.h>
1007-#include <thrift/transport/TTransportUtils.h>
1008-#include <thrift/TToString.h>
1009-
1010-#include <boost/make_shared.hpp>
1011-
chedeti00be9de2016-08-02 10:44:41 -07001012-#include <iostream>
chedetidd7a2a32016-07-31 21:57:47 -07001013-#include <stdexcept>
1014-#include <sstream>
1015-
1016-#include "../gen-cpp/Calculator.h"
chedeti00be9de2016-08-02 10:44:41 -07001017-
chedetidd7a2a32016-07-31 21:57:47 -07001018-using namespace std;
1019-using namespace apache::thrift;
1020-using namespace apache::thrift::concurrency;
1021-using namespace apache::thrift::protocol;
1022-using namespace apache::thrift::transport;
1023-using namespace apache::thrift::server;
chedeti00be9de2016-08-02 10:44:41 -07001024-
chedetidd7a2a32016-07-31 21:57:47 -07001025-using namespace tutorial;
1026-using namespace shared;
chedeti00be9de2016-08-02 10:44:41 -07001027-
chedetidd7a2a32016-07-31 21:57:47 -07001028-class CalculatorHandler : public CalculatorIf {
1029-public:
1030- CalculatorHandler() {}
chedeti00be9de2016-08-02 10:44:41 -07001031-
chedetidd7a2a32016-07-31 21:57:47 -07001032- void ping() { cout << "ping()" << endl; }
chedeti00be9de2016-08-02 10:44:41 -07001033-
chedetidd7a2a32016-07-31 21:57:47 -07001034- int32_t add(const int32_t n1, const int32_t n2) {
1035- cout << "add(" << n1 << ", " << n2 << ")" << endl;
1036- return n1 + n2;
1037- }
chedeti00be9de2016-08-02 10:44:41 -07001038-
chedetidd7a2a32016-07-31 21:57:47 -07001039- int32_t calculate(const int32_t logid, const Work& work) {
1040- cout << "calculate(" << logid << ", " << work << ")" << endl;
1041- int32_t val;
chedeti00be9de2016-08-02 10:44:41 -07001042-
chedetidd7a2a32016-07-31 21:57:47 -07001043- switch (work.op) {
1044- case Operation::ADD:
1045- val = work.num1 + work.num2;
1046- break;
1047- case Operation::SUBTRACT:
1048- val = work.num1 - work.num2;
1049- break;
1050- case Operation::MULTIPLY:
1051- val = work.num1 * work.num2;
1052- break;
1053- case Operation::DIVIDE:
1054- if (work.num2 == 0) {
1055- InvalidOperation io;
1056- io.whatOp = work.op;
1057- io.why = "Cannot divide by 0";
1058- throw io;
1059- }
1060- val = work.num1 / work.num2;
1061- break;
1062- default:
1063- InvalidOperation io;
1064- io.whatOp = work.op;
1065- io.why = "Invalid Operation";
1066- throw io;
1067- }
1068-
1069- SharedStruct ss;
1070- ss.key = logid;
1071- ss.value = to_string(val);
1072-
1073- log[logid] = ss;
1074-
1075- return val;
chedeti00be9de2016-08-02 10:44:41 -07001076- }
chedetidd7a2a32016-07-31 21:57:47 -07001077-
1078- void getStruct(SharedStruct& ret, const int32_t logid) {
1079- cout << "getStruct(" << logid << ")" << endl;
1080- ret = log[logid];
1081- }
1082-
1083- void zip() { cout << "zip()" << endl; }
1084-
1085-protected:
1086- map<int32_t, SharedStruct> log;
chedeti00be9de2016-08-02 10:44:41 -07001087-};
1088-
chedetidd7a2a32016-07-31 21:57:47 -07001089-/*
1090- CalculatorIfFactory is code generated.
1091- CalculatorCloneFactory is useful for getting access to the server side of the
1092- transport. It is also useful for making per-connection state. Without this
1093- CloneFactory, all connections will end up sharing the same handler instance.
1094-*/
1095-class CalculatorCloneFactory : virtual public CalculatorIfFactory {
1096- public:
1097- virtual ~CalculatorCloneFactory() {}
1098- virtual CalculatorIf* getHandler(const ::apache::thrift::TConnectionInfo& connInfo)
1099- {
1100- boost::shared_ptr<TSocket> sock = boost::dynamic_pointer_cast<TSocket>(connInfo.transport);
1101- cout << "Incoming connection\n";
1102- cout << "\tSocketInfo: " << sock->getSocketInfo() << "\n";
1103- cout << "\tPeerHost: " << sock->getPeerHost() << "\n";
1104- cout << "\tPeerAddress: " << sock->getPeerAddress() << "\n";
1105- cout << "\tPeerPort: " << sock->getPeerPort() << "\n";
1106- return new CalculatorHandler;
1107- }
1108- virtual void releaseHandler( ::shared::SharedServiceIf* handler) {
1109- delete handler;
1110- }
1111-};
chedeti00be9de2016-08-02 10:44:41 -07001112-
1113-int main() {
chedetidd7a2a32016-07-31 21:57:47 -07001114- TThreadedServer server(
1115- boost::make_shared<CalculatorProcessorFactory>(boost::make_shared<CalculatorCloneFactory>()),
1116- boost::make_shared<TServerSocket>(9090), //port
1117- boost::make_shared<TBufferedTransportFactory>(),
1118- boost::make_shared<TBinaryProtocolFactory>());
1119-
1120- /*
1121- // if you don't need per-connection state, do the following instead
1122- TThreadedServer server(
1123- boost::make_shared<CalculatorProcessor>(boost::make_shared<CalculatorHandler>()),
1124- boost::make_shared<TServerSocket>(9090), //port
1125- boost::make_shared<TBufferedTransportFactory>(),
1126- boost::make_shared<TBinaryProtocolFactory>());
1127- */
1128-
1129- /**
1130- * Here are some alternate server types...
1131-
1132- // This server only allows one connection at a time, but spawns no threads
1133- TSimpleServer server(
1134- boost::make_shared<CalculatorProcessor>(boost::make_shared<CalculatorHandler>()),
1135- boost::make_shared<TServerSocket>(9090),
1136- boost::make_shared<TBufferedTransportFactory>(),
1137- boost::make_shared<TBinaryProtocolFactory>());
1138-
1139- const int workerCount = 4;
1140-
1141- boost::shared_ptr<ThreadManager> threadManager =
1142- ThreadManager::newSimpleThreadManager(workerCount);
1143- threadManager->threadFactory(
1144- boost::make_shared<PlatformThreadFactory>());
1145- threadManager->start();
1146-
1147- // This server allows "workerCount" connection at a time, and reuses threads
1148- TThreadPoolServer server(
1149- boost::make_shared<CalculatorProcessorFactory>(boost::make_shared<CalculatorCloneFactory>()),
1150- boost::make_shared<TServerSocket>(9090),
1151- boost::make_shared<TBufferedTransportFactory>(),
1152- boost::make_shared<TBinaryProtocolFactory>(),
1153- threadManager);
1154- */
chedeti00be9de2016-08-02 10:44:41 -07001155-
chedetidd7a2a32016-07-31 21:57:47 -07001156- cout << "Starting the server..." << endl;
1157- server.serve();
1158- cout << "Done." << endl;
chedeti00be9de2016-08-02 10:44:41 -07001159- return 0;
1160-}
chedeti82afcaa2016-08-03 16:38:05 -07001161diff --git a/tutorial/cpp/GriftClient.cpp b/tutorial/cpp/GriftClient.cpp
chedeti00be9de2016-08-02 10:44:41 -07001162new file mode 100644
chedeti82afcaa2016-08-03 16:38:05 -07001163index 0000000..647a683
chedeti00be9de2016-08-02 10:44:41 -07001164--- /dev/null
chedeti82afcaa2016-08-03 16:38:05 -07001165+++ b/tutorial/cpp/GriftClient.cpp
1166@@ -0,0 +1,93 @@
chedeti00be9de2016-08-02 10:44:41 -07001167+/*
1168+ *
1169+ * Copyright 2016, Google Inc.
1170+ * All rights reserved.
1171+ *
1172+ * Redistribution and use in source and binary forms, with or without
1173+ * modification, are permitted provided that the following conditions are
1174+ * met:
1175+ *
1176+ * * Redistributions of source code must retain the above copyright
1177+ * notice, this list of conditions and the following disclaimer.
1178+ * * Redistributions in binary form must reproduce the above
1179+ * copyright notice, this list of conditions and the following disclaimer
1180+ * in the documentation and/or other materials provided with the
1181+ * distribution.
1182+ * * Neither the name of Google Inc. nor the names of its
1183+ * contributors may be used to endorse or promote products derived from
1184+ * this software without specific prior written permission.
1185+ *
1186+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1187+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1188+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1189+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
1190+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
1191+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
1192+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
1193+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
1194+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1195+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
1196+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1197+ *
1198+ */
1199+
1200+#include <iostream>
1201+#include <memory>
1202+#include <string>
1203+
1204+#include <grpc++/grpc++.h>
1205+
1206+#include "gen-cpp/Greeter.grpc.thrift.h"
1207+
1208+using grpc::Channel;
1209+using grpc::ClientContext;
1210+using grpc::Status;
1211+using test::Greeter;
chedeti00be9de2016-08-02 10:44:41 -07001212+
1213+class GreeterClient {
1214+ public:
1215+ GreeterClient(std::shared_ptr<Channel> channel)
1216+ : stub_(Greeter::NewStub(channel)) {}
1217+
1218+ // Assembles the client's payload, sends it and presents the response back
1219+ // from the server.
1220+ std::string SayHello(const std::string& user) {
1221+ // Data we are sending to the server.
1222+ Greeter::SayHelloReq req;
1223+ req.request.name = user;
1224+
1225+ // Container for the data we expect from the server.
1226+ Greeter::SayHelloResp reply;
1227+
1228+ // Context for the client. It could be used to convey extra information to
1229+ // the server and/or tweak certain RPC behaviors.
1230+ ClientContext context;
1231+
1232+ // The actual RPC.
1233+ Status status = stub_->SayHello(&context, req, &reply);
1234+
1235+ // Act upon its status.
1236+ if (status.ok()) {
1237+ return reply.success.message;
1238+ } else {
1239+ return "RPC failed";
1240+ }
1241+ }
1242+
1243+ private:
1244+ std::unique_ptr<Greeter::Stub> stub_;
1245+};
1246+
1247+int main() {
1248+ // Instantiate the client. It requires a channel, out of which the actual RPCs
1249+ // are created. This channel models a connection to an endpoint (in this case,
1250+ // localhost at port 50051). We indicate that the channel isn't authenticated
1251+ // (use of InsecureChannelCredentials()).
1252+ GreeterClient greeter(grpc::CreateChannel(
1253+ "localhost:50051", grpc::InsecureChannelCredentials()));
1254+ std::string user("world");
1255+ std::string reply = greeter.SayHello(user);
1256+ std::cout << "Greeter received: " << reply << std::endl;
1257+
1258+ return 0;
1259+}
chedeti82afcaa2016-08-03 16:38:05 -07001260diff --git a/tutorial/cpp/GriftServer.cpp b/tutorial/cpp/GriftServer.cpp
chedeti00be9de2016-08-02 10:44:41 -07001261new file mode 100644
chedeti82afcaa2016-08-03 16:38:05 -07001262index 0000000..7c01606
chedeti00be9de2016-08-02 10:44:41 -07001263--- /dev/null
chedeti82afcaa2016-08-03 16:38:05 -07001264+++ b/tutorial/cpp/GriftServer.cpp
1265@@ -0,0 +1,93 @@
chedeti00be9de2016-08-02 10:44:41 -07001266+/*
1267+ *
1268+ * Copyright 2016, Google Inc.
1269+ * All rights reserved.
1270+ *
1271+ * Redistribution and use in source and binary forms, with or without
1272+ * modification, are permitted provided that the following conditions are
1273+ * met:
1274+ *
1275+ * * Redistributions of source code must retain the above copyright
1276+ * notice, this list of conditions and the following disclaimer.
1277+ * * Redistributions in binary form must reproduce the above
1278+ * copyright notice, this list of conditions and the following disclaimer
1279+ * in the documentation and/or other materials provided with the
1280+ * distribution.
1281+ * * Neither the name of Google Inc. nor the names of its
1282+ * contributors may be used to endorse or promote products derived from
1283+ * this software without specific prior written permission.
1284+ *
1285+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1286+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1287+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1288+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
1289+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
1290+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
1291+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
1292+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
1293+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1294+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
1295+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1296+ *
1297+ */
1298+
1299+#include <iostream>
1300+#include <memory>
1301+#include <string>
1302+
1303+#include <grpc++/grpc++.h>
1304+
1305+#include "gen-cpp/Greeter.grpc.thrift.h"
1306+#include <grpc++/server_builder.h>
1307+
1308+using grpc::Server;
1309+using grpc::ServerBuilder;
1310+using grpc::ServerContext;
1311+using grpc::Status;
1312+using test::Greeter;
1313+
chedeti00be9de2016-08-02 10:44:41 -07001314+// Logic and data behind the server's behavior.
1315+class GreeterServiceImpl final : public Greeter::Service {
chedeti82afcaa2016-08-03 16:38:05 -07001316+ public:
1317+ ~GreeterServiceImpl() {
1318+ // shutdown server
1319+ server->Shutdown();
1320+ }
1321+
chedeti00be9de2016-08-02 10:44:41 -07001322+ Status SayHello(ServerContext* context,const Greeter::SayHelloReq* request,
1323+ Greeter::SayHelloResp* reply) override {
1324+ std::string prefix("Hello ");
1325+
1326+ reply->success.message = prefix + request->request.name;
1327+
1328+ return Status::OK;
1329+ }
chedeti82afcaa2016-08-03 16:38:05 -07001330+
1331+ void RunServer() {
1332+ std::string server_address("0.0.0.0:50051");
1333+
1334+ ServerBuilder builder;
1335+ // Listen on the given address without any authentication mechanism.
1336+ builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
1337+ // Register "service" as the instance through which we'll communicate with
1338+ // clients. In this case it corresponds to an *synchronous* service.
1339+ builder.RegisterService(this);
1340+ // Finally assemble the server.
1341+ server = builder.BuildAndStart();
1342+ std::cout << "Server listening on " << server_address << std::endl;
1343+
1344+ // Wait for the server to shutdown. Note that some other thread must be
1345+ // responsible for shutting down the server for this call to ever return.
1346+ server->Wait();
1347+ }
1348+
1349+ private:
1350+ std::unique_ptr<Server> server;
chedeti00be9de2016-08-02 10:44:41 -07001351+};
1352+
chedeti00be9de2016-08-02 10:44:41 -07001353+int main() {
chedeti82afcaa2016-08-03 16:38:05 -07001354+ GreeterServiceImpl service;
1355+ service.RunServer();
chedeti00be9de2016-08-02 10:44:41 -07001356+
1357+ return 0;
1358+}
chedetidd7a2a32016-07-31 21:57:47 -07001359diff --git a/tutorial/cpp/Makefile.am b/tutorial/cpp/Makefile.am
chedeti82afcaa2016-08-03 16:38:05 -07001360index 184a69d..6f91e28 100755
chedetidd7a2a32016-07-31 21:57:47 -07001361--- a/tutorial/cpp/Makefile.am
1362+++ b/tutorial/cpp/Makefile.am
1363@@ -18,44 +18,38 @@
1364 #
1365 AUTOMAKE_OPTIONS = subdir-objects serial-tests
1366
1367-BUILT_SOURCES = gen-cpp/shared_types.cpp \
1368- gen-cpp/tutorial_types.cpp
1369+BUILT_SOURCES = gen-cpp/test_types.cpp
1370
1371-noinst_LTLIBRARIES = libtutorialgencpp.la
1372-nodist_libtutorialgencpp_la_SOURCES = \
1373- gen-cpp/Calculator.cpp \
1374- gen-cpp/Calculator.h \
1375- gen-cpp/SharedService.cpp \
1376- gen-cpp/SharedService.h \
1377- gen-cpp/shared_constants.cpp \
1378- gen-cpp/shared_constants.h \
1379- gen-cpp/shared_types.cpp \
1380- gen-cpp/shared_types.h \
1381- gen-cpp/tutorial_constants.cpp \
1382- gen-cpp/tutorial_constants.h \
1383- gen-cpp/tutorial_types.cpp \
1384- gen-cpp/tutorial_types.h
1385+#noinst_LTLIBRARIES = libtutorialgencpp.la
1386+noinst_LTLIBRARIES = libtestgencpp.la
1387+nodist_libtestgencpp_la_SOURCES = \
1388+ gen-cpp/Greeter.grpc.thrift.cpp \
1389+ gen-cpp/Greeter.grpc.thrift.h \
1390+ gen-cpp/test_constants.cpp \
1391+ gen-cpp/test_constants.h \
1392+ gen-cpp/test_types.cpp \
1393+ gen-cpp/test_types.h
1394
1395
1396
1397-libtutorialgencpp_la_LIBADD = $(top_builddir)/lib/cpp/libthrift.la
1398+libtestgencpp_la_LIBADD = $(top_builddir)/lib/cpp/libthrift.la
1399
1400 noinst_PROGRAMS = \
1401- TutorialServer \
1402- TutorialClient
1403+ TestServer \
1404+ TestClient
1405
1406-TutorialServer_SOURCES = \
chedeti00be9de2016-08-02 10:44:41 -07001407- CppServer.cpp
chedetidd7a2a32016-07-31 21:57:47 -07001408+TestServer_SOURCES = \
chedeti82afcaa2016-08-03 16:38:05 -07001409+ GriftServer.cpp
chedetidd7a2a32016-07-31 21:57:47 -07001410
1411-TutorialServer_LDADD = \
1412- libtutorialgencpp.la \
1413+TestServer_LDADD = \
1414+ libtestgencpp.la \
1415 $(top_builddir)/lib/cpp/libthrift.la
1416
1417-TutorialClient_SOURCES = \
chedeti00be9de2016-08-02 10:44:41 -07001418- CppClient.cpp
chedetidd7a2a32016-07-31 21:57:47 -07001419+TestClient_SOURCES = \
chedeti82afcaa2016-08-03 16:38:05 -07001420+ GriftClient.cpp
chedetidd7a2a32016-07-31 21:57:47 -07001421
1422-TutorialClient_LDADD = \
1423- libtutorialgencpp.la \
1424+TestClient_LDADD = \
1425+ libtestgencpp.la \
1426 $(top_builddir)/lib/cpp/libthrift.la
1427
1428 #
chedeti00be9de2016-08-02 10:44:41 -07001429@@ -63,26 +57,26 @@ TutorialClient_LDADD = \
chedetidd7a2a32016-07-31 21:57:47 -07001430 #
1431 THRIFT = $(top_builddir)/compiler/cpp/thrift
1432
1433-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
1434+gen-cpp/Greeter.grpc.thrift.cpp gen-cpp/test_constants.cpp gen-cpp/test_types.cpp: $(top_srcdir)/tutorial/cpp/test.thrift
1435 $(THRIFT) --gen cpp -r $<
1436
1437 AM_CPPFLAGS = $(BOOST_CPPFLAGS) $(LIBEVENT_CPPFLAGS) -I$(top_srcdir)/lib/cpp/src -Igen-cpp
1438 AM_CXXFLAGS = -Wall -Wextra -pedantic
1439-AM_LDFLAGS = $(BOOST_LDFLAGS) $(LIBEVENT_LDFLAGS)
1440+AM_LDFLAGS = $(BOOST_LDFLAGS) $(LIBEVENT_LDFLAGS) `pkg-config --libs grpc++ grpc` -lpthread -ldl -lgrpc
1441
1442 clean-local:
1443- $(RM) gen-cpp/*
1444+ $(RM) -r gen-cpp
1445
1446-tutorialserver: all
1447- ./TutorialServer
1448+testserver: all
1449+ ./TestServer
1450
1451-tutorialclient: all
1452- ./TutorialClient
1453+testclient: all
1454+ ./TestClient
1455
1456 style-local:
1457 $(CPPSTYLE_CMD)
chedeti00be9de2016-08-02 10:44:41 -07001458
1459 EXTRA_DIST = \
1460 CMakeLists.txt \
1461- CppClient.cpp \
1462- CppServer.cpp
chedeti82afcaa2016-08-03 16:38:05 -07001463+ GriftClient.cpp \
1464+ GriftServer.cpp
chedetidd7a2a32016-07-31 21:57:47 -07001465diff --git a/tutorial/cpp/test.thrift b/tutorial/cpp/test.thrift
1466new file mode 100644
1467index 0000000..de3c9a4
1468--- /dev/null
1469+++ b/tutorial/cpp/test.thrift
1470@@ -0,0 +1,13 @@
1471+namespace cpp test
1472+
1473+struct HelloRequest {
1474+ 1:string name
1475+}
1476+
1477+struct HelloResponse {
1478+ 1:string message
1479+}
1480+
1481+service Greeter {
1482+ HelloResponse SayHello(1:HelloRequest request);
1483+}
1484\ No newline at end of file
1485--
14862.8.0.rc3.226.g39d4020
1487
1488
chedeti7e024be2016-08-05 11:15:37 -07001489From 3e4d75a2e2c474ee7700e7c9acaf89fdb768bedc Mon Sep 17 00:00:00 2001
chedetidd7a2a32016-07-31 21:57:47 -07001490From: chedeti <chedeti@google.com>
1491Date: Sun, 31 Jul 2016 16:23:53 -0700
chedeti00be9de2016-08-02 10:44:41 -07001492Subject: [PATCH 3/3] grpc java plugins generator
chedetidd7a2a32016-07-31 21:57:47 -07001493
1494for examples refer to https://github.com/grpc/grpc-java/tree/master/examples/thrift
1495---
1496 compiler/cpp/src/generate/t_java_generator.cc | 906 +++++++++++++++++++++++++-
1497 tutorial/Makefile.am | 8 +-
1498 2 files changed, 887 insertions(+), 27 deletions(-)
1499
1500diff --git a/compiler/cpp/src/generate/t_java_generator.cc b/compiler/cpp/src/generate/t_java_generator.cc
chedeti00be9de2016-08-02 10:44:41 -07001501index 2db8cb8..8b28fe2 100644
chedetidd7a2a32016-07-31 21:57:47 -07001502--- a/compiler/cpp/src/generate/t_java_generator.cc
1503+++ b/compiler/cpp/src/generate/t_java_generator.cc
1504@@ -97,10 +97,10 @@ public:
1505 } else if(iter->second.compare("suppress") == 0) {
1506 suppress_generated_annotations_ = true;
1507 } else {
1508- throw "unknown option java:" + iter->first + "=" + iter->second;
1509+ throw "unknown option java:" + iter->first + "=" + iter->second;
1510 }
1511 } else {
1512- throw "unknown option java:" + iter->first;
1513+ throw "unknown option java:" + iter->first;
1514 }
1515 }
1516
1517@@ -195,6 +195,17 @@ public:
1518 void generate_service_async_server(t_service* tservice);
1519 void generate_process_function(t_service* tservice, t_function* tfunction);
1520 void generate_process_async_function(t_service* tservice, t_function* tfunction);
1521+ void generate_service_impl_base(t_service* tservice);
1522+ void generate_method_descriptors(t_service* tservice);
1523+ void generate_stub(t_service* tservice);
1524+ void generate_blocking_stub(t_service* tservice);
1525+ void generate_future_stub(t_service* tservice);
1526+ void generate_method_ids(t_service* tservice);
1527+ void generate_method_handlers(t_service* tservice);
1528+ void generate_service_descriptors(t_service* tservice);
1529+ void generate_service_builder(t_service* tservice);
1530+ void generate_arg_ids(t_service* tservice);
1531+ void generate_message_factory(t_service* tservice);
1532
1533 void generate_java_union(t_struct* tstruct);
1534 void generate_union_constructor(ofstream& out, t_struct* tstruct);
1535@@ -307,6 +318,8 @@ public:
1536 std::string java_package();
1537 std::string java_type_imports();
1538 std::string java_suppressions();
1539+ std::string grpc_imports();
1540+ std::string import_extended_service(t_service* tservice);
1541 std::string type_name(t_type* ttype,
1542 bool in_container = false,
1543 bool in_init = false,
1544@@ -368,7 +381,7 @@ private:
1545 bool use_option_type_;
1546 bool undated_generated_annotations_;
1547 bool suppress_generated_annotations_;
1548-
1549+
1550 };
1551
1552 /**
1553@@ -456,6 +469,35 @@ string t_java_generator::java_suppressions() {
1554 return "@SuppressWarnings({\"cast\", \"rawtypes\", \"serial\", \"unchecked\", \"unused\"})\n";
1555 }
1556
1557+string t_java_generator::grpc_imports() {
1558+ return
1559+ string() +
1560+ "import static io.grpc.stub.ClientCalls.asyncUnaryCall;\n" +
1561+ "import static io.grpc.stub.ClientCalls.asyncServerStreamingCall;\n" +
1562+ "import static io.grpc.stub.ClientCalls.asyncClientStreamingCall;\n" +
1563+ "import static io.grpc.stub.ClientCalls.asyncBidiStreamingCall;\n" +
1564+ "import static io.grpc.stub.ClientCalls.blockingUnaryCall;\n" +
1565+ "import static io.grpc.stub.ClientCalls.blockingServerStreamingCall;\n" +
1566+ "import static io.grpc.stub.ClientCalls.futureUnaryCall;\n" +
1567+ "import static io.grpc.MethodDescriptor.generateFullMethodName;\n" +
1568+ "import static io.grpc.stub.ServerCalls.asyncUnaryCall;\n" +
1569+ "import static io.grpc.stub.ServerCalls.asyncServerStreamingCall;\n" +
1570+ "import static io.grpc.stub.ServerCalls.asyncClientStreamingCall;\n" +
1571+ "import static io.grpc.stub.ServerCalls.asyncBidiStreamingCall;\n" +
1572+ "import static io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall;\n" +
1573+ "import static io.grpc.stub.ServerCalls.asyncUnimplementedStreamingCall;\n" +
1574+ "import io.grpc.thrift.ThriftUtils;\n\n";
1575+}
1576+
1577+string t_java_generator::import_extended_service(t_service* tservice) {
chedeti00be9de2016-08-02 10:44:41 -07001578+ if (!tservice) {
chedetidd7a2a32016-07-31 21:57:47 -07001579+ return string() + "\n";
1580+ }
1581+ string ns = tservice->get_program()->get_namespace("java");
1582+ string extend_service_name = tservice->get_name() + "Grpc";
1583+ return string() + "import " + ns + "." + extend_service_name + ";\n\n";
1584+}
1585+
1586 /**
1587 * Nothing in Java
1588 */
1589@@ -2772,25 +2814,51 @@ void t_java_generator::generate_field_value_meta_data(std::ofstream& out, t_type
1590 */
1591 void t_java_generator::generate_service(t_service* tservice) {
1592 // Make output file
1593- string f_service_name = package_dir_ + "/" + make_valid_java_filename(service_name_) + ".java";
1594+ string f_service_name = package_dir_ + "/" + make_valid_java_filename(service_name_) + "Grpc.java";
1595 f_service_.open(f_service_name.c_str());
1596
1597- f_service_ << autogen_comment() << java_package() << java_type_imports() << java_suppressions();
1598+ f_service_ <<
1599+ autogen_comment() <<
1600+ java_package() <<
1601+ java_type_imports() <<
1602+ grpc_imports() <<
1603+ import_extended_service(tservice->get_extends());
1604+ java_suppressions();
1605+
1606+ f_service_ <<
1607+ "public class " << service_name_ << "Grpc {" << endl <<
1608+ endl;
1609
1610- if (!suppress_generated_annotations_) {
1611- generate_javax_generated_annotation(f_service_);
1612- }
1613- f_service_ << "public class " << service_name_ << " {" << endl << endl;
1614 indent_up();
1615
1616+ // generate constructor
1617+ f_service_ <<
1618+ indent() << "private " << service_name_ <<
1619+ "Grpc() {}" << endl << endl;
1620+
1621+ f_service_ <<
1622+ indent() << "public static final String SERVICE_NAME = " <<
1623+ "\"" << package_name_ << "." << service_name_ << "\";" << endl << endl;
1624+
1625 // Generate the three main parts of the service
1626 generate_service_interface(tservice);
1627- generate_service_async_interface(tservice);
1628- generate_service_client(tservice);
1629- generate_service_async_client(tservice);
1630- generate_service_server(tservice);
1631- generate_service_async_server(tservice);
1632+ generate_arg_ids(tservice);
1633+ generate_message_factory(tservice);
1634+ generate_service_impl_base(tservice);
1635+ //generate_service_async_interface(tservice);
1636+ //generate_service_client(tservice);
1637+ //generate_service_async_client(tservice);
1638+ //generate_service_server(tservice);
1639+ //generate_service_async_server(tservice);
1640 generate_service_helpers(tservice);
1641+ generate_method_descriptors(tservice);
1642+ generate_stub(tservice);
1643+ generate_blocking_stub(tservice);
1644+ generate_future_stub(tservice);
1645+ generate_method_ids(tservice);
1646+ generate_method_handlers(tservice);
1647+ generate_service_descriptors(tservice);
1648+ generate_service_builder(tservice);
1649
1650 indent_down();
1651 f_service_ << "}" << endl;
1652@@ -2805,24 +2873,820 @@ void t_java_generator::generate_service(t_service* tservice) {
1653 void t_java_generator::generate_service_interface(t_service* tservice) {
1654 string extends = "";
1655 string extends_iface = "";
1656- if (tservice->get_extends() != NULL) {
1657- extends = type_name(tservice->get_extends());
1658- extends_iface = " extends " + extends + ".Iface";
1659- }
1660
1661 generate_java_doc(f_service_, tservice);
1662- f_service_ << indent() << "public interface Iface" << extends_iface << " {" << endl << endl;
1663+ f_service_ << indent() <<
1664+ "@java.lang.Deprecated public static interface " << service_name_;
1665+
chedeti00be9de2016-08-02 10:44:41 -07001666+ if (tservice->get_extends()) {
chedetidd7a2a32016-07-31 21:57:47 -07001667+ f_service_ << " extends " << tservice->get_extends()->get_name() + "Grpc." <<
1668+ tservice->get_extends()->get_name() << endl;
1669+ }
1670+ f_service_ << " {" << endl;
1671+
1672+ indent_up();
1673+ vector<t_function*> functions = tservice->get_functions();
1674+ vector<t_function*>::iterator f_iter;
1675+ for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
1676+ //generate_java_doc(f_service_, *f_iter);
1677+ f_service_ <<
1678+ indent() << "public void " << (*f_iter)->get_name() << "(" << (*f_iter)->get_name() <<
1679+ "_args request," << endl <<
1680+ indent() << " io.grpc.stub.StreamObserver<" << (*f_iter)->get_name() <<
1681+ "_result> responseObserver);" << endl << endl;
1682+ }
1683+ indent_down();
1684+ f_service_ << indent() << "}" << endl << endl;
1685+}
1686+
1687+void t_java_generator::generate_arg_ids(t_service* tservice) {
1688+ vector<t_function*> functions = tservice->get_functions();
1689+ vector<t_function*>::iterator f_iter;
1690+ int i=0;
1691+ for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
1692+ f_service_ << indent() <<
1693+ "private static final int ARG_IN_METHOD_" <<
1694+ (*f_iter)->get_name() << " = " << ++i << ";" << endl;
1695+ f_service_ << indent() <<
1696+ "private static final int ARG_OUT_METHOD_" <<
1697+ (*f_iter)->get_name() << " = " << ++i << ";" << endl;
1698+ }
1699+ f_service_ << endl;
1700+
chedeti00be9de2016-08-02 10:44:41 -07001701+ if (tservice->get_extends()) {
chedetidd7a2a32016-07-31 21:57:47 -07001702+ f_service_ << indent() << "// ARG IDs for extended service" << endl;
1703+ t_service* extend_service = tservice->get_extends();
1704+ functions = extend_service->get_functions();
1705+ for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
1706+ f_service_ << indent() <<
1707+ "private static final int ARG_IN_METHOD_" <<
1708+ (*f_iter)->get_name() << " = " << ++i << ";" << endl;
1709+ f_service_ << indent() <<
1710+ "private static final int ARG_OUT_METHOD_" <<
1711+ (*f_iter)->get_name() << " = " << ++i << ";" << endl;
1712+ }
1713+ f_service_ << endl;
1714+ }
1715+}
1716+
1717+void t_java_generator::generate_message_factory(t_service* tservice) {
1718+ f_service_ << indent() <<
1719+ "private static final class ThriftMessageFactory<T extends " <<
1720+ "org.apache.thrift.TBase<T,?>>" << endl << indent() <<
1721+ " implements io.grpc.thrift.MessageFactory<T> {" << endl;
1722+ indent_up();
1723+ f_service_ << indent() <<
1724+ "private final int id;" << endl << endl;
1725+ f_service_ << endl;
1726+
1727+ f_service_ << indent() <<
1728+ "ThriftMessageFactory(int id) {" << endl <<
1729+ indent() << " this.id = id;" << endl <<
1730+ indent() << "}" << endl;
1731+
1732+ f_service_ << indent() <<
1733+ "@java.lang.Override" << endl <<
1734+ indent() << "public T newInstance() {" << endl;
1735+ indent_up();
1736+
1737+ f_service_ << indent() <<
1738+ "Object o;" << endl <<
1739+ indent() << "switch (id) {" << endl;
1740+
1741+ vector<t_function*> functions = tservice->get_functions();
1742+ vector<t_function*>::iterator f_iter;
1743+ for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
1744+ f_service_ << indent() <<
1745+ "case ARG_IN_METHOD_" << (*f_iter)->get_name() << ":" << endl <<
1746+ indent() << " o = new " << (*f_iter)->get_name() << "_args();" <<
1747+ endl << indent() << " break;" << endl;
1748+ f_service_ << indent() <<
1749+ "case ARG_OUT_METHOD_" << (*f_iter)->get_name() << ":" << endl <<
1750+ indent() << " o = new " << (*f_iter)->get_name() << "_result();" <<
1751+ endl << indent() << " break;" << endl;
1752+ }
1753+
chedeti00be9de2016-08-02 10:44:41 -07001754+ if (tservice->get_extends()) {
chedetidd7a2a32016-07-31 21:57:47 -07001755+ t_service* extend_service = tservice->get_extends();
1756+ functions = extend_service->get_functions();
1757+ string extend_service_name = extend_service->get_name() + "Grpc";
1758+ for (f_iter = functions.begin(); f_iter!= functions.end(); ++f_iter) {
1759+ f_service_ << indent() <<
1760+ "case ARG_IN_METHOD_" << (*f_iter)->get_name() << ":" << endl <<
1761+ indent() << " o = new " << extend_service_name << "." << (*f_iter)->get_name() << "_args();" <<
1762+ endl << indent() << " break;" << endl;
1763+ f_service_ << indent() <<
1764+ "case ARG_OUT_METHOD_" << (*f_iter)->get_name() << ":" << endl <<
1765+ indent() << " o = new " << extend_service_name << "." << (*f_iter)->get_name() << "_result();" <<
1766+ endl << indent() << " break;" << endl;
1767+ }
1768+ }
1769+
1770+ f_service_ << indent() <<
1771+ "default:" << endl << indent() <<
1772+ " throw new AssertionError();" << endl << indent() <<
1773+ "}" << endl;
1774+
1775+ f_service_ << indent() <<
1776+ "@java.lang.SuppressWarnings(\"unchecked\")" << endl <<
1777+ indent() << "T t = (T) o;" << endl << indent() <<
1778+ "return t;" << endl;
1779+
1780+ indent_down();
1781+ f_service_ <<
1782+ indent() << "}" << endl;
1783+
1784+ indent_down();
1785+ f_service_ << indent() << "}" << endl;
1786+}
1787+
1788+void t_java_generator::generate_service_impl_base(t_service* tservice) {
1789+ f_service_ <<
1790+ indent() << "public static abstract class " << service_name_ <<
1791+ "ImplBase implements " << service_name_ << ", io.grpc.BindableService {" << endl;
1792+ indent_up();
1793+
1794+ vector<t_function*> functions = tservice->get_functions();
1795+ vector<t_function*>::iterator f_iter;
1796+ for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
1797+ f_service_ <<
1798+ indent() << "@java.lang.Override" << endl <<
1799+ indent() << "public void " << (*f_iter)->get_name() << "(" << (*f_iter)->get_name() <<
1800+ "_args request, " << endl <<
1801+ indent() << " io.grpc.stub.StreamObserver<" << (*f_iter)->get_name() <<
1802+ "_result> responseObserver) {" << endl;
1803+ indent_up();
1804+ f_service_ <<
1805+ indent() << "asyncUnimplementedUnaryCall(METHOD_" << (*f_iter)->get_name() <<
1806+ ", responseObserver);" << endl;
1807+ indent_down();
1808+ f_service_ <<
1809+ indent() << "}" << endl << endl;
1810+ }
1811+
chedeti00be9de2016-08-02 10:44:41 -07001812+ if (tservice->get_extends()) {
chedetidd7a2a32016-07-31 21:57:47 -07001813+ t_service* extend_service = tservice->get_extends();
1814+ functions = extend_service->get_functions();
1815+ string extend_service_name = extend_service->get_name() + "Grpc" ;
1816+ for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
1817+ f_service_ <<
1818+ indent() << "@java.lang.Override" << endl <<
1819+ indent() << "public void " << (*f_iter)->get_name() << "(" <<
1820+ extend_service_name << "." << (*f_iter)->get_name() <<
1821+ "_args request, " << endl <<
1822+ indent() << " io.grpc.stub.StreamObserver<" << extend_service_name
1823+ << "." << (*f_iter)->get_name() << "_result> responseObserver) {" << endl;
1824+ indent_up();
1825+ f_service_ <<
1826+ indent() << "asyncUnimplementedUnaryCall(METHOD_" << (*f_iter)->get_name() <<
1827+ ", responseObserver);" << endl;
1828+ indent_down();
1829+ f_service_ <<
1830+ indent() << "}" << endl << endl;
1831+ }
1832+ }
1833+
1834+ f_service_ <<
1835+ indent() << "@java.lang.Override" <<
1836+ " public io.grpc.ServerServiceDefinition bindService() {" << endl;
1837 indent_up();
1838+ f_service_ <<
1839+ indent() << "return " << service_name_ << "Grpc.bindService(this);" << endl;
1840+ indent_down();
1841+ f_service_ <<
1842+ indent() << "}" << endl << endl;
1843+
1844+ indent_down();
1845+ f_service_ <<
1846+ indent() << "}" << endl << endl;
1847+
1848+ // generate Abstract Service
1849+ f_service_ <<
1850+ indent() << "@java.lang.Deprecated public static abstract class Abstract" << service_name_ <<
1851+ " extends " << service_name_ << "ImplBase {}" << endl << endl;
1852+}
1853+
1854+void t_java_generator::generate_method_descriptors(t_service* tservice) {
1855+ vector<t_function*> functions = tservice->get_functions();
1856+ vector<t_function*>::iterator f_iter;
1857+ for( f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
1858+ f_service_ <<
1859+ indent() << "public static final io.grpc.MethodDescriptor<" <<
1860+ (*f_iter)->get_name() << "_args," << endl <<
1861+ indent() << " " << (*f_iter)->get_name() << "_result> METHOD_" << (*f_iter)->get_name() <<
1862+ " = " << endl << indent() << " io.grpc.MethodDescriptor.create(" << endl;
1863+ indent_up();
1864+ f_service_ <<
1865+ indent() << " io.grpc.MethodDescriptor.MethodType.UNARY," << endl <<
1866+ indent() << " generateFullMethodName(" << "\"" << package_name_ << "." <<
1867+ service_name_ << "\" , \"" << (*f_iter)->get_name() << "\")," << endl <<
1868+ indent() << " io.grpc.thrift.ThriftUtils.marshaller(" << endl <<
1869+ indent() << " new ThriftMessageFactory<" << (*f_iter)->get_name() <<
1870+ "_args>( ARG_IN_METHOD_" << (*f_iter)->get_name() << "))," << endl <<
1871+ indent() << " io.grpc.thrift.ThriftUtils.marshaller(" << endl <<
1872+ indent() << " new ThriftMessageFactory<" << (*f_iter)->get_name() <<
1873+ "_result>( ARG_OUT_METHOD_" << (*f_iter)->get_name() << ")));" << endl << endl;
1874+ indent_down();
1875+ }
1876+
chedeti00be9de2016-08-02 10:44:41 -07001877+ if(tservice->get_extends()) {
chedetidd7a2a32016-07-31 21:57:47 -07001878+ t_service* extends_service = tservice->get_extends();
1879+ functions = extends_service->get_functions();
1880+ string extend_service_name = extends_service->get_name() + "Grpc";
1881+ for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
1882+ f_service_ <<
1883+ indent() << "public static final io.grpc.MethodDescriptor<" << extend_service_name << "." <<
1884+ (*f_iter)->get_name() << "_args," << endl <<
1885+ indent() << " " << extend_service_name << "." << (*f_iter)->get_name() << "_result> METHOD_"
1886+ << (*f_iter)->get_name() << " = " << endl << indent() <<
1887+ " io.grpc.MethodDescriptor.create(" << endl;
1888+ indent_up();
1889+ f_service_ <<
1890+ indent() << " io.grpc.MethodDescriptor.MethodType.UNARY," << endl <<
1891+ indent() << " generateFullMethodName(" << "\"" << package_name_ << "." <<
1892+ service_name_ << "\" , \"" << (*f_iter)->get_name() << "\")," << endl <<
1893+ indent() << " io.grpc.thrift.ThriftUtils.marshaller(" << endl <<
1894+ indent() << " new ThriftMessageFactory<" << extend_service_name << "." <<
1895+ (*f_iter)->get_name() << "_args>( ARG_IN_METHOD_" << (*f_iter)->get_name() << "))," << endl <<
1896+ indent() << " io.grpc.thrift.ThriftUtils.marshaller(" << endl <<
1897+ indent() << " new ThriftMessageFactory<" << extend_service_name << "." << (*f_iter)->get_name() <<
1898+ "_result>( ARG_OUT_METHOD_" << (*f_iter)->get_name() << ")));" << endl << endl;
1899+ indent_down();
1900+ }
1901+ }
1902+}
1903+
1904+void t_java_generator::generate_stub(t_service* tservice) {
1905+ f_service_ <<
1906+ indent() <<
1907+ "public static " << service_name_ <<
1908+ "Stub newStub(io.grpc.Channel channel) {" <<
1909+ endl;
1910+
1911+ indent_up();
1912+ f_service_ <<
1913+ indent() <<
1914+ "return new " << service_name_ << "Stub(channel);" << endl;
1915+ indent_down();
1916+ f_service_ <<
1917+ indent() << "}" << endl << endl;
1918+
1919+ // generate Stub impl
1920+
1921+ f_service_ <<
1922+ indent() << "public static class " <<
1923+ service_name_ << "Stub extends io.grpc.stub.AbstractStub<" <<
1924+ service_name_ << "Stub>" << endl <<
1925+ indent() << " implements " << service_name_ << "{" << endl;
1926+ indent_up();
1927+
1928+ f_service_ <<
1929+ indent() << "private " << service_name_ << "Stub(io.grpc.Channel channel) {" << endl;
1930+ indent_up();
1931+ f_service_ <<
1932+ indent() << "super(channel);" << endl;
1933+ indent_down();
1934+ f_service_ <<
1935+ indent() << "}" << endl << endl;
1936+
1937+ f_service_ <<
1938+ indent() << "private " << service_name_ << "Stub(io.grpc.Channel channel, " << endl <<
1939+ indent() << " io.grpc.CallOptions callOptions) {" << endl;
1940+ indent_up();
1941+ f_service_ <<
1942+ indent() << "super(channel, callOptions);" << endl;
1943+ indent_down();
1944+ f_service_ <<
1945+ indent() << "}" << endl << endl;
1946+
1947+ f_service_ <<
1948+ indent() << "@java.lang.Override" << endl <<
1949+ indent() << "protected " << service_name_ << "Stub build(io.grpc.Channel channel, " <<
1950+ endl << indent() << " io.grpc.CallOptions callOptions) {" << endl;
1951+ indent_up();
1952+ f_service_ <<
1953+ indent() << "return new " << service_name_ << "Stub(channel, callOptions);" << endl;
1954+ indent_down();
1955+ f_service_ <<
1956+ indent() << "}" << endl << endl;
1957+
1958+ vector<t_function*> functions = tservice->get_functions();
1959+ vector<t_function*>::iterator f_iter;
1960+ for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
1961+ f_service_ <<
1962+ indent() << "@java.lang.Override" << endl <<
1963+ indent() << "public void " << (*f_iter)->get_name() << "(" <<
1964+ (*f_iter)->get_name() << "_args request," << endl << indent() <<
1965+ " io.grpc.stub.StreamObserver<" << (*f_iter)->get_name() <<
1966+ "_result> responseObserver) {" << endl;
1967+ indent_up();
1968+ f_service_ <<
1969+ indent() << "asyncUnaryCall(" << endl <<
1970+ indent() << " getChannel().newCall(METHOD_" << (*f_iter)->get_name() <<
1971+ ", getCallOptions()), request, responseObserver);" << endl;
1972+ indent_down();
1973+ f_service_ <<
1974+ indent() << "}" << endl << endl;
1975+ }
1976+
chedeti00be9de2016-08-02 10:44:41 -07001977+ if (tservice->get_extends()) {
chedetidd7a2a32016-07-31 21:57:47 -07001978+ t_service* extend_service = tservice->get_extends();
1979+ functions = extend_service->get_functions();
1980+ string extend_service_name = extend_service->get_name() + "Grpc";
1981+ for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
1982+ f_service_ <<
1983+ indent() << "@java.lang.Override" << endl <<
1984+ indent() << "public void " << (*f_iter)->get_name() << "(" <<
1985+ extend_service_name << "." << (*f_iter)->get_name() << "_args request,"
1986+ << endl << indent() << " io.grpc.stub.StreamObserver<" <<
1987+ extend_service_name << "." << (*f_iter)->get_name() <<
1988+ "_result> responseObserver) {" << endl;
1989+ indent_up();
1990+ f_service_ <<
1991+ indent() << "asyncUnaryCall(" << endl <<
1992+ indent() << " getChannel().newCall(METHOD_" << (*f_iter)->get_name() <<
1993+ ", getCallOptions()), request, responseObserver);" << endl;
1994+ indent_down();
1995+ f_service_ <<
1996+ indent() << "}" << endl << endl;
1997+ }
1998+ }
1999+ indent_down();
2000+ f_service_ <<
2001+ indent() << "}" << endl << endl;
2002+}
2003+
2004+void t_java_generator::generate_blocking_stub(t_service* tservice) {
2005+ f_service_ <<
2006+ indent() << "public static " << service_name_ <<
2007+ "BlockingStub newBlockingStub(" << endl <<
2008+ indent() << " io.grpc.Channel channel) {" << endl;
2009+ indent_up();
2010+ f_service_ <<
2011+ indent() << "return new " << service_name_ << "BlockingStub(channel);" << endl;
2012+ indent_down();
2013+ f_service_ <<
2014+ indent() << "}" << endl << endl;
2015+
2016+ // generate Blocking Client
2017+ f_service_ <<
2018+ indent() << "@java.lang.Deprecated public static interface " << service_name_ <<
2019+ "BlockingClient " ;
2020+
chedeti00be9de2016-08-02 10:44:41 -07002021+ if (tservice->get_extends()) {
chedetidd7a2a32016-07-31 21:57:47 -07002022+ string extend_service_name = tservice->get_extends()->get_name();
2023+ f_service_ << endl << indent() << " extends " << extend_service_name << "Grpc." <<
2024+ extend_service_name << "BlockingClient " ;
2025+ }
2026+
2027+ f_service_ << "{" << endl;
2028+
2029+ indent_up();
2030+
2031 vector<t_function*> functions = tservice->get_functions();
2032 vector<t_function*>::iterator f_iter;
2033 for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
2034- generate_java_doc(f_service_, *f_iter);
2035- indent(f_service_) << "public " << function_signature(*f_iter) << ";" << endl << endl;
2036+ f_service_ <<
2037+ indent() << "public " << (*f_iter)->get_name() << "_result " <<
2038+ (*f_iter)->get_name() << "(" << (*f_iter)->get_name() << "_args request);" << endl << endl;
2039+ }
2040+ indent_down();
2041+ f_service_ <<
2042+ indent() << "}" << endl << endl;
2043+
2044+ // generate Blocking Stub impl
2045+
2046+ f_service_ <<
2047+ indent() << "public static class " <<
2048+ service_name_ << "BlockingStub extends io.grpc.stub.AbstractStub<" <<
2049+ service_name_ << "BlockingStub>" << endl <<
2050+ indent() << " implements " << service_name_ << "BlockingClient {";
2051+
2052+ indent_up();
2053+
2054+ f_service_ <<
2055+ indent() << "private " << service_name_ << "BlockingStub(io.grpc.Channel channel) {" << endl;
2056+ indent_up();
2057+ f_service_ <<
2058+ indent() << "super(channel);" << endl;
2059+ indent_down();
2060+ f_service_ <<
2061+ indent() << "}" << endl << endl;
2062+
2063+ f_service_ <<
2064+ indent() << "private " << service_name_ << "BlockingStub(io.grpc.Channel channel, " << endl <<
2065+ indent() << " io.grpc.CallOptions callOptions) {" << endl;
2066+ indent_up();
2067+ f_service_ <<
2068+ indent() << "super(channel, callOptions);" << endl;
2069+ indent_down();
2070+ f_service_ <<
2071+ indent() << "}" << endl << endl;
2072+
2073+ f_service_ <<
2074+ indent() << "@java.lang.Override" << endl <<
2075+ indent() << "protected " << service_name_ << "BlockingStub build(io.grpc.Channel channel, " <<
2076+ endl << indent() << " io.grpc.CallOptions callOptions) {" << endl;
2077+ indent_up();
2078+ f_service_ <<
2079+ indent() << "return new " << service_name_ << "BlockingStub(channel, callOptions);" << endl;
2080+ indent_down();
2081+ f_service_ <<
2082+ indent() << "}" << endl << endl;
2083+
2084+ for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
2085+ f_service_ <<
2086+ indent() << "@java.lang.Override" << endl <<
2087+ indent() << "public " << (*f_iter)->get_name() << "_result " << (*f_iter)->get_name() << "(" <<
2088+ (*f_iter)->get_name() << "_args request) {" << endl;
2089+ indent_up();
2090+ f_service_ <<
2091+ indent() << "return blockingUnaryCall(" << endl <<
2092+ indent() << " getChannel(), METHOD_" << (*f_iter)->get_name() <<
2093+ ", getCallOptions(), request);" << endl;
2094+ indent_down();
2095+ f_service_ <<
2096+ indent() << "}" << endl << endl;
2097+ }
2098+
chedeti00be9de2016-08-02 10:44:41 -07002099+ if (tservice->get_extends()) {
chedetidd7a2a32016-07-31 21:57:47 -07002100+ t_service* extend_service = tservice->get_extends();
2101+ functions = extend_service->get_functions();
2102+ string extend_service_name = extend_service->get_name() + "Grpc";
2103+ for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
2104+ f_service_ <<
2105+ indent() << "@java.lang.Override" << endl <<
2106+ indent() << "public " << extend_service_name << "." << (*f_iter)->get_name() <<
2107+ "_result " << (*f_iter)->get_name() << "(" << extend_service_name << "." <<
2108+ (*f_iter)->get_name() << "_args request) {" << endl;
2109+ indent_up();
2110+ f_service_ <<
2111+ indent() << "return blockingUnaryCall(" << endl <<
2112+ indent() << " getChannel(), METHOD_" << (*f_iter)->get_name() <<
2113+ ", getCallOptions(), request);" << endl;
2114+ indent_down();
2115+ f_service_ <<
2116+ indent() << "}" << endl << endl;
2117+ }
2118+ }
2119+ indent_down();
2120+ f_service_ <<
2121+ indent() << "}" << endl << endl;
2122+}
2123+
2124+void t_java_generator::generate_future_stub(t_service* tservice) {
2125+ f_service_ <<
2126+ indent() << "public static " << service_name_ <<
2127+ "FutureStub newFutureStub(" << endl <<
2128+ indent() << " io.grpc.Channel channel) {" << endl;
2129+ indent_up();
2130+ f_service_ <<
2131+ indent() << "return new " << service_name_ << "FutureStub(channel);" << endl;
2132+ indent_down();
2133+ f_service_ <<
2134+ indent() << "}" << endl << endl;
2135+
2136+ // generate Future Client
2137+ f_service_ <<
2138+ indent() << "@java.lang.Deprecated public static interface " << service_name_ <<
2139+ "FutureClient " ;
2140+
chedeti00be9de2016-08-02 10:44:41 -07002141+ if (tservice->get_extends()) {
chedetidd7a2a32016-07-31 21:57:47 -07002142+ string extend_service_name = tservice->get_extends()->get_name();
2143+ f_service_ << endl << indent() << " extends " << extend_service_name << "Grpc." <<
2144+ extend_service_name << "FutureClient " ;
2145+ }
2146+ f_service_ << "{" << endl;
2147+
2148+ indent_up();
2149+
2150+ vector<t_function*> functions = tservice->get_functions();
2151+ vector<t_function*>::iterator f_iter;
2152+ for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
2153+ f_service_ <<
2154+ indent() << "public com.google.common.util.concurrent.ListenableFuture<" <<
2155+ (*f_iter)->get_name() << "_result> " << (*f_iter)->get_name() << "(" << endl <<
2156+ indent() << " " << (*f_iter)->get_name() << "_args request);" << endl << endl;
2157+ }
2158+
chedeti00be9de2016-08-02 10:44:41 -07002159+ if (tservice->get_extends()) {
chedetidd7a2a32016-07-31 21:57:47 -07002160+ t_service* extend_service = tservice->get_extends();
2161+ functions = extend_service->get_functions();
2162+ string extend_service_name = extend_service->get_name() + "Grpc";
2163+ for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
2164+ f_service_ <<
2165+ indent() << "public com.google.common.util.concurrent.ListenableFuture<" <<
2166+ extend_service_name << "." << (*f_iter)->get_name() << "_result> " <<
2167+ (*f_iter)->get_name() << "(" << endl <<
2168+ indent() << " " << extend_service_name << "." << (*f_iter)->get_name() <<
2169+ "_args request);" << endl << endl;
2170+ }
2171+ }
2172+ indent_down();
2173+ f_service_ <<
2174+ indent() << "}" << endl << endl;
2175+
2176+ // generate Stub impl
2177+
2178+ f_service_ <<
2179+ indent() << "public static class " <<
2180+ service_name_ << "FutureStub extends io.grpc.stub.AbstractStub<" <<
2181+ service_name_ << "FutureStub>" << endl <<
2182+ indent() << " implements " << service_name_ << "FutureClient {" << endl;
2183+ indent_up();
2184+
2185+ f_service_ <<
2186+ indent() << "private " << service_name_ << "FutureStub(io.grpc.Channel channel) {" << endl;
2187+ indent_up();
2188+ f_service_ <<
2189+ indent() << "super(channel);" << endl;
2190+ indent_down();
2191+ f_service_ <<
2192+ indent() << "}" << endl << endl;
2193+
2194+ f_service_ <<
2195+ indent() << "private " << service_name_ << "FutureStub(io.grpc.Channel channel, " << endl <<
2196+ indent() << " io.grpc.CallOptions callOptions) {" << endl;
2197+ indent_up();
2198+ f_service_ <<
2199+ indent() << "super(channel, callOptions);" << endl;
2200+ indent_down();
2201+ f_service_ <<
2202+ indent() << "}" << endl << endl;
2203+
2204+ f_service_ <<
2205+ indent() << "@java.lang.Override" << endl <<
2206+ indent() << "protected " << service_name_ << "FutureStub build(io.grpc.Channel channel, " <<
2207+ endl << indent() << " io.grpc.CallOptions callOptions) {" << endl;
2208+ indent_up();
2209+ f_service_ <<
2210+ indent() << "return new " << service_name_ << "FutureStub(channel, callOptions);" << endl;
2211+ indent_down();
2212+ f_service_ <<
2213+ indent() << "}" << endl << endl;
2214+
2215+ functions = tservice->get_functions();
2216+ for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
2217+ f_service_ <<
2218+ indent() << "@java.lang.Override" << endl <<
2219+ indent() << "public com.google.common.util.concurrent.ListenableFuture<" <<
2220+ (*f_iter)->get_name() << "_result> " << (*f_iter)->get_name() << "(" <<
2221+ endl << indent() << " " << (*f_iter)->get_name() << "_args request) {" << endl;
2222+ indent_up();
2223+ f_service_ <<
2224+ indent() << "return futureUnaryCall(" << endl <<
2225+ indent() << " getChannel().newCall(METHOD_" << (*f_iter)->get_name() <<
2226+ ", getCallOptions()), request);" << endl;
2227+ indent_down();
2228+ f_service_ <<
2229+ indent() << "}" << endl << endl;
2230+ }
2231+
chedeti00be9de2016-08-02 10:44:41 -07002232+ if (tservice->get_extends()) {
chedetidd7a2a32016-07-31 21:57:47 -07002233+ t_service* extend_service = tservice->get_extends();
2234+ functions = extend_service->get_functions();
2235+ string extend_service_name = extend_service->get_name() + "Grpc";
2236+ for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
2237+ f_service_ <<
2238+ indent() << "@java.lang.Override" << endl <<
2239+ indent() << "public com.google.common.util.concurrent.ListenableFuture<" <<
2240+ extend_service_name << "." << (*f_iter)->get_name() << "_result> " <<
2241+ (*f_iter)->get_name() << "(" << endl << indent() << " " <<
2242+ extend_service_name << "." << (*f_iter)->get_name() << "_args request) {" << endl;
2243+ indent_up();
2244+ f_service_ <<
2245+ indent() << "return futureUnaryCall(" << endl <<
2246+ indent() << " getChannel().newCall(METHOD_" << (*f_iter)->get_name() <<
2247+ ", getCallOptions()), request);" << endl;
2248+ indent_down();
2249+ f_service_ <<
2250+ indent() << "}" << endl << endl;
2251+ }
2252+ }
2253+ indent_down();
2254+ f_service_ <<
2255+ indent() << "}" << endl << endl;
2256+}
2257+
2258+void t_java_generator::generate_method_ids(t_service* tservice) {
2259+ vector<t_function*> functions = tservice->get_functions();
2260+ vector<t_function*>::iterator f_iter;
2261+ int i=0;
2262+ for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter, ++i) {
2263+ f_service_ <<
2264+ indent() << "private static final int METHODID_" <<
2265+ (*f_iter)->get_name() << " = " << i << ";" << endl;
2266+ }
chedeti00be9de2016-08-02 10:44:41 -07002267+ if (tservice->get_extends()) {
chedetidd7a2a32016-07-31 21:57:47 -07002268+ t_service* extend_service = tservice->get_extends();
2269+ functions = extend_service->get_functions();
2270+ string extend_service_name = extend_service->get_name() + "Grpc";
2271+ for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter, ++i) {
2272+ f_service_ <<
2273+ indent() << "private static final int METHODID_" <<
2274+ (*f_iter)->get_name() << " = " << i << ";" << endl;
2275+ }
2276+ }
2277+ f_service_ << endl;
2278+}
2279+
2280+void t_java_generator::generate_method_handlers(t_service* tservice) {
2281+ f_service_ <<
2282+ indent() << "private static class MethodHandlers<Req, Resp> implements" <<
2283+ endl << indent() << " io.grpc.stub.ServerCalls.UnaryMethod<Req, Resp>," <<
2284+ endl << indent() << " io.grpc.stub.ServerCalls.ServerStreamingMethod<Req, Resp>," <<
2285+ endl << indent() << " io.grpc.stub.ServerCalls.ClientStreamingMethod<Req, Resp>," <<
2286+ endl << indent() << " io.grpc.stub.ServerCalls.BidiStreamingMethod<Req, Resp> {" <<
2287+ endl;
2288+ indent_up();
2289+ f_service_ <<
2290+ indent() << "private final " << service_name_ << " serviceImpl;" << endl <<
2291+ indent() << "private final int methodId;" << endl << endl;
2292+
2293+ f_service_ <<
2294+ indent() << "public MethodHandlers(" << service_name_ << " serviceImpl, int " <<
2295+ "methodId) {" << endl;
2296+ indent_up();
2297+ f_service_ <<
2298+ indent() << "this.serviceImpl = serviceImpl;" << endl <<
2299+ indent() << "this.methodId = methodId;" << endl;
2300+ indent_down();
2301+ f_service_ <<
2302+ indent() << "}" << endl << endl;
2303+
2304+ // invoke
2305+ f_service_ <<
2306+ indent() << "@java.lang.Override" << endl <<
2307+ indent() << "@java.lang.SuppressWarnings(\"unchecked\")" << endl <<
2308+ indent() << "public void invoke(Req request, io.grpc.stub.StreamObserver<Resp> responseObserver) {" <<
2309+ endl;
2310+ indent_up();
2311+ f_service_ <<
2312+ indent() << "switch (methodId) {" << endl;
2313+ indent_up();
2314+
2315+ vector<t_function*> functions = tservice->get_functions();
2316+ vector<t_function*>::iterator f_iter;
2317+ for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
2318+ f_service_ <<
2319+ indent() << "case METHODID_" << (*f_iter)->get_name() << ":" << endl;
2320+ indent_up();
2321+ f_service_ <<
2322+ indent() << "serviceImpl." << (*f_iter)->get_name() << "((" << (*f_iter)->get_name() <<
2323+ "_args) request," << endl <<
2324+ indent() << " (io.grpc.stub.StreamObserver<" << (*f_iter)->get_name() << "_result>)" <<
2325+ " responseObserver);" << endl <<
2326+ indent() << "break;" << endl << endl;
2327+ indent_down();
2328+ }
chedeti00be9de2016-08-02 10:44:41 -07002329+ if (tservice->get_extends()) {
chedetidd7a2a32016-07-31 21:57:47 -07002330+ t_service* extend_service = tservice->get_extends();
2331+ functions = extend_service->get_functions();
2332+ string extend_service_name = extend_service->get_name() + "Grpc";
2333+ for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
2334+ f_service_ <<
2335+ indent() << "case METHODID_" << (*f_iter)->get_name() << ":" << endl;
2336+ indent_up();
2337+ f_service_ <<
2338+ indent() << "serviceImpl." << (*f_iter)->get_name() << "((" << extend_service_name <<
2339+ "." << (*f_iter)->get_name() << "_args) request," << endl <<
2340+ indent() << " (io.grpc.stub.StreamObserver<" << extend_service_name << "." <<
2341+ (*f_iter)->get_name() << "_result>)" << " responseObserver);" << endl <<
2342+ indent() << "break;" << endl << endl;
2343+ indent_down();
2344+ }
2345 }
2346+ f_service_ <<
2347+ indent() << "default:" << endl <<
2348+ indent() << " throw new AssertionError();" << endl;
2349+ indent_down();
2350+ f_service_ <<
2351+ indent() << "}" << endl;
2352+ indent_down();
2353+ f_service_ <<
2354+ indent() << "}" << endl << endl;
2355+
2356+ // invoke
2357+ f_service_ <<
2358+ indent() << "@java.lang.Override" << endl <<
2359+ indent() << "@java.lang.SuppressWarnings(\"unchecked\")" << endl <<
2360+ indent() << "public io.grpc.stub.StreamObserver<Req> invoke(" << endl <<
2361+ indent() << " io.grpc.stub.StreamObserver<Resp> responseObserver) {" << endl;
2362+ indent_up();
2363+ f_service_ <<
2364+ indent() << "switch (methodId) {" << endl;
2365+ indent_up();
2366+ f_service_ <<
2367+ indent() << "default:" << endl;
2368+ f_service_ <<
2369+ indent() << " throw new AssertionError();" << endl;
2370+ indent_down();
2371+ f_service_ << indent() << "}" << endl;
2372 indent_down();
2373 f_service_ << indent() << "}" << endl << endl;
2374+ indent_down();
2375+ f_service_ << indent() << "}" << endl << endl;
2376+
2377 }
2378
2379+void t_java_generator::generate_service_descriptors(t_service* tservice) {
2380+ // generate service descriptor
2381+ vector<t_function*> functions = tservice->get_functions();
2382+ vector<t_function*>::iterator f_iter;
2383+ f_service_ <<
2384+ indent() << "public static io.grpc.ServiceDescriptor getServiceDescriptor() {" <<
2385+ endl;
2386+ indent_up();
2387+ f_service_ <<
2388+ indent() << "return new io.grpc.ServiceDescriptor(SERVICE_NAME";
2389+ for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
2390+ f_service_ <<
2391+ indent() << "," << endl <<
2392+ indent() << " METHOD_" << (*f_iter)->get_name();
2393+ }
chedeti00be9de2016-08-02 10:44:41 -07002394+ if (tservice->get_extends()) {
chedetidd7a2a32016-07-31 21:57:47 -07002395+ t_service* extend_service = tservice->get_extends();
2396+ functions = extend_service->get_functions();
2397+ for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
2398+ f_service_ <<
2399+ indent() << "," << endl <<
2400+ indent() << " METHOD_" << (*f_iter)->get_name();
2401+ }
2402+ }
2403+ f_service_ << ");" << endl;
2404+ indent_down();
2405+ f_service_ << indent() << "}" << endl << endl;
2406+}
2407+
2408+void t_java_generator::generate_service_builder(t_service* tservice) {
2409+ // bind Service
2410+ vector<t_function*> functions = tservice->get_functions();
2411+ vector<t_function*>::iterator f_iter;
2412+ f_service_ <<
2413+ indent() << "@java.lang.Deprecated public static io.grpc.ServerServiceDefinition" <<
2414+ " bindService(" << endl <<
2415+ indent() << " final " << service_name_ << " serviceImpl) {" << endl;
2416+ indent_up();
2417+ f_service_ <<
2418+ indent() << "return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor())" <<
2419+ endl;
2420+ for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
2421+ f_service_ <<
2422+ indent() << " .addMethod(" << endl;
2423+ indent_up();
2424+ f_service_ <<
2425+ indent() << " METHOD_" << (*f_iter)->get_name() << "," << endl <<
2426+ indent() << " asyncUnaryCall(" << endl;
2427+ indent_up();
2428+ f_service_ <<
2429+ indent() << " new MethodHandlers<" << endl;
2430+ indent_up();
2431+ f_service_ <<
2432+ indent() << " " << (*f_iter)->get_name() << "_args," << endl <<
2433+ indent() << " " << (*f_iter)->get_name() << "_result>(" << endl;
2434+ indent_up();
2435+ f_service_ <<
2436+ indent() << " serviceImpl, METHODID_" << (*f_iter)->get_name() << ")))" << endl;
2437+ indent_down();
2438+ indent_down();
2439+ indent_down();
2440+ indent_down();
2441+ }
2442+
chedeti00be9de2016-08-02 10:44:41 -07002443+ if (tservice->get_extends()) {
chedetidd7a2a32016-07-31 21:57:47 -07002444+ t_service* extend_service = tservice->get_extends();
2445+ functions = extend_service->get_functions();
2446+ string extend_service_name = extend_service->get_name() + "Grpc";
2447+ for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
2448+ f_service_ <<
2449+ indent() << " .addMethod(" << endl;
2450+ indent_up();
2451+ f_service_ <<
2452+ indent() << " METHOD_" << (*f_iter)->get_name() << "," << endl <<
2453+ indent() << " asyncUnaryCall(" << endl;
2454+ indent_up();
2455+ f_service_ <<
2456+ indent() << " new MethodHandlers<" << endl;
2457+ indent_up();
2458+ f_service_ <<
2459+ indent() << " " << extend_service_name << "." << (*f_iter)->get_name() << "_args," << endl <<
2460+ indent() << " " << extend_service_name << "." << (*f_iter)->get_name() << "_result>(" << endl;
2461+ indent_up();
2462+ f_service_ <<
2463+ indent() << " serviceImpl, METHODID_" << (*f_iter)->get_name() << ")))" << endl;
2464+ indent_down();
2465+ indent_down();
2466+ indent_down();
2467+ indent_down();
2468+ }
2469+ }
2470+ f_service_ <<
2471+ indent() << " .build();" << endl;
2472+ indent_down();
2473+ f_service_ << indent() << "}" << endl << endl;
2474+}
2475+
2476+
2477 void t_java_generator::generate_service_async_interface(t_service* tservice) {
2478 string extends = "";
2479 string extends_iface = "";
2480diff --git a/tutorial/Makefile.am b/tutorial/Makefile.am
2481index 5865c54..1cffbe6 100755
2482--- a/tutorial/Makefile.am
2483+++ b/tutorial/Makefile.am
2484@@ -35,11 +35,6 @@ if WITH_D
2485 SUBDIRS += d
2486 endif
2487
2488-if WITH_JAVA
2489-SUBDIRS += java
2490-SUBDIRS += js
2491-endif
2492-
2493 if WITH_PYTHON
2494 SUBDIRS += py
2495 SUBDIRS += py.twisted
2496@@ -95,4 +90,5 @@ EXTRA_DIST = \
2497 php \
2498 shared.thrift \
2499 tutorial.thrift \
2500- README.md
2501+ README.md \
2502+ java
2503--
25042.8.0.rc3.226.g39d4020
2505