Hello,

I was not able to compile a Java file generated by protoc 2.10 from a
rather big .proto file.
It seems I have hit the upper limit for a Java string literal
(65535???).

I slightly modified src/google/protobuf/compiler/java/java_file.cc so
that static initialization is performed from
an array of literal strings in the case CEscape(file_data).size() >
65535.

Is this a real problem, or am I missing something ?

Here is the patch:

diff -r -u protobuf-2.1.0/src/google/protobuf/compiler/java/
java_file.cc protobuf-2.1.0.new/src/google/protobuf/compiler/java/
java_file.cc
--- protobuf-2.1.0/src/google/protobuf/compiler/java/java_file.cc
2009-05-13 16:36:30.000000000 -0400
+++ protobuf-2.1.0.new/src/google/protobuf/compiler/java/java_file.cc
2009-07-22 10:37:28.000000000 -0400
@@ -207,6 +207,9 @@
   // This makes huge bytecode files and can easily hit the compiler's
internal
   // code size limits (error "code to large").  String literals are
apparently
   // embedded raw, which is what we want.
+  // In the case the FileDescriptorProto is too big for fitting into
a string
+  // literal, first creating ain array of string literals, then
concatenating
+  // them into the final FileDescriptorProto string.
   FileDescriptorProto file_proto;
   file_->CopyTo(&file_proto);
   string file_data;
@@ -218,22 +221,51 @@
     "  return descriptor;\n"
     "}\n"
     "private static com.google.protobuf.Descriptors.FileDescriptor\n"
-    "    descriptor;\n"
-    "static {\n"
-    "  java.lang.String descriptorData =\n");
-  printer->Indent();
-  printer->Indent();
+    "    descriptor;\n");

-  // Only write 40 bytes per line.
   static const int kBytesPerLine = 40;
-  for (int i = 0; i < file_data.size(); i += kBytesPerLine) {
-    if (i > 0) printer->Print(" +\n");
-    printer->Print("\"$data$\"",
-      "data", CEscape(file_data.substr(i, kBytesPerLine)));
-  }
-  printer->Print(";\n");

-  printer->Outdent();
+  // Limit for a Java literal string is 65535
+  bool stringTooLong = (CEscape(file_data).size() > 65535);
+
+  if (stringTooLong) {
+    printer->Print("static {\n"
+      "  java.lang.String descriptorDataArray[] = {\n");
+    printer->Indent();
+    printer->Indent();
+
+    // Only write 40 bytes per line.
+    for (int i = 0; i < file_data.size(); i += kBytesPerLine) {
+      if (i > 0) printer->Print(",\n");
+      printer->Print("\"$data$\"",
+        "data", CEscape(file_data.substr(i, kBytesPerLine)));
+    }
+    printer->Outdent();
+    printer->Print("\n"
+                                "};\n\n");
+    printer->Print("java.lang.String descriptorData = \"\";\n");
+    printer->Print("for (String data : descriptorDataArray) {\n");
+    printer->Indent();
+    printer->Print("descriptorData += data;\n");
+    printer->Outdent();
+    printer->Print("}\n\n");
+  } else {
+    printer->Print("static {\n"
+      "  java.lang.String descriptorData =\n");
+    printer->Indent();
+    printer->Indent();
+
+    // Only write 40 bytes per line.
+    static const int kBytesPerLine = 40;
+    for (int i = 0; i < file_data.size(); i += kBytesPerLine) {
+      if (i > 0) printer->Print(" +\n");
+        printer->Print("\"$data$\"",
+        "data", CEscape(file_data.substr(i, kBytesPerLine)));
+      }
+    printer->Print(";\n");
+
+    printer->Outdent();
+  }

   //
-----------------------------------------------------------------
   // Create the InternalDescriptorAssigner.

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Protocol Buffers" group.
To post to this group, send email to protobuf@googlegroups.com
To unsubscribe from this group, send email to 
protobuf+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/protobuf?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to