aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/google/protobuf/compiler/java/java_message.cc
diff options
context:
space:
mode:
authorGravatar Feng Xiao <xfxyjwf@gmail.com>2014-11-20 16:18:53 -0800
committerGravatar Feng Xiao <xfxyjwf@gmail.com>2014-11-20 16:18:53 -0800
commit99aa0f9e8f1a88def7bdebf1385678559cda0707 (patch)
tree7ccb663ee9a1c722bf6062435ac705e83568c7e8 /src/google/protobuf/compiler/java/java_message.cc
parent49bc8c09636ae61f9c685d121278c3738b9a809a (diff)
Down-integrate from internal code base.
Diffstat (limited to 'src/google/protobuf/compiler/java/java_message.cc')
-rw-r--r--src/google/protobuf/compiler/java/java_message.cc157
1 files changed, 124 insertions, 33 deletions
diff --git a/src/google/protobuf/compiler/java/java_message.cc b/src/google/protobuf/compiler/java/java_message.cc
index 70f379bc..1171b718 100644
--- a/src/google/protobuf/compiler/java/java_message.cc
+++ b/src/google/protobuf/compiler/java/java_message.cc
@@ -306,31 +306,28 @@ void ImmutableMessageGenerator::Generate(io::Printer* printer) {
variables["lite"]);
}
printer->Indent();
- // Using builder_type, instead of Builder, prevents the Builder class from
- // being loaded into PermGen space when the default instance is created.
- // This optimizes the PermGen space usage for clients that do not modify
- // messages.
- printer->Print(
- "// Use $classname$.newBuilder() to construct.\n"
- "private $classname$($buildertype$ builder) {\n"
- " super(builder);\n"
- "}\n",
- "classname", descriptor_->name(),
- "buildertype", builder_type);
- printer->Print(
- "private $classname$() {\n",
- "classname", descriptor_->name());
- printer->Indent();
- for (int i = 0; i < descriptor_->field_count(); i++) {
- if (!descriptor_->field(i)->containing_oneof()) {
- field_generators_.get(descriptor_->field(i))
- .GenerateInitializationCode(printer);
- }
+ if (HasDescriptorMethods(descriptor_)) {
+ // Using builder_type, instead of Builder, prevents the Builder class from
+ // being loaded into PermGen space when the default instance is created.
+ // This optimizes the PermGen space usage for clients that do not modify
+ // messages.
+ printer->Print(
+ "// Use $classname$.newBuilder() to construct.\n"
+ "private $classname$($buildertype$ builder) {\n"
+ " super(builder);\n"
+ "}\n",
+ "classname", descriptor_->name(),
+ "buildertype", builder_type);
+ printer->Print(
+ "private $classname$() {\n",
+ "classname", descriptor_->name());
+ printer->Indent();
+ GenerateInitializers(printer);
+ printer->Outdent();
+ printer->Print(
+ "}\n"
+ "\n");
}
- printer->Outdent();
- printer->Print(
- "}\n"
- "\n");
if (HasDescriptorMethods(descriptor_)) {
printer->Print(
@@ -480,10 +477,37 @@ void ImmutableMessageGenerator::Generate(io::Printer* printer) {
"// @@protoc_insertion_point(class_scope:$full_name$)\n",
"full_name", descriptor_->full_name());
+
// Carefully initialize the default instance in such a way that it doesn't
// conflict with other initialization.
- printer->Print("private static final $classname$ defaultInstance =\n"
- " new $classname$();\n"
+ printer->Print(
+ "private static final $classname$ defaultInstance;",
+ "classname", name_resolver_->GetImmutableClassName(descriptor_));
+ if (HasDescriptorMethods(descriptor_)) {
+ printer->Print(
+ "static {\n"
+ " defaultInstance = new $classname$();\n"
+ "}\n"
+ "\n",
+ "classname", name_resolver_->GetImmutableClassName(descriptor_));
+ } else {
+ // LITE_RUNTIME only has one constructor.
+ printer->Print(
+ "static {\n"
+ " try {\n"
+ " defaultInstance = new $classname$(\n"
+ " com.google.protobuf.Internal\n"
+ " .EMPTY_CODED_INPUT_STREAM,\n"
+ " com.google.protobuf.ExtensionRegistryLite\n"
+ " .getEmptyRegistry());\n"
+ " } catch (com.google.protobuf.InvalidProtocolBufferException e) {\n"
+ " throw new ExceptionInInitializerError(e);\n"
+ " }\n"
+ "}\n"
+ "\n",
+ "classname", descriptor_->name());
+ }
+ printer->Print(
"public static $classname$ getDefaultInstance() {\n"
" return defaultInstance;\n"
"}\n"
@@ -492,7 +516,7 @@ void ImmutableMessageGenerator::Generate(io::Printer* printer) {
" return defaultInstance;\n"
"}\n"
"\n",
- "classname", descriptor_->name());
+ "classname", name_resolver_->GetImmutableClassName(descriptor_));
// Extensions must be declared after the defaultInstance is initialized
// because the defaultInstance is used by the extension to lazily retrieve
@@ -773,6 +797,7 @@ void ImmutableMessageGenerator::GenerateBuilder(io::Printer* printer) {
if (HasGeneratedMethods(descriptor_)) {
GenerateIsInitialized(printer, DONT_MEMOIZE);
+ GenerateBuilderParsingMethods(printer);
}
// oneof
@@ -1034,10 +1059,33 @@ GenerateCommonBuilderMethods(io::Printer* printer) {
"classname", name_resolver_->GetImmutableClassName(descriptor_));
}
- printer->Print(
- "public $classname$ buildPartial() {\n"
- " $classname$ result = new $classname$(this);\n",
- "classname", name_resolver_->GetImmutableClassName(descriptor_));
+ if (HasDescriptorMethods(descriptor_)) {
+ printer->Print(
+ "public $classname$ buildPartial() {\n"
+ " $classname$ result = new $classname$(this);\n",
+ "classname", name_resolver_->GetImmutableClassName(descriptor_));
+ } else {
+ // LITE_RUNTIME only provides a single message constructor.
+ printer->Print(
+ "public $classname$ buildPartial() {\n"
+ " $classname$ result = null;\n"
+ " try {\n"
+ " result = new $classname$(\n"
+ " com.google.protobuf.Internal\n"
+ " .EMPTY_CODED_INPUT_STREAM,\n"
+ " com.google.protobuf.ExtensionRegistryLite\n"
+ " .getEmptyRegistry());\n"
+ " } catch (com.google.protobuf.InvalidProtocolBufferException e) {\n"
+ " throw new RuntimeException(e);\n"
+ " }\n"
+ " result.unknownFields = this.unknownFields;\n",
+ "classname", name_resolver_->GetImmutableClassName(descriptor_));
+
+ if (descriptor_->extension_range_count() > 0) {
+ printer->Print(
+ " result.extensions = this.buildExtensions();\n");
+ }
+ }
printer->Indent();
@@ -1193,6 +1241,34 @@ GenerateCommonBuilderMethods(io::Printer* printer) {
// ===================================================================
+void ImmutableMessageGenerator::
+GenerateBuilderParsingMethods(io::Printer* printer) {
+ if (HasDescriptorMethods(descriptor_)) {
+ // LITE_RUNTIME implements this at the GeneratedMessageLite level.
+ printer->Print(
+ "public Builder mergeFrom(\n"
+ " com.google.protobuf.CodedInputStream input,\n"
+ " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
+ " throws java.io.IOException {\n"
+ " $classname$ parsedMessage = null;\n"
+ " try {\n"
+ " parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);\n"
+ " } catch (com.google.protobuf.InvalidProtocolBufferException e) {\n"
+ " parsedMessage = ($classname$) e.getUnfinishedMessage();\n"
+ " throw e;\n"
+ " } finally {\n"
+ " if (parsedMessage != null) {\n"
+ " mergeFrom(parsedMessage);\n"
+ " }\n"
+ " }\n"
+ " return this;\n"
+ "}\n",
+ "classname", name_resolver_->GetImmutableClassName(descriptor_));
+ }
+}
+
+// ===================================================================
+
void ImmutableMessageGenerator::GenerateIsInitialized(
io::Printer* printer, UseMemoization useMemoization) {
bool memoization = useMemoization == MEMOIZE;
@@ -1488,8 +1564,13 @@ GenerateParsingConstructor(io::Printer* printer) {
printer->Indent();
// Initialize all fields to default.
- printer->Print(
- "this();\n");
+ if (HasDescriptorMethods(descriptor_)) {
+ printer->Print(
+ "this();\n");
+ } else {
+ // LITE_RUNTIME only has one constructor.
+ GenerateInitializers(printer);
+ }
// Use builder bits to track mutable repeated fields.
int totalBuilderBits = 0;
@@ -1703,6 +1784,16 @@ void ImmutableMessageGenerator::GenerateParser(io::Printer* printer) {
"classname", descriptor_->name());
}
+// ===================================================================
+void ImmutableMessageGenerator::GenerateInitializers(io::Printer* printer) {
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ if (!descriptor_->field(i)->containing_oneof()) {
+ field_generators_.get(descriptor_->field(i))
+ .GenerateInitializationCode(printer);
+ }
+ }
+}
+
} // namespace java
} // namespace compiler