1fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Protocol Buffers - Google's data interchange format
2fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Copyright 2008 Google Inc.  All rights reserved.
3afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson// https://developers.google.com/protocol-buffers/
4fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//
5fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Redistribution and use in source and binary forms, with or without
6fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// modification, are permitted provided that the following conditions are
7fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// met:
8fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//
9fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//     * Redistributions of source code must retain the above copyright
10fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// notice, this list of conditions and the following disclaimer.
11fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//     * Redistributions in binary form must reproduce the above
12fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// copyright notice, this list of conditions and the following disclaimer
13fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// in the documentation and/or other materials provided with the
14fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// distribution.
15fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//     * Neither the name of Google Inc. nor the names of its
16fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// contributors may be used to endorse or promote products derived from
17fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// this software without specific prior written permission.
18fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//
19fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
31fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Author: kenton@google.com (Kenton Varda)
32fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//  Based on original Protocol Buffers design by
33fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//  Sanjay Ghemawat, Jeff Dean, and others.
34fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
35fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/compiler/cpp/cpp_service.h>
36fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/compiler/cpp/cpp_helpers.h>
37fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/io/printer.h>
38fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/stubs/strutil.h>
39fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
40fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace google {
41fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace protobuf {
42fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace compiler {
43fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace cpp {
44fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
45fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleServiceGenerator::ServiceGenerator(const ServiceDescriptor* descriptor,
46a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson                                   const Options& options)
47fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  : descriptor_(descriptor) {
48fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  vars_["classname"] = descriptor_->name();
49fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  vars_["full_name"] = descriptor_->full_name();
50a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  if (options.dllexport_decl.empty()) {
51fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    vars_["dllexport"] = "";
52fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else {
53a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    vars_["dllexport"] = options.dllexport_decl + " ";
54fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
55fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
56fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
57fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleServiceGenerator::~ServiceGenerator() {}
58fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
59fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid ServiceGenerator::GenerateDeclarations(io::Printer* printer) {
60fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Forward-declare the stub type.
61fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(vars_,
62fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "class $classname$_Stub;\n"
63fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "\n");
64fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
65fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  GenerateInterface(printer);
66fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  GenerateStubDefinition(printer);
67fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
68fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
69fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid ServiceGenerator::GenerateInterface(io::Printer* printer) {
70fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(vars_,
71fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "class $dllexport$$classname$ : public ::google::protobuf::Service {\n"
72fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    " protected:\n"
73fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "  // This class should be treated as an abstract interface.\n"
74fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "  inline $classname$() {};\n"
75fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    " public:\n"
76fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "  virtual ~$classname$();\n");
77fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Indent();
78fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
79fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(vars_,
80fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "\n"
81fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "typedef $classname$_Stub Stub;\n"
82fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "\n"
83fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "static const ::google::protobuf::ServiceDescriptor* descriptor();\n"
84fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "\n");
85fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
86fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  GenerateMethodSignatures(VIRTUAL, printer);
87fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
88fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
89fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "\n"
90fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "// implements Service ----------------------------------------------\n"
91fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "\n"
92fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "const ::google::protobuf::ServiceDescriptor* GetDescriptor();\n"
93fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "void CallMethod(const ::google::protobuf::MethodDescriptor* method,\n"
94fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "                ::google::protobuf::RpcController* controller,\n"
95fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "                const ::google::protobuf::Message* request,\n"
96fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "                ::google::protobuf::Message* response,\n"
97fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "                ::google::protobuf::Closure* done);\n"
98fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "const ::google::protobuf::Message& GetRequestPrototype(\n"
99fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "  const ::google::protobuf::MethodDescriptor* method) const;\n"
100fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "const ::google::protobuf::Message& GetResponsePrototype(\n"
101fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "  const ::google::protobuf::MethodDescriptor* method) const;\n");
102fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
103fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Outdent();
104fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(vars_,
105fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "\n"
106fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    " private:\n"
107fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS($classname$);\n"
108fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "};\n"
109fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "\n");
110fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
111fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
112fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid ServiceGenerator::GenerateStubDefinition(io::Printer* printer) {
113fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(vars_,
114fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "class $dllexport$$classname$_Stub : public $classname$ {\n"
115fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    " public:\n");
116fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
117fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Indent();
118fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
119fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(vars_,
120fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "$classname$_Stub(::google::protobuf::RpcChannel* channel);\n"
121fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "$classname$_Stub(::google::protobuf::RpcChannel* channel,\n"
122fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "                 ::google::protobuf::Service::ChannelOwnership ownership);\n"
123fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "~$classname$_Stub();\n"
124fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "\n"
125fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "inline ::google::protobuf::RpcChannel* channel() { return channel_; }\n"
126fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "\n"
127fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "// implements $classname$ ------------------------------------------\n"
128fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "\n");
129fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
130fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  GenerateMethodSignatures(NON_VIRTUAL, printer);
131fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
132fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Outdent();
133fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(vars_,
134fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    " private:\n"
135fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "  ::google::protobuf::RpcChannel* channel_;\n"
136fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "  bool owns_channel_;\n"
137fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS($classname$_Stub);\n"
138fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "};\n"
139fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "\n");
140fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
141fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
142fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid ServiceGenerator::GenerateMethodSignatures(
143fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    VirtualOrNon virtual_or_non, io::Printer* printer) {
144fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor_->method_count(); i++) {
145fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const MethodDescriptor* method = descriptor_->method(i);
146fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    map<string, string> sub_vars;
147fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    sub_vars["name"] = method->name();
148fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    sub_vars["input_type"] = ClassName(method->input_type(), true);
149fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    sub_vars["output_type"] = ClassName(method->output_type(), true);
150fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    sub_vars["virtual"] = virtual_or_non == VIRTUAL ? "virtual " : "";
151fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
152fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(sub_vars,
153fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "$virtual$void $name$(::google::protobuf::RpcController* controller,\n"
154fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "                     const $input_type$* request,\n"
155fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "                     $output_type$* response,\n"
156fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "                     ::google::protobuf::Closure* done);\n");
157fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
158fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
159fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
160fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// ===================================================================
161fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
162fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid ServiceGenerator::GenerateDescriptorInitializer(
163fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    io::Printer* printer, int index) {
164fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  map<string, string> vars;
165fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  vars["classname"] = descriptor_->name();
166fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  vars["index"] = SimpleItoa(index);
167fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
168fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(vars,
169fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "$classname$_descriptor_ = file->service($index$);\n");
170fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
171fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
172fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// ===================================================================
173fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
174fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid ServiceGenerator::GenerateImplementation(io::Printer* printer) {
175fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(vars_,
176fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "$classname$::~$classname$() {}\n"
177fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "\n"
178fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "const ::google::protobuf::ServiceDescriptor* $classname$::descriptor() {\n"
179fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "  protobuf_AssignDescriptorsOnce();\n"
180fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "  return $classname$_descriptor_;\n"
181fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "}\n"
182fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "\n"
183fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "const ::google::protobuf::ServiceDescriptor* $classname$::GetDescriptor() {\n"
184fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "  protobuf_AssignDescriptorsOnce();\n"
185fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "  return $classname$_descriptor_;\n"
186fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "}\n"
187fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "\n");
188fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
189fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Generate methods of the interface.
190fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  GenerateNotImplementedMethods(printer);
191fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  GenerateCallMethod(printer);
192fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  GenerateGetPrototype(REQUEST, printer);
193fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  GenerateGetPrototype(RESPONSE, printer);
194fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
195fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Generate stub implementation.
196fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(vars_,
197fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "$classname$_Stub::$classname$_Stub(::google::protobuf::RpcChannel* channel)\n"
198fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "  : channel_(channel), owns_channel_(false) {}\n"
199fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "$classname$_Stub::$classname$_Stub(\n"
200fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "    ::google::protobuf::RpcChannel* channel,\n"
201fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "    ::google::protobuf::Service::ChannelOwnership ownership)\n"
202fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "  : channel_(channel),\n"
203fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "    owns_channel_(ownership == ::google::protobuf::Service::STUB_OWNS_CHANNEL) {}\n"
204fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "$classname$_Stub::~$classname$_Stub() {\n"
205fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "  if (owns_channel_) delete channel_;\n"
206fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "}\n"
207fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "\n");
208fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
209fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  GenerateStubMethods(printer);
210fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
211fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
212fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid ServiceGenerator::GenerateNotImplementedMethods(io::Printer* printer) {
213fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor_->method_count(); i++) {
214fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const MethodDescriptor* method = descriptor_->method(i);
215fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    map<string, string> sub_vars;
216fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    sub_vars["classname"] = descriptor_->name();
217fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    sub_vars["name"] = method->name();
218fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    sub_vars["index"] = SimpleItoa(i);
219fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    sub_vars["input_type"] = ClassName(method->input_type(), true);
220fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    sub_vars["output_type"] = ClassName(method->output_type(), true);
221fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
222fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(sub_vars,
223fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "void $classname$::$name$(::google::protobuf::RpcController* controller,\n"
224fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "                         const $input_type$*,\n"
225fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "                         $output_type$*,\n"
226fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "                         ::google::protobuf::Closure* done) {\n"
227fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "  controller->SetFailed(\"Method $name$() not implemented.\");\n"
228fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "  done->Run();\n"
229fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "}\n"
230fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "\n");
231fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
232fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
233fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
234fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid ServiceGenerator::GenerateCallMethod(io::Printer* printer) {
235fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(vars_,
236fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "void $classname$::CallMethod(const ::google::protobuf::MethodDescriptor* method,\n"
237fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "                             ::google::protobuf::RpcController* controller,\n"
238fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "                             const ::google::protobuf::Message* request,\n"
239fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "                             ::google::protobuf::Message* response,\n"
240fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "                             ::google::protobuf::Closure* done) {\n"
241fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "  GOOGLE_DCHECK_EQ(method->service(), $classname$_descriptor_);\n"
242fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "  switch(method->index()) {\n");
243fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
244fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor_->method_count(); i++) {
245fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const MethodDescriptor* method = descriptor_->method(i);
246fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    map<string, string> sub_vars;
247fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    sub_vars["name"] = method->name();
248fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    sub_vars["index"] = SimpleItoa(i);
249fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    sub_vars["input_type"] = ClassName(method->input_type(), true);
250fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    sub_vars["output_type"] = ClassName(method->output_type(), true);
251fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
252fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // Note:  down_cast does not work here because it only works on pointers,
253fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    //   not references.
254fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(sub_vars,
255fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "    case $index$:\n"
256fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "      $name$(controller,\n"
257fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "             ::google::protobuf::down_cast<const $input_type$*>(request),\n"
258fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "             ::google::protobuf::down_cast< $output_type$*>(response),\n"
259fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "             done);\n"
260fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "      break;\n");
261fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
262fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
263fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(vars_,
264fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "    default:\n"
265fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "      GOOGLE_LOG(FATAL) << \"Bad method index; this should never happen.\";\n"
266fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "      break;\n"
267fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "  }\n"
268fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "}\n"
269fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "\n");
270fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
271fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
272fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid ServiceGenerator::GenerateGetPrototype(RequestOrResponse which,
273fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                                            io::Printer* printer) {
274fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (which == REQUEST) {
275fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(vars_,
276fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "const ::google::protobuf::Message& $classname$::GetRequestPrototype(\n");
277fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else {
278fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(vars_,
279fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "const ::google::protobuf::Message& $classname$::GetResponsePrototype(\n");
280fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
281fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
282fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(vars_,
283fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "    const ::google::protobuf::MethodDescriptor* method) const {\n"
284fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "  GOOGLE_DCHECK_EQ(method->service(), descriptor());\n"
285fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "  switch(method->index()) {\n");
286fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
287fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor_->method_count(); i++) {
288fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const MethodDescriptor* method = descriptor_->method(i);
289fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const Descriptor* type =
290fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      (which == REQUEST) ? method->input_type() : method->output_type();
291fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
292fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    map<string, string> sub_vars;
293fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    sub_vars["index"] = SimpleItoa(i);
294fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    sub_vars["type"] = ClassName(type, true);
295fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
296fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(sub_vars,
297fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "    case $index$:\n"
298fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "      return $type$::default_instance();\n");
299fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
300fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
301fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(vars_,
302fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "    default:\n"
303fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "      GOOGLE_LOG(FATAL) << \"Bad method index; this should never happen.\";\n"
304b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer    "      return *static_cast< ::google::protobuf::Message*>(NULL);\n"
305fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "  }\n"
306fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "}\n"
307fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "\n");
308fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
309fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
310fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid ServiceGenerator::GenerateStubMethods(io::Printer* printer) {
311fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor_->method_count(); i++) {
312fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const MethodDescriptor* method = descriptor_->method(i);
313fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    map<string, string> sub_vars;
314fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    sub_vars["classname"] = descriptor_->name();
315fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    sub_vars["name"] = method->name();
316fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    sub_vars["index"] = SimpleItoa(i);
317fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    sub_vars["input_type"] = ClassName(method->input_type(), true);
318fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    sub_vars["output_type"] = ClassName(method->output_type(), true);
319fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
320fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(sub_vars,
321fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "void $classname$_Stub::$name$(::google::protobuf::RpcController* controller,\n"
322fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "                              const $input_type$* request,\n"
323fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "                              $output_type$* response,\n"
324fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "                              ::google::protobuf::Closure* done) {\n"
325fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "  channel_->CallMethod(descriptor()->method($index$),\n"
326fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "                       controller, request, response, done);\n"
327fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "}\n");
328fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
329fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
330fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
331fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}  // namespace cpp
332fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}  // namespace compiler
333fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}  // namespace protobuf
334fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}  // namespace google
335