Merge pull request #12845 from ncteisen/fix-posix-build

Fix compilation on Mac
diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec
index 7ad6812..ca5301a 100644
--- a/gRPC-Core.podspec
+++ b/gRPC-Core.podspec
@@ -84,6 +84,7 @@
     # build.
     'USE_HEADERMAP' => 'NO',
     'ALWAYS_SEARCH_USER_PATHS' => 'NO',
+    'GCC_PREPROCESSOR_DEFINITIONS' => '"$(inherited)" "COCOAPODS=1" "PB_NO_PACKED_STRUCTS=1"',
   }
 
   s.default_subspecs = 'Interface', 'Implementation'
diff --git a/src/compiler/objective_c_generator.cc b/src/compiler/objective_c_generator.cc
index c05d153..33b5fed 100644
--- a/src/compiler/objective_c_generator.cc
+++ b/src/compiler/objective_c_generator.cc
@@ -17,6 +17,7 @@
  */
 
 #include <map>
+#include <set>
 #include <sstream>
 
 #include "src/compiler/config.h"
@@ -29,7 +30,9 @@
 using ::grpc::protobuf::io::Printer;
 using ::grpc::protobuf::MethodDescriptor;
 using ::grpc::protobuf::ServiceDescriptor;
+using ::grpc::protobuf::FileDescriptor;
 using ::std::map;
+using ::std::set;
 
 namespace grpc_objective_c_generator {
 namespace {
@@ -190,6 +193,24 @@
 
 }  // namespace
 
+::grpc::string GetAllMessageClasses(const FileDescriptor *file) {
+  ::grpc::string output;
+  set< ::grpc::string> classes;
+  for (int i = 0; i < file->service_count(); i++) {
+    const auto service = file->service(i);
+    for (int i = 0; i < service->method_count(); i++) {
+      const auto method = service->method(i);
+      classes.insert(ClassName(method->input_type()));
+      classes.insert(ClassName(method->output_type()));
+    }
+  }
+  for (auto one_class : classes) {
+    output += "  @class " + one_class + ";\n";
+  }
+
+  return output;
+}
+
 ::grpc::string GetHeader(const ServiceDescriptor *service) {
   ::grpc::string output;
   {
diff --git a/src/compiler/objective_c_generator.h b/src/compiler/objective_c_generator.h
index edbee7f..e912a52 100644
--- a/src/compiler/objective_c_generator.h
+++ b/src/compiler/objective_c_generator.h
@@ -24,8 +24,12 @@
 namespace grpc_objective_c_generator {
 
 using ::grpc::protobuf::ServiceDescriptor;
+using ::grpc::protobuf::FileDescriptor;
 using ::grpc::string;
 
+// Returns forward declaration of classes in the generated header file.
+string GetAllMessageClasses(const FileDescriptor *file);
+
 // Returns the content to be included in the "global_scope" insertion point of
 // the generated header file.
 string GetHeader(const ServiceDescriptor *service);
diff --git a/src/compiler/objective_c_plugin.cc b/src/compiler/objective_c_plugin.cc
index 96a3375..e751d05 100644
--- a/src/compiler/objective_c_plugin.cc
+++ b/src/compiler/objective_c_plugin.cc
@@ -58,9 +58,10 @@
                                "#import <RxLibrary/GRXWriteable.h>\n"
                                "#import <RxLibrary/GRXWriter.h>\n";
 
-      // TODO(jcanizales): Instead forward-declare the input and output types
-      // and import the files in the .pbrpc.m
       ::grpc::string proto_imports;
+      proto_imports += "#if GPB_GRPC_FORWARD_DECLARE_MESSAGE_PROTO\n" +
+                       grpc_objective_c_generator::GetAllMessageClasses(file) +
+                       "#else\n";
       for (int i = 0; i < file->dependency_count(); i++) {
         ::grpc::string header =
             grpc_objective_c_generator::MessageHeaderName(file->dependency(i));
@@ -70,19 +71,20 @@
           grpc_generator::StripPrefix(&base_name, "google/protobuf/");
           // create the import code snippet
           proto_imports +=
-              "#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS\n"
-              "  #import <" +
+              "  #if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS\n"
+              "    #import <" +
               ::grpc::string(ProtobufLibraryFrameworkName) + "/" + base_name +
               ">\n"
-              "#else\n"
-              "  #import \"" +
+              "  #else\n"
+              "    #import \"" +
               header +
               "\"\n"
-              "#endif\n";
+              "  #endif\n";
         } else {
-          proto_imports += ::grpc::string("#import \"") + header + "\"\n";
+          proto_imports += ::grpc::string("  #import \"") + header + "\"\n";
         }
       }
+      proto_imports += "#endif\n";
 
       ::grpc::string declarations;
       for (int i = 0; i < file->service_count(); i++) {
@@ -106,6 +108,28 @@
                                ".pbrpc.h\"\n\n"
                                "#import <ProtoRPC/ProtoRPC.h>\n"
                                "#import <RxLibrary/GRXWriter+Immediate.h>\n";
+      for (int i = 0; i < file->dependency_count(); i++) {
+        ::grpc::string header =
+            grpc_objective_c_generator::MessageHeaderName(file->dependency(i));
+        const grpc::protobuf::FileDescriptor *dependency = file->dependency(i);
+        if (IsProtobufLibraryBundledProtoFile(dependency)) {
+          ::grpc::string base_name = header;
+          grpc_generator::StripPrefix(&base_name, "google/protobuf/");
+          // create the import code snippet
+          imports +=
+              "#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS\n"
+              "  #import <" +
+              ::grpc::string(ProtobufLibraryFrameworkName) + "/" + base_name +
+              ">\n"
+              "#else\n"
+              "  #import \"" +
+              header +
+              "\"\n"
+              "#endif\n";
+        } else {
+          imports += ::grpc::string("#import \"") + header + "\"\n";
+        }
+      }
 
       ::grpc::string definitions;
       for (int i = 0; i < file->service_count(); i++) {
diff --git a/templates/gRPC-Core.podspec.template b/templates/gRPC-Core.podspec.template
index 77191aa..f3ac30c 100644
--- a/templates/gRPC-Core.podspec.template
+++ b/templates/gRPC-Core.podspec.template
@@ -119,6 +119,7 @@
       # build.
       'USE_HEADERMAP' => 'NO',
       'ALWAYS_SEARCH_USER_PATHS' => 'NO',
+      'GCC_PREPROCESSOR_DEFINITIONS' => '"$(inherited)" "COCOAPODS=1" "PB_NO_PACKED_STRUCTS=1"',
     }
 
     s.default_subspecs = 'Interface', 'Implementation'