From fccb146e3fe437b0df1e9c50d4b8e1080ddb4bd9 Mon Sep 17 00:00:00 2001 From: "kenton@google.com" Date: Fri, 18 Dec 2009 02:11:36 +0000 Subject: Massive roll-up of changes. See CHANGES.txt. --- src/google/protobuf/compiler/java/java_message.cc | 83 +++++++++++++++++------ 1 file changed, 62 insertions(+), 21 deletions(-) (limited to 'src/google/protobuf/compiler/java/java_message.cc') diff --git a/src/google/protobuf/compiler/java/java_message.cc b/src/google/protobuf/compiler/java/java_message.cc index 99b57c95..1f8e209c 100644 --- a/src/google/protobuf/compiler/java/java_message.cc +++ b/src/google/protobuf/compiler/java/java_message.cc @@ -127,7 +127,7 @@ static bool HasRequiredFields( if (field->is_required()) { return true; } - if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { + if (GetJavaType(field) == JAVATYPE_MESSAGE) { if (HasRequiredFields(field->message_type(), already_seen)) { return true; } @@ -292,9 +292,14 @@ void MessageGenerator::Generate(io::Printer* printer) { printer->Indent(); printer->Print( "// Use $classname$.newBuilder() to construct.\n" - "private $classname$() {}\n" + "private $classname$() {\n" + " initFields();\n" + "}\n" + // Used when constructing the default instance, which cannot be initialized + // immediately because it may cyclically refer to other default instances. + "private $classname$(boolean noInit) {}\n" "\n" - "private static final $classname$ defaultInstance = new $classname$();\n" + "private static final $classname$ defaultInstance;\n" "public static $classname$ getDefaultInstance() {\n" " return defaultInstance;\n" "}\n" @@ -344,6 +349,17 @@ void MessageGenerator::Generate(io::Printer* printer) { printer->Print("\n"); } + // Called by the constructor, except in the case of the default instance, + // in which case this is called by static init code later on. + printer->Print("private void initFields() {\n"); + printer->Indent(); + for (int i = 0; i < descriptor_->field_count(); i++) { + field_generators_.get(descriptor_->field(i)) + .GenerateInitializationCode(printer); + } + printer->Outdent(); + printer->Print("}\n"); + if (HasGeneratedMethods(descriptor_)) { GenerateIsInitialized(printer); GenerateMessageSerializationMethods(printer); @@ -352,25 +368,23 @@ void MessageGenerator::Generate(io::Printer* printer) { GenerateParseFromMethods(printer); GenerateBuilder(printer); - if (HasDescriptorMethods(descriptor_)) { - // Force the static initialization code for the file to run, since it may - // initialize static variables declared in this class. - printer->Print( - "\n" - "static {\n" - " $file$.getDescriptor();\n" - "}\n", - "file", ClassName(descriptor_->file())); - } - // Force initialization of outer class. Otherwise, nested extensions may - // not be initialized. + // not be initialized. Also carefully initialize the default instance in + // such a way that it doesn't conflict with other initialization. printer->Print( "\n" "static {\n" + " defaultInstance = new $classname$(true);\n" " $file$.internalForceInit();\n" + " defaultInstance.initFields();\n" "}\n", - "file", ClassName(descriptor_->file())); + "file", ClassName(descriptor_->file()), + "classname", descriptor_->name()); + + printer->Print( + "\n" + "// @@protoc_insertion_point(class_scope:$full_name$)\n", + "full_name", descriptor_->full_name()); printer->Outdent(); printer->Print("}\n\n"); @@ -529,14 +543,23 @@ GenerateParseFromMethods(io::Printer* printer) { "}\n" "public static $classname$ parseDelimitedFrom(java.io.InputStream input)\n" " throws java.io.IOException {\n" - " return newBuilder().mergeDelimitedFrom(input).buildParsed();\n" + " Builder builder = newBuilder();\n" + " if (builder.mergeDelimitedFrom(input)) {\n" + " return builder.buildParsed();\n" + " } else {\n" + " return null;\n" + " }\n" "}\n" "public static $classname$ parseDelimitedFrom(\n" " java.io.InputStream input,\n" " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n" " throws java.io.IOException {\n" - " return newBuilder().mergeDelimitedFrom(input, extensionRegistry)\n" - " .buildParsed();\n" + " Builder builder = newBuilder();\n" + " if (builder.mergeDelimitedFrom(input, extensionRegistry)) {\n" + " return builder.buildParsed();\n" + " } else {\n" + " return null;\n" + " }\n" "}\n" "public static $classname$ parseFrom(\n" " com.google.protobuf.CodedInputStream input)\n" @@ -827,7 +850,7 @@ void MessageGenerator::GenerateBuilderParsingMethods(io::Printer* printer) { for (int i = 0; i < descriptor_->field_count(); i++) { const FieldDescriptor* field = sorted_fields[i]; uint32 tag = WireFormatLite::MakeTag(field->number(), - WireFormat::WireTypeForField(field)); + WireFormat::WireTypeForFieldType(field->type())); printer->Print( "case $tag$: {\n", @@ -840,6 +863,24 @@ void MessageGenerator::GenerateBuilderParsingMethods(io::Printer* printer) { printer->Print( " break;\n" "}\n"); + + if (field->is_packable()) { + // To make packed = true wire compatible, we generate parsing code from a + // packed version of this field regardless of field->options().packed(). + uint32 packed_tag = WireFormatLite::MakeTag(field->number(), + WireFormatLite::WIRETYPE_LENGTH_DELIMITED); + printer->Print( + "case $tag$: {\n", + "tag", SimpleItoa(packed_tag)); + printer->Indent(); + + field_generators_.get(field).GenerateParsingCodeFromPacked(printer); + + printer->Outdent(); + printer->Print( + " break;\n" + "}\n"); + } } printer->Outdent(); @@ -875,7 +916,7 @@ void MessageGenerator::GenerateIsInitialized(io::Printer* printer) { // Now check that all embedded messages are initialized. for (int i = 0; i < descriptor_->field_count(); i++) { const FieldDescriptor* field = descriptor_->field(i); - if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE && + if (GetJavaType(field) == JAVATYPE_MESSAGE && HasRequiredFields(field->message_type())) { switch (field->label()) { case FieldDescriptor::LABEL_REQUIRED: -- cgit v1.2.3