objective_c_plugin.cc 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. /*
  2. *
  3. * Copyright 2015 gRPC authors.
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. *
  17. */
  18. // Generates Objective C gRPC service interface out of Protobuf IDL.
  19. #include <memory>
  20. #include "src/compiler/config.h"
  21. #include "src/compiler/objective_c_generator.h"
  22. #include "src/compiler/objective_c_generator_helpers.h"
  23. #include <google/protobuf/compiler/objectivec/objectivec_helpers.h>
  24. using ::google::protobuf::compiler::objectivec::
  25. IsProtobufLibraryBundledProtoFile;
  26. using ::google::protobuf::compiler::objectivec::ProtobufLibraryFrameworkName;
  27. class ObjectiveCGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator {
  28. public:
  29. ObjectiveCGrpcGenerator() {}
  30. virtual ~ObjectiveCGrpcGenerator() {}
  31. virtual bool Generate(const grpc::protobuf::FileDescriptor* file,
  32. const ::grpc::string& parameter,
  33. grpc::protobuf::compiler::GeneratorContext* context,
  34. ::grpc::string* error) const {
  35. if (file->service_count() == 0) {
  36. // No services. Do nothing.
  37. return true;
  38. }
  39. ::grpc::string file_name =
  40. google::protobuf::compiler::objectivec::FilePath(file);
  41. ::grpc::string prefix = file->options().objc_class_prefix();
  42. {
  43. // Generate .pbrpc.h
  44. ::grpc::string imports = ::grpc::string("#import \"") + file_name +
  45. ".pbobjc.h\"\n\n"
  46. "#import <ProtoRPC/ProtoService.h>\n"
  47. "#import <ProtoRPC/ProtoRPC.h>\n"
  48. "#import <RxLibrary/GRXWriteable.h>\n"
  49. "#import <RxLibrary/GRXWriter.h>\n";
  50. ::grpc::string proto_imports;
  51. proto_imports += "#if GPB_GRPC_FORWARD_DECLARE_MESSAGE_PROTO\n" +
  52. grpc_objective_c_generator::GetAllMessageClasses(file) +
  53. "#else\n";
  54. for (int i = 0; i < file->dependency_count(); i++) {
  55. ::grpc::string header =
  56. grpc_objective_c_generator::MessageHeaderName(file->dependency(i));
  57. const grpc::protobuf::FileDescriptor* dependency = file->dependency(i);
  58. if (IsProtobufLibraryBundledProtoFile(dependency)) {
  59. ::grpc::string base_name = header;
  60. grpc_generator::StripPrefix(&base_name, "google/protobuf/");
  61. // create the import code snippet
  62. proto_imports +=
  63. " #if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS\n"
  64. " #import <" +
  65. ::grpc::string(ProtobufLibraryFrameworkName) + "/" + base_name +
  66. ">\n"
  67. " #else\n"
  68. " #import \"" +
  69. header +
  70. "\"\n"
  71. " #endif\n";
  72. } else {
  73. proto_imports += ::grpc::string(" #import \"") + header + "\"\n";
  74. }
  75. }
  76. proto_imports += "#endif\n";
  77. ::grpc::string declarations;
  78. for (int i = 0; i < file->service_count(); i++) {
  79. const grpc::protobuf::ServiceDescriptor* service = file->service(i);
  80. declarations += grpc_objective_c_generator::GetHeader(service);
  81. }
  82. static const ::grpc::string kNonNullBegin =
  83. "\nNS_ASSUME_NONNULL_BEGIN\n\n";
  84. static const ::grpc::string kNonNullEnd = "\nNS_ASSUME_NONNULL_END\n";
  85. Write(context, file_name + ".pbrpc.h",
  86. imports + '\n' + proto_imports + '\n' + kNonNullBegin +
  87. declarations + kNonNullEnd);
  88. }
  89. {
  90. // Generate .pbrpc.m
  91. ::grpc::string imports = ::grpc::string("#import \"") + file_name +
  92. ".pbrpc.h\"\n\n"
  93. "#import <ProtoRPC/ProtoRPC.h>\n"
  94. "#import <RxLibrary/GRXWriter+Immediate.h>\n";
  95. for (int i = 0; i < file->dependency_count(); i++) {
  96. ::grpc::string header =
  97. grpc_objective_c_generator::MessageHeaderName(file->dependency(i));
  98. const grpc::protobuf::FileDescriptor* dependency = file->dependency(i);
  99. if (IsProtobufLibraryBundledProtoFile(dependency)) {
  100. ::grpc::string base_name = header;
  101. grpc_generator::StripPrefix(&base_name, "google/protobuf/");
  102. // create the import code snippet
  103. imports +=
  104. "#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS\n"
  105. " #import <" +
  106. ::grpc::string(ProtobufLibraryFrameworkName) + "/" + base_name +
  107. ">\n"
  108. "#else\n"
  109. " #import \"" +
  110. header +
  111. "\"\n"
  112. "#endif\n";
  113. } else {
  114. imports += ::grpc::string("#import \"") + header + "\"\n";
  115. }
  116. }
  117. ::grpc::string definitions;
  118. for (int i = 0; i < file->service_count(); i++) {
  119. const grpc::protobuf::ServiceDescriptor* service = file->service(i);
  120. definitions += grpc_objective_c_generator::GetSource(service);
  121. }
  122. Write(context, file_name + ".pbrpc.m", imports + '\n' + definitions);
  123. }
  124. return true;
  125. }
  126. private:
  127. // Write the given code into the given file.
  128. void Write(grpc::protobuf::compiler::GeneratorContext* context,
  129. const ::grpc::string& filename, const ::grpc::string& code) const {
  130. std::unique_ptr<grpc::protobuf::io::ZeroCopyOutputStream> output(
  131. context->Open(filename));
  132. grpc::protobuf::io::CodedOutputStream coded_out(output.get());
  133. coded_out.WriteRaw(code.data(), code.size());
  134. }
  135. };
  136. int main(int argc, char* argv[]) {
  137. ObjectiveCGrpcGenerator generator;
  138. return grpc::protobuf::compiler::PluginMain(argc, argv, &generator);
  139. }