1*cc02d7e2SAndroid Build Coastguard Worker /*
2*cc02d7e2SAndroid Build Coastguard Worker *
3*cc02d7e2SAndroid Build Coastguard Worker * Copyright 2015 gRPC authors.
4*cc02d7e2SAndroid Build Coastguard Worker *
5*cc02d7e2SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
6*cc02d7e2SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
7*cc02d7e2SAndroid Build Coastguard Worker * You may obtain a copy of the License at
8*cc02d7e2SAndroid Build Coastguard Worker *
9*cc02d7e2SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
10*cc02d7e2SAndroid Build Coastguard Worker *
11*cc02d7e2SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
12*cc02d7e2SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
13*cc02d7e2SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*cc02d7e2SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
15*cc02d7e2SAndroid Build Coastguard Worker * limitations under the License.
16*cc02d7e2SAndroid Build Coastguard Worker *
17*cc02d7e2SAndroid Build Coastguard Worker */
18*cc02d7e2SAndroid Build Coastguard Worker
19*cc02d7e2SAndroid Build Coastguard Worker // Generates Objective C gRPC service interface out of Protobuf IDL.
20*cc02d7e2SAndroid Build Coastguard Worker
21*cc02d7e2SAndroid Build Coastguard Worker #include <memory>
22*cc02d7e2SAndroid Build Coastguard Worker
23*cc02d7e2SAndroid Build Coastguard Worker #include <google/protobuf/compiler/objectivec/names.h>
24*cc02d7e2SAndroid Build Coastguard Worker
25*cc02d7e2SAndroid Build Coastguard Worker #include "src/compiler/config.h"
26*cc02d7e2SAndroid Build Coastguard Worker #include "src/compiler/objective_c_generator.h"
27*cc02d7e2SAndroid Build Coastguard Worker #include "src/compiler/objective_c_generator_helpers.h"
28*cc02d7e2SAndroid Build Coastguard Worker
29*cc02d7e2SAndroid Build Coastguard Worker using ::google::protobuf::compiler::objectivec::
30*cc02d7e2SAndroid Build Coastguard Worker IsProtobufLibraryBundledProtoFile;
31*cc02d7e2SAndroid Build Coastguard Worker using ::google::protobuf::compiler::objectivec::ProtobufLibraryFrameworkName;
32*cc02d7e2SAndroid Build Coastguard Worker #ifdef SUPPORT_OBJC_PREFIX_VALIDATION
33*cc02d7e2SAndroid Build Coastguard Worker using ::google::protobuf::compiler::objectivec::ValidateObjCClassPrefixes;
34*cc02d7e2SAndroid Build Coastguard Worker #endif
35*cc02d7e2SAndroid Build Coastguard Worker using ::grpc_objective_c_generator::FrameworkImport;
36*cc02d7e2SAndroid Build Coastguard Worker using ::grpc_objective_c_generator::LocalImport;
37*cc02d7e2SAndroid Build Coastguard Worker using ::grpc_objective_c_generator::PreprocIfElse;
38*cc02d7e2SAndroid Build Coastguard Worker using ::grpc_objective_c_generator::PreprocIfNot;
39*cc02d7e2SAndroid Build Coastguard Worker using ::grpc_objective_c_generator::SystemImport;
40*cc02d7e2SAndroid Build Coastguard Worker
41*cc02d7e2SAndroid Build Coastguard Worker namespace {
42*cc02d7e2SAndroid Build Coastguard Worker
ImportProtoHeaders(const grpc::protobuf::FileDescriptor * dep,const char * indent,const::std::string & framework,const::std::string & pb_runtime_import_prefix)43*cc02d7e2SAndroid Build Coastguard Worker inline ::std::string ImportProtoHeaders(
44*cc02d7e2SAndroid Build Coastguard Worker const grpc::protobuf::FileDescriptor* dep, const char* indent,
45*cc02d7e2SAndroid Build Coastguard Worker const ::std::string& framework,
46*cc02d7e2SAndroid Build Coastguard Worker const ::std::string& pb_runtime_import_prefix) {
47*cc02d7e2SAndroid Build Coastguard Worker ::std::string header = grpc_objective_c_generator::MessageHeaderName(dep);
48*cc02d7e2SAndroid Build Coastguard Worker
49*cc02d7e2SAndroid Build Coastguard Worker if (!IsProtobufLibraryBundledProtoFile(dep)) {
50*cc02d7e2SAndroid Build Coastguard Worker if (framework.empty()) {
51*cc02d7e2SAndroid Build Coastguard Worker return indent + LocalImport(header);
52*cc02d7e2SAndroid Build Coastguard Worker } else {
53*cc02d7e2SAndroid Build Coastguard Worker return indent + FrameworkImport(header, framework);
54*cc02d7e2SAndroid Build Coastguard Worker }
55*cc02d7e2SAndroid Build Coastguard Worker }
56*cc02d7e2SAndroid Build Coastguard Worker
57*cc02d7e2SAndroid Build Coastguard Worker ::std::string base_name = header;
58*cc02d7e2SAndroid Build Coastguard Worker grpc_generator::StripPrefix(&base_name, "google/protobuf/");
59*cc02d7e2SAndroid Build Coastguard Worker ::std::string file_name = "GPB" + base_name;
60*cc02d7e2SAndroid Build Coastguard Worker // create the import code snippet
61*cc02d7e2SAndroid Build Coastguard Worker ::std::string framework_header =
62*cc02d7e2SAndroid Build Coastguard Worker ::std::string(ProtobufLibraryFrameworkName) + "/" + file_name;
63*cc02d7e2SAndroid Build Coastguard Worker ::std::string local_header = file_name;
64*cc02d7e2SAndroid Build Coastguard Worker if (!pb_runtime_import_prefix.empty()) {
65*cc02d7e2SAndroid Build Coastguard Worker local_header = pb_runtime_import_prefix + "/" + file_name;
66*cc02d7e2SAndroid Build Coastguard Worker }
67*cc02d7e2SAndroid Build Coastguard Worker
68*cc02d7e2SAndroid Build Coastguard Worker static const ::std::string kFrameworkImportsCondition =
69*cc02d7e2SAndroid Build Coastguard Worker "GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS";
70*cc02d7e2SAndroid Build Coastguard Worker return PreprocIfElse(kFrameworkImportsCondition,
71*cc02d7e2SAndroid Build Coastguard Worker indent + SystemImport(framework_header),
72*cc02d7e2SAndroid Build Coastguard Worker indent + LocalImport(local_header));
73*cc02d7e2SAndroid Build Coastguard Worker }
74*cc02d7e2SAndroid Build Coastguard Worker
75*cc02d7e2SAndroid Build Coastguard Worker } // namespace
76*cc02d7e2SAndroid Build Coastguard Worker
77*cc02d7e2SAndroid Build Coastguard Worker class ObjectiveCGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator {
78*cc02d7e2SAndroid Build Coastguard Worker public:
ObjectiveCGrpcGenerator()79*cc02d7e2SAndroid Build Coastguard Worker ObjectiveCGrpcGenerator() {}
~ObjectiveCGrpcGenerator()80*cc02d7e2SAndroid Build Coastguard Worker virtual ~ObjectiveCGrpcGenerator() {}
81*cc02d7e2SAndroid Build Coastguard Worker
82*cc02d7e2SAndroid Build Coastguard Worker public:
GetSupportedFeatures() const83*cc02d7e2SAndroid Build Coastguard Worker uint64_t GetSupportedFeatures() const override {
84*cc02d7e2SAndroid Build Coastguard Worker return FEATURE_PROTO3_OPTIONAL
85*cc02d7e2SAndroid Build Coastguard Worker #ifdef GRPC_PROTOBUF_EDITION_SUPPORT
86*cc02d7e2SAndroid Build Coastguard Worker | FEATURE_SUPPORTS_EDITIONS
87*cc02d7e2SAndroid Build Coastguard Worker #endif
88*cc02d7e2SAndroid Build Coastguard Worker ;
89*cc02d7e2SAndroid Build Coastguard Worker }
90*cc02d7e2SAndroid Build Coastguard Worker
91*cc02d7e2SAndroid Build Coastguard Worker #ifdef GRPC_PROTOBUF_EDITION_SUPPORT
GetMinimumEdition() const92*cc02d7e2SAndroid Build Coastguard Worker grpc::protobuf::Edition GetMinimumEdition() const override {
93*cc02d7e2SAndroid Build Coastguard Worker return grpc::protobuf::Edition::EDITION_PROTO2;
94*cc02d7e2SAndroid Build Coastguard Worker }
GetMaximumEdition() const95*cc02d7e2SAndroid Build Coastguard Worker grpc::protobuf::Edition GetMaximumEdition() const override {
96*cc02d7e2SAndroid Build Coastguard Worker return grpc::protobuf::Edition::EDITION_2023;
97*cc02d7e2SAndroid Build Coastguard Worker }
98*cc02d7e2SAndroid Build Coastguard Worker #endif
99*cc02d7e2SAndroid Build Coastguard Worker
Generate(const grpc::protobuf::FileDescriptor * file,const::std::string & parameter,grpc::protobuf::compiler::GeneratorContext * context,::std::string * error) const100*cc02d7e2SAndroid Build Coastguard Worker virtual bool Generate(const grpc::protobuf::FileDescriptor* file,
101*cc02d7e2SAndroid Build Coastguard Worker const ::std::string& parameter,
102*cc02d7e2SAndroid Build Coastguard Worker grpc::protobuf::compiler::GeneratorContext* context,
103*cc02d7e2SAndroid Build Coastguard Worker ::std::string* error) const override {
104*cc02d7e2SAndroid Build Coastguard Worker if (file->service_count() == 0) {
105*cc02d7e2SAndroid Build Coastguard Worker // No services. Do nothing.
106*cc02d7e2SAndroid Build Coastguard Worker return true;
107*cc02d7e2SAndroid Build Coastguard Worker }
108*cc02d7e2SAndroid Build Coastguard Worker
109*cc02d7e2SAndroid Build Coastguard Worker #ifdef SUPPORT_OBJC_PREFIX_VALIDATION
110*cc02d7e2SAndroid Build Coastguard Worker // Default options will use env variables for controls.
111*cc02d7e2SAndroid Build Coastguard Worker if (!ValidateObjCClassPrefixes({file}, {}, error)) {
112*cc02d7e2SAndroid Build Coastguard Worker return false;
113*cc02d7e2SAndroid Build Coastguard Worker }
114*cc02d7e2SAndroid Build Coastguard Worker #endif
115*cc02d7e2SAndroid Build Coastguard Worker
116*cc02d7e2SAndroid Build Coastguard Worker bool grpc_local_import = false;
117*cc02d7e2SAndroid Build Coastguard Worker ::std::string framework;
118*cc02d7e2SAndroid Build Coastguard Worker ::std::string pb_runtime_import_prefix;
119*cc02d7e2SAndroid Build Coastguard Worker ::std::string grpc_local_import_prefix;
120*cc02d7e2SAndroid Build Coastguard Worker std::vector<::std::string> params_list =
121*cc02d7e2SAndroid Build Coastguard Worker grpc_generator::tokenize(parameter, ",");
122*cc02d7e2SAndroid Build Coastguard Worker for (auto param_str = params_list.begin(); param_str != params_list.end();
123*cc02d7e2SAndroid Build Coastguard Worker ++param_str) {
124*cc02d7e2SAndroid Build Coastguard Worker std::vector<::std::string> param =
125*cc02d7e2SAndroid Build Coastguard Worker grpc_generator::tokenize(*param_str, "=");
126*cc02d7e2SAndroid Build Coastguard Worker if (param[0] == "generate_for_named_framework") {
127*cc02d7e2SAndroid Build Coastguard Worker if (param.size() != 2) {
128*cc02d7e2SAndroid Build Coastguard Worker *error =
129*cc02d7e2SAndroid Build Coastguard Worker std::string("Format: generate_for_named_framework=<Framework>");
130*cc02d7e2SAndroid Build Coastguard Worker return false;
131*cc02d7e2SAndroid Build Coastguard Worker } else if (param[1].empty()) {
132*cc02d7e2SAndroid Build Coastguard Worker *error =
133*cc02d7e2SAndroid Build Coastguard Worker std::string("Name of framework cannot be empty for parameter: ") +
134*cc02d7e2SAndroid Build Coastguard Worker param[0];
135*cc02d7e2SAndroid Build Coastguard Worker return false;
136*cc02d7e2SAndroid Build Coastguard Worker }
137*cc02d7e2SAndroid Build Coastguard Worker framework = param[1];
138*cc02d7e2SAndroid Build Coastguard Worker } else if (param[0] == "runtime_import_prefix") {
139*cc02d7e2SAndroid Build Coastguard Worker if (param.size() != 2) {
140*cc02d7e2SAndroid Build Coastguard Worker *error = grpc::string("Format: runtime_import_prefix=dir/");
141*cc02d7e2SAndroid Build Coastguard Worker return false;
142*cc02d7e2SAndroid Build Coastguard Worker }
143*cc02d7e2SAndroid Build Coastguard Worker pb_runtime_import_prefix = param[1];
144*cc02d7e2SAndroid Build Coastguard Worker grpc_generator::StripSuffix(&pb_runtime_import_prefix, "/");
145*cc02d7e2SAndroid Build Coastguard Worker } else if (param[0] == "grpc_local_import_prefix") {
146*cc02d7e2SAndroid Build Coastguard Worker grpc_local_import = true;
147*cc02d7e2SAndroid Build Coastguard Worker if (param.size() != 2) {
148*cc02d7e2SAndroid Build Coastguard Worker *error = grpc::string("Format: grpc_local_import_prefix=dir/");
149*cc02d7e2SAndroid Build Coastguard Worker return false;
150*cc02d7e2SAndroid Build Coastguard Worker }
151*cc02d7e2SAndroid Build Coastguard Worker grpc_local_import_prefix = param[1];
152*cc02d7e2SAndroid Build Coastguard Worker }
153*cc02d7e2SAndroid Build Coastguard Worker }
154*cc02d7e2SAndroid Build Coastguard Worker
155*cc02d7e2SAndroid Build Coastguard Worker static const ::std::string kNonNullBegin = "NS_ASSUME_NONNULL_BEGIN\n";
156*cc02d7e2SAndroid Build Coastguard Worker static const ::std::string kNonNullEnd = "NS_ASSUME_NONNULL_END\n";
157*cc02d7e2SAndroid Build Coastguard Worker static const ::std::string kProtocolOnly = "GPB_GRPC_PROTOCOL_ONLY";
158*cc02d7e2SAndroid Build Coastguard Worker static const ::std::string kForwardDeclare =
159*cc02d7e2SAndroid Build Coastguard Worker "GPB_GRPC_FORWARD_DECLARE_MESSAGE_PROTO";
160*cc02d7e2SAndroid Build Coastguard Worker
161*cc02d7e2SAndroid Build Coastguard Worker ::std::string file_name =
162*cc02d7e2SAndroid Build Coastguard Worker google::protobuf::compiler::objectivec::FilePath(file);
163*cc02d7e2SAndroid Build Coastguard Worker
164*cc02d7e2SAndroid Build Coastguard Worker grpc_objective_c_generator::Parameters generator_params;
165*cc02d7e2SAndroid Build Coastguard Worker generator_params.no_v1_compatibility = false;
166*cc02d7e2SAndroid Build Coastguard Worker
167*cc02d7e2SAndroid Build Coastguard Worker if (!parameter.empty()) {
168*cc02d7e2SAndroid Build Coastguard Worker std::vector<std::string> parameters_list =
169*cc02d7e2SAndroid Build Coastguard Worker grpc_generator::tokenize(parameter, ",");
170*cc02d7e2SAndroid Build Coastguard Worker for (auto parameter_string = parameters_list.begin();
171*cc02d7e2SAndroid Build Coastguard Worker parameter_string != parameters_list.end(); parameter_string++) {
172*cc02d7e2SAndroid Build Coastguard Worker std::vector<std::string> param =
173*cc02d7e2SAndroid Build Coastguard Worker grpc_generator::tokenize(*parameter_string, "=");
174*cc02d7e2SAndroid Build Coastguard Worker if (param[0] == "no_v1_compatibility") {
175*cc02d7e2SAndroid Build Coastguard Worker generator_params.no_v1_compatibility = true;
176*cc02d7e2SAndroid Build Coastguard Worker }
177*cc02d7e2SAndroid Build Coastguard Worker }
178*cc02d7e2SAndroid Build Coastguard Worker }
179*cc02d7e2SAndroid Build Coastguard Worker
180*cc02d7e2SAndroid Build Coastguard Worker // Write out a file header.
181*cc02d7e2SAndroid Build Coastguard Worker ::std::string file_header =
182*cc02d7e2SAndroid Build Coastguard Worker "// Code generated by gRPC proto compiler. DO NOT EDIT!\n"
183*cc02d7e2SAndroid Build Coastguard Worker "// source: " +
184*cc02d7e2SAndroid Build Coastguard Worker file->name() + "\n\n";
185*cc02d7e2SAndroid Build Coastguard Worker
186*cc02d7e2SAndroid Build Coastguard Worker {
187*cc02d7e2SAndroid Build Coastguard Worker // Generate .pbrpc.h
188*cc02d7e2SAndroid Build Coastguard Worker
189*cc02d7e2SAndroid Build Coastguard Worker ::std::string imports;
190*cc02d7e2SAndroid Build Coastguard Worker if (framework.empty()) {
191*cc02d7e2SAndroid Build Coastguard Worker imports = LocalImport(file_name + ".pbobjc.h");
192*cc02d7e2SAndroid Build Coastguard Worker } else {
193*cc02d7e2SAndroid Build Coastguard Worker imports = FrameworkImport(file_name + ".pbobjc.h", framework);
194*cc02d7e2SAndroid Build Coastguard Worker }
195*cc02d7e2SAndroid Build Coastguard Worker
196*cc02d7e2SAndroid Build Coastguard Worker ::std::string system_imports;
197*cc02d7e2SAndroid Build Coastguard Worker if (grpc_local_import) {
198*cc02d7e2SAndroid Build Coastguard Worker system_imports =
199*cc02d7e2SAndroid Build Coastguard Worker LocalImport(grpc_local_import_prefix + "ProtoRPC/ProtoService.h");
200*cc02d7e2SAndroid Build Coastguard Worker if (generator_params.no_v1_compatibility) {
201*cc02d7e2SAndroid Build Coastguard Worker system_imports +=
202*cc02d7e2SAndroid Build Coastguard Worker LocalImport(grpc_local_import_prefix + "ProtoRPC/ProtoRPC.h");
203*cc02d7e2SAndroid Build Coastguard Worker } else {
204*cc02d7e2SAndroid Build Coastguard Worker system_imports += LocalImport(grpc_local_import_prefix +
205*cc02d7e2SAndroid Build Coastguard Worker "ProtoRPC/ProtoRPCLegacy.h");
206*cc02d7e2SAndroid Build Coastguard Worker system_imports += LocalImport(grpc_local_import_prefix +
207*cc02d7e2SAndroid Build Coastguard Worker "RxLibrary/GRXWriteable.h");
208*cc02d7e2SAndroid Build Coastguard Worker system_imports +=
209*cc02d7e2SAndroid Build Coastguard Worker LocalImport(grpc_local_import_prefix + "RxLibrary/GRXWriter.h");
210*cc02d7e2SAndroid Build Coastguard Worker }
211*cc02d7e2SAndroid Build Coastguard Worker } else {
212*cc02d7e2SAndroid Build Coastguard Worker system_imports = SystemImport("ProtoRPC/ProtoService.h");
213*cc02d7e2SAndroid Build Coastguard Worker if (generator_params.no_v1_compatibility) {
214*cc02d7e2SAndroid Build Coastguard Worker system_imports += SystemImport("ProtoRPC/ProtoRPC.h");
215*cc02d7e2SAndroid Build Coastguard Worker } else {
216*cc02d7e2SAndroid Build Coastguard Worker system_imports += SystemImport("ProtoRPC/ProtoRPCLegacy.h");
217*cc02d7e2SAndroid Build Coastguard Worker system_imports += SystemImport("RxLibrary/GRXWriteable.h");
218*cc02d7e2SAndroid Build Coastguard Worker system_imports += SystemImport("RxLibrary/GRXWriter.h");
219*cc02d7e2SAndroid Build Coastguard Worker }
220*cc02d7e2SAndroid Build Coastguard Worker }
221*cc02d7e2SAndroid Build Coastguard Worker
222*cc02d7e2SAndroid Build Coastguard Worker ::std::string forward_declarations =
223*cc02d7e2SAndroid Build Coastguard Worker "@class GRPCUnaryProtoCall;\n"
224*cc02d7e2SAndroid Build Coastguard Worker "@class GRPCStreamingProtoCall;\n"
225*cc02d7e2SAndroid Build Coastguard Worker "@class GRPCCallOptions;\n"
226*cc02d7e2SAndroid Build Coastguard Worker "@protocol GRPCProtoResponseHandler;\n";
227*cc02d7e2SAndroid Build Coastguard Worker if (!generator_params.no_v1_compatibility) {
228*cc02d7e2SAndroid Build Coastguard Worker forward_declarations += "@class GRPCProtoCall;\n";
229*cc02d7e2SAndroid Build Coastguard Worker }
230*cc02d7e2SAndroid Build Coastguard Worker forward_declarations += "\n";
231*cc02d7e2SAndroid Build Coastguard Worker
232*cc02d7e2SAndroid Build Coastguard Worker ::std::string class_declarations =
233*cc02d7e2SAndroid Build Coastguard Worker grpc_objective_c_generator::GetAllMessageClasses(file);
234*cc02d7e2SAndroid Build Coastguard Worker
235*cc02d7e2SAndroid Build Coastguard Worker ::std::string class_imports;
236*cc02d7e2SAndroid Build Coastguard Worker for (int i = 0; i < file->dependency_count(); i++) {
237*cc02d7e2SAndroid Build Coastguard Worker class_imports += ImportProtoHeaders(
238*cc02d7e2SAndroid Build Coastguard Worker file->dependency(i), " ", framework, pb_runtime_import_prefix);
239*cc02d7e2SAndroid Build Coastguard Worker }
240*cc02d7e2SAndroid Build Coastguard Worker
241*cc02d7e2SAndroid Build Coastguard Worker ::std::string ng_protocols;
242*cc02d7e2SAndroid Build Coastguard Worker for (int i = 0; i < file->service_count(); i++) {
243*cc02d7e2SAndroid Build Coastguard Worker const grpc::protobuf::ServiceDescriptor* service = file->service(i);
244*cc02d7e2SAndroid Build Coastguard Worker ng_protocols += grpc_objective_c_generator::GetV2Protocol(service);
245*cc02d7e2SAndroid Build Coastguard Worker }
246*cc02d7e2SAndroid Build Coastguard Worker
247*cc02d7e2SAndroid Build Coastguard Worker ::std::string protocols;
248*cc02d7e2SAndroid Build Coastguard Worker for (int i = 0; i < file->service_count(); i++) {
249*cc02d7e2SAndroid Build Coastguard Worker const grpc::protobuf::ServiceDescriptor* service = file->service(i);
250*cc02d7e2SAndroid Build Coastguard Worker protocols +=
251*cc02d7e2SAndroid Build Coastguard Worker grpc_objective_c_generator::GetProtocol(service, generator_params);
252*cc02d7e2SAndroid Build Coastguard Worker }
253*cc02d7e2SAndroid Build Coastguard Worker
254*cc02d7e2SAndroid Build Coastguard Worker ::std::string interfaces;
255*cc02d7e2SAndroid Build Coastguard Worker for (int i = 0; i < file->service_count(); i++) {
256*cc02d7e2SAndroid Build Coastguard Worker const grpc::protobuf::ServiceDescriptor* service = file->service(i);
257*cc02d7e2SAndroid Build Coastguard Worker interfaces +=
258*cc02d7e2SAndroid Build Coastguard Worker grpc_objective_c_generator::GetInterface(service, generator_params);
259*cc02d7e2SAndroid Build Coastguard Worker }
260*cc02d7e2SAndroid Build Coastguard Worker
261*cc02d7e2SAndroid Build Coastguard Worker Write(context, file_name + ".pbrpc.h",
262*cc02d7e2SAndroid Build Coastguard Worker file_header + SystemImport("Foundation/Foundation.h") + "\n" +
263*cc02d7e2SAndroid Build Coastguard Worker PreprocIfNot(kForwardDeclare, imports) + "\n" +
264*cc02d7e2SAndroid Build Coastguard Worker PreprocIfNot(kProtocolOnly, system_imports) + "\n" +
265*cc02d7e2SAndroid Build Coastguard Worker class_declarations + "\n" +
266*cc02d7e2SAndroid Build Coastguard Worker PreprocIfNot(kForwardDeclare, class_imports) + "\n" +
267*cc02d7e2SAndroid Build Coastguard Worker forward_declarations + "\n" + kNonNullBegin + "\n" +
268*cc02d7e2SAndroid Build Coastguard Worker ng_protocols + protocols + "\n" +
269*cc02d7e2SAndroid Build Coastguard Worker PreprocIfNot(kProtocolOnly, interfaces) + "\n" + kNonNullEnd +
270*cc02d7e2SAndroid Build Coastguard Worker "\n");
271*cc02d7e2SAndroid Build Coastguard Worker }
272*cc02d7e2SAndroid Build Coastguard Worker
273*cc02d7e2SAndroid Build Coastguard Worker {
274*cc02d7e2SAndroid Build Coastguard Worker // Generate .pbrpc.m
275*cc02d7e2SAndroid Build Coastguard Worker
276*cc02d7e2SAndroid Build Coastguard Worker ::std::string imports;
277*cc02d7e2SAndroid Build Coastguard Worker if (framework.empty()) {
278*cc02d7e2SAndroid Build Coastguard Worker imports = LocalImport(file_name + ".pbrpc.h") +
279*cc02d7e2SAndroid Build Coastguard Worker LocalImport(file_name + ".pbobjc.h");
280*cc02d7e2SAndroid Build Coastguard Worker } else {
281*cc02d7e2SAndroid Build Coastguard Worker imports = FrameworkImport(file_name + ".pbrpc.h", framework) +
282*cc02d7e2SAndroid Build Coastguard Worker FrameworkImport(file_name + ".pbobjc.h", framework);
283*cc02d7e2SAndroid Build Coastguard Worker }
284*cc02d7e2SAndroid Build Coastguard Worker
285*cc02d7e2SAndroid Build Coastguard Worker if (grpc_local_import) {
286*cc02d7e2SAndroid Build Coastguard Worker if (generator_params.no_v1_compatibility) {
287*cc02d7e2SAndroid Build Coastguard Worker imports +=
288*cc02d7e2SAndroid Build Coastguard Worker LocalImport(grpc_local_import_prefix + "ProtoRPC/ProtoRPC.h");
289*cc02d7e2SAndroid Build Coastguard Worker } else {
290*cc02d7e2SAndroid Build Coastguard Worker imports += LocalImport(grpc_local_import_prefix +
291*cc02d7e2SAndroid Build Coastguard Worker "ProtoRPC/ProtoRPCLegacy.h");
292*cc02d7e2SAndroid Build Coastguard Worker imports += LocalImport(grpc_local_import_prefix +
293*cc02d7e2SAndroid Build Coastguard Worker "RxLibrary/GRXWriter+Immediate.h");
294*cc02d7e2SAndroid Build Coastguard Worker }
295*cc02d7e2SAndroid Build Coastguard Worker } else {
296*cc02d7e2SAndroid Build Coastguard Worker if (generator_params.no_v1_compatibility) {
297*cc02d7e2SAndroid Build Coastguard Worker imports += SystemImport("ProtoRPC/ProtoRPC.h");
298*cc02d7e2SAndroid Build Coastguard Worker } else {
299*cc02d7e2SAndroid Build Coastguard Worker imports += SystemImport("ProtoRPC/ProtoRPCLegacy.h");
300*cc02d7e2SAndroid Build Coastguard Worker imports += SystemImport("RxLibrary/GRXWriter+Immediate.h");
301*cc02d7e2SAndroid Build Coastguard Worker }
302*cc02d7e2SAndroid Build Coastguard Worker }
303*cc02d7e2SAndroid Build Coastguard Worker
304*cc02d7e2SAndroid Build Coastguard Worker ::std::string class_imports;
305*cc02d7e2SAndroid Build Coastguard Worker for (int i = 0; i < file->dependency_count(); i++) {
306*cc02d7e2SAndroid Build Coastguard Worker class_imports += ImportProtoHeaders(file->dependency(i), "", framework,
307*cc02d7e2SAndroid Build Coastguard Worker pb_runtime_import_prefix);
308*cc02d7e2SAndroid Build Coastguard Worker }
309*cc02d7e2SAndroid Build Coastguard Worker
310*cc02d7e2SAndroid Build Coastguard Worker ::std::string definitions;
311*cc02d7e2SAndroid Build Coastguard Worker for (int i = 0; i < file->service_count(); i++) {
312*cc02d7e2SAndroid Build Coastguard Worker const grpc::protobuf::ServiceDescriptor* service = file->service(i);
313*cc02d7e2SAndroid Build Coastguard Worker definitions +=
314*cc02d7e2SAndroid Build Coastguard Worker grpc_objective_c_generator::GetSource(service, generator_params);
315*cc02d7e2SAndroid Build Coastguard Worker }
316*cc02d7e2SAndroid Build Coastguard Worker
317*cc02d7e2SAndroid Build Coastguard Worker Write(context, file_name + ".pbrpc.m",
318*cc02d7e2SAndroid Build Coastguard Worker file_header +
319*cc02d7e2SAndroid Build Coastguard Worker PreprocIfNot(kProtocolOnly, imports + "\n" + class_imports +
320*cc02d7e2SAndroid Build Coastguard Worker "\n" + definitions));
321*cc02d7e2SAndroid Build Coastguard Worker }
322*cc02d7e2SAndroid Build Coastguard Worker
323*cc02d7e2SAndroid Build Coastguard Worker return true;
324*cc02d7e2SAndroid Build Coastguard Worker }
325*cc02d7e2SAndroid Build Coastguard Worker
326*cc02d7e2SAndroid Build Coastguard Worker private:
327*cc02d7e2SAndroid Build Coastguard Worker // Write the given code into the given file.
Write(grpc::protobuf::compiler::GeneratorContext * context,const::std::string & filename,const::std::string & code) const328*cc02d7e2SAndroid Build Coastguard Worker void Write(grpc::protobuf::compiler::GeneratorContext* context,
329*cc02d7e2SAndroid Build Coastguard Worker const ::std::string& filename, const ::std::string& code) const {
330*cc02d7e2SAndroid Build Coastguard Worker std::unique_ptr<grpc::protobuf::io::ZeroCopyOutputStream> output(
331*cc02d7e2SAndroid Build Coastguard Worker context->Open(filename));
332*cc02d7e2SAndroid Build Coastguard Worker grpc::protobuf::io::CodedOutputStream coded_out(output.get());
333*cc02d7e2SAndroid Build Coastguard Worker coded_out.WriteRaw(code.data(), code.size());
334*cc02d7e2SAndroid Build Coastguard Worker }
335*cc02d7e2SAndroid Build Coastguard Worker };
336*cc02d7e2SAndroid Build Coastguard Worker
main(int argc,char * argv[])337*cc02d7e2SAndroid Build Coastguard Worker int main(int argc, char* argv[]) {
338*cc02d7e2SAndroid Build Coastguard Worker ObjectiveCGrpcGenerator generator;
339*cc02d7e2SAndroid Build Coastguard Worker return grpc::protobuf::compiler::PluginMain(argc, argv, &generator);
340*cc02d7e2SAndroid Build Coastguard Worker }
341