Use bit-field int values in buildPartial to skip work on unset groups of fields.

Changes to make this improvement:
1) All non-repeated builder fields (including maps) now have a presence bit regardless of syntax.
2) The buildPartial method is split into one method per 32-field block (aligned with bit-mask ints)
3) If a presence bit-mask int is set to 0, no fields are present, so we can skip the logic for all of those fields in the buildPartial step.

For messages with a lot of fields (> 100) that are sparsely populated this can result in a significant improvement. Not only does it potentially skip a lot of field copying logic, but also breaks the buildPartial method into chunks that should be more easily digested by the JIT compiler as discussed in this issue: https://github.com/protocolbuffers/protobuf/issues/10247.

PiperOrigin-RevId: 485952448
pull/10960/head
Protobuf Team Bot 2 years ago committed by Jerry Berg
parent accd49b95a
commit b0f7bff40c
  1. 181
      src/google/protobuf/compiler/java/enum_field.cc
  2. 32
      src/google/protobuf/compiler/java/enum_field.h
  3. 2
      src/google/protobuf/compiler/java/field.h
  4. 327
      src/google/protobuf/compiler/java/map_field.cc
  5. 7
      src/google/protobuf/compiler/java/map_field.h
  6. 257
      src/google/protobuf/compiler/java/message_builder.cc
  7. 5
      src/google/protobuf/compiler/java/message_builder.h
  8. 315
      src/google/protobuf/compiler/java/message_field.cc
  9. 57
      src/google/protobuf/compiler/java/message_field.h
  10. 199
      src/google/protobuf/compiler/java/primitive_field.cc
  11. 33
      src/google/protobuf/compiler/java/primitive_field.h
  12. 145
      src/google/protobuf/compiler/java/string_field.cc
  13. 32
      src/google/protobuf/compiler/java/string_field.h

@ -32,24 +32,24 @@
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
#include <google/protobuf/compiler/java/enum_field.h>
#include "google/protobuf/compiler/java/enum_field.h"
#include <cstdint>
#include <map>
#include <string>
#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/io/printer.h>
#include <google/protobuf/wire_format.h>
#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/compiler/java/context.h>
#include <google/protobuf/compiler/java/doc_comment.h>
#include <google/protobuf/compiler/java/helpers.h>
#include <google/protobuf/compiler/java/name_resolver.h>
#include "google/protobuf/stubs/logging.h"
#include "google/protobuf/stubs/common.h"
#include "google/protobuf/io/printer.h"
#include "google/protobuf/wire_format.h"
#include "google/protobuf/stubs/strutil.h"
#include "google/protobuf/compiler/java/context.h"
#include "google/protobuf/compiler/java/doc_comment.h"
#include "google/protobuf/compiler/java/helpers.h"
#include "google/protobuf/compiler/java/name_resolver.h"
// Must be last.
#include <google/protobuf/port_def.inc>
#include "google/protobuf/port_def.inc"
namespace google {
namespace protobuf {
@ -58,10 +58,11 @@ namespace java {
namespace {
void SetEnumVariables(const FieldDescriptor* descriptor, int messageBitIndex,
int builderBitIndex, const FieldGeneratorInfo* info,
ClassNameResolver* name_resolver,
std::map<std::string, std::string>* variables) {
void SetEnumVariables(
const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex,
const FieldGeneratorInfo* info, ClassNameResolver* name_resolver,
std::map<std::string, std::string>* variables,
Context* context) {
SetCommonFieldVariables(descriptor, info, variables);
(*variables)["type"] =
@ -80,40 +81,27 @@ void SetEnumVariables(const FieldDescriptor* descriptor, int messageBitIndex,
// by the proto compiler
(*variables)["deprecation"] =
descriptor->options().deprecated() ? "@java.lang.Deprecated " : "";
(*variables)["kt_deprecation"] =
descriptor->options().deprecated()
? "@kotlin.Deprecated(message = \"Field " + (*variables)["name"] +
" is deprecated\") "
: "";
(*variables)["on_changed"] = "onChanged();";
// Use deprecated valueOf() method to be compatible with old generated code
// for v2.5.0/v2.6.1.
// TODO(xiaofeng): Use "forNumber" when we no longer support compatibility
// with v2.5.0/v2.6.1, and remove the @SuppressWarnings annotations.
(*variables)["for_number"] = "valueOf";
variables->insert(
{"kt_deprecation",
descriptor->options().deprecated()
? StrCat("@kotlin.Deprecated(message = \"Field ",
(*variables)["name"], " is deprecated\") ")
: ""});
if (HasHasbit(descriptor)) {
// 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)["set_has_field_bit_to_local"] =
GenerateSetBitToLocal(messageBitIndex);
(*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"] + "_ != " + (*variables)["default"] +
".getNumber()";
(*variables)["set_has_field_bit_to_local"] = "";
variables->insert({"is_field_present_message",
StrCat((*variables)["name"], "_ != ",
(*variables)["default"], ".getNumber()")});
}
// For repeated builders, one bit is used for whether the array is immutable.
@ -121,15 +109,21 @@ void SetEnumVariables(const FieldDescriptor* descriptor, int messageBitIndex,
(*variables)["set_mutable_bit_builder"] = GenerateSetBit(builderBitIndex);
(*variables)["clear_mutable_bit_builder"] = GenerateClearBit(builderBitIndex);
(*variables)["get_has_field_bit_builder"] = GenerateGetBit(builderBitIndex);
// Note that these have a trailing ";".
(*variables)["set_has_field_bit_builder"] =
GenerateSetBit(builderBitIndex) + ";";
(*variables)["clear_has_field_bit_builder"] =
GenerateClearBit(builderBitIndex) + ";";
(*variables)["get_has_field_bit_from_local"] =
GenerateGetBitFromLocal(builderBitIndex);
(*variables)["set_has_field_bit_to_local"] =
GenerateSetBitToLocal(messageBitIndex);
if (SupportUnknownEnumValue(descriptor->file())) {
(*variables)["unknown"] = (*variables)["type"] + ".UNRECOGNIZED";
variables->insert(
{"unknown", StrCat((*variables)["type"], ".UNRECOGNIZED")});
} else {
(*variables)["unknown"] = (*variables)["default"];
variables->insert({"unknown", (*variables)["default"]});
}
}
@ -140,21 +134,30 @@ void SetEnumVariables(const FieldDescriptor* descriptor, int messageBitIndex,
ImmutableEnumFieldGenerator::ImmutableEnumFieldGenerator(
const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex,
Context* context)
: descriptor_(descriptor), name_resolver_(context->GetNameResolver()) {
: descriptor_(descriptor),
message_bit_index_(messageBitIndex),
builder_bit_index_(builderBitIndex),
name_resolver_(context->GetNameResolver()) {
SetEnumVariables(descriptor, messageBitIndex, builderBitIndex,
context->GetFieldGeneratorInfo(descriptor), name_resolver_,
&variables_);
&variables_, context);
}
ImmutableEnumFieldGenerator::~ImmutableEnumFieldGenerator() {}
int ImmutableEnumFieldGenerator::GetMessageBitIndex() const {
return message_bit_index_;
}
int ImmutableEnumFieldGenerator::GetBuilderBitIndex() const {
return builder_bit_index_;
}
int ImmutableEnumFieldGenerator::GetNumBitsForMessage() const {
return HasHasbit(descriptor_) ? 1 : 0;
}
int ImmutableEnumFieldGenerator::GetNumBitsForBuilder() const {
return GetNumBitsForMessage();
}
int ImmutableEnumFieldGenerator::GetNumBitsForBuilder() const { return 1; }
void ImmutableEnumFieldGenerator::GenerateInterfaceMembers(
io::Printer* printer) const {
@ -173,7 +176,7 @@ void ImmutableEnumFieldGenerator::GenerateInterfaceMembers(
}
void ImmutableEnumFieldGenerator::GenerateMembers(io::Printer* printer) const {
printer->Print(variables_, "private int $name$_;\n");
printer->Print(variables_, "private int $name$_ = $default_number$;\n");
PrintExtraFieldInfo(variables_, printer);
if (HasHazzer(descriptor_)) {
WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
@ -197,8 +200,7 @@ void ImmutableEnumFieldGenerator::GenerateMembers(io::Printer* printer) const {
printer->Print(variables_,
"@java.lang.Override $deprecation$public $type$ "
"${$get$capitalized_name$$}$() {\n"
" @SuppressWarnings(\"deprecation\")\n"
" $type$ result = $type$.$for_number$($name$_);\n"
" $type$ result = $type$.forNumber($name$_);\n"
" return result == null ? $unknown$ : result;\n"
"}\n");
printer->Annotate("{", "}", descriptor_);
@ -229,9 +231,9 @@ void ImmutableEnumFieldGenerator::GenerateBuilderMembers(
printer->Print(variables_,
"$deprecation$public Builder "
"${$set$capitalized_name$Value$}$(int value) {\n"
" $set_has_field_bit_builder$\n"
" $name$_ = value;\n"
" $on_changed$\n"
" $set_has_field_bit_builder$\n"
" onChanged();\n"
" return this;\n"
"}\n");
printer->Annotate("{", "}", descriptor_);
@ -240,8 +242,7 @@ void ImmutableEnumFieldGenerator::GenerateBuilderMembers(
printer->Print(variables_,
"@java.lang.Override\n"
"$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
" @SuppressWarnings(\"deprecation\")\n"
" $type$ result = $type$.$for_number$($name$_);\n"
" $type$ result = $type$.forNumber($name$_);\n"
" return result == null ? $unknown$ : result;\n"
"}\n");
printer->Annotate("{", "}", descriptor_);
@ -255,7 +256,7 @@ void ImmutableEnumFieldGenerator::GenerateBuilderMembers(
" }\n"
" $set_has_field_bit_builder$\n"
" $name$_ = value.getNumber();\n"
" $on_changed$\n"
" onChanged();\n"
" return this;\n"
"}\n");
printer->Annotate("{", "}", descriptor_);
@ -266,7 +267,7 @@ void ImmutableEnumFieldGenerator::GenerateBuilderMembers(
"$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n"
" $clear_has_field_bit_builder$\n"
" $name$_ = $default_number$;\n"
" $on_changed$\n"
" onChanged();\n"
" return this;\n"
"}\n");
printer->Annotate("{", "}", descriptor_);
@ -313,9 +314,7 @@ void ImmutableEnumFieldGenerator::GenerateInitializationCode(
void ImmutableEnumFieldGenerator::GenerateBuilderClearCode(
io::Printer* printer) const {
printer->Print(variables_,
"$name$_ = $default_number$;\n"
"$clear_has_field_bit_builder$\n");
printer->Print(variables_, "$name$_ = $default_number$;\n");
}
void ImmutableEnumFieldGenerator::GenerateMergingCode(
@ -338,13 +337,13 @@ void ImmutableEnumFieldGenerator::GenerateMergingCode(
void ImmutableEnumFieldGenerator::GenerateBuildingCode(
io::Printer* printer) const {
if (HasHazzer(descriptor_)) {
printer->Print(variables_,
"if ($get_has_field_bit_from_local$) {\n"
" $set_has_field_bit_to_local$;\n"
"}\n");
printer->Print(variables_,
"if ($get_has_field_bit_from_local$) {\n"
" result.$name$_ = $name$_;\n");
if (GetNumBitsForMessage() > 0) {
printer->Print(variables_, " $set_has_field_bit_to_local$;\n");
}
printer->Print(variables_, "result.$name$_ = $name$_;\n");
printer->Print("}\n");
}
void ImmutableEnumFieldGenerator::GenerateBuilderParsingCode(
@ -440,8 +439,7 @@ void ImmutableEnumOneofFieldGenerator::GenerateMembers(
printer->Print(variables_,
"$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
" if ($has_oneof_case_message$) {\n"
" @SuppressWarnings(\"deprecation\")\n"
" $type$ result = $type$.$for_number$(\n"
" $type$ result = $type$.forNumber(\n"
" (java.lang.Integer) $oneof_name$_);\n"
" return result == null ? $unknown$ : result;\n"
" }\n"
@ -480,7 +478,7 @@ void ImmutableEnumOneofFieldGenerator::GenerateBuilderMembers(
"${$set$capitalized_name$Value$}$(int value) {\n"
" $set_oneof_case_message$;\n"
" $oneof_name$_ = value;\n"
" $on_changed$\n"
" onChanged();\n"
" return this;\n"
"}\n");
printer->Annotate("{", "}", descriptor_);
@ -490,14 +488,14 @@ void ImmutableEnumOneofFieldGenerator::GenerateBuilderMembers(
"@java.lang.Override\n"
"$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
" if ($has_oneof_case_message$) {\n"
" @SuppressWarnings(\"deprecation\")\n"
" $type$ result = $type$.$for_number$(\n"
" $type$ result = $type$.forNumber(\n"
" (java.lang.Integer) $oneof_name$_);\n"
" return result == null ? $unknown$ : result;\n"
" }\n"
" return $default$;\n"
"}\n");
printer->Annotate("{", "}", descriptor_);
WriteFieldAccessorDocComment(printer, descriptor_, SETTER,
/* builder */ true);
printer->Print(variables_,
@ -508,10 +506,11 @@ void ImmutableEnumOneofFieldGenerator::GenerateBuilderMembers(
" }\n"
" $set_oneof_case_message$;\n"
" $oneof_name$_ = value.getNumber();\n"
" $on_changed$\n"
" onChanged();\n"
" return this;\n"
"}\n");
printer->Annotate("{", "}", descriptor_);
WriteFieldAccessorDocComment(printer, descriptor_, CLEARER,
/* builder */ true);
printer->Print(
@ -520,7 +519,7 @@ void ImmutableEnumOneofFieldGenerator::GenerateBuilderMembers(
" if ($has_oneof_case_message$) {\n"
" $clear_oneof_case_message$;\n"
" $oneof_name$_ = null;\n"
" $on_changed$\n"
" onChanged();\n"
" }\n"
" return this;\n"
"}\n");
@ -534,10 +533,7 @@ void ImmutableEnumOneofFieldGenerator::GenerateBuilderClearCode(
void ImmutableEnumOneofFieldGenerator::GenerateBuildingCode(
io::Printer* printer) const {
printer->Print(variables_,
"if ($has_oneof_case_message$) {\n"
" result.$oneof_name$_ = $oneof_name$_;\n"
"}\n");
// No-Op: Handled by single statement for the oneof
}
void ImmutableEnumOneofFieldGenerator::GenerateMergingCode(
@ -626,11 +622,8 @@ void ImmutableEnumOneofFieldGenerator::GenerateHashCode(
RepeatedImmutableEnumFieldGenerator::RepeatedImmutableEnumFieldGenerator(
const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex,
Context* context)
: descriptor_(descriptor), name_resolver_(context->GetNameResolver()) {
SetEnumVariables(descriptor, messageBitIndex, builderBitIndex,
context->GetFieldGeneratorInfo(descriptor), name_resolver_,
&variables_);
}
: ImmutableEnumFieldGenerator(descriptor, messageBitIndex, builderBitIndex,
context) {}
RepeatedImmutableEnumFieldGenerator::~RepeatedImmutableEnumFieldGenerator() {}
@ -670,6 +663,7 @@ void RepeatedImmutableEnumFieldGenerator::GenerateMembers(
io::Printer* printer) const {
printer->Print(
variables_,
"@SuppressWarnings(\"serial\")\n"
"private java.util.List<java.lang.Integer> $name$_;\n"
"private static final "
"com.google.protobuf.Internal.ListAdapter.Converter<\n"
@ -677,8 +671,7 @@ void RepeatedImmutableEnumFieldGenerator::GenerateMembers(
" new com.google.protobuf.Internal.ListAdapter.Converter<\n"
" java.lang.Integer, $type$>() {\n"
" public $type$ convert(java.lang.Integer from) {\n"
" @SuppressWarnings(\"deprecation\")\n"
" $type$ result = $type$.$for_number$(from);\n"
" $type$ result = $type$.forNumber(from);\n"
" return result == null ? $unknown$ : result;\n"
" }\n"
" };\n");
@ -794,7 +787,7 @@ void RepeatedImmutableEnumFieldGenerator::GenerateBuilderMembers(
" }\n"
" ensure$capitalized_name$IsMutable();\n"
" $name$_.set(index, value.getNumber());\n"
" $on_changed$\n"
" onChanged();\n"
" return this;\n"
"}\n");
printer->Annotate("{", "}", descriptor_);
@ -808,7 +801,7 @@ void RepeatedImmutableEnumFieldGenerator::GenerateBuilderMembers(
" }\n"
" ensure$capitalized_name$IsMutable();\n"
" $name$_.add(value.getNumber());\n"
" $on_changed$\n"
" onChanged();\n"
" return this;\n"
"}\n");
printer->Annotate("{", "}", descriptor_);
@ -821,7 +814,7 @@ void RepeatedImmutableEnumFieldGenerator::GenerateBuilderMembers(
" for ($type$ value : values) {\n"
" $name$_.add(value.getNumber());\n"
" }\n"
" $on_changed$\n"
" onChanged();\n"
" return this;\n"
"}\n");
printer->Annotate("{", "}", descriptor_);
@ -832,7 +825,7 @@ void RepeatedImmutableEnumFieldGenerator::GenerateBuilderMembers(
"$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n"
" $name$_ = java.util.Collections.emptyList();\n"
" $clear_mutable_bit_builder$;\n"
" $on_changed$\n"
" onChanged();\n"
" return this;\n"
"}\n");
printer->Annotate("{", "}", descriptor_);
@ -862,7 +855,7 @@ void RepeatedImmutableEnumFieldGenerator::GenerateBuilderMembers(
" int index, int value) {\n"
" ensure$capitalized_name$IsMutable();\n"
" $name$_.set(index, value);\n"
" $on_changed$\n"
" onChanged();\n"
" return this;\n"
"}\n");
printer->Annotate("{", "}", descriptor_);
@ -873,7 +866,7 @@ void RepeatedImmutableEnumFieldGenerator::GenerateBuilderMembers(
"${$add$capitalized_name$Value$}$(int value) {\n"
" ensure$capitalized_name$IsMutable();\n"
" $name$_.add(value);\n"
" $on_changed$\n"
" onChanged();\n"
" return this;\n"
"}\n");
printer->Annotate("{", "}", descriptor_);
@ -887,7 +880,7 @@ void RepeatedImmutableEnumFieldGenerator::GenerateBuilderMembers(
" for (int value : values) {\n"
" $name$_.add(value);\n"
" }\n"
" $on_changed$\n"
" onChanged();\n"
" return this;\n"
"}\n");
printer->Annotate("{", "}", descriptor_);
@ -927,7 +920,7 @@ void RepeatedImmutableEnumFieldGenerator::GenerateMergingCode(
" ensure$capitalized_name$IsMutable();\n"
" $name$_.addAll(other.$name$_);\n"
" }\n"
" $on_changed$\n"
" onChanged();\n"
"}\n");
}
@ -1154,4 +1147,4 @@ std::string RepeatedImmutableEnumFieldGenerator::GetBoxedType() const {
} // namespace protobuf
} // namespace google
#include <google/protobuf/port_undef.inc>
#include "google/protobuf/port_undef.inc"

@ -38,7 +38,7 @@
#include <map>
#include <string>
#include <google/protobuf/compiler/java/field.h>
#include "google/protobuf/compiler/java/field.h"
namespace google {
namespace protobuf {
@ -61,10 +61,15 @@ class ImmutableEnumFieldGenerator : public ImmutableFieldGenerator {
explicit ImmutableEnumFieldGenerator(const FieldDescriptor* descriptor,
int messageBitIndex, int builderBitIndex,
Context* context);
ImmutableEnumFieldGenerator(const ImmutableEnumFieldGenerator&) = delete;
ImmutableEnumFieldGenerator& operator=(const ImmutableEnumFieldGenerator&) =
delete;
~ImmutableEnumFieldGenerator() override;
// implements ImmutableFieldGenerator
// ---------------------------------------
int GetMessageBitIndex() const override;
int GetBuilderBitIndex() const override;
int GetNumBitsForMessage() const override;
int GetNumBitsForBuilder() const override;
void GenerateInterfaceMembers(io::Printer* printer) const override;
@ -87,11 +92,10 @@ class ImmutableEnumFieldGenerator : public ImmutableFieldGenerator {
protected:
const FieldDescriptor* descriptor_;
int message_bit_index_;
int builder_bit_index_;
std::map<std::string, std::string> variables_;
ClassNameResolver* name_resolver_;
private:
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableEnumFieldGenerator);
};
class ImmutableEnumOneofFieldGenerator : public ImmutableEnumFieldGenerator {
@ -99,6 +103,10 @@ class ImmutableEnumOneofFieldGenerator : public ImmutableEnumFieldGenerator {
ImmutableEnumOneofFieldGenerator(const FieldDescriptor* descriptor,
int messageBitIndex, int builderBitIndex,
Context* context);
ImmutableEnumOneofFieldGenerator(const ImmutableEnumOneofFieldGenerator&) =
delete;
ImmutableEnumOneofFieldGenerator& operator=(
const ImmutableEnumOneofFieldGenerator&) = delete;
~ImmutableEnumOneofFieldGenerator() override;
void GenerateMembers(io::Printer* printer) const override;
@ -111,16 +119,17 @@ class ImmutableEnumOneofFieldGenerator : public ImmutableEnumFieldGenerator {
void GenerateSerializedSizeCode(io::Printer* printer) const override;
void GenerateEqualsCode(io::Printer* printer) const override;
void GenerateHashCode(io::Printer* printer) const override;
private:
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableEnumOneofFieldGenerator);
};
class RepeatedImmutableEnumFieldGenerator : public ImmutableFieldGenerator {
class RepeatedImmutableEnumFieldGenerator : public ImmutableEnumFieldGenerator {
public:
explicit RepeatedImmutableEnumFieldGenerator(
const FieldDescriptor* descriptor, int messageBitIndex,
int builderBitIndex, Context* context);
RepeatedImmutableEnumFieldGenerator(
const RepeatedImmutableEnumFieldGenerator&) = delete;
RepeatedImmutableEnumFieldGenerator& operator=(
const RepeatedImmutableEnumFieldGenerator&) = delete;
~RepeatedImmutableEnumFieldGenerator() override;
// implements ImmutableFieldGenerator ---------------------------------------
@ -145,13 +154,6 @@ class RepeatedImmutableEnumFieldGenerator : public ImmutableFieldGenerator {
void GenerateKotlinDslMembers(io::Printer* printer) const override;
std::string GetBoxedType() const override;
private:
const FieldDescriptor* descriptor_;
std::map<std::string, std::string> variables_;
ClassNameResolver* name_resolver_;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedImmutableEnumFieldGenerator);
};
} // namespace java

@ -68,6 +68,8 @@ class ImmutableFieldGenerator {
ImmutableFieldGenerator() {}
virtual ~ImmutableFieldGenerator();
virtual int GetMessageBitIndex() const = 0;
virtual int GetBuilderBitIndex() const = 0;
virtual int GetNumBitsForMessage() const = 0;
virtual int GetNumBitsForBuilder() const = 0;
virtual void GenerateInterfaceMembers(io::Printer* printer) const = 0;

@ -28,16 +28,16 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <google/protobuf/compiler/java/map_field.h>
#include "google/protobuf/compiler/java/map_field.h"
#include <google/protobuf/io/printer.h>
#include <google/protobuf/compiler/java/context.h>
#include <google/protobuf/compiler/java/doc_comment.h>
#include <google/protobuf/compiler/java/helpers.h>
#include <google/protobuf/compiler/java/name_resolver.h>
#include "google/protobuf/io/printer.h"
#include "google/protobuf/compiler/java/context.h"
#include "google/protobuf/compiler/java/doc_comment.h"
#include "google/protobuf/compiler/java/helpers.h"
#include "google/protobuf/compiler/java/name_resolver.h"
// Must be last.
#include <google/protobuf/port_def.inc>
#include "google/protobuf/port_def.inc"
namespace google {
namespace protobuf {
@ -88,10 +88,10 @@ std::string WireType(const FieldDescriptor* field) {
std::string(FieldTypeName(field->type()));
}
void SetMessageVariables(const FieldDescriptor* descriptor, int messageBitIndex,
int builderBitIndex, const FieldGeneratorInfo* info,
Context* context,
std::map<std::string, std::string>* variables) {
void SetMessageVariables(
const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex,
const FieldGeneratorInfo* info, Context* context,
std::map<std::string, std::string>* variables) {
SetCommonFieldVariables(descriptor, info, variables);
ClassNameResolver* name_resolver = context->GetNameResolver();
@ -120,13 +120,14 @@ void SetMessageVariables(const FieldDescriptor* descriptor, int messageBitIndex,
: "";
(*variables)["value_null_check"] =
valueJavaType != JAVATYPE_ENUM && IsReferenceType(valueJavaType)
? "if (value == null) {\n"
" throw new NullPointerException(\"map value\");\n"
"}\n"
? "if (value == null) { "
"throw new NullPointerException(\"map value\"); }"
: "";
if (valueJavaType == JAVATYPE_ENUM) {
// We store enums as Integers internally.
(*variables)["value_type"] = "int";
variables->insert(
{"value_type_pass_through_nullness", (*variables)["value_type"]});
(*variables)["boxed_value_type"] = "java.lang.Integer";
(*variables)["value_wire_type"] = WireType(value);
(*variables)["value_default_value"] =
@ -134,13 +135,15 @@ void SetMessageVariables(const FieldDescriptor* descriptor, int messageBitIndex,
(*variables)["value_enum_type"] = TypeName(value, name_resolver, false);
(*variables)["value_enum_type_pass_through_nullness"] =
pass_through_nullness + (*variables)["value_enum_type"];
variables->insert(
{"value_enum_type_pass_through_nullness",
StrCat(pass_through_nullness, (*variables)["value_enum_type"])});
if (SupportUnknownEnumValue(descriptor->file())) {
// Map unknown values to a special UNRECOGNIZED value if supported.
(*variables)["unrecognized_value"] =
(*variables)["value_enum_type"] + ".UNRECOGNIZED";
variables->insert(
{"unrecognized_value",
StrCat((*variables)["value_enum_type"], ".UNRECOGNIZED")});
} else {
// Map unknown values to the default value if we don't have UNRECOGNIZED.
(*variables)["unrecognized_value"] =
@ -149,35 +152,48 @@ void SetMessageVariables(const FieldDescriptor* descriptor, int messageBitIndex,
} else {
(*variables)["value_type"] = TypeName(value, name_resolver, false);
(*variables)["value_type_pass_through_nullness"] =
(IsReferenceType(valueJavaType) ? pass_through_nullness : "") +
(*variables)["value_type"];
variables->insert(
{"value_type_pass_through_nullness",
StrCat(
(IsReferenceType(valueJavaType) ? pass_through_nullness : ""),
(*variables)["value_type"])});
(*variables)["boxed_value_type"] = TypeName(value, name_resolver, true);
(*variables)["value_wire_type"] = WireType(value);
(*variables)["value_default_value"] =
DefaultValue(value, true, name_resolver);
}
(*variables)["type_parameters"] =
(*variables)["boxed_key_type"] + ", " + (*variables)["boxed_value_type"];
variables->insert(
{"type_parameters", StrCat((*variables)["boxed_key_type"], ", ",
(*variables)["boxed_value_type"])});
// TODO(birdo): Add @deprecated javadoc when generating javadoc is supported
// by the proto compiler
(*variables)["deprecation"] =
descriptor->options().deprecated() ? "@java.lang.Deprecated " : "";
(*variables)["kt_deprecation"] =
descriptor->options().deprecated()
? "@kotlin.Deprecated(message = \"Field " + (*variables)["name"] +
" is deprecated\") "
: "";
variables->insert(
{"kt_deprecation",
descriptor->options().deprecated()
? StrCat("@kotlin.Deprecated(message = \"Field ",
(*variables)["name"], " is deprecated\") ")
: ""});
(*variables)["on_changed"] = "onChanged();";
(*variables)["default_entry"] =
(*variables)["capitalized_name"] + "DefaultEntryHolder.defaultEntry";
(*variables)["map_field_parameter"] = (*variables)["default_entry"];
variables->insert(
{"default_entry", StrCat((*variables)["capitalized_name"],
"DefaultEntryHolder.defaultEntry")});
variables->insert({"map_field_parameter", (*variables)["default_entry"]});
(*variables)["descriptor"] =
name_resolver->GetImmutableClassName(descriptor->file()) + ".internal_" +
UniqueFileScopeIdentifier(descriptor->message_type()) + "_descriptor, ";
(*variables)["ver"] = GeneratedCodeVersionSuffix();
(*variables)["get_has_field_bit_builder"] = GenerateGetBit(builderBitIndex);
(*variables)["get_has_field_bit_from_local"] =
GenerateGetBitFromLocal(builderBitIndex);
(*variables)["set_has_field_bit_builder"] =
GenerateSetBit(builderBitIndex) + ";";
(*variables)["clear_has_field_bit_builder"] =
GenerateClearBit(builderBitIndex) + ";";
}
} // namespace
@ -185,7 +201,11 @@ void SetMessageVariables(const FieldDescriptor* descriptor, int messageBitIndex,
ImmutableMapFieldGenerator::ImmutableMapFieldGenerator(
const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex,
Context* context)
: descriptor_(descriptor), name_resolver_(context->GetNameResolver()) {
: descriptor_(descriptor),
message_bit_index_(messageBitIndex),
builder_bit_index_(builderBitIndex),
name_resolver_(context->GetNameResolver()),
context_(context) {
SetMessageVariables(descriptor, messageBitIndex, builderBitIndex,
context->GetFieldGeneratorInfo(descriptor), context,
&variables_);
@ -193,6 +213,14 @@ ImmutableMapFieldGenerator::ImmutableMapFieldGenerator(
ImmutableMapFieldGenerator::~ImmutableMapFieldGenerator() {}
int ImmutableMapFieldGenerator::GetMessageBitIndex() const {
return message_bit_index_;
}
int ImmutableMapFieldGenerator::GetBuilderBitIndex() const {
return builder_bit_index_;
}
int ImmutableMapFieldGenerator::GetNumBitsForMessage() const { return 0; }
int ImmutableMapFieldGenerator::GetNumBitsForBuilder() const { return 1; }
@ -254,16 +282,16 @@ void ImmutableMapFieldGenerator::GenerateInterfaceMembers(
printer->Annotate("{", "}", descriptor_);
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$\n"
"$value_type$ ${$get$capitalized_name$ValueOrDefault$}$(\n"
"$deprecation$$value_type_pass_through_nullness$ "
"${$get$capitalized_name$ValueOrDefault$}$(\n"
" $key_type$ key,\n"
" $value_type$ defaultValue);\n");
" $value_type_pass_through_nullness$ defaultValue);\n");
printer->Annotate("{", "}", descriptor_);
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$\n"
"$value_type$ ${$get$capitalized_name$ValueOrThrow$}$(\n"
" $key_type$ key);\n");
printer->Print(
variables_,
"$deprecation$$value_type$ ${$get$capitalized_name$ValueOrThrow$}$(\n"
" $key_type$ key);\n");
printer->Annotate("{", "}", descriptor_);
}
} else {
@ -282,17 +310,16 @@ void ImmutableMapFieldGenerator::GenerateInterfaceMembers(
printer->Annotate("{", "}", descriptor_);
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$\n"
"$value_type_pass_through_nullness$ "
"$deprecation$$value_type_pass_through_nullness$ "
"${$get$capitalized_name$OrDefault$}$(\n"
" $key_type$ key,\n"
" $value_type_pass_through_nullness$ defaultValue);\n");
printer->Annotate("{", "}", descriptor_);
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$\n"
"$value_type$ ${$get$capitalized_name$OrThrow$}$(\n"
" $key_type$ key);\n");
printer->Print(
variables_,
"$deprecation$$value_type$ ${$get$capitalized_name$OrThrow$}$(\n"
" $key_type$ key);\n");
printer->Annotate("{", "}", descriptor_);
}
}
@ -312,6 +339,7 @@ void ImmutableMapFieldGenerator::GenerateMembers(io::Printer* printer) const {
" $value_default_value$);\n"
"}\n");
printer->Print(variables_,
"@SuppressWarnings(\"serial\")\n"
"private com.google.protobuf.MapField<\n"
" $type_parameters$> $name$_;\n"
"private com.google.protobuf.MapField<$type_parameters$>\n"
@ -347,42 +375,45 @@ void ImmutableMapFieldGenerator::GenerateMembers(io::Printer* printer) const {
void ImmutableMapFieldGenerator::GenerateBuilderMembers(
io::Printer* printer) const {
printer->Print(variables_,
"private com.google.protobuf.MapField<\n"
" $type_parameters$> $name$_;\n"
"private com.google.protobuf.MapField<$type_parameters$>\n"
"internalGet$capitalized_name$() {\n"
" if ($name$_ == null) {\n"
" return com.google.protobuf.MapField.emptyMapField(\n"
" $map_field_parameter$);\n"
" }\n"
" return $name$_;\n"
"}\n"
"private com.google.protobuf.MapField<$type_parameters$>\n"
"internalGetMutable$capitalized_name$() {\n"
" $on_changed$;\n"
" if ($name$_ == null) {\n"
" $name$_ = com.google.protobuf.MapField.newMapField(\n"
" $map_field_parameter$);\n"
" }\n"
" if (!$name$_.isMutable()) {\n"
" $name$_ = $name$_.copy();\n"
" }\n"
" return $name$_;\n"
"}\n");
printer->Print(
variables_,
"private com.google.protobuf.MapField<\n"
" $type_parameters$> $name$_;\n"
"$deprecation$private com.google.protobuf.MapField<$type_parameters$>\n"
" internalGet$capitalized_name$() {\n"
" if ($name$_ == null) {\n"
" return com.google.protobuf.MapField.emptyMapField(\n"
" $map_field_parameter$);\n"
" }\n"
" return $name$_;\n"
"}\n"
"$deprecation$private com.google.protobuf.MapField<$type_parameters$>\n"
" internalGetMutable$capitalized_name$() {\n"
" if ($name$_ == null) {\n"
" $name$_ = com.google.protobuf.MapField.newMapField(\n"
" $map_field_parameter$);\n"
" }\n"
" if (!$name$_.isMutable()) {\n"
" $name$_ = $name$_.copy();\n"
" }\n"
" $set_has_field_bit_builder$\n"
" $on_changed$\n"
" return $name$_;\n"
"}\n");
GenerateMapGetters(printer);
printer->Print(variables_,
"$deprecation$\n"
"public Builder ${$clear$capitalized_name$$}$() {\n"
" internalGetMutable$capitalized_name$().getMutableMap()\n"
" .clear();\n"
" return this;\n"
"}\n");
printer->Print(
variables_,
"$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n"
" $clear_has_field_bit_builder$\n"
" internalGetMutable$capitalized_name$().getMutableMap()\n"
" .clear();\n"
" return this;\n"
"}\n");
printer->Annotate("{", "}", descriptor_);
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$\n"
"public Builder ${$remove$capitalized_name$$}$(\n"
"$deprecation$public Builder ${$remove$capitalized_name$$}$(\n"
" $key_type$ key) {\n"
" $key_null_check$\n"
" internalGetMutable$capitalized_name$().getMutableMap()\n"
@ -390,6 +421,7 @@ void ImmutableMapFieldGenerator::GenerateBuilderMembers(
" return this;\n"
"}\n");
printer->Annotate("{", "}", descriptor_);
if (GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) {
printer->Print(
variables_,
@ -398,7 +430,8 @@ void ImmutableMapFieldGenerator::GenerateBuilderMembers(
" */\n"
"@java.lang.Deprecated\n"
"public java.util.Map<$boxed_key_type$, $value_enum_type$>\n"
"${$getMutable$capitalized_name$$}$() {\n"
" ${$getMutable$capitalized_name$$}$() {\n"
" $set_has_field_bit_builder$\n"
" return internalGetAdapted$capitalized_name$Map(\n"
" internalGetMutable$capitalized_name$().getMutableMap());\n"
"}\n");
@ -412,9 +445,11 @@ void ImmutableMapFieldGenerator::GenerateBuilderMembers(
" $value_null_check$\n"
" internalGetMutable$capitalized_name$().getMutableMap()\n"
" .put(key, $name$ValueConverter.doBackward(value));\n"
" $set_has_field_bit_builder$\n"
" return this;\n"
"}\n");
printer->Annotate("{", "}", descriptor_);
WriteFieldDocComment(printer, descriptor_);
printer->Print(
variables_,
@ -423,9 +458,11 @@ void ImmutableMapFieldGenerator::GenerateBuilderMembers(
" internalGetAdapted$capitalized_name$Map(\n"
" internalGetMutable$capitalized_name$().getMutableMap())\n"
" .putAll(values);\n"
" $set_has_field_bit_builder$\n"
" return this;\n"
"}\n");
printer->Annotate("{", "}", descriptor_);
if (SupportUnknownEnumValue(descriptor_->file())) {
printer->Print(
variables_,
@ -435,6 +472,7 @@ void ImmutableMapFieldGenerator::GenerateBuilderMembers(
"@java.lang.Deprecated\n"
"public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n"
"${$getMutable$capitalized_name$Value$}$() {\n"
" $set_has_field_bit_builder$\n"
" return internalGetMutable$capitalized_name$().getMutableMap();\n"
"}\n");
printer->Annotate("{", "}", descriptor_);
@ -448,9 +486,11 @@ void ImmutableMapFieldGenerator::GenerateBuilderMembers(
" $value_null_check$\n"
" internalGetMutable$capitalized_name$().getMutableMap()\n"
" .put(key, value);\n"
" $set_has_field_bit_builder$\n"
" return this;\n"
"}\n");
printer->Annotate("{", "}", descriptor_);
WriteFieldDocComment(printer, descriptor_);
printer->Print(
variables_,
@ -458,6 +498,7 @@ void ImmutableMapFieldGenerator::GenerateBuilderMembers(
" java.util.Map<$boxed_key_type$, $boxed_value_type$> values) {\n"
" internalGetMutable$capitalized_name$().getMutableMap()\n"
" .putAll(values);\n"
" $set_has_field_bit_builder$\n"
" return this;\n"
"}\n");
printer->Annotate("{", "}", descriptor_);
@ -470,55 +511,59 @@ void ImmutableMapFieldGenerator::GenerateBuilderMembers(
" */\n"
"@java.lang.Deprecated\n"
"public java.util.Map<$type_parameters$>\n"
"${$getMutable$capitalized_name$$}$() {\n"
" ${$getMutable$capitalized_name$$}$() {\n"
" $set_has_field_bit_builder$\n"
" return internalGetMutable$capitalized_name$().getMutableMap();\n"
"}\n");
printer->Annotate("{", "}", descriptor_);
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$"
"public Builder ${$put$capitalized_name$$}$(\n"
"$deprecation$public Builder ${$put$capitalized_name$$}$(\n"
" $key_type$ key,\n"
" $value_type$ value) {\n"
" $key_null_check$\n"
" $value_null_check$\n"
" internalGetMutable$capitalized_name$().getMutableMap()\n"
" .put(key, value);\n"
" $set_has_field_bit_builder$\n"
" return this;\n"
"}\n");
printer->Annotate("{", "}", descriptor_);
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$\n"
"public Builder ${$putAll$capitalized_name$$}$(\n"
" java.util.Map<$type_parameters$> values) {\n"
" internalGetMutable$capitalized_name$().getMutableMap()\n"
" .putAll(values);\n"
" return this;\n"
"}\n");
printer->Print(
variables_,
"$deprecation$public Builder ${$putAll$capitalized_name$$}$(\n"
" java.util.Map<$type_parameters$> values) {\n"
" internalGetMutable$capitalized_name$().getMutableMap()\n"
" .putAll(values);\n"
" $set_has_field_bit_builder$\n"
" return this;\n"
"}\n");
printer->Annotate("{", "}", descriptor_);
}
}
void ImmutableMapFieldGenerator::GenerateMapGetters(
io::Printer* printer) const {
printer->Print(variables_,
"$deprecation$\n"
"public int ${$get$capitalized_name$Count$}$() {\n"
" return internalGet$capitalized_name$().getMap().size();\n"
"}\n");
printer->Print(
variables_,
"$deprecation$public int ${$get$capitalized_name$Count$}$() {\n"
" return internalGet$capitalized_name$().getMap().size();\n"
"}\n");
printer->Annotate("{", "}", descriptor_);
WriteFieldDocComment(printer, descriptor_);
printer->Print(
variables_,
"$deprecation$\n"
"@java.lang.Override\n"
"public boolean ${$contains$capitalized_name$$}$(\n"
"$deprecation$public boolean ${$contains$capitalized_name$$}$(\n"
" $key_type$ key) {\n"
" $key_null_check$\n"
" return internalGet$capitalized_name$().getMap().containsKey(key);\n"
"}\n");
printer->Annotate("{", "}", descriptor_);
if (GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) {
printer->Print(variables_,
"/**\n"
@ -534,19 +579,19 @@ void ImmutableMapFieldGenerator::GenerateMapGetters(
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"@java.lang.Override\n"
"$deprecation$\n"
"public java.util.Map<$boxed_key_type$, $value_enum_type$>\n"
"$deprecation$public java.util.Map<$boxed_key_type$, "
"$value_enum_type$>\n"
"${$get$capitalized_name$Map$}$() {\n"
" return internalGetAdapted$capitalized_name$Map(\n"
" internalGet$capitalized_name$().getMap());"
"}\n");
printer->Annotate("{", "}", descriptor_);
WriteFieldDocComment(printer, descriptor_);
printer->Print(
variables_,
"@java.lang.Override\n"
"$deprecation$\n"
"public $value_enum_type_pass_through_nullness$ "
"$deprecation$public $value_enum_type_pass_through_nullness$ "
"${$get$capitalized_name$OrDefault$}$(\n"
" $key_type$ key,\n"
" $value_enum_type_pass_through_nullness$ defaultValue) {\n"
@ -558,12 +603,12 @@ void ImmutableMapFieldGenerator::GenerateMapGetters(
" : defaultValue;\n"
"}\n");
printer->Annotate("{", "}", descriptor_);
WriteFieldDocComment(printer, descriptor_);
printer->Print(
variables_,
"@java.lang.Override\n"
"$deprecation$\n"
"public $value_enum_type$ ${$get$capitalized_name$OrThrow$}$(\n"
"$deprecation$public $value_enum_type$ get$capitalized_name$OrThrow(\n"
" $key_type$ key) {\n"
" $key_null_check$\n"
" java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n"
@ -574,6 +619,7 @@ void ImmutableMapFieldGenerator::GenerateMapGetters(
" return $name$ValueConverter.doForward(map.get(key));\n"
"}\n");
printer->Annotate("{", "}", descriptor_);
if (SupportUnknownEnumValue(descriptor_->file())) {
printer->Print(
variables_,
@ -588,23 +634,22 @@ void ImmutableMapFieldGenerator::GenerateMapGetters(
"}\n");
printer->Annotate("{", "}", descriptor_);
WriteFieldDocComment(printer, descriptor_);
printer->Print(
variables_,
"@java.lang.Override\n"
"$deprecation$\n"
"public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n"
"${$get$capitalized_name$ValueMap$}$() {\n"
" return internalGet$capitalized_name$().getMap();\n"
"}\n");
printer->Print(variables_,
"@java.lang.Override\n"
"$deprecation$public java.util.Map<$boxed_key_type$, "
"$boxed_value_type$>\n"
"${$get$capitalized_name$ValueMap$}$() {\n"
" return internalGet$capitalized_name$().getMap();\n"
"}\n");
printer->Annotate("{", "}", descriptor_);
WriteFieldDocComment(printer, descriptor_);
printer->Print(
variables_,
"@java.lang.Override\n"
"$deprecation$\n"
"public $value_type$ ${$get$capitalized_name$ValueOrDefault$}$(\n"
"$deprecation$public $value_type_pass_through_nullness$ "
"${$get$capitalized_name$ValueOrDefault$}$(\n"
" $key_type$ key,\n"
" $value_type$ defaultValue) {\n"
" $value_type_pass_through_nullness$ defaultValue) {\n"
" $key_null_check$\n"
" java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n"
" internalGet$capitalized_name$().getMap();\n"
@ -615,8 +660,8 @@ void ImmutableMapFieldGenerator::GenerateMapGetters(
printer->Print(
variables_,
"@java.lang.Override\n"
"$deprecation$\n"
"public $value_type$ ${$get$capitalized_name$ValueOrThrow$}$(\n"
"$deprecation$public $value_type$ "
"${$get$capitalized_name$ValueOrThrow$}$(\n"
" $key_type$ key) {\n"
" $key_null_check$\n"
" java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n"
@ -643,8 +688,7 @@ void ImmutableMapFieldGenerator::GenerateMapGetters(
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"@java.lang.Override\n"
"$deprecation$\n"
"public java.util.Map<$type_parameters$> "
"$deprecation$public java.util.Map<$type_parameters$> "
"${$get$capitalized_name$Map$}$() {\n"
" return internalGet$capitalized_name$().getMap();\n"
"}\n");
@ -653,10 +697,10 @@ void ImmutableMapFieldGenerator::GenerateMapGetters(
printer->Print(
variables_,
"@java.lang.Override\n"
"$deprecation$\n"
"public $value_type$ ${$get$capitalized_name$OrDefault$}$(\n"
"$deprecation$public $value_type_pass_through_nullness$ "
"${$get$capitalized_name$OrDefault$}$(\n"
" $key_type$ key,\n"
" $value_type$ defaultValue) {\n"
" $value_type_pass_through_nullness$ defaultValue) {\n"
" $key_null_check$\n"
" java.util.Map<$type_parameters$> map =\n"
" internalGet$capitalized_name$().getMap();\n"
@ -664,19 +708,19 @@ void ImmutableMapFieldGenerator::GenerateMapGetters(
"}\n");
printer->Annotate("{", "}", descriptor_);
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"@java.lang.Override\n"
"$deprecation$\n"
"public $value_type$ ${$get$capitalized_name$OrThrow$}$(\n"
" $key_type$ key) {\n"
" $key_null_check$\n"
" java.util.Map<$type_parameters$> map =\n"
" internalGet$capitalized_name$().getMap();\n"
" if (!map.containsKey(key)) {\n"
" throw new java.lang.IllegalArgumentException();\n"
" }\n"
" return map.get(key);\n"
"}\n");
printer->Print(
variables_,
"@java.lang.Override\n"
"$deprecation$public $value_type$ ${$get$capitalized_name$OrThrow$}$(\n"
" $key_type$ key) {\n"
" $key_null_check$\n"
" java.util.Map<$type_parameters$> map =\n"
" internalGet$capitalized_name$().getMap();\n"
" if (!map.containsKey(key)) {\n"
" throw new java.lang.IllegalArgumentException();\n"
" }\n"
" return map.get(key);\n"
"}\n");
printer->Annotate("{", "}", descriptor_);
}
}
@ -775,6 +819,7 @@ void ImmutableMapFieldGenerator::GenerateInitializationCode(
void ImmutableMapFieldGenerator::GenerateBuilderClearCode(
io::Printer* printer) const {
// No need to clear the has-bit since we clear the bitField ints all at once.
printer->Print(variables_,
"internalGetMutable$capitalized_name$().clear();\n");
}
@ -783,14 +828,17 @@ void ImmutableMapFieldGenerator::GenerateMergingCode(
io::Printer* printer) const {
printer->Print(variables_,
"internalGetMutable$capitalized_name$().mergeFrom(\n"
" other.internalGet$capitalized_name$());\n");
" other.internalGet$capitalized_name$());\n"
"$set_has_field_bit_builder$\n");
}
void ImmutableMapFieldGenerator::GenerateBuildingCode(
io::Printer* printer) const {
printer->Print(variables_,
"result.$name$_ = internalGet$capitalized_name$();\n"
"result.$name$_.makeImmutable();\n");
"if ($get_has_field_bit_from_local$) {\n"
" result.$name$_ = internalGet$capitalized_name$();\n"
" result.$name$_.makeImmutable();\n"
"}\n");
}
void ImmutableMapFieldGenerator::GenerateBuilderParsingCode(
@ -807,6 +855,7 @@ void ImmutableMapFieldGenerator::GenerateBuilderParsingCode(
"} else {\n"
" internalGetMutable$capitalized_name$().getMutableMap().put(\n"
" $name$__.getKey(), $name$__.getValue());\n"
" $set_has_field_bit_builder$\n"
"}\n");
} else {
printer->Print(
@ -815,10 +864,10 @@ void ImmutableMapFieldGenerator::GenerateBuilderParsingCode(
"$name$__ = input.readMessage(\n"
" $default_entry$.getParserForType(), extensionRegistry);\n"
"internalGetMutable$capitalized_name$().getMutableMap().put(\n"
" $name$__.getKey(), $name$__.getValue());\n");
" $name$__.getKey(), $name$__.getValue());\n"
"$set_has_field_bit_builder$\n");
}
}
void ImmutableMapFieldGenerator::GenerateSerializationCode(
io::Printer* printer) const {
printer->Print(variables_,
@ -871,4 +920,4 @@ std::string ImmutableMapFieldGenerator::GetBoxedType() const {
} // namespace protobuf
} // namespace google
#include <google/protobuf/port_undef.inc>
#include "google/protobuf/port_undef.inc"

@ -31,7 +31,7 @@
#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_MAP_FIELD_H__
#define GOOGLE_PROTOBUF_COMPILER_JAVA_MAP_FIELD_H__
#include <google/protobuf/compiler/java/field.h>
#include "google/protobuf/compiler/java/field.h"
namespace google {
namespace protobuf {
@ -46,6 +46,8 @@ class ImmutableMapFieldGenerator : public ImmutableFieldGenerator {
~ImmutableMapFieldGenerator() override;
// implements ImmutableFieldGenerator ---------------------------------------
int GetMessageBitIndex() const override;
int GetBuilderBitIndex() const override;
int GetNumBitsForMessage() const override;
int GetNumBitsForBuilder() const override;
void GenerateInterfaceMembers(io::Printer* printer) const override;
@ -68,8 +70,11 @@ class ImmutableMapFieldGenerator : public ImmutableFieldGenerator {
private:
const FieldDescriptor* descriptor_;
int message_bit_index_;
int builder_bit_index_;
std::map<std::string, std::string> variables_;
ClassNameResolver* name_resolver_;
Context* context_;
void GenerateMapGetters(io::Printer* printer) const;
};

@ -32,29 +32,30 @@
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
#include <google/protobuf/compiler/java/message_builder.h>
#include "google/protobuf/compiler/java/message_builder.h"
#include <algorithm>
#include <map>
#include <memory>
#include <set>
#include <vector>
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/io/printer.h>
#include <google/protobuf/wire_format.h>
#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/stubs/substitute.h>
#include <google/protobuf/compiler/java/context.h>
#include <google/protobuf/compiler/java/doc_comment.h>
#include <google/protobuf/compiler/java/enum.h>
#include <google/protobuf/compiler/java/extension.h>
#include <google/protobuf/compiler/java/generator_factory.h>
#include <google/protobuf/compiler/java/helpers.h>
#include <google/protobuf/compiler/java/name_resolver.h>
#include <google/protobuf/descriptor.pb.h>
#include "google/protobuf/io/coded_stream.h"
#include "google/protobuf/io/printer.h"
#include "google/protobuf/wire_format.h"
#include "google/protobuf/stubs/strutil.h"
#include "google/protobuf/stubs/substitute.h"
#include "google/protobuf/compiler/java/context.h"
#include "google/protobuf/compiler/java/doc_comment.h"
#include "google/protobuf/compiler/java/enum.h"
#include "google/protobuf/compiler/java/extension.h"
#include "google/protobuf/compiler/java/generator_factory.h"
#include "google/protobuf/compiler/java/helpers.h"
#include "google/protobuf/compiler/java/name_resolver.h"
#include "google/protobuf/descriptor.pb.h"
// Must be last.
#include <google/protobuf/port_def.inc>
#include "google/protobuf/port_def.inc"
namespace google {
namespace protobuf {
@ -145,12 +146,11 @@ void MessageBuilderGenerator::Generate(io::Printer* printer) {
"\n"
"public Builder clear$oneof_capitalized_name$() {\n"
" $oneof_name$Case_ = 0;\n"
" $oneof_name$_ = null;\n");
printer->Print(" onChanged();\n");
printer->Print(
" return this;\n"
"}\n"
"\n");
" $oneof_name$_ = null;\n"
" onChanged();\n"
" return this;\n"
"}\n"
"\n");
}
// Integers for bit fields.
@ -355,6 +355,11 @@ void MessageBuilderGenerator::GenerateCommonBuilderMethods(
" super.clear();\n");
printer->Indent();
int totalBuilderInts = (descriptor_->field_count() + 31) / 32;
for (int i = 0; i < totalBuilderInts; i++) {
printer->Print("$bit_field_name$ = 0;\n", "bit_field_name",
GetBitFieldName(i));
}
for (int i = 0; i < descriptor_->field_count(); i++) {
field_generators_.get(descriptor_->field(i))
@ -406,63 +411,7 @@ void MessageBuilderGenerator::GenerateCommonBuilderMethods(
"\n",
"classname", name_resolver_->GetImmutableClassName(descriptor_));
printer->Print(
"@java.lang.Override\n"
"public $classname$ buildPartial() {\n"
" $classname$ result = new $classname$(this);\n",
"classname", name_resolver_->GetImmutableClassName(descriptor_));
printer->Indent();
int totalBuilderBits = 0;
int totalMessageBits = 0;
for (int i = 0; i < descriptor_->field_count(); i++) {
const ImmutableFieldGenerator& field =
field_generators_.get(descriptor_->field(i));
totalBuilderBits += field.GetNumBitsForBuilder();
totalMessageBits += field.GetNumBitsForMessage();
}
int totalBuilderInts = (totalBuilderBits + 31) / 32;
int totalMessageInts = (totalMessageBits + 31) / 32;
// Local vars for from and to bit fields to avoid accessing the builder and
// message over and over for these fields. Seems to provide a slight
// perforamance improvement in micro benchmark and this is also what proto1
// code does.
for (int i = 0; i < totalBuilderInts; i++) {
printer->Print("int from_$bit_field_name$ = $bit_field_name$;\n",
"bit_field_name", GetBitFieldName(i));
}
for (int i = 0; i < totalMessageInts; i++) {
printer->Print("int to_$bit_field_name$ = 0;\n", "bit_field_name",
GetBitFieldName(i));
}
// Output generation code for each field.
for (int i = 0; i < descriptor_->field_count(); i++) {
field_generators_.get(descriptor_->field(i)).GenerateBuildingCode(printer);
}
// Copy the bit field results to the generated message
for (int i = 0; i < totalMessageInts; i++) {
printer->Print("result.$bit_field_name$ = to_$bit_field_name$;\n",
"bit_field_name", GetBitFieldName(i));
}
for (auto oneof : oneofs_) {
printer->Print("result.$oneof_name$Case_ = $oneof_name$Case_;\n",
"oneof_name", context_->GetOneofGeneratorInfo(oneof)->name);
}
printer->Outdent();
printer->Print(" onBuilt();\n");
printer->Print(
" return result;\n"
"}\n"
"\n",
"classname", name_resolver_->GetImmutableClassName(descriptor_));
GenerateBuildPartial(printer);
// Override methods declared in GeneratedMessage to return the concrete
// generated type so callsites won't depend on GeneratedMessage. This
@ -610,6 +559,156 @@ void MessageBuilderGenerator::GenerateCommonBuilderMethods(
}
}
void MessageBuilderGenerator::GenerateBuildPartial(io::Printer* printer) {
printer->Print(
"@java.lang.Override\n"
"public $classname$ buildPartial() {\n"
" $classname$ result = new $classname$(this);\n",
"classname", name_resolver_->GetImmutableClassName(descriptor_));
printer->Indent();
// Handle the repeated fields first so that the "mutable bits" are cleared.
bool has_repeated_fields = false;
for (int i = 0; i < descriptor_->field_count(); ++i) {
if (descriptor_->field(i)->is_repeated() &&
!IsMapField(descriptor_->field(i))) {
has_repeated_fields = true;
printer->Print("buildPartialRepeatedFields(result);\n");
break;
}
}
// One buildPartial#() per from_bit_field
int totalBuilderInts = (descriptor_->field_count() + 31) / 32;
if (totalBuilderInts > 0) {
for (int i = 0; i < totalBuilderInts; ++i) {
printer->Print(
"if ($bit_field_name$ != 0) { buildPartial$piece$(result); }\n",
"bit_field_name", GetBitFieldName(i), "piece", StrCat(i));
}
}
if (!oneofs_.empty()) {
printer->Print("buildPartialOneofs(result);\n");
}
printer->Outdent();
printer->Print(
" onBuilt();\n"
" return result;\n"
"}\n"
"\n",
"classname", name_resolver_->GetImmutableClassName(descriptor_));
// Build Repeated Fields
if (has_repeated_fields) {
printer->Print(
"private void buildPartialRepeatedFields($classname$ result) {\n",
"classname", name_resolver_->GetImmutableClassName(descriptor_));
printer->Indent();
for (int i = 0; i < descriptor_->field_count(); ++i) {
if (descriptor_->field(i)->is_repeated() &&
!IsMapField(descriptor_->field(i))) {
const ImmutableFieldGenerator& field =
field_generators_.get(descriptor_->field(i));
field.GenerateBuildingCode(printer);
}
}
printer->Outdent();
printer->Print("}\n\n");
}
// Build non-oneof fields
int start_field = 0;
for (int i = 0; i < totalBuilderInts; i++) {
start_field = GenerateBuildPartialPiece(printer, i, start_field);
}
// Build Oneofs
if (!oneofs_.empty()) {
printer->Print("private void buildPartialOneofs($classname$ result) {\n",
"classname",
name_resolver_->GetImmutableClassName(descriptor_));
printer->Indent();
for (auto oneof : oneofs_) {
printer->Print(
"result.$oneof_name$Case_ = $oneof_name$Case_;\n"
"result.$oneof_name$_ = this.$oneof_name$_;\n",
"oneof_name", context_->GetOneofGeneratorInfo(oneof)->name);
for (int i = 0; i < oneof->field_count(); ++i) {
if (oneof->field(i)->message_type() != nullptr) {
const ImmutableFieldGenerator& field =
field_generators_.get(oneof->field(i));
field.GenerateBuildingCode(printer);
}
}
}
printer->Outdent();
printer->Print("}\n\n");
}
}
int MessageBuilderGenerator::GenerateBuildPartialPiece(io::Printer* printer,
int piece,
int first_field) {
printer->Print(
"private void buildPartial$piece$($classname$ result) {\n"
" int from_$bit_field_name$ = $bit_field_name$;\n",
"classname", name_resolver_->GetImmutableClassName(descriptor_), "piece",
StrCat(piece), "bit_field_name", GetBitFieldName(piece));
printer->Indent();
std::set<int> declared_to_bitfields;
int bit = 0;
int next = first_field;
for (; bit < 32 && next < descriptor_->field_count(); ++next) {
const ImmutableFieldGenerator& field =
field_generators_.get(descriptor_->field(next));
bit += field.GetNumBitsForBuilder();
// Skip oneof fields that are handled separately
if (IsRealOneof(descriptor_->field(next))) {
continue;
}
// Skip repeated fields because they are currently handled
// in separate buildPartial sub-methods.
if (descriptor_->field(next)->is_repeated() &&
!IsMapField(descriptor_->field(next))) {
continue;
}
// Skip fields without presence bits in the builder
if (field.GetNumBitsForBuilder() == 0) {
continue;
}
// Track message bits if necessary
if (field.GetNumBitsForMessage() > 0) {
int to_bitfield = field.GetMessageBitIndex() / 32;
if (declared_to_bitfields.count(to_bitfield) == 0) {
printer->Print("int to_$bit_field_name$ = 0;\n", "bit_field_name",
GetBitFieldName(to_bitfield));
declared_to_bitfields.insert(to_bitfield);
}
}
// Copy the field from the builder to the message
field.GenerateBuildingCode(printer);
}
// Copy the bit field results to the generated message
for (int to_bitfield : declared_to_bitfields) {
printer->Print("result.$bit_field_name$ |= to_$bit_field_name$;\n",
"bit_field_name", GetBitFieldName(to_bitfield));
}
printer->Outdent();
printer->Print("}\n\n");
return next;
}
// ===================================================================
void MessageBuilderGenerator::GenerateBuilderParsingMethods(
@ -807,4 +906,4 @@ void MessageBuilderGenerator::GenerateIsInitialized(io::Printer* printer) {
} // namespace protobuf
} // namespace google
#include <google/protobuf/port_undef.inc>
#include "google/protobuf/port_undef.inc"

@ -69,6 +69,11 @@ class MessageBuilderGenerator {
private:
void GenerateCommonBuilderMethods(io::Printer* printer);
void GenerateBuildPartial(io::Printer* printer);
int GenerateBuildPartialPiece(io::Printer* printer, int piece,
int first_field);
int GenerateBuildPartialPieceWithoutPresence(io::Printer* printer, int piece,
int first_field);
void GenerateDescriptorMethods(io::Printer* printer);
void GenerateBuilderParsingMethods(io::Printer* printer);
void GenerateBuilderFieldParsingCases(io::Printer* printer);

@ -32,21 +32,21 @@
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
#include <google/protobuf/compiler/java/message_field.h>
#include "google/protobuf/compiler/java/message_field.h"
#include <map>
#include <string>
#include <google/protobuf/io/printer.h>
#include <google/protobuf/wire_format.h>
#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/compiler/java/context.h>
#include <google/protobuf/compiler/java/doc_comment.h>
#include <google/protobuf/compiler/java/helpers.h>
#include <google/protobuf/compiler/java/name_resolver.h>
#include "google/protobuf/io/printer.h"
#include "google/protobuf/wire_format.h"
#include "google/protobuf/stubs/strutil.h"
#include "google/protobuf/compiler/java/context.h"
#include "google/protobuf/compiler/java/doc_comment.h"
#include "google/protobuf/compiler/java/helpers.h"
#include "google/protobuf/compiler/java/name_resolver.h"
// Must be last.
#include <google/protobuf/port_def.inc>
#include "google/protobuf/port_def.inc"
namespace google {
namespace protobuf {
@ -56,10 +56,11 @@ namespace java {
namespace {
void SetMessageVariables(const FieldDescriptor* descriptor, int messageBitIndex,
int builderBitIndex, const FieldGeneratorInfo* info,
ClassNameResolver* name_resolver,
std::map<std::string, std::string>* variables) {
void SetMessageVariables(
const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex,
const FieldGeneratorInfo* info, ClassNameResolver* name_resolver,
std::map<std::string, std::string>* variables,
Context* context) {
SetCommonFieldVariables(descriptor, info, variables);
(*variables)["type"] =
@ -74,11 +75,12 @@ void SetMessageVariables(const FieldDescriptor* descriptor, int messageBitIndex,
// by the proto compiler
(*variables)["deprecation"] =
descriptor->options().deprecated() ? "@java.lang.Deprecated " : "";
(*variables)["kt_deprecation"] =
descriptor->options().deprecated()
? "@kotlin.Deprecated(message = \"Field " + (*variables)["name"] +
" is deprecated\") "
: "";
variables->insert(
{"kt_deprecation",
descriptor->options().deprecated()
? StrCat("@kotlin.Deprecated(message = \"Field ",
(*variables)["name"], " is deprecated\") ")
: ""});
(*variables)["on_changed"] = "onChanged();";
(*variables)["ver"] = GeneratedCodeVersionSuffix();
(*variables)["get_parser"] =
@ -88,24 +90,16 @@ void SetMessageVariables(const FieldDescriptor* descriptor, int messageBitIndex,
if (HasHasbit(descriptor)) {
// 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)["set_has_field_bit_to_local"] =
GenerateSetBitToLocal(messageBitIndex);
(*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";
(*variables)["set_has_field_bit_to_local"] = "";
variables->insert({"is_field_present_message",
StrCat((*variables)["name"], "_ != null")});
}
// For repeated builders, one bit is used for whether the array is immutable.
@ -113,10 +107,13 @@ void SetMessageVariables(const FieldDescriptor* descriptor, int messageBitIndex,
(*variables)["set_mutable_bit_builder"] = GenerateSetBit(builderBitIndex);
(*variables)["clear_mutable_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)["get_has_field_bit_from_local"] =
GenerateGetBitFromLocal(builderBitIndex);
(*variables)["set_has_field_bit_to_local"] =
GenerateSetBitToLocal(messageBitIndex);
}
} // namespace
@ -126,21 +123,31 @@ void SetMessageVariables(const FieldDescriptor* descriptor, int messageBitIndex,
ImmutableMessageFieldGenerator::ImmutableMessageFieldGenerator(
const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex,
Context* context)
: descriptor_(descriptor), name_resolver_(context->GetNameResolver()) {
: descriptor_(descriptor),
message_bit_index_(messageBitIndex),
builder_bit_index_(builderBitIndex),
name_resolver_(context->GetNameResolver()),
context_(context) {
SetMessageVariables(descriptor, messageBitIndex, builderBitIndex,
context->GetFieldGeneratorInfo(descriptor),
name_resolver_, &variables_);
name_resolver_, &variables_, context);
}
ImmutableMessageFieldGenerator::~ImmutableMessageFieldGenerator() {}
int ImmutableMessageFieldGenerator::GetMessageBitIndex() const {
return message_bit_index_;
}
int ImmutableMessageFieldGenerator::GetBuilderBitIndex() const {
return builder_bit_index_;
}
int ImmutableMessageFieldGenerator::GetNumBitsForMessage() const {
return HasHasbit(descriptor_) ? 1 : 0;
}
int ImmutableMessageFieldGenerator::GetNumBitsForBuilder() const {
return GetNumBitsForMessage();
}
int ImmutableMessageFieldGenerator::GetNumBitsForBuilder() const { return 1; }
void ImmutableMessageFieldGenerator::GenerateInterfaceMembers(
io::Printer* printer) const {
@ -173,24 +180,6 @@ void ImmutableMessageFieldGenerator::GenerateMembers(
" return $get_has_field_bit_message$;\n"
"}\n");
printer->Annotate("{", "}", descriptor_);
WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
printer->Print(
variables_,
"@java.lang.Override\n"
"$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
" return $name$_ == null ? $type$.getDefaultInstance() : $name$_;\n"
"}\n");
printer->Annotate("{", "}", descriptor_);
WriteFieldDocComment(printer, descriptor_);
printer->Print(
variables_,
"@java.lang.Override\n"
"$deprecation$public $type$OrBuilder "
"${$get$capitalized_name$OrBuilder$}$() {\n"
" return $name$_ == null ? $type$.getDefaultInstance() : $name$_;\n"
"}\n");
printer->Annotate("{", "}", descriptor_);
} else {
WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
printer->Print(
@ -200,24 +189,25 @@ void ImmutableMessageFieldGenerator::GenerateMembers(
" return $name$_ != null;\n"
"}\n");
printer->Annotate("{", "}", descriptor_);
WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
printer->Print(
variables_,
"@java.lang.Override\n"
"$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
" return $name$_ == null ? $type$.getDefaultInstance() : $name$_;\n"
"}\n");
printer->Annotate("{", "}", descriptor_);
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"@java.lang.Override\n"
"$deprecation$public $type$OrBuilder "
"${$get$capitalized_name$OrBuilder$}$() {\n"
" return get$capitalized_name$();\n"
"}\n");
printer->Annotate("{", "}", descriptor_);
}
WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
printer->Print(
variables_,
"@java.lang.Override\n"
"$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
" return $name$_ == null ? $type$.getDefaultInstance() : $name$_;\n"
"}\n");
printer->Annotate("{", "}", descriptor_);
WriteFieldDocComment(printer, descriptor_);
printer->Print(
variables_,
"@java.lang.Override\n"
"$deprecation$public $type$OrBuilder "
"${$get$capitalized_name$OrBuilder$}$() {\n"
" return $name$_ == null ? $type$.getDefaultInstance() : $name$_;\n"
"}\n");
printer->Annotate("{", "}", descriptor_);
}
void ImmutableMessageFieldGenerator::PrintNestedBuilderCondition(
@ -255,9 +245,6 @@ void ImmutableMessageFieldGenerator::GenerateBuilderMembers(
// 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.
bool has_hasbit = HasHasbit(descriptor_);
printer->Print(variables_, "private $type$ $name$_;\n");
printer->Print(variables_,
@ -272,21 +259,11 @@ void ImmutableMessageFieldGenerator::GenerateBuilderMembers(
// boolean hasField()
WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
if (has_hasbit) {
printer->Print(
variables_,
"$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
" return $get_has_field_bit_builder$;\n"
"}\n");
printer->Annotate("{", "}", descriptor_);
} else {
printer->Print(
variables_,
"$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
" return $name$Builder_ != null || $name$_ != null;\n"
"}\n");
printer->Annotate("{", "}", descriptor_);
}
printer->Print(variables_,
"$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
" return $get_has_field_bit_builder$;\n"
"}\n");
printer->Annotate("{", "}", descriptor_);
// Field getField()
WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
@ -304,12 +281,12 @@ void ImmutableMessageFieldGenerator::GenerateBuilderMembers(
"if (value == null) {\n"
" throw new NullPointerException();\n"
"}\n"
"$name$_ = value;\n"
"$on_changed$\n",
"$name$_ = value;\n",
"$name$Builder_.setMessage(value);\n",
"$set_has_field_bit_builder$\n"
"$on_changed$\n"
"return this;\n");
// Field.Builder setField(Field.Builder builderForValue)
@ -319,58 +296,48 @@ void ImmutableMessageFieldGenerator::GenerateBuilderMembers(
"$deprecation$public Builder ${$set$capitalized_name$$}$(\n"
" $type$.Builder builderForValue)",
"$name$_ = builderForValue.build();\n"
"$on_changed$\n",
"$name$_ = builderForValue.build();\n",
"$name$Builder_.setMessage(builderForValue.build());\n",
"$set_has_field_bit_builder$\n"
"$on_changed$\n"
"return this;\n");
// Field.Builder mergeField(Field value)
// Message.Builder mergeField(Field value)
WriteFieldDocComment(printer, descriptor_);
PrintNestedBuilderFunction(
printer,
"$deprecation$public Builder ${$merge$capitalized_name$$}$($type$ value)",
has_hasbit
? "if ($get_has_field_bit_builder$ &&\n"
" $name$_ != null &&\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",
"if ($get_has_field_bit_builder$ &&\n"
" $name$_ != null &&\n"
" $name$_ != $type$.getDefaultInstance()) {\n"
" get$capitalized_name$Builder().mergeFrom(value);\n"
"} else {\n"
" $name$_ = value;\n"
"}\n",
"$name$Builder_.mergeFrom(value);\n",
"$set_has_field_bit_builder$\n"
"$on_changed$\n"
"return this;\n");
// Field.Builder clearField()
// Message.Builder clearField()
WriteFieldDocComment(printer, descriptor_);
PrintNestedBuilderFunction(
printer, "$deprecation$public Builder ${$clear$capitalized_name$$}$()",
"$name$_ = null;\n"
"$on_changed$\n",
has_hasbit ? "$name$Builder_.clear();\n"
: "$name$_ = null;\n"
"$name$Builder_ = null;\n",
"$clear_has_field_bit_builder$\n"
"return this;\n");
printer->Print(variables_,
"$deprecation$public Builder clear$capitalized_name$() {\n"
" $clear_has_field_bit_builder$\n"
" $name$_ = null;\n"
" if ($name$Builder_ != null) {\n"
" $name$Builder_.dispose();\n"
" $name$Builder_ = null;\n"
" }\n"
" $on_changed$\n"
" return this;\n"
"}\n");
// Field.Builder getFieldBuilder()
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$public $type$.Builder "
@ -380,6 +347,8 @@ void ImmutableMessageFieldGenerator::GenerateBuilderMembers(
" return get$capitalized_name$FieldBuilder().getBuilder();\n"
"}\n");
printer->Annotate("{", "}", descriptor_);
// FieldOrBuilder getFieldOrBuilder()
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$public $type$OrBuilder "
@ -392,6 +361,8 @@ void ImmutableMessageFieldGenerator::GenerateBuilderMembers(
" }\n"
"}\n");
printer->Annotate("{", "}", descriptor_);
// SingleFieldBuilder getFieldFieldBuilder
WriteFieldDocComment(printer, descriptor_);
printer->Print(
variables_,
@ -449,9 +420,7 @@ void ImmutableMessageFieldGenerator::GenerateKotlinOrNull(io::Printer* printer)
void ImmutableMessageFieldGenerator::GenerateFieldBuilderInitializationCode(
io::Printer* printer) const {
if (HasHasbit(descriptor_)) {
printer->Print(variables_, "get$capitalized_name$FieldBuilder();\n");
}
printer->Print(variables_, "get$capitalized_name$FieldBuilder();\n");
}
void ImmutableMessageFieldGenerator::GenerateInitializationCode(
@ -459,17 +428,13 @@ void ImmutableMessageFieldGenerator::GenerateInitializationCode(
void ImmutableMessageFieldGenerator::GenerateBuilderClearCode(
io::Printer* printer) const {
if (HasHasbit(descriptor_)) {
PrintNestedBuilderCondition(printer, "$name$_ = null;\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");
}
// No need to clear the has-bit since we clear the bitField ints all at once.
printer->Print(variables_,
"$name$_ = null;\n"
"if ($name$Builder_ != null) {\n"
" $name$Builder_.dispose();\n"
" $name$Builder_ = null;\n"
"}\n");
}
void ImmutableMessageFieldGenerator::GenerateMergingCode(
@ -482,19 +447,15 @@ void ImmutableMessageFieldGenerator::GenerateMergingCode(
void ImmutableMessageFieldGenerator::GenerateBuildingCode(
io::Printer* printer) const {
if (HasHasbit(descriptor_)) {
printer->Print(variables_, "if ($get_has_field_bit_from_local$) {\n");
printer->Indent();
PrintNestedBuilderCondition(printer, "result.$name$_ = $name$_;\n",
"result.$name$_ = $name$Builder_.build();\n");
printer->Outdent();
printer->Print(variables_,
" $set_has_field_bit_to_local$;\n"
"}\n");
} else {
PrintNestedBuilderCondition(printer, "result.$name$_ = $name$_;\n",
"result.$name$_ = $name$Builder_.build();\n");
printer->Print(variables_,
"if ($get_has_field_bit_from_local$) {\n"
" result.$name$_ = $name$Builder_ == null\n"
" ? $name$_\n"
" : $name$Builder_.build();\n");
if (GetNumBitsForMessage() > 0) {
printer->Print(variables_, " $set_has_field_bit_to_local$;\n");
}
printer->Print("}\n");
}
void ImmutableMessageFieldGenerator::GenerateBuilderParsingCode(
@ -575,6 +536,7 @@ void ImmutableMessageOneofFieldGenerator::GenerateMembers(
" return $has_oneof_case_message$;\n"
"}\n");
printer->Annotate("{", "}", descriptor_);
WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
printer->Print(variables_,
"@java.lang.Override\n"
@ -758,7 +720,7 @@ void ImmutableMessageOneofFieldGenerator::GenerateBuilderMembers(
" $oneof_name$_ = null;\n"
" }\n"
" $set_oneof_case_message$;\n"
" $on_changed$;\n"
" $on_changed$\n"
" return $name$Builder_;\n"
"}\n");
printer->Annotate("{", "}", descriptor_);
@ -775,16 +737,11 @@ void ImmutableMessageOneofFieldGenerator::GenerateBuilderClearCode(
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");
printer->Print(variables_,
"if ($has_oneof_case_message$ &&\n"
" $name$Builder_ != null) {\n"
" result.$oneof_name$_ = $name$Builder_.build();\n"
"}\n");
}
void ImmutableMessageOneofFieldGenerator::GenerateMergingCode(
@ -834,11 +791,8 @@ void ImmutableMessageOneofFieldGenerator::GenerateSerializedSizeCode(
RepeatedImmutableMessageFieldGenerator::RepeatedImmutableMessageFieldGenerator(
const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex,
Context* context)
: descriptor_(descriptor), name_resolver_(context->GetNameResolver()) {
SetMessageVariables(descriptor, messageBitIndex, builderBitIndex,
context->GetFieldGeneratorInfo(descriptor),
name_resolver_, &variables_);
}
: ImmutableMessageFieldGenerator(descriptor, messageBitIndex,
builderBitIndex, context) {}
RepeatedImmutableMessageFieldGenerator::
~RepeatedImmutableMessageFieldGenerator() {}
@ -881,7 +835,8 @@ void RepeatedImmutableMessageFieldGenerator::GenerateInterfaceMembers(
void RepeatedImmutableMessageFieldGenerator::GenerateMembers(
io::Printer* printer) const {
printer->Print(variables_, "private java.util.List<$type$> $name$_;\n");
printer->Print(variables_, "@SuppressWarnings(\"serial\")\n"
"private java.util.List<$type$> $name$_;\n");
PrintExtraFieldInfo(variables_, printer);
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
@ -891,6 +846,8 @@ void RepeatedImmutableMessageFieldGenerator::GenerateMembers(
" return $name$_;\n" // note: unmodifiable list
"}\n");
printer->Annotate("{", "}", descriptor_);
// List<FieldOrBuilder> getFieldOrBuilderList()
WriteFieldDocComment(printer, descriptor_);
printer->Print(
variables_,
@ -900,6 +857,8 @@ void RepeatedImmutableMessageFieldGenerator::GenerateMembers(
" return $name$_;\n"
"}\n");
printer->Annotate("{", "}", descriptor_);
// int getFieldCount()
WriteFieldDocComment(printer, descriptor_);
printer->Print(
variables_,
@ -908,6 +867,8 @@ void RepeatedImmutableMessageFieldGenerator::GenerateMembers(
" return $name$_.size();\n"
"}\n");
printer->Annotate("{", "}", descriptor_);
// Field getField(int index)
WriteFieldDocComment(printer, descriptor_);
printer->Print(
variables_,
@ -916,6 +877,8 @@ void RepeatedImmutableMessageFieldGenerator::GenerateMembers(
" return $name$_.get(index);\n"
"}\n");
printer->Annotate("{", "}", descriptor_);
// FieldOrBuilder getFieldOrBuilder(int index)
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"@java.lang.Override\n"
@ -1141,7 +1104,7 @@ void RepeatedImmutableMessageFieldGenerator::GenerateBuilderMembers(
"return this;\n");
// Builder clearAllRepeatedField()
// Builder clearRepeatedField()
WriteFieldDocComment(printer, descriptor_);
PrintNestedBuilderFunction(
printer, "$deprecation$public Builder ${$clear$capitalized_name$$}$()",
@ -1168,6 +1131,7 @@ void RepeatedImmutableMessageFieldGenerator::GenerateBuilderMembers(
"return this;\n");
// Field.Builder getRepeatedFieldBuilder(int index)
WriteFieldDocComment(printer, descriptor_);
printer->Print(
variables_,
@ -1177,6 +1141,7 @@ void RepeatedImmutableMessageFieldGenerator::GenerateBuilderMembers(
"}\n");
printer->Annotate("{", "}", descriptor_);
// FieldOrBuilder getRepeatedFieldOrBuilder(int index)
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$public $type$OrBuilder "
@ -1190,6 +1155,7 @@ void RepeatedImmutableMessageFieldGenerator::GenerateBuilderMembers(
"}\n");
printer->Annotate("{", "}", descriptor_);
// List<FieldOrBuilder> getRepeatedFieldOrBuilderList()
WriteFieldDocComment(printer, descriptor_);
printer->Print(
variables_,
@ -1203,6 +1169,7 @@ void RepeatedImmutableMessageFieldGenerator::GenerateBuilderMembers(
"}\n");
printer->Annotate("{", "}", descriptor_);
// Field.Builder addRepeatedField()
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$public $type$.Builder "
@ -1211,6 +1178,8 @@ void RepeatedImmutableMessageFieldGenerator::GenerateBuilderMembers(
" $type$.getDefaultInstance());\n"
"}\n");
printer->Annotate("{", "}", descriptor_);
// Field.Builder addRepeatedFieldBuilder(int index)
WriteFieldDocComment(printer, descriptor_);
printer->Print(
variables_,
@ -1220,6 +1189,8 @@ void RepeatedImmutableMessageFieldGenerator::GenerateBuilderMembers(
" index, $type$.getDefaultInstance());\n"
"}\n");
printer->Annotate("{", "}", descriptor_);
// List<Field.Builder> getRepeatedFieldBuilderList()
WriteFieldDocComment(printer, descriptor_);
printer->Print(
variables_,
@ -1478,4 +1449,4 @@ void RepeatedImmutableMessageFieldGenerator::GenerateKotlinDslMembers(
} // namespace protobuf
} // namespace google
#include <google/protobuf/port_undef.inc>
#include "google/protobuf/port_undef.inc"

@ -38,7 +38,7 @@
#include <map>
#include <string>
#include <google/protobuf/compiler/java/field.h>
#include "google/protobuf/compiler/java/field.h"
namespace google {
namespace protobuf {
@ -62,10 +62,16 @@ class ImmutableMessageFieldGenerator : public ImmutableFieldGenerator {
int messageBitIndex,
int builderBitIndex,
Context* context);
ImmutableMessageFieldGenerator(const ImmutableMessageFieldGenerator&) =
delete;
ImmutableMessageFieldGenerator& operator=(
const ImmutableMessageFieldGenerator&) = delete;
~ImmutableMessageFieldGenerator() override;
// implements ImmutableFieldGenerator
// ---------------------------------------
int GetMessageBitIndex() const override;
int GetBuilderBitIndex() const override;
int GetNumBitsForMessage() const override;
int GetNumBitsForBuilder() const override;
void GenerateInterfaceMembers(io::Printer* printer) const override;
@ -88,20 +94,22 @@ class ImmutableMessageFieldGenerator : public ImmutableFieldGenerator {
protected:
const FieldDescriptor* descriptor_;
int message_bit_index_;
int builder_bit_index_;
std::map<std::string, std::string> variables_;
ClassNameResolver* name_resolver_;
Context* context_;
void PrintNestedBuilderCondition(io::Printer* printer,
const char* regular_case,
const char* nested_builder_case) const;
void PrintNestedBuilderFunction(io::Printer* printer,
const char* method_prototype,
const char* regular_case,
const char* nested_builder_case,
const char* trailing_code) const;
virtual void PrintNestedBuilderCondition(
io::Printer* printer, const char* regular_case,
const char* nested_builder_case) const;
virtual void PrintNestedBuilderFunction(io::Printer* printer,
const char* method_prototype,
const char* regular_case,
const char* nested_builder_case,
const char* trailing_code) const;
private:
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableMessageFieldGenerator);
void GenerateKotlinOrNull(io::Printer* printer) const;
};
@ -111,6 +119,10 @@ class ImmutableMessageOneofFieldGenerator
ImmutableMessageOneofFieldGenerator(const FieldDescriptor* descriptor,
int messageBitIndex, int builderBitIndex,
Context* context);
ImmutableMessageOneofFieldGenerator(
const ImmutableMessageOneofFieldGenerator&) = delete;
ImmutableMessageOneofFieldGenerator& operator=(
const ImmutableMessageOneofFieldGenerator&) = delete;
~ImmutableMessageOneofFieldGenerator() override;
void GenerateMembers(io::Printer* printer) const override;
@ -121,16 +133,18 @@ class ImmutableMessageOneofFieldGenerator
void GenerateBuilderParsingCode(io::Printer* printer) const override;
void GenerateSerializationCode(io::Printer* printer) const override;
void GenerateSerializedSizeCode(io::Printer* printer) const override;
private:
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableMessageOneofFieldGenerator);
};
class RepeatedImmutableMessageFieldGenerator : public ImmutableFieldGenerator {
class RepeatedImmutableMessageFieldGenerator
: public ImmutableMessageFieldGenerator {
public:
explicit RepeatedImmutableMessageFieldGenerator(
const FieldDescriptor* descriptor, int messageBitIndex,
int builderBitIndex, Context* context);
RepeatedImmutableMessageFieldGenerator(
const RepeatedImmutableMessageFieldGenerator&) = delete;
RepeatedImmutableMessageFieldGenerator& operator=(
const RepeatedImmutableMessageFieldGenerator&) = delete;
~RepeatedImmutableMessageFieldGenerator() override;
// implements ImmutableFieldGenerator ---------------------------------------
@ -155,21 +169,14 @@ class RepeatedImmutableMessageFieldGenerator : public ImmutableFieldGenerator {
std::string GetBoxedType() const override;
protected:
const FieldDescriptor* descriptor_;
std::map<std::string, std::string> variables_;
ClassNameResolver* name_resolver_;
void PrintNestedBuilderCondition(io::Printer* printer,
const char* regular_case,
const char* nested_builder_case) const;
void PrintNestedBuilderCondition(
io::Printer* printer, const char* regular_case,
const char* nested_builder_case) const override;
void PrintNestedBuilderFunction(io::Printer* printer,
const char* method_prototype,
const char* regular_case,
const char* nested_builder_case,
const char* trailing_code) const;
private:
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedImmutableMessageFieldGenerator);
const char* trailing_code) const override;
};
} // namespace java

@ -32,21 +32,21 @@
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
#include <google/protobuf/compiler/java/primitive_field.h>
#include "google/protobuf/compiler/java/primitive_field.h"
#include <cstdint>
#include <map>
#include <string>
#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/io/printer.h>
#include <google/protobuf/wire_format.h>
#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/compiler/java/context.h>
#include <google/protobuf/compiler/java/doc_comment.h>
#include <google/protobuf/compiler/java/helpers.h>
#include <google/protobuf/compiler/java/name_resolver.h>
#include "google/protobuf/stubs/logging.h"
#include "google/protobuf/stubs/common.h"
#include "google/protobuf/io/printer.h"
#include "google/protobuf/wire_format.h"
#include "google/protobuf/stubs/strutil.h"
#include "google/protobuf/compiler/java/context.h"
#include "google/protobuf/compiler/java/doc_comment.h"
#include "google/protobuf/compiler/java/helpers.h"
#include "google/protobuf/compiler/java/name_resolver.h"
namespace google {
namespace protobuf {
@ -57,53 +57,55 @@ using internal::WireFormat;
namespace {
void SetPrimitiveVariables(const FieldDescriptor* descriptor,
int messageBitIndex, int builderBitIndex,
const FieldGeneratorInfo* info,
ClassNameResolver* name_resolver,
std::map<std::string, std::string>* variables) {
void SetPrimitiveVariables(
const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex,
const FieldGeneratorInfo* info, ClassNameResolver* name_resolver,
std::map<std::string, std::string>* variables,
Context* context) {
SetCommonFieldVariables(descriptor, info, variables);
JavaType javaType = GetJavaType(descriptor);
(*variables)["type"] = PrimitiveTypeName(javaType);
(*variables)["boxed_type"] = BoxedPrimitiveTypeName(javaType);
(*variables)["kt_type"] = KotlinTypeName(javaType);
(*variables)["field_type"] = (*variables)["type"];
variables->insert({"field_type", (*variables)["type"]});
std::string name = (*variables)["name"];
if (javaType == JAVATYPE_BOOLEAN || javaType == JAVATYPE_DOUBLE ||
javaType == JAVATYPE_FLOAT || javaType == JAVATYPE_INT ||
javaType == JAVATYPE_LONG) {
std::string capitalized_type = UnderscoresToCamelCase(
PrimitiveTypeName(javaType), /*cap_first_letter=*/true);
(*variables)["field_list_type"] =
"com.google.protobuf.Internal." + capitalized_type + "List";
(*variables)["empty_list"] = "empty" + capitalized_type + "List()";
(*variables)["create_list"] = "new" + capitalized_type + "List()";
StrCat("com.google.protobuf.Internal.", capitalized_type, "List");
(*variables)["empty_list"] =
StrCat("empty", capitalized_type, "List()");
(*variables)["create_list"] =
StrCat("new", capitalized_type, "List()");
(*variables)["mutable_copy_list"] =
"mutableCopy(" + (*variables)["name"] + "_)";
StrCat("mutableCopy(", name, "_)");
(*variables)["name_make_immutable"] =
(*variables)["name"] + "_.makeImmutable()";
StrCat(name, "_.makeImmutable()");
(*variables)["repeated_get"] =
(*variables)["name"] + "_.get" + capitalized_type;
StrCat(name, "_.get", capitalized_type);
(*variables)["repeated_add"] =
(*variables)["name"] + "_.add" + capitalized_type;
StrCat(name, "_.add", capitalized_type);
(*variables)["repeated_set"] =
(*variables)["name"] + "_.set" + capitalized_type;
StrCat(name, "_.set", capitalized_type);
} else {
std::string boxed_type = (*variables)["boxed_type"];
(*variables)["field_list_type"] =
"java.util.List<" + (*variables)["boxed_type"] + ">";
StrCat("java.util.List<", boxed_type, ">");
(*variables)["create_list"] =
"new java.util.ArrayList<" + (*variables)["boxed_type"] + ">()";
(*variables)["mutable_copy_list"] = "new java.util.ArrayList<" +
(*variables)["boxed_type"] + ">(" +
(*variables)["name"] + "_)";
StrCat("new java.util.ArrayList<", boxed_type, ">()");
(*variables)["mutable_copy_list"] =
StrCat("new java.util.ArrayList<", boxed_type, ">(", name, "_)");
(*variables)["empty_list"] = "java.util.Collections.emptyList()";
(*variables)["name_make_immutable"] =
(*variables)["name"] + "_ = java.util.Collections.unmodifiableList(" +
(*variables)["name"] + "_)";
(*variables)["repeated_get"] = (*variables)["name"] + "_.get";
(*variables)["repeated_add"] = (*variables)["name"] + "_.add";
(*variables)["repeated_set"] = (*variables)["name"] + "_.set";
(*variables)["name_make_immutable"] = StrCat(
name, "_ = java.util.Collections.unmodifiableList(", name, "_)");
(*variables)["repeated_get"] = StrCat(name, "_.get");
(*variables)["repeated_add"] = StrCat(name, "_.add");
(*variables)["repeated_set"] = StrCat(name, "_.set");
}
(*variables)["default"] = ImmutableDefaultValue(descriptor, name_resolver);
@ -119,9 +121,7 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor,
WireFormat::TagSize(descriptor->number(), GetType(descriptor)));
if (IsReferenceType(GetJavaType(descriptor))) {
(*variables)["null_check"] =
" if (value == null) {\n"
" throw new NullPointerException();\n"
" }\n";
"if (value == null) { throw new NullPointerException(); }";
} else {
(*variables)["null_check"] = "";
}
@ -131,8 +131,8 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor,
descriptor->options().deprecated() ? "@java.lang.Deprecated " : "";
(*variables)["kt_deprecation"] =
descriptor->options().deprecated()
? "@kotlin.Deprecated(message = \"Field " + (*variables)["name"] +
" is deprecated\") "
? StrCat("@kotlin.Deprecated(message = \"Field ", name,
" is deprecated\") ")
: "";
int fixed_size = FixedSize(GetType(descriptor));
if (fixed_size != -1) {
@ -143,40 +143,29 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor,
if (HasHasbit(descriptor)) {
// 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)["set_has_field_bit_to_local"] =
GenerateSetBitToLocal(messageBitIndex) + ";";
(*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)["set_has_field_bit_to_local"] = "";
switch (descriptor->type()) {
case FieldDescriptor::TYPE_BYTES:
(*variables)["is_field_present_message"] =
"!" + (*variables)["name"] + "_.isEmpty()";
StrCat("!", name, "_.isEmpty()");
break;
case FieldDescriptor::TYPE_FLOAT:
(*variables)["is_field_present_message"] =
"java.lang.Float.floatToRawIntBits(" + (*variables)["name"] +
"_) != 0";
StrCat("java.lang.Float.floatToRawIntBits(", name, "_) != 0");
break;
case FieldDescriptor::TYPE_DOUBLE:
(*variables)["is_field_present_message"] =
"java.lang.Double.doubleToRawLongBits(" + (*variables)["name"] +
"_) != 0";
(*variables)["is_field_present_message"] = StrCat(
"java.lang.Double.doubleToRawLongBits(", name, "_) != 0");
break;
default:
(*variables)["is_field_present_message"] =
(*variables)["name"] + "_ != " + (*variables)["default"];
variables->insert(
{"is_field_present_message",
StrCat(name, "_ != ", (*variables)["default"])});
break;
}
}
@ -186,10 +175,15 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor,
(*variables)["set_mutable_bit_builder"] = GenerateSetBit(builderBitIndex);
(*variables)["clear_mutable_bit_builder"] = GenerateClearBit(builderBitIndex);
// Always track the presence of a field explicitly in the builder, regardless
// of syntax.
(*variables)["get_has_field_bit_builder"] = GenerateGetBit(builderBitIndex);
(*variables)["get_has_field_bit_from_local"] =
GenerateGetBitFromLocal(builderBitIndex);
(*variables)["set_has_field_bit_to_local"] =
GenerateSetBitToLocal(messageBitIndex);
(*variables)["set_has_field_bit_builder"] =
GenerateSetBit(builderBitIndex) + ";";
(*variables)["clear_has_field_bit_builder"] =
GenerateClearBit(builderBitIndex) + ";";
}
} // namespace
@ -199,21 +193,30 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor,
ImmutablePrimitiveFieldGenerator::ImmutablePrimitiveFieldGenerator(
const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex,
Context* context)
: descriptor_(descriptor), name_resolver_(context->GetNameResolver()) {
: descriptor_(descriptor),
message_bit_index_(messageBitIndex),
builder_bit_index_(builderBitIndex),
name_resolver_(context->GetNameResolver()) {
SetPrimitiveVariables(descriptor, messageBitIndex, builderBitIndex,
context->GetFieldGeneratorInfo(descriptor),
name_resolver_, &variables_);
name_resolver_, &variables_, context);
}
ImmutablePrimitiveFieldGenerator::~ImmutablePrimitiveFieldGenerator() {}
int ImmutablePrimitiveFieldGenerator::GetMessageBitIndex() const {
return message_bit_index_;
}
int ImmutablePrimitiveFieldGenerator::GetBuilderBitIndex() const {
return builder_bit_index_;
}
int ImmutablePrimitiveFieldGenerator::GetNumBitsForMessage() const {
return HasHasbit(descriptor_) ? 1 : 0;
}
int ImmutablePrimitiveFieldGenerator::GetNumBitsForBuilder() const {
return GetNumBitsForMessage();
}
int ImmutablePrimitiveFieldGenerator::GetNumBitsForBuilder() const { return 1; }
void ImmutablePrimitiveFieldGenerator::GenerateInterfaceMembers(
io::Printer* printer) const {
@ -228,7 +231,7 @@ void ImmutablePrimitiveFieldGenerator::GenerateInterfaceMembers(
void ImmutablePrimitiveFieldGenerator::GenerateMembers(
io::Printer* printer) const {
printer->Print(variables_, "private $field_type$ $name$_;\n");
printer->Print(variables_, "private $field_type$ $name$_ = $default$;\n");
PrintExtraFieldInfo(variables_, printer);
if (HasHazzer(descriptor_)) {
WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
@ -278,9 +281,9 @@ void ImmutablePrimitiveFieldGenerator::GenerateBuilderMembers(
printer->Print(variables_,
"$deprecation$public Builder "
"${$set$capitalized_name$$}$($type$ value) {\n"
"$null_check$"
" $set_has_field_bit_builder$\n"
" $null_check$\n"
" $name$_ = value;\n"
" $set_has_field_bit_builder$\n"
" $on_changed$\n"
" return this;\n"
"}\n");
@ -352,9 +355,8 @@ void ImmutablePrimitiveFieldGenerator::GenerateInitializationCode(
void ImmutablePrimitiveFieldGenerator::GenerateBuilderClearCode(
io::Printer* printer) const {
printer->Print(variables_,
"$name$_ = $default$;\n"
"$clear_has_field_bit_builder$\n");
// No need to clear the has-bit since we clear the bitField ints all at once.
printer->Print(variables_, "$name$_ = $default$;\n");
}
void ImmutablePrimitiveFieldGenerator::GenerateMergingCode(
@ -374,23 +376,13 @@ void ImmutablePrimitiveFieldGenerator::GenerateMergingCode(
void ImmutablePrimitiveFieldGenerator::GenerateBuildingCode(
io::Printer* printer) const {
if (HasHazzer(descriptor_)) {
if (IsDefaultValueJavaDefault(descriptor_)) {
printer->Print(variables_,
"if ($get_has_field_bit_from_local$) {\n"
" result.$name$_ = $name$_;\n"
" $set_has_field_bit_to_local$;\n"
"}\n");
} else {
printer->Print(variables_,
"if ($get_has_field_bit_from_local$) {\n"
" $set_has_field_bit_to_local$;\n"
"}\n"
"result.$name$_ = $name$_;\n");
}
} else {
printer->Print(variables_, "result.$name$_ = $name$_;\n");
printer->Print(variables_,
"if ($get_has_field_bit_from_local$) {\n"
" result.$name$_ = $name$_;\n");
if (GetNumBitsForMessage() > 0) {
printer->Print(variables_, " $set_has_field_bit_to_local$\n");
}
printer->Print("}\n");
}
void ImmutablePrimitiveFieldGenerator::GenerateBuilderParsingCode(
@ -579,7 +571,7 @@ void ImmutablePrimitiveOneofFieldGenerator::GenerateBuilderMembers(
printer->Print(variables_,
"$deprecation$public Builder "
"${$set$capitalized_name$$}$($type$ value) {\n"
"$null_check$"
" $null_check$\n"
" $set_oneof_case_message$;\n"
" $oneof_name$_ = value;\n"
" $on_changed$\n"
@ -610,10 +602,7 @@ void ImmutablePrimitiveOneofFieldGenerator::GenerateBuilderClearCode(
void ImmutablePrimitiveOneofFieldGenerator::GenerateBuildingCode(
io::Printer* printer) const {
printer->Print(variables_,
"if ($has_oneof_case_message$) {\n"
" result.$oneof_name$_ = $oneof_name$_;\n"
"}\n");
// no-op
}
void ImmutablePrimitiveOneofFieldGenerator::GenerateMergingCode(
@ -671,11 +660,8 @@ RepeatedImmutablePrimitiveFieldGenerator::
int messageBitIndex,
int builderBitIndex,
Context* context)
: descriptor_(descriptor), name_resolver_(context->GetNameResolver()) {
SetPrimitiveVariables(descriptor, messageBitIndex, builderBitIndex,
context->GetFieldGeneratorInfo(descriptor),
name_resolver_, &variables_);
}
: ImmutablePrimitiveFieldGenerator(descriptor, messageBitIndex,
builderBitIndex, context) {}
RepeatedImmutablePrimitiveFieldGenerator::
~RepeatedImmutablePrimitiveFieldGenerator() {}
@ -704,7 +690,8 @@ void RepeatedImmutablePrimitiveFieldGenerator::GenerateInterfaceMembers(
void RepeatedImmutablePrimitiveFieldGenerator::GenerateMembers(
io::Printer* printer) const {
printer->Print(variables_, "private $field_list_type$ $name$_;\n");
printer->Print(variables_, "@SuppressWarnings(\"serial\")\n"
"private $field_list_type$ $name$_;\n");
PrintExtraFieldInfo(variables_, printer);
WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER);
printer->Print(variables_,
@ -754,7 +741,7 @@ void RepeatedImmutablePrimitiveFieldGenerator::GenerateBuilderMembers(
" if (!$get_mutable_bit_builder$) {\n"
" $name$_ = $mutable_copy_list$;\n"
" $set_mutable_bit_builder$;\n"
" }\n"
" }\n"
"}\n");
// Note: We return an unmodifiable list because otherwise the caller
@ -789,7 +776,7 @@ void RepeatedImmutablePrimitiveFieldGenerator::GenerateBuilderMembers(
printer->Print(variables_,
"$deprecation$public Builder ${$set$capitalized_name$$}$(\n"
" int index, $type$ value) {\n"
"$null_check$"
" $null_check$\n"
" ensure$capitalized_name$IsMutable();\n"
" $repeated_set$(index, value);\n"
" $on_changed$\n"
@ -801,7 +788,7 @@ void RepeatedImmutablePrimitiveFieldGenerator::GenerateBuilderMembers(
printer->Print(variables_,
"$deprecation$public Builder "
"${$add$capitalized_name$$}$($type$ value) {\n"
"$null_check$"
" $null_check$\n"
" ensure$capitalized_name$IsMutable();\n"
" $repeated_add$(value);\n"
" $on_changed$\n"
@ -939,9 +926,7 @@ void RepeatedImmutablePrimitiveFieldGenerator::GenerateInitializationCode(
void RepeatedImmutablePrimitiveFieldGenerator::GenerateBuilderClearCode(
io::Printer* printer) const {
printer->Print(variables_,
"$name$_ = $empty_list$;\n"
"$clear_mutable_bit_builder$;\n");
printer->Print(variables_, "$name$_ = $empty_list$;\n");
}
void RepeatedImmutablePrimitiveFieldGenerator::GenerateMergingCode(

@ -38,7 +38,7 @@
#include <map>
#include <string>
#include <google/protobuf/compiler/java/field.h>
#include "google/protobuf/compiler/java/field.h"
namespace google {
namespace protobuf {
@ -62,10 +62,16 @@ class ImmutablePrimitiveFieldGenerator : public ImmutableFieldGenerator {
int messageBitIndex,
int builderBitIndex,
Context* context);
ImmutablePrimitiveFieldGenerator(const ImmutablePrimitiveFieldGenerator&) =
delete;
ImmutablePrimitiveFieldGenerator& operator=(
const ImmutablePrimitiveFieldGenerator&) = delete;
~ImmutablePrimitiveFieldGenerator() override;
// implements ImmutableFieldGenerator
// ---------------------------------------
int GetMessageBitIndex() const override;
int GetBuilderBitIndex() const override;
int GetNumBitsForMessage() const override;
int GetNumBitsForBuilder() const override;
void GenerateInterfaceMembers(io::Printer* printer) const override;
@ -88,11 +94,10 @@ class ImmutablePrimitiveFieldGenerator : public ImmutableFieldGenerator {
protected:
const FieldDescriptor* descriptor_;
int message_bit_index_;
int builder_bit_index_;
std::map<std::string, std::string> variables_;
ClassNameResolver* name_resolver_;
private:
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutablePrimitiveFieldGenerator);
};
class ImmutablePrimitiveOneofFieldGenerator
@ -101,6 +106,10 @@ class ImmutablePrimitiveOneofFieldGenerator
ImmutablePrimitiveOneofFieldGenerator(const FieldDescriptor* descriptor,
int messageBitIndex,
int builderBitIndex, Context* context);
ImmutablePrimitiveOneofFieldGenerator(
const ImmutablePrimitiveOneofFieldGenerator&) = delete;
ImmutablePrimitiveOneofFieldGenerator& operator=(
const ImmutablePrimitiveOneofFieldGenerator&) = delete;
~ImmutablePrimitiveOneofFieldGenerator() override;
void GenerateMembers(io::Printer* printer) const override;
@ -111,17 +120,18 @@ class ImmutablePrimitiveOneofFieldGenerator
void GenerateBuilderParsingCode(io::Printer* printer) const override;
void GenerateSerializationCode(io::Printer* printer) const override;
void GenerateSerializedSizeCode(io::Printer* printer) const override;
private:
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutablePrimitiveOneofFieldGenerator);
};
class RepeatedImmutablePrimitiveFieldGenerator
: public ImmutableFieldGenerator {
: public ImmutablePrimitiveFieldGenerator {
public:
explicit RepeatedImmutablePrimitiveFieldGenerator(
const FieldDescriptor* descriptor, int messageBitIndex,
int builderBitIndex, Context* context);
RepeatedImmutablePrimitiveFieldGenerator(
const RepeatedImmutablePrimitiveFieldGenerator&) = delete;
RepeatedImmutablePrimitiveFieldGenerator& operator=(
const RepeatedImmutablePrimitiveFieldGenerator&) = delete;
~RepeatedImmutablePrimitiveFieldGenerator() override;
// implements ImmutableFieldGenerator ---------------------------------------
@ -146,13 +156,6 @@ class RepeatedImmutablePrimitiveFieldGenerator
void GenerateKotlinDslMembers(io::Printer* printer) const override;
std::string GetBoxedType() const override;
private:
const FieldDescriptor* descriptor_;
std::map<std::string, std::string> variables_;
ClassNameResolver* name_resolver_;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedImmutablePrimitiveFieldGenerator);
};
} // namespace java

@ -33,21 +33,21 @@
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
#include <google/protobuf/compiler/java/string_field.h>
#include "google/protobuf/compiler/java/string_field.h"
#include <cstdint>
#include <map>
#include <string>
#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/io/printer.h>
#include <google/protobuf/wire_format.h>
#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/compiler/java/context.h>
#include <google/protobuf/compiler/java/doc_comment.h>
#include <google/protobuf/compiler/java/helpers.h>
#include <google/protobuf/compiler/java/name_resolver.h>
#include "google/protobuf/stubs/logging.h"
#include "google/protobuf/stubs/common.h"
#include "google/protobuf/io/printer.h"
#include "google/protobuf/wire_format.h"
#include "google/protobuf/stubs/strutil.h"
#include "google/protobuf/compiler/java/context.h"
#include "google/protobuf/compiler/java/doc_comment.h"
#include "google/protobuf/compiler/java/helpers.h"
#include "google/protobuf/compiler/java/name_resolver.h"
namespace google {
namespace protobuf {
@ -59,11 +59,11 @@ using internal::WireFormatLite;
namespace {
void SetPrimitiveVariables(const FieldDescriptor* descriptor,
int messageBitIndex, int builderBitIndex,
const FieldGeneratorInfo* info,
ClassNameResolver* name_resolver,
std::map<std::string, std::string>* variables) {
void SetPrimitiveVariables(
const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex,
const FieldGeneratorInfo* info, ClassNameResolver* name_resolver,
std::map<std::string, std::string>* variables,
Context* context) {
SetCommonFieldVariables(descriptor, info, variables);
(*variables)["empty_list"] = "com.google.protobuf.LazyStringArrayList.EMPTY";
@ -77,9 +77,7 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor,
(*variables)["tag_size"] = StrCat(
WireFormat::TagSize(descriptor->number(), GetType(descriptor)));
(*variables)["null_check"] =
" if (value == null) {\n"
" throw new NullPointerException();\n"
" }\n";
"if (value == null) { throw new NullPointerException(); }";
(*variables)["isStringEmpty"] = "com.google.protobuf.GeneratedMessage" +
GeneratedCodeVersionSuffix() +
".isStringEmpty";
@ -93,34 +91,33 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor,
// by the proto compiler
(*variables)["deprecation"] =
descriptor->options().deprecated() ? "@java.lang.Deprecated " : "";
(*variables)["kt_deprecation"] =
descriptor->options().deprecated()
? "@kotlin.Deprecated(message = \"Field " + (*variables)["name"] +
" is deprecated\") "
: "";
variables->insert(
{"kt_deprecation",
descriptor->options().deprecated()
? StrCat("@kotlin.Deprecated(message = \"Field ",
(*variables)["name"], " is deprecated\") ")
: ""});
(*variables)["on_changed"] = "onChanged();";
if (HasHasbit(descriptor)) {
// 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);
(*variables)["set_has_field_bit_to_local"] =
GenerateSetBitToLocal(messageBitIndex);
// 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)["is_field_present_message"] = GenerateGetBit(messageBitIndex);
} else {
(*variables)["get_has_field_bit_message"] = "";
(*variables)["set_has_field_bit_to_local"] = "";
(*variables)["set_has_field_bit_message"] = "";
(*variables)["set_has_field_bit_builder"] = "";
(*variables)["clear_has_field_bit_builder"] = "";
(*variables)["is_field_present_message"] =
"!" + (*variables)["isStringEmpty"] + "(" + (*variables)["name"] + "_)";
variables->insert({"is_field_present_message",
StrCat("!", (*variables)["isStringEmpty"], "(",
(*variables)["name"], "_)")});
}
// For repeated builders, one bit is used for whether the array is immutable.
@ -128,10 +125,13 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor,
(*variables)["set_mutable_bit_builder"] = GenerateSetBit(builderBitIndex);
(*variables)["clear_mutable_bit_builder"] = GenerateClearBit(builderBitIndex);
(*variables)["get_has_field_bit_builder"] = GenerateGetBit(builderBitIndex);
(*variables)["get_has_field_bit_from_local"] =
GenerateGetBitFromLocal(builderBitIndex);
(*variables)["set_has_field_bit_to_local"] =
GenerateSetBitToLocal(messageBitIndex);
(*variables)["set_has_field_bit_builder"] =
GenerateSetBit(builderBitIndex) + ";";
(*variables)["clear_has_field_bit_builder"] =
GenerateClearBit(builderBitIndex) + ";";
}
} // namespace
@ -141,21 +141,30 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor,
ImmutableStringFieldGenerator::ImmutableStringFieldGenerator(
const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex,
Context* context)
: descriptor_(descriptor), name_resolver_(context->GetNameResolver()) {
: descriptor_(descriptor),
message_bit_index_(messageBitIndex),
builder_bit_index_(builderBitIndex),
name_resolver_(context->GetNameResolver()) {
SetPrimitiveVariables(descriptor, messageBitIndex, builderBitIndex,
context->GetFieldGeneratorInfo(descriptor),
name_resolver_, &variables_);
name_resolver_, &variables_, context);
}
ImmutableStringFieldGenerator::~ImmutableStringFieldGenerator() {}
int ImmutableStringFieldGenerator::GetMessageBitIndex() const {
return message_bit_index_;
}
int ImmutableStringFieldGenerator::GetBuilderBitIndex() const {
return builder_bit_index_;
}
int ImmutableStringFieldGenerator::GetNumBitsForMessage() const {
return HasHasbit(descriptor_) ? 1 : 0;
}
int ImmutableStringFieldGenerator::GetNumBitsForBuilder() const {
return GetNumBitsForMessage();
}
int ImmutableStringFieldGenerator::GetNumBitsForBuilder() const { return 1; }
// A note about how strings are handled. This code used to just store a String
// in the Message. This had two issues:
@ -207,7 +216,9 @@ void ImmutableStringFieldGenerator::GenerateInterfaceMembers(
void ImmutableStringFieldGenerator::GenerateMembers(
io::Printer* printer) const {
printer->Print(variables_, "private volatile java.lang.Object $name$_;\n");
printer->Print(variables_,
"@SuppressWarnings(\"serial\")\n"
"private volatile java.lang.Object $name$_ = $default$;\n");
PrintExtraFieldInfo(variables_, printer);
if (HasHazzer(descriptor_)) {
@ -326,9 +337,9 @@ void ImmutableStringFieldGenerator::GenerateBuilderMembers(
printer->Print(variables_,
"$deprecation$public Builder ${$set$capitalized_name$$}$(\n"
" java.lang.String value) {\n"
"$null_check$"
" $set_has_field_bit_builder$\n"
" $null_check$\n"
" $name$_ = value;\n"
" $set_has_field_bit_builder$\n"
" $on_changed$\n"
" return this;\n"
"}\n");
@ -337,14 +348,14 @@ void ImmutableStringFieldGenerator::GenerateBuilderMembers(
/* builder */ true);
printer->Print(
variables_,
"$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n"
" $clear_has_field_bit_builder$\n");
"$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n");
printer->Annotate("{", "}", descriptor_);
// The default value is not a simple literal so we want to avoid executing
// it multiple times. Instead, get the default out of the default instance.
printer->Print(variables_,
" $name$_ = getDefaultInstance().get$capitalized_name$();\n");
printer->Print(variables_,
" $clear_has_field_bit_builder$\n"
" $on_changed$\n"
" return this;\n"
"}\n");
@ -355,14 +366,14 @@ void ImmutableStringFieldGenerator::GenerateBuilderMembers(
variables_,
"$deprecation$public Builder ${$set$capitalized_name$Bytes$}$(\n"
" com.google.protobuf.ByteString value) {\n"
"$null_check$");
" $null_check$\n");
printer->Annotate("{", "}", descriptor_);
if (CheckUtf8(descriptor_)) {
printer->Print(variables_, " checkByteStringIsUtf8(value);\n");
}
printer->Print(variables_,
" $set_has_field_bit_builder$\n"
" $name$_ = value;\n"
" $set_has_field_bit_builder$\n"
" $on_changed$\n"
" return this;\n"
"}\n");
@ -409,9 +420,7 @@ void ImmutableStringFieldGenerator::GenerateInitializationCode(
void ImmutableStringFieldGenerator::GenerateBuilderClearCode(
io::Printer* printer) const {
printer->Print(variables_,
"$name$_ = $default$;\n"
"$clear_has_field_bit_builder$\n");
printer->Print(variables_, "$name$_ = $default$;\n");
}
void ImmutableStringFieldGenerator::GenerateMergingCode(
@ -421,14 +430,15 @@ void ImmutableStringFieldGenerator::GenerateMergingCode(
// all string fields to Strings when copying fields from a Message.
printer->Print(variables_,
"if (other.has$capitalized_name$()) {\n"
" $set_has_field_bit_builder$\n"
" $name$_ = other.$name$_;\n"
" $set_has_field_bit_builder$\n"
" $on_changed$\n"
"}\n");
} else {
printer->Print(variables_,
"if (!other.get$capitalized_name$().isEmpty()) {\n"
" $name$_ = other.$name$_;\n"
" $set_has_field_bit_builder$\n"
" $on_changed$\n"
"}\n");
}
@ -436,13 +446,13 @@ void ImmutableStringFieldGenerator::GenerateMergingCode(
void ImmutableStringFieldGenerator::GenerateBuildingCode(
io::Printer* printer) const {
if (HasHazzer(descriptor_)) {
printer->Print(variables_,
"if ($get_has_field_bit_from_local$) {\n"
" $set_has_field_bit_to_local$;\n"
"}\n");
printer->Print(variables_,
"if ($get_has_field_bit_from_local$) {\n"
" result.$name$_ = $name$_;\n");
if (GetNumBitsForMessage() > 0) {
printer->Print(variables_, " $set_has_field_bit_to_local$;\n");
}
printer->Print(variables_, "result.$name$_ = $name$_;\n");
printer->Print("}\n");
}
void ImmutableStringFieldGenerator::GenerateBuilderParsingCode(
@ -641,7 +651,7 @@ void ImmutableStringOneofFieldGenerator::GenerateBuilderMembers(
printer->Print(variables_,
"$deprecation$public Builder ${$set$capitalized_name$$}$(\n"
" java.lang.String value) {\n"
"$null_check$"
" $null_check$\n"
" $set_oneof_case_message$;\n"
" $oneof_name$_ = value;\n"
" $on_changed$\n"
@ -668,7 +678,7 @@ void ImmutableStringOneofFieldGenerator::GenerateBuilderMembers(
variables_,
"$deprecation$public Builder ${$set$capitalized_name$Bytes$}$(\n"
" com.google.protobuf.ByteString value) {\n"
"$null_check$");
" $null_check$\n");
printer->Annotate("{", "}", descriptor_);
if (CheckUtf8(descriptor_)) {
printer->Print(variables_, " checkByteStringIsUtf8(value);\n");
@ -698,10 +708,7 @@ void ImmutableStringOneofFieldGenerator::GenerateMergingCode(
void ImmutableStringOneofFieldGenerator::GenerateBuildingCode(
io::Printer* printer) const {
printer->Print(variables_,
"if ($has_oneof_case_message$) {\n"
" result.$oneof_name$_ = $oneof_name$_;\n"
"}\n");
// No-Op: oneof fields are built by a single statement
}
void ImmutableStringOneofFieldGenerator::GenerateBuilderParsingCode(
@ -740,11 +747,8 @@ void ImmutableStringOneofFieldGenerator::GenerateSerializedSizeCode(
RepeatedImmutableStringFieldGenerator::RepeatedImmutableStringFieldGenerator(
const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex,
Context* context)
: descriptor_(descriptor), name_resolver_(context->GetNameResolver()) {
SetPrimitiveVariables(descriptor, messageBitIndex, builderBitIndex,
context->GetFieldGeneratorInfo(descriptor),
name_resolver_, &variables_);
}
: ImmutableStringFieldGenerator(descriptor, messageBitIndex,
builderBitIndex, context) {}
RepeatedImmutableStringFieldGenerator::
~RepeatedImmutableStringFieldGenerator() {}
@ -787,6 +791,7 @@ void RepeatedImmutableStringFieldGenerator::GenerateInterfaceMembers(
void RepeatedImmutableStringFieldGenerator::GenerateMembers(
io::Printer* printer) const {
printer->Print(variables_,
"@SuppressWarnings(\"serial\")\n"
"private com.google.protobuf.LazyStringList $name$_;\n");
PrintExtraFieldInfo(variables_, printer);
WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER);
@ -882,7 +887,7 @@ void RepeatedImmutableStringFieldGenerator::GenerateBuilderMembers(
printer->Print(variables_,
"$deprecation$public Builder ${$set$capitalized_name$$}$(\n"
" int index, java.lang.String value) {\n"
"$null_check$"
" $null_check$\n"
" ensure$capitalized_name$IsMutable();\n"
" $name$_.set(index, value);\n"
" $on_changed$\n"
@ -894,7 +899,7 @@ void RepeatedImmutableStringFieldGenerator::GenerateBuilderMembers(
printer->Print(variables_,
"$deprecation$public Builder ${$add$capitalized_name$$}$(\n"
" java.lang.String value) {\n"
"$null_check$"
" $null_check$\n"
" ensure$capitalized_name$IsMutable();\n"
" $name$_.add(value);\n"
" $on_changed$\n"
@ -931,7 +936,7 @@ void RepeatedImmutableStringFieldGenerator::GenerateBuilderMembers(
variables_,
"$deprecation$public Builder ${$add$capitalized_name$Bytes$}$(\n"
" com.google.protobuf.ByteString value) {\n"
"$null_check$");
" $null_check$\n");
printer->Annotate("{", "}", descriptor_);
if (CheckUtf8(descriptor_)) {
printer->Print(variables_, " checkByteStringIsUtf8(value);\n");

@ -39,7 +39,7 @@
#include <map>
#include <string>
#include <google/protobuf/compiler/java/field.h>
#include "google/protobuf/compiler/java/field.h"
namespace google {
namespace protobuf {
@ -62,10 +62,15 @@ class ImmutableStringFieldGenerator : public ImmutableFieldGenerator {
explicit ImmutableStringFieldGenerator(const FieldDescriptor* descriptor,
int messageBitIndex,
int builderBitIndex, Context* context);
ImmutableStringFieldGenerator(const ImmutableStringFieldGenerator&) = delete;
ImmutableStringFieldGenerator& operator=(
const ImmutableStringFieldGenerator&) = delete;
~ImmutableStringFieldGenerator() override;
// implements ImmutableFieldGenerator
// ---------------------------------------
int GetMessageBitIndex() const override;
int GetBuilderBitIndex() const override;
int GetNumBitsForMessage() const override;
int GetNumBitsForBuilder() const override;
void GenerateInterfaceMembers(io::Printer* printer) const override;
@ -88,11 +93,10 @@ class ImmutableStringFieldGenerator : public ImmutableFieldGenerator {
protected:
const FieldDescriptor* descriptor_;
int message_bit_index_;
int builder_bit_index_;
std::map<std::string, std::string> variables_;
ClassNameResolver* name_resolver_;
private:
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableStringFieldGenerator);
};
class ImmutableStringOneofFieldGenerator
@ -101,6 +105,10 @@ class ImmutableStringOneofFieldGenerator
ImmutableStringOneofFieldGenerator(const FieldDescriptor* descriptor,
int messageBitIndex, int builderBitIndex,
Context* context);
ImmutableStringOneofFieldGenerator(
const ImmutableStringOneofFieldGenerator&) = delete;
ImmutableStringOneofFieldGenerator& operator=(
const ImmutableStringOneofFieldGenerator&) = delete;
~ImmutableStringOneofFieldGenerator() override;
private:
@ -112,15 +120,18 @@ class ImmutableStringOneofFieldGenerator
void GenerateBuilderParsingCode(io::Printer* printer) const override;
void GenerateSerializationCode(io::Printer* printer) const override;
void GenerateSerializedSizeCode(io::Printer* printer) const override;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableStringOneofFieldGenerator);
};
class RepeatedImmutableStringFieldGenerator : public ImmutableFieldGenerator {
class RepeatedImmutableStringFieldGenerator
: public ImmutableStringFieldGenerator {
public:
explicit RepeatedImmutableStringFieldGenerator(
const FieldDescriptor* descriptor, int messageBitIndex,
int builderBitIndex, Context* context);
RepeatedImmutableStringFieldGenerator(
const RepeatedImmutableStringFieldGenerator&) = delete;
RepeatedImmutableStringFieldGenerator& operator=(
const RepeatedImmutableStringFieldGenerator&) = delete;
~RepeatedImmutableStringFieldGenerator() override;
// implements ImmutableFieldGenerator ---------------------------------------
@ -143,13 +154,6 @@ class RepeatedImmutableStringFieldGenerator : public ImmutableFieldGenerator {
void GenerateKotlinDslMembers(io::Printer* printer) const override;
std::string GetBoxedType() const override;
private:
const FieldDescriptor* descriptor_;
std::map<std::string, std::string> variables_;
ClassNameResolver* name_resolver_;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedImmutableStringFieldGenerator);
};
} // namespace java

Loading…
Cancel
Save