blob: d1482a40d07840a5c909416f97d679c3efcab962 [file] [log] [blame]
murgatroid99d3efd0a2015-04-07 11:40:29 -07001/*
2 *
3 * Copyright 2015, Google Inc.
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met:
9 *
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following disclaimer
14 * in the documentation and/or other materials provided with the
15 * distribution.
16 * * Neither the name of Google Inc. nor the names of its
17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 */
33
34#include <map>
35
36#include "src/compiler/objective_c_generator.h"
37#include "src/compiler/objective_c_generator_helpers.h"
38
39#include "src/compiler/config.h"
40
41#include <sstream>
42
43namespace grpc_objective_c_generator {
44namespace {
45
Jorge Canizales9a065d22015-04-27 00:05:01 -070046using ::grpc::protobuf::io::Printer;
47using ::grpc::protobuf::MethodDescriptor;
48using ::std::map;
49using ::grpc::string;
murgatroid99d3efd0a2015-04-07 11:40:29 -070050
Jorge Canizales9a065d22015-04-27 00:05:01 -070051void PrintProtoRpcDeclarationAsPragma(Printer *printer,
52 const MethodDescriptor *method,
53 map<string, string> vars) {
54 vars["client_stream"] = method->client_streaming() ? "stream " : "";
55 vars["server_stream"] = method->server_streaming() ? "stream " : "";
56
57 printer->Print(vars,
58 "#pragma mark $method_name$($client_stream$$request_type$)"
59 " returns ($server_stream$$response_type$)\n\n");
60}
61
62void PrintMethodSignature(Printer *printer,
63 const MethodDescriptor *method,
64 const map<string, string>& vars) {
65 // TODO(jcanizales): Print method comments.
66
67 printer->Print(vars, "- ($return_type$)$method_name$With");
68 if (method->client_streaming()) {
69 printer->Print("RequestsWriter:(id<GRXWriter>)request");
murgatroid99d3efd0a2015-04-07 11:40:29 -070070 } else {
Jorge Canizales9a065d22015-04-27 00:05:01 -070071 printer->Print(vars, "Request:($prefix$$request_type$ *)request");
murgatroid99d3efd0a2015-04-07 11:40:29 -070072 }
Jorge Canizales9a065d22015-04-27 00:05:01 -070073
74 // TODO(jcanizales): Put this on a new line and align colons.
75 printer->Print(" handler:(void(^)(");
76 if (method->server_streaming()) {
77 printer->Print("BOOL done, ");
78 }
79 printer->Print(vars,
80 "$prefix$$response_type$ *response, NSError *error))handler");
murgatroid99d3efd0a2015-04-07 11:40:29 -070081}
82
Jorge Canizales9a065d22015-04-27 00:05:01 -070083void PrintSimpleSignature(Printer *printer,
84 const MethodDescriptor *method,
85 map<string, string> vars) {
86 vars["method_name"] =
87 grpc_generator::LowercaseFirstLetter(vars["method_name"]);
88 vars["return_type"] = "void";
89 PrintMethodSignature(printer, method, vars);
murgatroid99d3efd0a2015-04-07 11:40:29 -070090}
91
Jorge Canizales9a065d22015-04-27 00:05:01 -070092void PrintAdvancedSignature(Printer *printer,
93 const MethodDescriptor *method,
94 map<string, string> vars) {
95 vars["method_name"] = "RPCTo" + vars["method_name"];
96 vars["return_type"] = "ProtoRPC *";
97 PrintMethodSignature(printer, method, vars);
murgatroid99d3efd0a2015-04-07 11:40:29 -070098}
99
Jorge Canizales9a065d22015-04-27 00:05:01 -0700100void PrintMethodDeclarations(Printer *printer,
101 const MethodDescriptor *method,
102 map<string, string> vars) {
103 vars["method_name"] = method->name();
104 vars["request_type"] = method->input_type()->name();
105 vars["response_type"] = method->output_type()->name();
murgatroid99ac0002a2015-04-07 12:49:14 -0700106
Jorge Canizales9a065d22015-04-27 00:05:01 -0700107 PrintProtoRpcDeclarationAsPragma(printer, method, vars);
108
109 PrintSimpleSignature(printer, method, vars);
110 printer->Print(";\n\n");
111 PrintAdvancedSignature(printer, method, vars);
112 printer->Print(";\n\n\n");
113}
114
115void PrintSourceMethodSimpleBlock(Printer *printer,
116 const MethodDescriptor *method,
117 map<string, string> vars) {
118 vars["method_name"] = method->name();
119 vars["request_type"] = method->input_type()->name();
120 vars["response_type"] = method->output_type()->name();
121
122 PrintSimpleSignature(printer, method, vars);
123
murgatroid99ac0002a2015-04-07 12:49:14 -0700124 printer->Print(" {\n");
125 printer->Indent();
Jorge Canizales9a065d22015-04-27 00:05:01 -0700126 printer->Print(vars, "return [[self $method_name$WithRequest:request] "
murgatroid99ac0002a2015-04-07 12:49:14 -0700127 "connectHandler:^(id value, NSError *error) {\n");
128 printer->Indent();
129 printer->Print("handler(value, error);\n");
130 printer->Outdent();
131 printer->Print("}];\n");
132 printer->Outdent();
133 printer->Print("}\n");
134}
135
Jorge Canizales9a065d22015-04-27 00:05:01 -0700136void PrintSourceMethodAdvanced(Printer *printer,
137 const MethodDescriptor *method,
138 map<string, string> vars) {
139 vars["method_name"] = method->name();
140 vars["request_type"] = method->input_type()->name();
141 vars["response_type"] = method->output_type()->name();
murgatroid99ac0002a2015-04-07 12:49:14 -0700142
murgatroid99ac0002a2015-04-07 12:49:14 -0700143 PrintAdvancedSignature(printer, method, vars);
144
murgatroid99ac0002a2015-04-07 12:49:14 -0700145 printer->Print(" {\n");
146 printer->Indent();
Jorge Canizales9a065d22015-04-27 00:05:01 -0700147 printer->Print(vars, "return [self $method_name$WithRequest:request "
murgatroid99ac0002a2015-04-07 12:49:14 -0700148 "client:[self newClient]];\n");
149 printer->Outdent();
150 printer->Print("}\n");
151}
152
Jorge Canizales9a065d22015-04-27 00:05:01 -0700153void PrintSourceMethodHandler(Printer *printer,
154 const MethodDescriptor *method,
murgatroid99ac0002a2015-04-07 12:49:14 -0700155 std::map<grpc::string, grpc::string> *vars) {
156 (*vars)["method_name"] = method->name();
157 (*vars)["response_type"] = PrefixedName(method->output_type()->name());
158 (*vars)["caps_name"] = grpc_generator::CapitalizeFirstLetter(method->name());
159
160 printer->Print(*vars, "- (GRXSource *)$method_name$WithRequest:"
161 "(id<GRXSource>)request client:(PBgRPCClient *)client {\n");
162 printer->Indent();
163 printer->Print(*vars,
164 "return [self responseWithMethod:$@\"$caps_name\"\n");
165 printer->Print(*vars,
166 " class:[$response_type$ class]\n");
167 printer->Print(" request:request\n");
168 printer->Print(" client:client];\n");
169 printer->Outdent();
170 printer->Print("}\n");
171}
172
173}
174
175grpc::string GetHeader(const grpc::protobuf::ServiceDescriptor *service,
Jorge Canizales9a065d22015-04-27 00:05:01 -0700176 const string prefix) {
murgatroid99d3efd0a2015-04-07 11:40:29 -0700177 grpc::string output;
178 grpc::protobuf::io::StringOutputStream output_stream(&output);
Jorge Canizales9a065d22015-04-27 00:05:01 -0700179 Printer printer(&output_stream, '$');
180
181 printer.Print("@protocol GRXWriteable;\n");
182 printer.Print("@protocol GRXWriter;\n\n");
183
184 map<string, string> vars = {{"service_name", service->name()},
185 {"prefix", prefix}};
186 printer.Print(vars, "@protocol $prefix$$service_name$ <NSObject>\n\n");
187
murgatroid99d3efd0a2015-04-07 11:40:29 -0700188 for (int i = 0; i < service->method_count(); i++) {
Jorge Canizales9a065d22015-04-27 00:05:01 -0700189 PrintMethodDeclarations(&printer, service->method(i), vars);
murgatroid99d3efd0a2015-04-07 11:40:29 -0700190 }
murgatroid99d3efd0a2015-04-07 11:40:29 -0700191 printer.Print("@end\n\n");
Jorge Canizales9a065d22015-04-27 00:05:01 -0700192
193 printer.Print("// Basic service implementation, over gRPC, that only does"
194 " marshalling and parsing.\n");
195 // use prefix
196 printer.Print(vars, "@interface RMT$service_name$ :"
197 " ProtoService<RMT$service_name$>\n");
198 printer.Print("- (instancetype)initWithHost:(NSString *)host"
199 " NS_DESIGNATED_INITIALIZER;\n");
murgatroid99d3efd0a2015-04-07 11:40:29 -0700200 printer.Print("@end\n");
201 return output;
202}
203
Jorge Canizales9a065d22015-04-27 00:05:01 -0700204grpc::string GetSource(const grpc::protobuf::ServiceDescriptor *service,
205 const string prefix) {
murgatroid99d3efd0a2015-04-07 11:40:29 -0700206 grpc::string output;
207 grpc::protobuf::io::StringOutputStream output_stream(&output);
Jorge Canizales9a065d22015-04-27 00:05:01 -0700208 Printer printer(&output_stream, '$');
209
210 map<string, string> vars = {{"service_name", service->name()},
211 {"prefix", prefix}};
murgatroid99ac0002a2015-04-07 12:49:14 -0700212 printer.Print(vars, "#import \"$service_name$Stub.pb.h\"\n");
murgatroid99d3efd0a2015-04-07 11:40:29 -0700213 printer.Print("#import \"PBGeneratedMessage+GRXSource.h\"\n\n");
214 vars["full_name"] = service->full_name();
murgatroid99ac0002a2015-04-07 12:49:14 -0700215 printer.Print(vars,
murgatroid99d3efd0a2015-04-07 11:40:29 -0700216 "static NSString *const kInterface = @\"$full_name$\";\n");
217 printer.Print("@implementation $service_name$Stub\n\n");
218 printer.Print("- (instancetype)initWithHost:(NSString *)host {\n");
219 printer.Indent();
220 printer.Print("if ((self = [super initWithHost:host "
221 "interface:kInterface])) {\n");
222 printer.Print("}\n");
223 printer.Print("return self;\n");
224 printer.Outdent();
225 printer.Print("}\n\n");
226 printer.Print("#pragma mark Simple block handlers.\n");
227 for (int i = 0; i < service->method_count(); i++) {
Jorge Canizales9a065d22015-04-27 00:05:01 -0700228 PrintSourceMethodSimpleBlock(&printer, service->method(i), vars);
murgatroid99d3efd0a2015-04-07 11:40:29 -0700229 }
230 printer.Print("\n");
231 printer.Print("#pragma mark Advanced handlers.\n");
232 for (int i = 0; i < service->method_count(); i++) {
Jorge Canizales9a065d22015-04-27 00:05:01 -0700233 PrintSourceMethodAdvanced(&printer, service->method(i), vars);
murgatroid99d3efd0a2015-04-07 11:40:29 -0700234 }
235 printer.Print("\n");
236 printer.Print("#pragma mark Handlers for subclasses "
237 "(stub wrappers) to override.\n");
238 for (int i = 0; i < service->method_count(); i++) {
239 PrintSourceMethodHandler(&printer, service->method(i), &vars);
240 }
241 printer.Print("@end\n");
242 return output;
243}
244
245} // namespace grpc_objective_c_generator