diff options
author | jieluo@google.com <jieluo@google.com@630680e5-0e50-0410-840e-4b1c322b438d> | 2014-07-18 00:47:59 +0000 |
---|---|---|
committer | jieluo@google.com <jieluo@google.com@630680e5-0e50-0410-840e-4b1c322b438d> | 2014-07-18 00:47:59 +0000 |
commit | 4de8f55113007fdc8e34107950e605fc0209d465 (patch) | |
tree | 92b7da8757a7740d9e1f2d3ead233542947d8c8c /src/google/protobuf/compiler/java/java_message_field.cc | |
parent | c5553a3d18f80132b9079c5504bc0aa1f7f950a0 (diff) |
down integrate to svn
Diffstat (limited to 'src/google/protobuf/compiler/java/java_message_field.cc')
-rw-r--r-- | src/google/protobuf/compiler/java/java_message_field.cc | 631 |
1 files changed, 500 insertions, 131 deletions
diff --git a/src/google/protobuf/compiler/java/java_message_field.cc b/src/google/protobuf/compiler/java/java_message_field.cc index b0b284f7..80b9a382 100644 --- a/src/google/protobuf/compiler/java/java_message_field.cc +++ b/src/google/protobuf/compiler/java/java_message_field.cc @@ -35,9 +35,11 @@ #include <map> #include <string> +#include <google/protobuf/compiler/java/java_context.h> #include <google/protobuf/compiler/java/java_message_field.h> #include <google/protobuf/compiler/java/java_doc_comment.h> #include <google/protobuf/compiler/java/java_helpers.h> +#include <google/protobuf/compiler/java/java_name_resolver.h> #include <google/protobuf/io/printer.h> #include <google/protobuf/wire_format.h> #include <google/protobuf/stubs/strutil.h> @@ -49,19 +51,18 @@ namespace java { namespace { -// TODO(kenton): Factor out a "SetCommonFieldVariables()" to get rid of -// repeat code between this and the other field types. void SetMessageVariables(const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex, + const FieldGeneratorInfo* info, + ClassNameResolver* name_resolver, map<string, string>* variables) { - (*variables)["name"] = - UnderscoresToCamelCase(descriptor); - (*variables)["capitalized_name"] = - UnderscoresToCapitalizedCamelCase(descriptor); - (*variables)["constant_name"] = FieldConstantName(descriptor); - (*variables)["number"] = SimpleItoa(descriptor->number()); - (*variables)["type"] = ClassName(descriptor->message_type()); + SetCommonFieldVariables(descriptor, info, variables); + + (*variables)["type"] = + name_resolver->GetImmutableClassName(descriptor->message_type()); + (*variables)["mutable_type"] = + name_resolver->GetMutableClassName(descriptor->message_type()); (*variables)["group_or_message"] = (GetType(descriptor) == FieldDescriptor::TYPE_GROUP) ? "Group" : "Message"; @@ -72,14 +73,28 @@ void SetMessageVariables(const FieldDescriptor* descriptor, (*variables)["on_changed"] = HasDescriptorMethods(descriptor->containing_type()) ? "onChanged();" : ""; - // For singular messages and builders, one bit is used for the hasField bit. - (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex); - (*variables)["set_has_field_bit_message"] = GenerateSetBit(messageBitIndex); + if (SupportFieldPresence(descriptor->file())) { + // For singular messages and builders, one bit is used for the hasField bit. + (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex); + (*variables)["get_has_field_bit_builder"] = GenerateGetBit(builderBitIndex); + + // Note that these have a trailing ";". + (*variables)["set_has_field_bit_message"] = + GenerateSetBit(messageBitIndex) + ";"; + (*variables)["set_has_field_bit_builder"] = + GenerateSetBit(builderBitIndex) + ";"; + (*variables)["clear_has_field_bit_builder"] = + GenerateClearBit(builderBitIndex) + ";"; - (*variables)["get_has_field_bit_builder"] = GenerateGetBit(builderBitIndex); - (*variables)["set_has_field_bit_builder"] = GenerateSetBit(builderBitIndex); - (*variables)["clear_has_field_bit_builder"] = - GenerateClearBit(builderBitIndex); + (*variables)["is_field_present_message"] = GenerateGetBit(messageBitIndex); + } else { + (*variables)["set_has_field_bit_message"] = ""; + (*variables)["set_has_field_bit_builder"] = ""; + (*variables)["clear_has_field_bit_builder"] = ""; + + (*variables)["is_field_present_message"] = + (*variables)["name"] + "_ != null"; + } // For repated builders, one bit is used for whether the array is immutable. (*variables)["get_mutable_bit_builder"] = GenerateGetBit(builderBitIndex); @@ -103,35 +118,41 @@ void SetMessageVariables(const FieldDescriptor* descriptor, // =================================================================== -MessageFieldGenerator:: -MessageFieldGenerator(const FieldDescriptor* descriptor, +ImmutableMessageFieldGenerator:: +ImmutableMessageFieldGenerator(const FieldDescriptor* descriptor, int messageBitIndex, - int builderBitIndex) + int builderBitIndex, + Context* context) : descriptor_(descriptor), messageBitIndex_(messageBitIndex), - builderBitIndex_(builderBitIndex) { - SetMessageVariables(descriptor, messageBitIndex, builderBitIndex, - &variables_); + builderBitIndex_(builderBitIndex), context_(context), + name_resolver_(context->GetNameResolver()) { + SetMessageVariables(descriptor, messageBitIndex, builderBitIndex, + context->GetFieldGeneratorInfo(descriptor), + name_resolver_, &variables_); } -MessageFieldGenerator::~MessageFieldGenerator() {} +ImmutableMessageFieldGenerator::~ImmutableMessageFieldGenerator() {} -int MessageFieldGenerator::GetNumBitsForMessage() const { +int ImmutableMessageFieldGenerator::GetNumBitsForMessage() const { return 1; } -int MessageFieldGenerator::GetNumBitsForBuilder() const { +int ImmutableMessageFieldGenerator::GetNumBitsForBuilder() const { return 1; } -void MessageFieldGenerator:: +void ImmutableMessageFieldGenerator:: GenerateInterfaceMembers(io::Printer* printer) const { // TODO(jonp): In the future, consider having a method specific to the // interface so that builders can choose dynamically to either return a // message or a nested builder, so that asking for the interface doesn't // cause a message to ever be built. - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "$deprecation$boolean has$capitalized_name$();\n"); + if (SupportFieldPresence(descriptor_->file()) || + descriptor_->containing_oneof() == NULL) { + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$boolean has$capitalized_name$();\n"); + } WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, "$deprecation$$type$ get$capitalized_name$();\n"); @@ -143,31 +164,56 @@ GenerateInterfaceMembers(io::Printer* printer) const { } } -void MessageFieldGenerator:: +void ImmutableMessageFieldGenerator:: GenerateMembers(io::Printer* printer) const { printer->Print(variables_, "private $type$ $name$_;\n"); - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "$deprecation$public boolean has$capitalized_name$() {\n" - " return $get_has_field_bit_message$;\n" - "}\n"); - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "$deprecation$public $type$ get$capitalized_name$() {\n" - " return $name$_;\n" - "}\n"); + PrintExtraFieldInfo(variables_, printer); - if (HasNestedBuilders(descriptor_->containing_type())) { + if (SupportFieldPresence(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$OrBuilder get$capitalized_name$OrBuilder() {\n" + "$deprecation$public boolean has$capitalized_name$() {\n" + " return $get_has_field_bit_message$;\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public $type$ get$capitalized_name$() {\n" " return $name$_;\n" "}\n"); + + if (HasNestedBuilders(descriptor_->containing_type())) { + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public $type$OrBuilder " + "get$capitalized_name$OrBuilder() {\n" + " return $name$_;\n" + "}\n"); + } + } else { + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public boolean has$capitalized_name$() {\n" + " return $name$_ != null;\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public $type$ get$capitalized_name$() {\n" + " return $name$_ == null ? $type$.getDefaultInstance() : $name$_;\n" + "}\n"); + + if (HasNestedBuilders(descriptor_->containing_type())) { + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public $type$OrBuilder " + "get$capitalized_name$OrBuilder() {\n" + " return get$capitalized_name$();\n" + "}\n"); + } } } -void MessageFieldGenerator::PrintNestedBuilderCondition( +void ImmutableMessageFieldGenerator::PrintNestedBuilderCondition( io::Printer* printer, const char* regular_case, const char* nested_builder_case) const { @@ -186,7 +232,7 @@ void MessageFieldGenerator::PrintNestedBuilderCondition( } } -void MessageFieldGenerator::PrintNestedBuilderFunction( +void ImmutableMessageFieldGenerator::PrintNestedBuilderFunction( io::Printer* printer, const char* method_prototype, const char* regular_case, @@ -203,15 +249,22 @@ void MessageFieldGenerator::PrintNestedBuilderFunction( printer->Print("}\n"); } -void MessageFieldGenerator:: +void ImmutableMessageFieldGenerator:: GenerateBuilderMembers(io::Printer* printer) const { // When using nested-builders, the code initially works just like the // non-nested builder case. It only creates a nested builder lazily on // demand and then forever delegates to it after creation. - printer->Print(variables_, - // Used when the builder is null. - "private $type$ $name$_ = $type$.getDefaultInstance();\n"); + bool support_field_presence = SupportFieldPresence(descriptor_->file()); + + if (support_field_presence) { + printer->Print(variables_, + // Used when the builder is null. + "private $type$ $name$_ = $type$.getDefaultInstance();\n"); + } else { + printer->Print(variables_, + "private $type$ $name$_ = null;\n"); + } if (HasNestedBuilders(descriptor_->containing_type())) { printer->Print(variables_, @@ -227,17 +280,26 @@ GenerateBuilderMembers(io::Printer* printer) const { // boolean hasField() WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "$deprecation$public boolean has$capitalized_name$() {\n" - " return $get_has_field_bit_builder$;\n" - "}\n"); + if (support_field_presence) { + printer->Print(variables_, + "$deprecation$public boolean has$capitalized_name$() {\n" + " return $get_has_field_bit_builder$;\n" + "}\n"); + } else { + printer->Print(variables_, + "$deprecation$public boolean has$capitalized_name$() {\n" + " return $name$Builder_ != null || $name$_ != null;\n" + "}\n"); + } // Field getField() WriteFieldDocComment(printer, descriptor_); PrintNestedBuilderFunction(printer, "$deprecation$public $type$ get$capitalized_name$()", - "return $name$_;\n", + support_field_presence + ? "return $name$_;\n" + : "return $name$_ == null ? $type$.getDefaultInstance() : $name$_;\n", "return $name$Builder_.getMessage();\n", @@ -256,7 +318,7 @@ GenerateBuilderMembers(io::Printer* printer) const { "$name$Builder_.setMessage(value);\n", - "$set_has_field_bit_builder$;\n" + "$set_has_field_bit_builder$\n" "return this;\n"); // Field.Builder setField(Field.Builder builderForValue) @@ -270,7 +332,7 @@ GenerateBuilderMembers(io::Printer* printer) const { "$name$Builder_.setMessage(builderForValue.build());\n", - "$set_has_field_bit_builder$;\n" + "$set_has_field_bit_builder$\n" "return this;\n"); // Field.Builder mergeField(Field value) @@ -278,18 +340,26 @@ GenerateBuilderMembers(io::Printer* printer) const { PrintNestedBuilderFunction(printer, "$deprecation$public Builder merge$capitalized_name$($type$ value)", - "if ($get_has_field_bit_builder$ &&\n" - " $name$_ != $type$.getDefaultInstance()) {\n" - " $name$_ =\n" - " $type$.newBuilder($name$_).mergeFrom(value).buildPartial();\n" - "} else {\n" - " $name$_ = value;\n" - "}\n" - "$on_changed$\n", + support_field_presence + ? "if ($get_has_field_bit_builder$ &&\n" + " $name$_ != $type$.getDefaultInstance()) {\n" + " $name$_ =\n" + " $type$.newBuilder($name$_).mergeFrom(value).buildPartial();\n" + "} else {\n" + " $name$_ = value;\n" + "}\n" + "$on_changed$\n" + : "if ($name$_ != null) {\n" + " $name$_ =\n" + " $type$.newBuilder($name$_).mergeFrom(value).buildPartial();\n" + "} else {\n" + " $name$_ = value;\n" + "}\n" + "$on_changed$\n", "$name$Builder_.mergeFrom(value);\n", - "$set_has_field_bit_builder$;\n" + "$set_has_field_bit_builder$\n" "return this;\n"); // Field.Builder clearField() @@ -297,19 +367,25 @@ GenerateBuilderMembers(io::Printer* printer) const { PrintNestedBuilderFunction(printer, "$deprecation$public Builder clear$capitalized_name$()", - "$name$_ = $type$.getDefaultInstance();\n" - "$on_changed$\n", + support_field_presence + ? "$name$_ = $type$.getDefaultInstance();\n" + "$on_changed$\n" + : "$name$_ = null;\n" + "$on_changed$\n", - "$name$Builder_.clear();\n", + support_field_presence + ? "$name$Builder_.clear();\n" + : "$name$_ = null;\n" + "$name$Builder_ = null;\n", - "$clear_has_field_bit_builder$;\n" + "$clear_has_field_bit_builder$\n" "return this;\n"); if (HasNestedBuilders(descriptor_->containing_type())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, "$deprecation$public $type$.Builder get$capitalized_name$Builder() {\n" - " $set_has_field_bit_builder$;\n" + " $set_has_field_bit_builder$\n" " $on_changed$\n" " return get$capitalized_name$FieldBuilder().getBuilder();\n" "}\n"); @@ -318,8 +394,16 @@ GenerateBuilderMembers(io::Printer* printer) const { "$deprecation$public $type$OrBuilder get$capitalized_name$OrBuilder() {\n" " if ($name$Builder_ != null) {\n" " return $name$Builder_.getMessageOrBuilder();\n" - " } else {\n" - " return $name$_;\n" + " } else {\n"); + if (support_field_presence) { + printer->Print(variables_, + " return $name$_;\n"); + } else { + printer->Print(variables_, + " return $name$_ == null ?\n" + " $type$.getDefaultInstance() : $name$_;\n"); + } + printer->Print(variables_, " }\n" "}\n"); WriteFieldDocComment(printer, descriptor_); @@ -330,7 +414,7 @@ GenerateBuilderMembers(io::Printer* printer) const { " if ($name$Builder_ == null) {\n" " $name$Builder_ = new com.google.protobuf.SingleFieldBuilder<\n" " $type$, $type$.Builder, $type$OrBuilder>(\n" - " $name$_,\n" + " get$capitalized_name$(),\n" " getParentForChildren(),\n" " isClean());\n" " $name$_ = null;\n" @@ -340,28 +424,40 @@ GenerateBuilderMembers(io::Printer* printer) const { } } -void MessageFieldGenerator:: +void ImmutableMessageFieldGenerator:: GenerateFieldBuilderInitializationCode(io::Printer* printer) const { - printer->Print(variables_, - "get$capitalized_name$FieldBuilder();\n"); + if (SupportFieldPresence(descriptor_->file())) { + printer->Print(variables_, + "get$capitalized_name$FieldBuilder();\n"); + } } -void MessageFieldGenerator:: +void ImmutableMessageFieldGenerator:: GenerateInitializationCode(io::Printer* printer) const { - printer->Print(variables_, "$name$_ = $type$.getDefaultInstance();\n"); + if (SupportFieldPresence(descriptor_->file())) { + printer->Print(variables_, "$name$_ = $type$.getDefaultInstance();\n"); + } } -void MessageFieldGenerator:: +void ImmutableMessageFieldGenerator:: GenerateBuilderClearCode(io::Printer* printer) const { - PrintNestedBuilderCondition(printer, - "$name$_ = $type$.getDefaultInstance();\n", + if (SupportFieldPresence(descriptor_->file())) { + PrintNestedBuilderCondition(printer, + "$name$_ = $type$.getDefaultInstance();\n", - "$name$Builder_.clear();\n"); - printer->Print(variables_, "$clear_has_field_bit_builder$;\n"); + "$name$Builder_.clear();\n"); + printer->Print(variables_, "$clear_has_field_bit_builder$\n"); + } else { + PrintNestedBuilderCondition(printer, + "$name$_ = null;\n", + + "$name$_ = null;\n" + "$name$Builder_ = null;\n"); + } } -void MessageFieldGenerator:: +void ImmutableMessageFieldGenerator:: GenerateMergingCode(io::Printer* printer) const { printer->Print(variables_, "if (other.has$capitalized_name$()) {\n" @@ -369,13 +465,14 @@ GenerateMergingCode(io::Printer* printer) const { "}\n"); } -void MessageFieldGenerator:: +void ImmutableMessageFieldGenerator:: GenerateBuildingCode(io::Printer* printer) const { - - printer->Print(variables_, - "if ($get_has_field_bit_from_local$) {\n" - " $set_has_field_bit_to_local$;\n" - "}\n"); + if (SupportFieldPresence(descriptor_->file())) { + printer->Print(variables_, + "if ($get_has_field_bit_from_local$) {\n" + " $set_has_field_bit_to_local$;\n" + "}\n"); + } PrintNestedBuilderCondition(printer, "result.$name$_ = $name$_;\n", @@ -383,11 +480,11 @@ GenerateBuildingCode(io::Printer* printer) const { "result.$name$_ = $name$Builder_.build();\n"); } -void MessageFieldGenerator:: +void ImmutableMessageFieldGenerator:: GenerateParsingCode(io::Printer* printer) const { printer->Print(variables_, "$type$.Builder subBuilder = null;\n" - "if ($get_has_field_bit_message$) {\n" + "if ($is_field_present_message$) {\n" " subBuilder = $name$_.toBuilder();\n" "}\n"); @@ -404,74 +501,344 @@ GenerateParsingCode(io::Printer* printer) const { "if (subBuilder != null) {\n" " subBuilder.mergeFrom($name$_);\n" " $name$_ = subBuilder.buildPartial();\n" - "}\n"); - printer->Print(variables_, - "$set_has_field_bit_message$;\n"); + "}\n" + "$set_has_field_bit_message$\n"); } -void MessageFieldGenerator:: +void ImmutableMessageFieldGenerator:: GenerateParsingDoneCode(io::Printer* printer) const { // noop for messages. } -void MessageFieldGenerator:: +void ImmutableMessageFieldGenerator:: GenerateSerializationCode(io::Printer* printer) const { printer->Print(variables_, - "if ($get_has_field_bit_message$) {\n" + "if ($is_field_present_message$) {\n" " output.write$group_or_message$($number$, $name$_);\n" "}\n"); } -void MessageFieldGenerator:: +void ImmutableMessageFieldGenerator:: GenerateSerializedSizeCode(io::Printer* printer) const { printer->Print(variables_, - "if ($get_has_field_bit_message$) {\n" + "if ($is_field_present_message$) {\n" " size += com.google.protobuf.CodedOutputStream\n" " .compute$group_or_message$Size($number$, $name$_);\n" "}\n"); } -void MessageFieldGenerator:: +void ImmutableMessageFieldGenerator:: GenerateEqualsCode(io::Printer* printer) const { printer->Print(variables_, "result = result && get$capitalized_name$()\n" " .equals(other.get$capitalized_name$());\n"); } -void MessageFieldGenerator:: +void ImmutableMessageFieldGenerator:: GenerateHashCode(io::Printer* printer) const { printer->Print(variables_, "hash = (37 * hash) + $constant_name$;\n" "hash = (53 * hash) + get$capitalized_name$().hashCode();\n"); } -string MessageFieldGenerator::GetBoxedType() const { - return ClassName(descriptor_->message_type()); +string ImmutableMessageFieldGenerator::GetBoxedType() const { + return name_resolver_->GetImmutableClassName(descriptor_->message_type()); +} + +// =================================================================== + +ImmutableMessageOneofFieldGenerator:: +ImmutableMessageOneofFieldGenerator(const FieldDescriptor* descriptor, + int messageBitIndex, + int builderBitIndex, + Context* context) + : ImmutableMessageFieldGenerator( + descriptor, messageBitIndex, builderBitIndex, context) { + const OneofGeneratorInfo* info = + context->GetOneofGeneratorInfo(descriptor->containing_oneof()); + SetCommonOneofVariables(descriptor, info, &variables_); +} + +ImmutableMessageOneofFieldGenerator:: +~ImmutableMessageOneofFieldGenerator() {} + +void ImmutableMessageOneofFieldGenerator:: +GenerateMembers(io::Printer* printer) const { + PrintExtraFieldInfo(variables_, printer); + if (SupportFieldPresence(descriptor_->file())) { + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public boolean has$capitalized_name$() {\n" + " return $has_oneof_case_message$;\n" + "}\n"); + } + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public $type$ get$capitalized_name$() {\n" + " if ($has_oneof_case_message$) {\n" + " return ($type$) $oneof_name$_;\n" + " }\n" + " return $type$.getDefaultInstance();\n" + "}\n"); + + if (HasNestedBuilders(descriptor_->containing_type())) { + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public $type$OrBuilder get$capitalized_name$OrBuilder() {\n" + " if ($has_oneof_case_message$) {\n" + " return ($type$) $oneof_name$_;\n" + " }\n" + " return $type$.getDefaultInstance();\n" + "}\n"); + } +} + +void ImmutableMessageOneofFieldGenerator:: +GenerateBuilderMembers(io::Printer* printer) const { + // When using nested-builders, the code initially works just like the + // non-nested builder case. It only creates a nested builder lazily on + // demand and then forever delegates to it after creation. + if (HasNestedBuilders(descriptor_->containing_type())) { + printer->Print(variables_, + // If this builder is non-null, it is used and the other fields are + // ignored. + "private com.google.protobuf.SingleFieldBuilder<\n" + " $type$, $type$.Builder, $type$OrBuilder> $name$Builder_;" + "\n"); + } + + // The comments above the methods below are based on a hypothetical + // field of type "Field" called "Field". + + if (SupportFieldPresence(descriptor_->file())) { + // boolean hasField() + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public boolean has$capitalized_name$() {\n" + " return $has_oneof_case_message$;\n" + "}\n"); + } + + // Field getField() + WriteFieldDocComment(printer, descriptor_); + PrintNestedBuilderFunction(printer, + "$deprecation$public $type$ get$capitalized_name$()", + + "if ($has_oneof_case_message$) {\n" + " return ($type$) $oneof_name$_;\n" + "}\n" + "return $type$.getDefaultInstance();\n", + + "if ($has_oneof_case_message$) {\n" + " return $name$Builder_.getMessage();\n" + "}\n" + "return $type$.getDefaultInstance();\n", + + NULL); + + // Field.Builder setField(Field value) + WriteFieldDocComment(printer, descriptor_); + PrintNestedBuilderFunction(printer, + "$deprecation$public Builder set$capitalized_name$($type$ value)", + + "if (value == null) {\n" + " throw new NullPointerException();\n" + "}\n" + "$oneof_name$_ = value;\n" + "$on_changed$\n", + + "$name$Builder_.setMessage(value);\n", + + "$set_oneof_case_message$;\n" + "return this;\n"); + + // Field.Builder setField(Field.Builder builderForValue) + WriteFieldDocComment(printer, descriptor_); + PrintNestedBuilderFunction(printer, + "$deprecation$public Builder set$capitalized_name$(\n" + " $type$.Builder builderForValue)", + + "$oneof_name$_ = builderForValue.build();\n" + "$on_changed$\n", + + "$name$Builder_.setMessage(builderForValue.build());\n", + + "$set_oneof_case_message$;\n" + "return this;\n"); + + // Field.Builder mergeField(Field value) + WriteFieldDocComment(printer, descriptor_); + PrintNestedBuilderFunction(printer, + "$deprecation$public Builder merge$capitalized_name$($type$ value)", + + "if ($has_oneof_case_message$ &&\n" + " $oneof_name$_ != $type$.getDefaultInstance()) {\n" + " $oneof_name$_ = $type$.newBuilder(($type$) $oneof_name$_)\n" + " .mergeFrom(value).buildPartial();\n" + "} else {\n" + " $oneof_name$_ = value;\n" + "}\n" + "$on_changed$\n", + + "if ($has_oneof_case_message$) {\n" + " $name$Builder_.mergeFrom(value);\n" + "}\n" + "$name$Builder_.setMessage(value);\n", + + "$set_oneof_case_message$;\n" + "return this;\n"); + + // Field.Builder clearField() + WriteFieldDocComment(printer, descriptor_); + PrintNestedBuilderFunction(printer, + "$deprecation$public Builder clear$capitalized_name$()", + + "if ($has_oneof_case_message$) {\n" + " $clear_oneof_case_message$;\n" + " $oneof_name$_ = null;\n" + " $on_changed$\n" + "}\n", + + "if ($has_oneof_case_message$) {\n" + " $clear_oneof_case_message$;\n" + " $oneof_name$_ = null;\n" + "}\n" + "$name$Builder_.clear();\n", + + "return this;\n"); + + if (HasNestedBuilders(descriptor_->containing_type())) { + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public $type$.Builder get$capitalized_name$Builder() {\n" + " return get$capitalized_name$FieldBuilder().getBuilder();\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public $type$OrBuilder get$capitalized_name$OrBuilder() {\n" + " if (($has_oneof_case_message$) && ($name$Builder_ != null)) {\n" + " return $name$Builder_.getMessageOrBuilder();\n" + " } else {\n" + " if ($has_oneof_case_message$) {\n" + " return ($type$) $oneof_name$_;\n" + " }\n" + " return $type$.getDefaultInstance();\n" + " }\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "private com.google.protobuf.SingleFieldBuilder<\n" + " $type$, $type$.Builder, $type$OrBuilder> \n" + " get$capitalized_name$FieldBuilder() {\n" + " if ($name$Builder_ == null) {\n" + " if (!($has_oneof_case_message$)) {\n" + " $oneof_name$_ = $type$.getDefaultInstance();\n" + " }\n" + " $name$Builder_ = new com.google.protobuf.SingleFieldBuilder<\n" + " $type$, $type$.Builder, $type$OrBuilder>(\n" + " ($type$) $oneof_name$_,\n" + " getParentForChildren(),\n" + " isClean());\n" + " $oneof_name$_ = null;\n" + " }\n" + " $set_oneof_case_message$;\n" + " return $name$Builder_;\n" + "}\n"); + } +} + +void ImmutableMessageOneofFieldGenerator:: +GenerateBuildingCode(io::Printer* printer) const { + + printer->Print(variables_, + "if ($has_oneof_case_message$) {\n"); + printer->Indent(); + + PrintNestedBuilderCondition(printer, + "result.$oneof_name$_ = $oneof_name$_;\n", + + "result.$oneof_name$_ = $name$Builder_.build();\n"); + + printer->Outdent(); + printer->Print("}\n"); +} + +void ImmutableMessageOneofFieldGenerator:: +GenerateMergingCode(io::Printer* printer) const { + printer->Print(variables_, + "merge$capitalized_name$(other.get$capitalized_name$());\n"); +} + +void ImmutableMessageOneofFieldGenerator:: +GenerateParsingCode(io::Printer* printer) const { + printer->Print(variables_, + "$type$.Builder subBuilder = null;\n" + "if ($has_oneof_case_message$) {\n" + " subBuilder = (($type$) $oneof_name$_).toBuilder();\n" + "}\n"); + + if (GetType(descriptor_) == FieldDescriptor::TYPE_GROUP) { + printer->Print(variables_, + "$oneof_name$_ = input.readGroup($number$, $type$.PARSER,\n" + " extensionRegistry);\n"); + } else { + printer->Print(variables_, + "$oneof_name$_ = input.readMessage($type$.PARSER, extensionRegistry);\n"); + } + + printer->Print(variables_, + "if (subBuilder != null) {\n" + " subBuilder.mergeFrom(($type$) $oneof_name$_);\n" + " $oneof_name$_ = subBuilder.buildPartial();\n" + "}\n"); + printer->Print(variables_, + "$set_oneof_case_message$;\n"); +} + +void ImmutableMessageOneofFieldGenerator:: +GenerateSerializationCode(io::Printer* printer) const { + printer->Print(variables_, + "if ($has_oneof_case_message$) {\n" + " output.write$group_or_message$($number$, ($type$) $oneof_name$_);\n" + "}\n"); +} + +void ImmutableMessageOneofFieldGenerator:: +GenerateSerializedSizeCode(io::Printer* printer) const { + printer->Print(variables_, + "if ($has_oneof_case_message$) {\n" + " size += com.google.protobuf.CodedOutputStream\n" + " .compute$group_or_message$Size($number$, ($type$) $oneof_name$_);\n" + "}\n"); } // =================================================================== -RepeatedMessageFieldGenerator:: -RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor, - int messageBitIndex, - int builderBitIndex) +RepeatedImmutableMessageFieldGenerator:: +RepeatedImmutableMessageFieldGenerator(const FieldDescriptor* descriptor, + int messageBitIndex, + int builderBitIndex, + Context* context) : descriptor_(descriptor), messageBitIndex_(messageBitIndex), - builderBitIndex_(builderBitIndex) { + builderBitIndex_(builderBitIndex), context_(context), + name_resolver_(context->GetNameResolver()) { SetMessageVariables(descriptor, messageBitIndex, builderBitIndex, - &variables_); + context->GetFieldGeneratorInfo(descriptor), + name_resolver_, &variables_); } -RepeatedMessageFieldGenerator::~RepeatedMessageFieldGenerator() {} +RepeatedImmutableMessageFieldGenerator:: +~RepeatedImmutableMessageFieldGenerator() {} -int RepeatedMessageFieldGenerator::GetNumBitsForMessage() const { +int RepeatedImmutableMessageFieldGenerator::GetNumBitsForMessage() const { return 0; } -int RepeatedMessageFieldGenerator::GetNumBitsForBuilder() const { +int RepeatedImmutableMessageFieldGenerator::GetNumBitsForBuilder() const { return 1; } -void RepeatedMessageFieldGenerator:: +void RepeatedImmutableMessageFieldGenerator:: GenerateInterfaceMembers(io::Printer* printer) const { // TODO(jonp): In the future, consider having methods specific to the // interface so that builders can choose dynamically to either return a @@ -499,10 +866,11 @@ GenerateInterfaceMembers(io::Printer* printer) const { } } -void RepeatedMessageFieldGenerator:: +void RepeatedImmutableMessageFieldGenerator:: GenerateMembers(io::Printer* printer) const { printer->Print(variables_, "private java.util.List<$type$> $name$_;\n"); + PrintExtraFieldInfo(variables_, printer); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, "$deprecation$public java.util.List<$type$> get$capitalized_name$List() {\n" @@ -533,7 +901,7 @@ GenerateMembers(io::Printer* printer) const { } -void RepeatedMessageFieldGenerator::PrintNestedBuilderCondition( +void RepeatedImmutableMessageFieldGenerator::PrintNestedBuilderCondition( io::Printer* printer, const char* regular_case, const char* nested_builder_case) const { @@ -552,7 +920,7 @@ void RepeatedMessageFieldGenerator::PrintNestedBuilderCondition( } } -void RepeatedMessageFieldGenerator::PrintNestedBuilderFunction( +void RepeatedImmutableMessageFieldGenerator::PrintNestedBuilderFunction( io::Printer* printer, const char* method_prototype, const char* regular_case, @@ -569,7 +937,7 @@ void RepeatedMessageFieldGenerator::PrintNestedBuilderFunction( printer->Print("}\n"); } -void RepeatedMessageFieldGenerator:: +void RepeatedImmutableMessageFieldGenerator:: GenerateBuilderMembers(io::Printer* printer) const { // When using nested-builders, the code initially works just like the // non-nested builder case. It only creates a nested builder lazily on @@ -737,7 +1105,8 @@ GenerateBuilderMembers(io::Printer* printer) const { " java.lang.Iterable<? extends $type$> values)", "ensure$capitalized_name$IsMutable();\n" - "super.addAll(values, $name$_);\n" + "com.google.protobuf.AbstractMessageLite.Builder.addAll(\n" + " values, $name$_);\n" "$on_changed$\n", "$name$Builder_.addAllMessages(values);\n", @@ -836,18 +1205,18 @@ GenerateBuilderMembers(io::Printer* printer) const { } } -void RepeatedMessageFieldGenerator:: +void RepeatedImmutableMessageFieldGenerator:: GenerateFieldBuilderInitializationCode(io::Printer* printer) const { printer->Print(variables_, "get$capitalized_name$FieldBuilder();\n"); } -void RepeatedMessageFieldGenerator:: +void RepeatedImmutableMessageFieldGenerator:: GenerateInitializationCode(io::Printer* printer) const { printer->Print(variables_, "$name$_ = java.util.Collections.emptyList();\n"); } -void RepeatedMessageFieldGenerator:: +void RepeatedImmutableMessageFieldGenerator:: GenerateBuilderClearCode(io::Printer* printer) const { PrintNestedBuilderCondition(printer, "$name$_ = java.util.Collections.emptyList();\n" @@ -856,7 +1225,7 @@ GenerateBuilderClearCode(io::Printer* printer) const { "$name$Builder_.clear();\n"); } -void RepeatedMessageFieldGenerator:: +void RepeatedImmutableMessageFieldGenerator:: GenerateMergingCode(io::Printer* printer) const { // The code below does two optimizations (non-nested builder case): // 1. If the other list is empty, there's nothing to do. This ensures we @@ -890,7 +1259,7 @@ GenerateMergingCode(io::Printer* printer) const { "}\n"); } -void RepeatedMessageFieldGenerator:: +void RepeatedImmutableMessageFieldGenerator:: GenerateBuildingCode(io::Printer* printer) const { // The code below (non-nested builder case) ensures that the result has an // immutable list. If our list is immutable, we can just reuse it. If not, @@ -905,7 +1274,7 @@ GenerateBuildingCode(io::Printer* printer) const { "result.$name$_ = $name$Builder_.build();\n"); } -void RepeatedMessageFieldGenerator:: +void RepeatedImmutableMessageFieldGenerator:: GenerateParsingCode(io::Printer* printer) const { printer->Print(variables_, "if (!$get_mutable_bit_parser$) {\n" @@ -923,7 +1292,7 @@ GenerateParsingCode(io::Printer* printer) const { } } -void RepeatedMessageFieldGenerator:: +void RepeatedImmutableMessageFieldGenerator:: GenerateParsingDoneCode(io::Printer* printer) const { printer->Print(variables_, "if ($get_mutable_bit_parser$) {\n" @@ -931,7 +1300,7 @@ GenerateParsingDoneCode(io::Printer* printer) const { "}\n"); } -void RepeatedMessageFieldGenerator:: +void RepeatedImmutableMessageFieldGenerator:: GenerateSerializationCode(io::Printer* printer) const { printer->Print(variables_, "for (int i = 0; i < $name$_.size(); i++) {\n" @@ -939,7 +1308,7 @@ GenerateSerializationCode(io::Printer* printer) const { "}\n"); } -void RepeatedMessageFieldGenerator:: +void RepeatedImmutableMessageFieldGenerator:: GenerateSerializedSizeCode(io::Printer* printer) const { printer->Print(variables_, "for (int i = 0; i < $name$_.size(); i++) {\n" @@ -948,14 +1317,14 @@ GenerateSerializedSizeCode(io::Printer* printer) const { "}\n"); } -void RepeatedMessageFieldGenerator:: +void RepeatedImmutableMessageFieldGenerator:: GenerateEqualsCode(io::Printer* printer) const { printer->Print(variables_, "result = result && get$capitalized_name$List()\n" " .equals(other.get$capitalized_name$List());\n"); } -void RepeatedMessageFieldGenerator:: +void RepeatedImmutableMessageFieldGenerator:: GenerateHashCode(io::Printer* printer) const { printer->Print(variables_, "if (get$capitalized_name$Count() > 0) {\n" @@ -964,8 +1333,8 @@ GenerateHashCode(io::Printer* printer) const { "}\n"); } -string RepeatedMessageFieldGenerator::GetBoxedType() const { - return ClassName(descriptor_->message_type()); +string RepeatedImmutableMessageFieldGenerator::GetBoxedType() const { + return name_resolver_->GetImmutableClassName(descriptor_->message_type()); } } // namespace java |