Эх сурвалжийг харах

Merge pull request #481 from Qartar/master

Workaround for MSVC's string literal compiler limit.
Feng Xiao 10 жил өмнө
parent
commit
54a4cccb97

+ 1 - 0
cmake/tests.cmake

@@ -25,6 +25,7 @@ set(tests_protos
   google/protobuf/unittest_drop_unknown_fields.proto
   google/protobuf/unittest_drop_unknown_fields.proto
   google/protobuf/unittest_embed_optimize_for.proto
   google/protobuf/unittest_embed_optimize_for.proto
   google/protobuf/unittest_empty.proto
   google/protobuf/unittest_empty.proto
+  google/protobuf/unittest_enormous_descriptor.proto
   google/protobuf/unittest_import.proto
   google/protobuf/unittest_import.proto
   google/protobuf/unittest_import_public.proto
   google/protobuf/unittest_import_public.proto
   google/protobuf/unittest_lite_imports_nonlite.proto
   google/protobuf/unittest_lite_imports_nonlite.proto

+ 4 - 2
src/Makefile.am

@@ -412,6 +412,7 @@ protoc_inputs =                                                \
   google/protobuf/unittest_drop_unknown_fields.proto           \
   google/protobuf/unittest_drop_unknown_fields.proto           \
   google/protobuf/unittest_embed_optimize_for.proto            \
   google/protobuf/unittest_embed_optimize_for.proto            \
   google/protobuf/unittest_empty.proto                         \
   google/protobuf/unittest_empty.proto                         \
+  google/protobuf/unittest_enormous_descriptor.proto           \
   google/protobuf/unittest_import_lite.proto                   \
   google/protobuf/unittest_import_lite.proto                   \
   google/protobuf/unittest_import.proto                        \
   google/protobuf/unittest_import.proto                        \
   google/protobuf/unittest_import_public_lite.proto            \
   google/protobuf/unittest_import_public_lite.proto            \
@@ -453,8 +454,7 @@ EXTRA_DIST =                                                   \
   google/protobuf/compiler/ruby/ruby_generated_code.proto      \
   google/protobuf/compiler/ruby/ruby_generated_code.proto      \
   google/protobuf/compiler/ruby/ruby_generated_code.rb         \
   google/protobuf/compiler/ruby/ruby_generated_code.rb         \
   google/protobuf/compiler/package_info.h                      \
   google/protobuf/compiler/package_info.h                      \
-  google/protobuf/compiler/zip_output_unittest.sh              \
-  google/protobuf/unittest_enormous_descriptor.proto
+  google/protobuf/compiler/zip_output_unittest.sh
 
 
 protoc_lite_outputs =                                          \
 protoc_lite_outputs =                                          \
   google/protobuf/map_lite_unittest.pb.cc                      \
   google/protobuf/map_lite_unittest.pb.cc                      \
@@ -486,6 +486,8 @@ protoc_outputs =                                               \
   google/protobuf/unittest_embed_optimize_for.pb.h             \
   google/protobuf/unittest_embed_optimize_for.pb.h             \
   google/protobuf/unittest_empty.pb.cc                         \
   google/protobuf/unittest_empty.pb.cc                         \
   google/protobuf/unittest_empty.pb.h                          \
   google/protobuf/unittest_empty.pb.h                          \
+  google/protobuf/unittest_enormous_descriptor.pb.cc           \
+  google/protobuf/unittest_enormous_descriptor.pb.h            \
   google/protobuf/unittest_import.pb.cc                        \
   google/protobuf/unittest_import.pb.cc                        \
   google/protobuf/unittest_import.pb.h                         \
   google/protobuf/unittest_import.pb.h                         \
   google/protobuf/unittest_import_public.pb.cc                 \
   google/protobuf/unittest_import_public.pb.cc                 \

+ 45 - 13
src/google/protobuf/compiler/cpp/cpp_file.cc

@@ -434,20 +434,52 @@ void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) {
     string file_data;
     string file_data;
     file_proto.SerializeToString(&file_data);
     file_proto.SerializeToString(&file_data);
 
 
-    printer->Print(
-      "::google::protobuf::DescriptorPool::InternalAddGeneratedFile(");
-
-    // Only write 40 bytes per line.
-    static const int kBytesPerLine = 40;
-    for (int i = 0; i < file_data.size(); i += kBytesPerLine) {
-      printer->Print("\n  \"$data$\"",
-                     "data",
-                     EscapeTrigraphs(
-                         CEscape(file_data.substr(i, kBytesPerLine))));
+    // Workaround for MSVC: "Error C1091: compiler limit: string exceeds 65535
+    // bytes in length". Declare a static array of characters rather than use a
+    // string literal.
+    if (file_data.size() > 65535) {
+      printer->Print(
+        "static const char descriptor[] = {\n");
+      printer->Indent();
+
+      // Only write 25 bytes per line.
+      static const int kBytesPerLine = 25;
+      for (int i = 0; i < file_data.size();) {
+          for (int j = 0; j < kBytesPerLine && i < file_data.size(); ++i, ++j) {
+            printer->Print(
+              "$char$, ",
+              "char", SimpleItoa(file_data[i]));
+          }
+          printer->Print(
+            "\n");
+      }
+
+      printer->Outdent();
+      printer->Print(
+        "};\n");
+
+      printer->Print(
+        "::google::protobuf::DescriptorPool::InternalAddGeneratedFile(descriptor, $size$);\n",
+        "size", SimpleItoa(file_data.size()));
+
+    } else {
+
+      printer->Print(
+        "::google::protobuf::DescriptorPool::InternalAddGeneratedFile(");
+  
+      // Only write 40 bytes per line.
+      static const int kBytesPerLine = 40;
+      for (int i = 0; i < file_data.size(); i += kBytesPerLine) {
+        printer->Print("\n  \"$data$\"",
+                       "data",
+                       EscapeTrigraphs(
+                           CEscape(file_data.substr(i, kBytesPerLine))));
+      }
+      printer->Print(
+          ", $size$);\n",
+        "size", SimpleItoa(file_data.size()));
+  
     }
     }
-    printer->Print(
-        ", $size$);\n",
-      "size", SimpleItoa(file_data.size()));
 
 
     // Call MessageFactory::InternalRegisterGeneratedFile().
     // Call MessageFactory::InternalRegisterGeneratedFile().
     printer->Print(
     printer->Print(

+ 12 - 0
src/google/protobuf/compiler/cpp/cpp_unittest.cc

@@ -55,6 +55,7 @@
 #include <google/protobuf/unittest.pb.h>
 #include <google/protobuf/unittest.pb.h>
 #include <google/protobuf/unittest_optimize_for.pb.h>
 #include <google/protobuf/unittest_optimize_for.pb.h>
 #include <google/protobuf/unittest_embed_optimize_for.pb.h>
 #include <google/protobuf/unittest_embed_optimize_for.pb.h>
+#include <google/protobuf/unittest_enormous_descriptor.pb.h>
 #include <google/protobuf/unittest_no_generic_services.pb.h>
 #include <google/protobuf/unittest_no_generic_services.pb.h>
 #include <google/protobuf/test_util.h>
 #include <google/protobuf/test_util.h>
 #include <google/protobuf/compiler/cpp/cpp_helpers.h>
 #include <google/protobuf/compiler/cpp/cpp_helpers.h>
@@ -130,6 +131,17 @@ TEST(GeneratedDescriptorTest, IdenticalDescriptors) {
             generated_decsriptor_proto.DebugString());
             generated_decsriptor_proto.DebugString());
 }
 }
 
 
+// Test that generated code has proper descriptors:
+// Touch a descriptor generated from an enormous message to validate special
+// handling for descriptors exceeding the C++ standard's recommended minimum
+// limit for string literal size
+TEST(GeneratedDescriptorTest, EnormousDescriptor) {
+  const Descriptor* generated_descriptor =
+    TestEnormousDescriptor::descriptor();
+
+  EXPECT_TRUE(generated_descriptor != NULL);
+}
+
 #endif  // !PROTOBUF_TEST_NO_DESCRIPTORS
 #endif  // !PROTOBUF_TEST_NO_DESCRIPTORS
 
 
 // ===================================================================
 // ===================================================================