Merge pull request #481 from Qartar/master

Workaround for MSVC's string literal compiler limit.
This commit is contained in:
Feng Xiao 2015-06-12 14:56:02 -07:00
commit 54a4cccb97
4 changed files with 61 additions and 14 deletions

View File

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

View File

@ -412,6 +412,7 @@ protoc_inputs = \
google/protobuf/unittest_drop_unknown_fields.proto \
google/protobuf/unittest_embed_optimize_for.proto \
google/protobuf/unittest_empty.proto \
google/protobuf/unittest_enormous_descriptor.proto \
google/protobuf/unittest_import_lite.proto \
google/protobuf/unittest_import.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.rb \
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 = \
google/protobuf/map_lite_unittest.pb.cc \
@ -486,6 +486,8 @@ protoc_outputs = \
google/protobuf/unittest_embed_optimize_for.pb.h \
google/protobuf/unittest_empty.pb.cc \
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.h \
google/protobuf/unittest_import_public.pb.cc \

View File

@ -434,20 +434,52 @@ void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) {
string file_data;
file_proto.SerializeToString(&file_data);
printer->Print(
"::google::protobuf::DescriptorPool::InternalAddGeneratedFile(");
// 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 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))));
// 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().
printer->Print(

View File

@ -55,6 +55,7 @@
#include <google/protobuf/unittest.pb.h>
#include <google/protobuf/unittest_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/test_util.h>
#include <google/protobuf/compiler/cpp/cpp_helpers.h>
@ -130,6 +131,17 @@ TEST(GeneratedDescriptorTest, IdenticalDescriptors) {
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
// ===================================================================