Precompute the most common field properties in FieldGeneratorBase

This is a cleanup that is intended to reduce the noise in current and planned protocol compiler code, and improve readability of the code.

PiperOrigin-RevId: 550631662
pull/13383/head
Martijn Vels 1 year ago committed by Copybara-Service
parent 46ddd14efd
commit d4f2d48101
  1. 39
      src/google/protobuf/compiler/cpp/field.cc
  2. 62
      src/google/protobuf/compiler/cpp/field.h
  3. 27
      src/google/protobuf/compiler/cpp/field_generators/cord_field.cc
  4. 40
      src/google/protobuf/compiler/cpp/field_generators/enum_field.cc
  5. 6
      src/google/protobuf/compiler/cpp/field_generators/map_field.cc
  6. 60
      src/google/protobuf/compiler/cpp/field_generators/message_field.cc
  7. 42
      src/google/protobuf/compiler/cpp/field_generators/primitive_field.cc
  8. 91
      src/google/protobuf/compiler/cpp/field_generators/string_field.cc

@ -117,6 +117,43 @@ std::vector<Sub> FieldVars(const FieldDescriptor* field, const Options& opts) {
return vars;
}
FieldGeneratorBase::FieldGeneratorBase(const FieldDescriptor* descriptor,
const Options& options,
MessageSCCAnalyzer* scc)
: descriptor_(descriptor), options_(options) {
should_split_ = ShouldSplit(descriptor, options);
is_oneof_ = descriptor->real_containing_oneof() != nullptr;
switch (descriptor->cpp_type()) {
case FieldDescriptor::CPPTYPE_ENUM:
case FieldDescriptor::CPPTYPE_INT32:
case FieldDescriptor::CPPTYPE_INT64:
case FieldDescriptor::CPPTYPE_UINT32:
case FieldDescriptor::CPPTYPE_UINT64:
case FieldDescriptor::CPPTYPE_FLOAT:
case FieldDescriptor::CPPTYPE_DOUBLE:
case FieldDescriptor::CPPTYPE_BOOL:
is_trivial_ = !(descriptor->is_repeated() || descriptor->is_map());
has_trivial_value_ = is_trivial_;
break;
case FieldDescriptor::CPPTYPE_STRING:
is_string_ = true;
string_type_ = descriptor->options().ctype();
is_inlined_ = IsStringInlined(descriptor, options);
is_bytes_ = descriptor->type() == FieldDescriptor::TYPE_BYTES;
break;
case FieldDescriptor::CPPTYPE_MESSAGE:
is_message_ = true;
is_group_ = descriptor->type() == FieldDescriptor::TYPE_GROUP;
is_foreign_ = IsCrossFileMessage(descriptor);
is_lazy_ = IsLazy(descriptor, options, scc);
is_weak_ = IsImplicitWeakField(descriptor, options, scc);
if (!(descriptor->is_repeated() || descriptor->is_map())) {
has_trivial_value_ = !is_lazy_;
}
break;
}
}
void FieldGeneratorBase::GenerateAggregateInitializer(io::Printer* p) const {
if (ShouldSplit(descriptor_, options_)) {
p->Emit(R"cc(
@ -144,7 +181,7 @@ void FieldGeneratorBase::GenerateCopyAggregateInitializer(
}
void FieldGeneratorBase::GenerateCopyConstructorCode(io::Printer* p) const {
if (ShouldSplit(descriptor_, options_)) {
if (should_split()) {
// There is no copy constructor for the `Split` struct, so we need to copy
// the value here.
Formatter format(p, variables_);

@ -62,14 +62,57 @@ namespace cpp {
// matter of clean composability.
class FieldGeneratorBase {
public:
FieldGeneratorBase(const FieldDescriptor* descriptor, const Options& options)
: descriptor_(descriptor), options_(options) {}
FieldGeneratorBase(const FieldDescriptor* descriptor, const Options& options,
MessageSCCAnalyzer* scc_analyzer);
FieldGeneratorBase(const FieldGeneratorBase&) = delete;
FieldGeneratorBase& operator=(const FieldGeneratorBase&) = delete;
virtual ~FieldGeneratorBase() = 0;
// Returns true if this field should be placed in the cold 'Split' section.
bool should_split() const { return should_split_; }
// Returns true if this field is trivial. (int, float, double, enum, bool)
bool is_trivial() const { return is_trivial_; }
// Returns true if the field value itself is trivial, i.e., the field is
// trivial, or a (raw) pointer value to a singular, non lazy message.
bool has_trivial_value() const { return has_trivial_value_; }
// Returns true if the field is a singular or repeated message.
// This includes group message types. To explicitly check if a message
// type is a group type, use the `is_group()` function,
bool is_message() const { return is_message_; }
// Returns true if the field is a group message field (TYPE_GROUP).
bool is_group() const { return is_group_; }
// Returns true if the field is a weak message
bool is_weak() const { return is_weak_; }
// Returns true if the field is a lazy message.
bool is_lazy() const { return is_lazy_; }
// Returns true if the field is a foreign message field.
bool is_foreign() const { return is_foreign_; }
// Returns true if the field is a string field.
bool is_string() const { return is_string_; }
// Returns true if the field API uses bytes (void) instead of chars.
bool is_bytes() const { return is_bytes_; }
// Returns the public API string type for string fields.
FieldOptions::CType string_type() const { return string_type_; }
// Returns true if this field is part of a oneof field.
bool is_oneof() const { return is_oneof_; }
// Returns true if the field should be inlined instead of dynamically
// allocated. Applies to string and message value.
bool is_inlined() const { return is_inlined_; }
virtual std::vector<io::Printer::Sub> MakeVars() const { return {}; }
virtual void GeneratePrivateMembers(io::Printer* p) const = 0;
@ -131,6 +174,21 @@ class FieldGeneratorBase {
const FieldDescriptor* descriptor_;
const Options& options_;
absl::flat_hash_map<absl::string_view, std::string> variables_;
private:
bool should_split_ = false;
bool is_trivial_ = false;
bool has_trivial_value_ = false;
bool is_message_ = false;
bool is_group_ = false;
bool is_string_ = false;
bool is_bytes_ = false;
bool is_inlined_ = false;
bool is_foreign_ = false;
bool is_lazy_ = false;
bool is_weak_ = false;
bool is_oneof_ = false;
FieldOptions::CType string_type_ = FieldOptions::STRING;
};
inline FieldGeneratorBase::~FieldGeneratorBase() = default;

@ -77,7 +77,8 @@ void SetCordVariables(
class CordFieldGenerator : public FieldGeneratorBase {
public:
CordFieldGenerator(const FieldDescriptor* descriptor, const Options& options);
CordFieldGenerator(const FieldDescriptor* descriptor, const Options& options,
MessageSCCAnalyzer* scc);
~CordFieldGenerator() override = default;
void GeneratePrivateMembers(io::Printer* printer) const override;
@ -103,7 +104,7 @@ class CordFieldGenerator : public FieldGeneratorBase {
class CordOneofFieldGenerator : public CordFieldGenerator {
public:
CordOneofFieldGenerator(const FieldDescriptor* descriptor,
const Options& options);
const Options& options, MessageSCCAnalyzer* scc);
~CordOneofFieldGenerator() override = default;
void GeneratePrivateMembers(io::Printer* printer) const override;
@ -123,8 +124,9 @@ class CordOneofFieldGenerator : public CordFieldGenerator {
CordFieldGenerator::CordFieldGenerator(const FieldDescriptor* descriptor,
const Options& options)
: FieldGeneratorBase(descriptor, options) {
const Options& options,
MessageSCCAnalyzer* scc)
: FieldGeneratorBase(descriptor, options, scc) {
SetCordVariables(descriptor, &variables_, options);
}
@ -215,7 +217,7 @@ void CordFieldGenerator::GenerateSwappingCode(io::Printer* printer) const {
}
void CordFieldGenerator::GenerateConstructorCode(io::Printer* printer) const {
ABSL_CHECK(!ShouldSplit(descriptor_, options_));
ABSL_CHECK(!should_split());
Formatter format(printer, variables_);
if (!descriptor_->default_value_string().empty()) {
format("$field$ = ::absl::string_view($default$, $default_length$);\n");
@ -224,7 +226,7 @@ void CordFieldGenerator::GenerateConstructorCode(io::Printer* printer) const {
void CordFieldGenerator::GenerateDestructorCode(io::Printer* printer) const {
Formatter format(printer, variables_);
if (ShouldSplit(descriptor_, options_)) {
if (should_split()) {
// A cord field in the `Split` struct is automatically destroyed when the
// split pointer is deleted and should not be explicitly destroyed here.
return;
@ -270,7 +272,7 @@ void CordFieldGenerator::GenerateConstexprAggregateInitializer(
)cc");
} else {
p->Emit(
{{"Split", ShouldSplit(descriptor_, options_) ? "Split::" : ""}},
{{"Split", should_split() ? "Split::" : ""}},
R"cc(
/*decltype($field$)*/ {::absl::strings_internal::MakeStringConstant(
$classname$::Impl_::$Split$_default_$name$_func_{})},
@ -279,7 +281,7 @@ void CordFieldGenerator::GenerateConstexprAggregateInitializer(
}
void CordFieldGenerator::GenerateAggregateInitializer(io::Printer* p) const {
if (ShouldSplit(descriptor_, options_)) {
if (should_split()) {
p->Emit(R"cc(
decltype(Impl_::Split::$name$_){},
)cc");
@ -293,8 +295,9 @@ void CordFieldGenerator::GenerateAggregateInitializer(io::Printer* p) const {
// ===================================================================
CordOneofFieldGenerator::CordOneofFieldGenerator(
const FieldDescriptor* descriptor, const Options& options)
: CordFieldGenerator(descriptor, options) {}
const FieldDescriptor* descriptor, const Options& options,
MessageSCCAnalyzer* scc)
: CordFieldGenerator(descriptor, options, scc) {}
void CordOneofFieldGenerator::GeneratePrivateMembers(
io::Printer* printer) const {
@ -410,14 +413,14 @@ void CordOneofFieldGenerator::GenerateArenaDestructorCode(
std::unique_ptr<FieldGeneratorBase> MakeSingularCordGenerator(
const FieldDescriptor* desc, const Options& options,
MessageSCCAnalyzer* scc) {
return absl::make_unique<CordFieldGenerator>(desc, options);
return absl::make_unique<CordFieldGenerator>(desc, options, scc);
}
std::unique_ptr<FieldGeneratorBase> MakeOneofCordGenerator(
const FieldDescriptor* desc, const Options& options,
MessageSCCAnalyzer* scc) {
return absl::make_unique<CordOneofFieldGenerator>(desc, options);
return absl::make_unique<CordOneofFieldGenerator>(desc, options, scc);
}
} // namespace cpp

@ -75,11 +75,9 @@ std::vector<Sub> Vars(const FieldDescriptor* field, const Options& opts) {
class SingularEnum : public FieldGeneratorBase {
public:
SingularEnum(const FieldDescriptor* field, const Options& opts)
: FieldGeneratorBase(field, opts),
field_(field),
opts_(&opts),
is_oneof_(field->real_containing_oneof() != nullptr) {}
SingularEnum(const FieldDescriptor* field, const Options& opts,
MessageSCCAnalyzer* scc)
: FieldGeneratorBase(field, opts, scc), field_(field), opts_(&opts) {}
~SingularEnum() override = default;
std::vector<Sub> MakeVars() const override { return Vars(field_, *opts_); }
@ -103,7 +101,7 @@ class SingularEnum : public FieldGeneratorBase {
}
void GenerateSwappingCode(io::Printer* p) const override {
if (is_oneof_) return;
if (is_oneof()) return;
p->Emit(R"cc(
swap($field_$, other->$field_$);
@ -111,7 +109,7 @@ class SingularEnum : public FieldGeneratorBase {
}
void GenerateConstructorCode(io::Printer* p) const override {
if (!is_oneof_) return;
if (!is_oneof()) return;
p->Emit(R"cc(
$ns$::_$Msg$_default_instance_.$field_$ = $kDefault$;
)cc");
@ -145,7 +143,7 @@ class SingularEnum : public FieldGeneratorBase {
}
void GenerateAggregateInitializer(io::Printer* p) const override {
if (ShouldSplit(descriptor_, options_)) {
if (should_split()) {
p->Emit(R"cc(
decltype(Impl_::Split::$name$_){$kDefault$},
)cc");
@ -168,7 +166,6 @@ class SingularEnum : public FieldGeneratorBase {
private:
const FieldDescriptor* field_;
const Options* opts_;
bool is_oneof_;
};
void SingularEnum::GenerateAccessorDeclarations(io::Printer* p) const {
@ -202,7 +199,7 @@ void SingularEnum::GenerateInlineAccessorDefinitions(io::Printer* p) const {
}
)cc");
if (is_oneof_) {
if (is_oneof()) {
p->Emit(R"cc(
inline $Enum$ $Msg$::_internal_$name$() const {
if ($has_field$) {
@ -237,19 +234,20 @@ void SingularEnum::GenerateInlineAccessorDefinitions(io::Printer* p) const {
class RepeatedEnum : public FieldGeneratorBase {
public:
RepeatedEnum(const FieldDescriptor* field, const Options& opts)
: FieldGeneratorBase(field, opts),
RepeatedEnum(const FieldDescriptor* field, const Options& opts,
MessageSCCAnalyzer* scc)
: FieldGeneratorBase(field, opts, scc),
field_(field),
opts_(&opts),
has_cached_size_(field_->is_packed() &&
HasGeneratedMethods(field_->file(), opts) &&
!ShouldSplit(descriptor_, options_)) {}
!should_split()) {}
~RepeatedEnum() override = default;
std::vector<Sub> MakeVars() const override { return Vars(field_, *opts_); }
void GeneratePrivateMembers(io::Printer* p) const override {
if (ShouldSplit(descriptor_, options_)) {
if (should_split()) {
p->Emit(R"cc(
$pbi$::RawPtr<$pb$::RepeatedField<int>> $name$_;
)cc");
@ -280,7 +278,7 @@ class RepeatedEnum : public FieldGeneratorBase {
_this->_internal_mutable_$name$()->MergeFrom(from._internal_$name$());
)cc");
};
if (!ShouldSplit(descriptor_, options_)) {
if (!should_split()) {
body();
} else {
p->Emit({{"body", body}}, R"cc(
@ -292,14 +290,14 @@ class RepeatedEnum : public FieldGeneratorBase {
}
void GenerateSwappingCode(io::Printer* p) const override {
ABSL_CHECK(!ShouldSplit(descriptor_, options_));
ABSL_CHECK(!should_split());
p->Emit(R"cc(
$field_$.InternalSwap(&other->$field_$);
)cc");
}
void GenerateDestructorCode(io::Printer* p) const override {
if (ShouldSplit(descriptor_, options_)) {
if (should_split()) {
p->Emit(R"cc(
$field_$.DeleteIfNotDefault();
)cc");
@ -347,7 +345,7 @@ class RepeatedEnum : public FieldGeneratorBase {
}
void GenerateCopyConstructorCode(io::Printer* p) const override {
if (ShouldSplit(descriptor_, options_)) {
if (should_split()) {
p->Emit(R"cc(
if (!from._internal_$name$().empty()) {
_internal_mutable_$name$()->MergeFrom(from._internal_$name$());
@ -425,7 +423,7 @@ void RepeatedEnum::GenerateInlineAccessorDefinitions(io::Printer* p) const {
return _internal_mutable_$name$();
}
)cc");
if (ShouldSplit(descriptor_, options_)) {
if (should_split()) {
p->Emit(R"cc(
inline const $pb$::RepeatedField<int>& $Msg$::_internal_$name$() const {
$TsanDetectConcurrentRead$;
@ -544,13 +542,13 @@ void RepeatedEnum::GenerateByteSize(io::Printer* p) const {
std::unique_ptr<FieldGeneratorBase> MakeSinguarEnumGenerator(
const FieldDescriptor* desc, const Options& options,
MessageSCCAnalyzer* scc) {
return absl::make_unique<SingularEnum>(desc, options);
return absl::make_unique<SingularEnum>(desc, options, scc);
}
std::unique_ptr<FieldGeneratorBase> MakeRepeatedEnumGenerator(
const FieldDescriptor* desc, const Options& options,
MessageSCCAnalyzer* scc) {
return absl::make_unique<RepeatedEnum>(desc, options);
return absl::make_unique<RepeatedEnum>(desc, options, scc);
}
} // namespace cpp

@ -80,7 +80,7 @@ class Map : public FieldGeneratorBase {
public:
Map(const FieldDescriptor* field, const Options& opts,
MessageSCCAnalyzer* scc)
: FieldGeneratorBase(field, opts),
: FieldGeneratorBase(field, opts, scc),
field_(field),
key_(field->message_type()->map_key()),
val_(field->message_type()->map_value()),
@ -141,7 +141,7 @@ class Map : public FieldGeneratorBase {
}
void GenerateAggregateInitializer(io::Printer* p) const override {
if (ShouldSplit(field_, *opts_)) {
if (should_split()) {
p->Emit(R"cc(
/* decltype($Msg$::Split::$name$_) */ {
$pbi$::ArenaInitialized(),
@ -158,7 +158,7 @@ class Map : public FieldGeneratorBase {
void GenerateConstructorCode(io::Printer* p) const override {}
void GenerateDestructorCode(io::Printer* p) const override {
if (ShouldSplit(field_, *opts_)) {
if (should_split()) {
p->Emit(R"cc(
$cached_split_ptr$->$name$_.~$MapField$();
)cc");

@ -99,19 +99,16 @@ class SingularMessage : public FieldGeneratorBase {
public:
SingularMessage(const FieldDescriptor* field, const Options& opts,
MessageSCCAnalyzer* scc)
: FieldGeneratorBase(field, opts),
: FieldGeneratorBase(field, opts, scc),
field_(field),
opts_(&opts),
weak_(IsImplicitWeakField(field, opts, scc)),
has_required_(scc->HasRequiredFields(field->message_type())),
has_hasbit_(HasHasbit(field)),
is_oneof_(field_->real_containing_oneof() != nullptr),
is_foreign_(IsCrossFileMessage(field)) {}
has_hasbit_(HasHasbit(field)) {}
~SingularMessage() override = default;
std::vector<Sub> MakeVars() const override {
return Vars(field_, *opts_, weak_);
return Vars(field_, *opts_, is_weak());
}
void GeneratePrivateMembers(io::Printer* p) const override {
@ -145,11 +142,8 @@ class SingularMessage : public FieldGeneratorBase {
const FieldDescriptor* field_;
const Options* opts_;
bool weak_;
bool has_required_;
bool has_hasbit_;
bool is_oneof_;
bool is_foreign_;
};
void SingularMessage::GenerateAccessorDeclarations(io::Printer* p) const {
@ -310,7 +304,7 @@ void SingularMessage::GenerateInlineAccessorDefinitions(io::Printer* p) const {
void SingularMessage::GenerateInternalAccessorDeclarations(
io::Printer* p) const {
if (!weak_) {
if (!is_weak()) {
p->Emit(R"cc(
static const $Submsg$& $name$(const $Msg$* msg);
)cc");
@ -329,7 +323,7 @@ void SingularMessage::GenerateInternalAccessorDefinitions(
// practice, the linker is then not able to throw them out making implicit
// weak dependencies not work at all.
if (!weak_) {
if (!is_weak()) {
// This inline accessor directly returns member field and is used in
// Serialize such that AFDO profile correctly captures access information to
// message fields under serialize.
@ -355,7 +349,7 @@ void SingularMessage::GenerateInternalAccessorDefinitions(
}},
{"is_already_set",
[&] {
if (!is_oneof_) {
if (!is_oneof()) {
p->Emit("msg->$field_$ == nullptr");
} else {
p->Emit("msg->$not_has_field$");
@ -363,7 +357,7 @@ void SingularMessage::GenerateInternalAccessorDefinitions(
}},
{"clear_oneof",
[&] {
if (!is_oneof_) return;
if (!is_oneof()) return;
p->Emit(R"cc(
msg->clear_$oneof_name$();
msg->set_has_$name$();
@ -420,7 +414,7 @@ void SingularMessage::GenerateMessageClearingCode(io::Printer* p) const {
}
void SingularMessage::GenerateMergingCode(io::Printer* p) const {
if (weak_) {
if (is_weak()) {
p->Emit(
"_Internal::mutable_$name$(_this)->CheckTypeAndMergeFrom(\n"
" _Internal::$name$(&from));\n");
@ -444,7 +438,7 @@ void SingularMessage::GenerateDestructorCode(io::Printer* p) const {
// care when handling them.
p->Emit("if (this != internal_default_instance()) ");
}
if (ShouldSplit(field_, *opts_)) {
if (should_split()) {
p->Emit("delete $cached_split_ptr$->$name$_;\n");
return;
}
@ -469,7 +463,7 @@ void SingularMessage::GenerateCopyConstructorCode(io::Printer* p) const {
void SingularMessage::GenerateSerializeWithCachedSizesToArray(
io::Printer* p) const {
if (field_->type() == FieldDescriptor::TYPE_MESSAGE) {
if (!is_group()) {
p->Emit(
"target = $pbi$::WireFormatLite::\n"
" InternalWrite$declared_type$($number$, _Internal::$name$(this),\n"
@ -520,7 +514,7 @@ void SingularMessage::GenerateCopyAggregateInitializer(io::Printer* p) const {
}
void SingularMessage::GenerateAggregateInitializer(io::Printer* p) const {
if (ShouldSplit(field_, *opts_)) {
if (should_split()) {
p->Emit(R"cc(
decltype(Impl_::Split::$name$_){nullptr},
)cc");
@ -638,7 +632,7 @@ void OneofMessage::GenerateInlineAccessorDefinitions(io::Printer* p) const {
" clear_$oneof_name$();\n"
" if ($name$) {\n"
" set_has_$name$();\n");
if (weak_) {
if (is_weak()) {
p->Emit(
" $field_$ = "
"reinterpret_cast<$pb$::MessageLite*>($name$);\n");
@ -656,7 +650,7 @@ void OneofMessage::GenerateInlineAccessorDefinitions(io::Printer* p) const {
" if ($not_has_field$) {\n"
" clear_$oneof_name$();\n"
" set_has_$name$();\n");
if (weak_) {
if (is_weak()) {
p->Emit(
" $field_$ = "
"reinterpret_cast<$pb$::MessageLite*>(CreateMaybeMessage< "
@ -716,17 +710,15 @@ class RepeatedMessage : public FieldGeneratorBase {
public:
RepeatedMessage(const FieldDescriptor* field, const Options& opts,
MessageSCCAnalyzer* scc)
: FieldGeneratorBase(field, opts),
: FieldGeneratorBase(field, opts, scc),
field_(field),
opts_(&opts),
weak_(IsImplicitWeakField(field, opts, scc)),
split_(ShouldSplit(field, opts)),
has_required_(scc->HasRequiredFields(field->message_type())) {}
~RepeatedMessage() override = default;
std::vector<Sub> MakeVars() const override {
return Vars(field_, *opts_, weak_);
return Vars(field_, *opts_, is_weak());
}
void GeneratePrivateMembers(io::Printer* p) const override;
@ -745,13 +737,11 @@ class RepeatedMessage : public FieldGeneratorBase {
private:
const FieldDescriptor* field_;
const Options* opts_;
bool weak_;
bool split_;
bool has_required_;
};
void RepeatedMessage::GeneratePrivateMembers(io::Printer* p) const {
if (split_) {
if (should_split()) {
p->Emit(R"cc(
$pbi$::RawPtr<$pb$::$Weak$RepeatedPtrField<$Submsg$>> $name$_;
)cc");
@ -772,7 +762,7 @@ void RepeatedMessage::GenerateAccessorDeclarations(io::Printer* p) const {
"private:\n"
"const $pb$::RepeatedPtrField<$Submsg$>& _internal_$name$() const;\n"
"$pb$::RepeatedPtrField<$Submsg$>* _internal_mutable_$name$();\n");
if (weak_) {
if (is_weak()) {
format(
"const $pb$::WeakRepeatedPtrField<$Submsg$>& _internal_weak_$name$() "
"const;\n"
@ -839,7 +829,7 @@ void RepeatedMessage::GenerateInlineAccessorDefinitions(io::Printer* p) const {
" return _internal_$name$();\n"
"}\n");
if (split_) {
if (should_split()) {
p->Emit(R"cc(
inline const $pb$::$Weak$RepeatedPtrField<$Submsg$>&
$Msg$::_internal$_weak$_$name$() const {
@ -872,7 +862,7 @@ void RepeatedMessage::GenerateInlineAccessorDefinitions(io::Printer* p) const {
}
)cc");
}
if (weak_) {
if (is_weak()) {
p->Emit(R"cc(
inline const $pb$::RepeatedPtrField<$Submsg$>& $Msg$::_internal_$name$()
const {
@ -898,7 +888,7 @@ void RepeatedMessage::GenerateMergingCode(io::Printer* p) const {
from._internal$_weak$_$name$());
)cc");
};
if (!split_) {
if (!should_split()) {
body();
} else {
p->Emit({{"body", body}}, R"cc(
@ -910,7 +900,7 @@ void RepeatedMessage::GenerateMergingCode(io::Printer* p) const {
}
void RepeatedMessage::GenerateSwappingCode(io::Printer* p) const {
ABSL_CHECK(!split_);
ABSL_CHECK(!should_split());
p->Emit(R"cc(
$field_$.InternalSwap(&other->$field_$);
)cc");
@ -923,7 +913,7 @@ void RepeatedMessage::GenerateConstructorCode(io::Printer* p) const {
void RepeatedMessage::GenerateCopyConstructorCode(io::Printer* p) const {
// TODO(b/291633281): For split repeated fields we might want to use type
// erasure to reduce binary size costs.
if (split_) {
if (should_split()) {
p->Emit(R"cc(
if (!from._internal$_weak$_$name$().empty()) {
_internal_mutable$_weak$_$name$()->MergeFrom(from._internal$_weak$_$name$());
@ -933,7 +923,7 @@ void RepeatedMessage::GenerateCopyConstructorCode(io::Printer* p) const {
}
void RepeatedMessage::GenerateDestructorCode(io::Printer* p) const {
if (split_) {
if (should_split()) {
p->Emit(R"cc(
$field_$.DeleteIfNotDefault();
)cc");
@ -944,7 +934,7 @@ void RepeatedMessage::GenerateDestructorCode(io::Printer* p) const {
void RepeatedMessage::GenerateSerializeWithCachedSizesToArray(
io::Printer* p) const {
if (weak_) {
if (is_weak()) {
p->Emit(
"for (auto it = this->$field_$.pointer_begin(),\n"
" end = this->$field_$.pointer_end(); it < end; ++it) {\n");
@ -996,7 +986,7 @@ void RepeatedMessage::GenerateByteSize(io::Printer* p) const {
void RepeatedMessage::GenerateIsInitialized(io::Printer* p) const {
if (!has_required_) return;
if (weak_) {
if (is_weak()) {
p->Emit(
"if (!$pbi$::AllAreInitializedWeak($field_$.weak))\n"
" return false;\n");

@ -110,11 +110,9 @@ std::vector<Sub> Vars(const FieldDescriptor* field, const Options& options) {
class SingularPrimitive final : public FieldGeneratorBase {
public:
SingularPrimitive(const FieldDescriptor* field, const Options& opts)
: FieldGeneratorBase(field, opts),
field_(field),
opts_(&opts),
is_oneof_(field_->real_containing_oneof() != nullptr) {}
SingularPrimitive(const FieldDescriptor* field, const Options& opts,
MessageSCCAnalyzer* scc)
: FieldGeneratorBase(field, opts, scc), field_(field), opts_(&opts) {}
~SingularPrimitive() override = default;
std::vector<Sub> MakeVars() const override { return Vars(field_, *opts_); }
@ -138,7 +136,7 @@ class SingularPrimitive final : public FieldGeneratorBase {
}
void GenerateSwappingCode(io::Printer* p) const override {
if (is_oneof_) {
if (is_oneof()) {
// Don't print any swapping code. Swapping the union will swap this field.
return;
}
@ -150,7 +148,7 @@ class SingularPrimitive final : public FieldGeneratorBase {
}
void GenerateConstructorCode(io::Printer* p) const override {
if (!is_oneof_) {
if (!is_oneof()) {
return;
}
@ -191,7 +189,6 @@ class SingularPrimitive final : public FieldGeneratorBase {
private:
const FieldDescriptor* field_;
const Options* opts_;
bool is_oneof_;
};
void SingularPrimitive::GenerateAccessorDeclarations(io::Printer* p) const {
@ -226,7 +223,7 @@ void SingularPrimitive::GenerateInlineAccessorDefinitions(
}
)cc");
if (is_oneof_) {
if (is_oneof()) {
p->Emit(R"cc(
inline $Type$ $Msg$::_internal_$name$() const {
if ($has_field$) {
@ -309,8 +306,9 @@ void SingularPrimitive::GenerateByteSize(io::Printer* p) const {
class RepeatedPrimitive final : public FieldGeneratorBase {
public:
RepeatedPrimitive(const FieldDescriptor* field, const Options& opts)
: FieldGeneratorBase(field, opts), field_(field), opts_(&opts) {}
RepeatedPrimitive(const FieldDescriptor* field, const Options& opts,
MessageSCCAnalyzer* scc)
: FieldGeneratorBase(field, opts, scc), field_(field), opts_(&opts) {}
~RepeatedPrimitive() override = default;
std::vector<Sub> MakeVars() const override { return Vars(field_, *opts_); }
@ -329,7 +327,7 @@ class RepeatedPrimitive final : public FieldGeneratorBase {
_this->_internal_mutable_$name$()->MergeFrom(from._internal_$name$());
)cc");
};
if (!ShouldSplit(descriptor_, options_)) {
if (!should_split()) {
body();
} else {
p->Emit({{"body", body}}, R"cc(
@ -341,14 +339,14 @@ class RepeatedPrimitive final : public FieldGeneratorBase {
}
void GenerateSwappingCode(io::Printer* p) const override {
ABSL_CHECK(!ShouldSplit(descriptor_, options_));
ABSL_CHECK(!should_split());
p->Emit(R"cc(
$field_$.InternalSwap(&other->$field_$);
)cc");
}
void GenerateDestructorCode(io::Printer* p) const override {
if (ShouldSplit(descriptor_, options_)) {
if (should_split()) {
p->Emit(R"cc(
$field_$.DeleteIfNotDefault();
)cc");
@ -362,7 +360,7 @@ class RepeatedPrimitive final : public FieldGeneratorBase {
void GenerateConstructorCode(io::Printer* p) const override {}
void GenerateCopyConstructorCode(io::Printer* p) const override {
if (ShouldSplit(descriptor_, options_)) {
if (should_split()) {
p->Emit(R"cc(
if (!from._internal_$name$().empty()) {
_internal_mutable_$name$()->MergeFrom(from._internal_$name$());
@ -379,7 +377,7 @@ class RepeatedPrimitive final : public FieldGeneratorBase {
}
void GenerateAggregateInitializer(io::Printer* p) const override {
ABSL_CHECK(!ShouldSplit(descriptor_, options_));
ABSL_CHECK(!should_split());
p->Emit(R"cc(
decltype($field_$){arena},
)cc");
@ -387,7 +385,7 @@ class RepeatedPrimitive final : public FieldGeneratorBase {
}
void GenerateCopyAggregateInitializer(io::Printer* p) const override {
ABSL_CHECK(!ShouldSplit(descriptor_, options_));
ABSL_CHECK(!should_split());
p->Emit(R"cc(
decltype($field_$){from.$field_$},
)cc");
@ -405,7 +403,7 @@ class RepeatedPrimitive final : public FieldGeneratorBase {
bool is_packed_varint =
field_->is_packed() && !FixedSize(field_->type()).has_value();
return is_packed_varint && HasGeneratedMethods(field_->file(), *opts_) &&
!ShouldSplit(descriptor_, options_);
!should_split();
}
void GenerateCacheSizeInitializer(io::Printer* p) const {
@ -422,7 +420,7 @@ class RepeatedPrimitive final : public FieldGeneratorBase {
};
void RepeatedPrimitive::GeneratePrivateMembers(io::Printer* p) const {
if (ShouldSplit(descriptor_, options_)) {
if (should_split()) {
p->Emit(R"cc(
$pbi$::RawPtr<$pb$::RepeatedField<$Type$>> $name$_;
)cc");
@ -494,7 +492,7 @@ void RepeatedPrimitive::GenerateInlineAccessorDefinitions(
}
)cc");
if (ShouldSplit(descriptor_, options_)) {
if (should_split()) {
p->Emit(R"cc(
inline const $pb$::RepeatedField<$Type$>& $Msg$::_internal_$name$()
const {
@ -632,13 +630,13 @@ void RepeatedPrimitive::GenerateByteSize(io::Printer* p) const {
std::unique_ptr<FieldGeneratorBase> MakeSinguarPrimitiveGenerator(
const FieldDescriptor* desc, const Options& options,
MessageSCCAnalyzer* scc) {
return absl::make_unique<SingularPrimitive>(desc, options);
return absl::make_unique<SingularPrimitive>(desc, options, scc);
}
std::unique_ptr<FieldGeneratorBase> MakeRepeatedPrimitiveGenerator(
const FieldDescriptor* desc, const Options& options,
MessageSCCAnalyzer* scc) {
return absl::make_unique<RepeatedPrimitive>(desc, options);
return absl::make_unique<RepeatedPrimitive>(desc, options, scc);
}
} // namespace cpp

@ -65,7 +65,7 @@ std::vector<Sub> Vars(const FieldDescriptor* field, const Options& opts) {
"::", MakeDefaultFieldName(field));
bool empty_default = field->default_value_string().empty();
bool is_bytes = field->type() == FieldDescriptor::TYPE_BYTES;
bool bytes = field->type() == FieldDescriptor::TYPE_BYTES;
return {
{"kDefault", DefaultValue(opts, field)},
@ -82,33 +82,31 @@ std::vector<Sub> Vars(const FieldDescriptor* field, const Options& opts) {
Sub{"lazy_args", !empty_default ? absl::StrCat(lazy_var, ",") : ""}
.WithSuffix(","),
{"byte", is_bytes ? "void" : "char"},
{"Set", is_bytes ? "SetBytes" : "Set"},
{"byte", bytes ? "void" : "char"},
{"Set", bytes ? "SetBytes" : "Set"},
};
}
class SingularString : public FieldGeneratorBase {
public:
SingularString(const FieldDescriptor* field, const Options& opts)
: FieldGeneratorBase(field, opts),
field_(field),
opts_(&opts),
is_oneof_(field->real_containing_oneof() != nullptr),
inlined_(IsStringInlined(field, opts)) {}
SingularString(const FieldDescriptor* field, const Options& opts,
MessageSCCAnalyzer* scc)
: FieldGeneratorBase(field, opts, scc), field_(field), opts_(&opts) {}
~SingularString() override = default;
std::vector<Sub> MakeVars() const override { return Vars(field_, *opts_); }
bool IsInlined() const override { return inlined_; }
bool IsInlined() const override { return is_inlined(); }
ArenaDtorNeeds NeedsArenaDestructor() const override {
return inlined_ ? ArenaDtorNeeds::kOnDemand : ArenaDtorNeeds::kNone;
return is_inlined() ? ArenaDtorNeeds::kOnDemand : ArenaDtorNeeds::kNone;
}
void GeneratePrivateMembers(io::Printer* p) const override {
// Skips the automatic destruction if inlined; rather calls it explicitly if
// allocating arena is null.
p->Emit({{"Str", inlined_ ? "InlinedStringField" : "ArenaStringPtr"}}, R"cc(
p->Emit({{"Str", is_inlined() ? "InlinedStringField" : "ArenaStringPtr"}},
R"cc(
$pbi$::$Str$ $name$_;
)cc");
}
@ -120,7 +118,7 @@ class SingularString : public FieldGeneratorBase {
}
void GenerateArenaDestructorCode(io::Printer* p) const override {
if (!inlined_) return;
if (!is_inlined()) return;
p->Emit(R"cc(
if (!_this->_internal_$name$_donated()) {
@ -172,8 +170,6 @@ class SingularString : public FieldGeneratorBase {
const FieldDescriptor* field_;
const Options* opts_;
bool is_oneof_;
bool inlined_;
};
void SingularString::GenerateStaticMembers(io::Printer* p) const {
@ -182,7 +178,7 @@ void SingularString::GenerateStaticMembers(io::Printer* p) const {
static const $pbi$::LazyString $default_variable_name$;
)cc");
}
if (inlined_) {
if (is_inlined()) {
// `_init_inline_xxx` is used for initializing default instances.
p->Emit(R"cc(
static std::true_type _init_inline_$name$_;
@ -231,7 +227,7 @@ void SingularString::GenerateAccessorDeclarations(io::Printer* p) const {
p->Emit(
{{"donated",
[&] {
if (!inlined_) return;
if (!is_inlined()) return;
p->Emit(R"cc(
inline PROTOBUF_ALWAYS_INLINE bool _internal_$name$_donated() const;
)cc");
@ -288,7 +284,7 @@ void ArgsForSetter(io::Printer* p, bool inlined) {
}
void SingularString::ReleaseImpl(io::Printer* p) const {
if (is_oneof_) {
if (is_oneof()) {
p->Emit(R"cc(
if ($not_has_field$) {
return nullptr;
@ -306,7 +302,7 @@ void SingularString::ReleaseImpl(io::Printer* p) const {
return;
}
if (inlined_) {
if (is_inlined()) {
p->Emit(R"cc(
if (($has_hasbit$) == 0) {
return nullptr;
@ -342,7 +338,7 @@ void SingularString::ReleaseImpl(io::Printer* p) const {
}
void SingularString::SetAllocatedImpl(io::Printer* p) const {
if (is_oneof_) {
if (is_oneof()) {
p->Emit(R"cc(
if (has_$oneof_name$()) {
clear_$oneof_name$();
@ -365,7 +361,7 @@ void SingularString::SetAllocatedImpl(io::Printer* p) const {
)cc");
}
if (inlined_) {
if (is_inlined()) {
// Currently, string fields with default value can't be inlined.
p->Emit(R"cc(
$field_$.SetAllocated(nullptr, value, $set_args$);
@ -393,18 +389,18 @@ void SingularString::GenerateInlineAccessorDefinitions(io::Printer* p) const {
{
{"if_IsDefault",
[&] {
if (EmptyDefault() || is_oneof_) return;
if (EmptyDefault() || is_oneof()) return;
p->Emit(R"cc(
if ($field_$.IsDefault()) {
return $default_variable_field$.get();
}
)cc");
}},
{"update_hasbit", [&] { UpdateHasbitSet(p, is_oneof_); }},
{"set_args", [&] { ArgsForSetter(p, inlined_); }},
{"update_hasbit", [&] { UpdateHasbitSet(p, is_oneof()); }},
{"set_args", [&] { ArgsForSetter(p, is_inlined()); }},
{"check_hasbit",
[&] {
if (!is_oneof_) return;
if (!is_oneof()) return;
p->Emit(R"cc(
if ($not_has_field$) {
return $kDefaultStr$;
@ -473,7 +469,7 @@ void SingularString::GenerateInlineAccessorDefinitions(io::Printer* p) const {
}
)cc");
if (inlined_) {
if (is_inlined()) {
p->Emit(R"cc(
inline bool $Msg$::_internal_$name$_donated() const {
return $inlined_string_donated$;
@ -483,7 +479,7 @@ void SingularString::GenerateInlineAccessorDefinitions(io::Printer* p) const {
}
void SingularString::GenerateClearingCode(io::Printer* p) const {
if (is_oneof_) {
if (is_oneof()) {
p->Emit(R"cc(
$field_$.Destroy();
)cc");
@ -497,14 +493,14 @@ void SingularString::GenerateClearingCode(io::Printer* p) const {
return;
}
ABSL_DCHECK(!inlined_);
ABSL_DCHECK(!is_inlined());
p->Emit(R"cc(
$field_$.ClearToDefault($lazy_var$, GetArenaForAllocation());
)cc");
}
void SingularString::GenerateMessageClearingCode(io::Printer* p) const {
if (is_oneof_) {
if (is_oneof()) {
p->Emit(R"cc(
$field_$.Destroy();
)cc");
@ -520,7 +516,7 @@ void SingularString::GenerateMessageClearingCode(io::Printer* p) const {
// will have checked that this field is set. If so, we can avoid redundant
// checks against the default variable.
if (inlined_ && HasHasbit(field_)) {
if (is_inlined() && HasHasbit(field_)) {
// Calling mutable_$name$() gives us a string reference and sets the has bit
// for $name$ (in proto2). We may get here when the string field is inlined
// but the string's contents have not been changed by the user, so we cannot
@ -551,12 +547,12 @@ void SingularString::GenerateMessageClearingCode(io::Printer* p) const {
}
void SingularString::GenerateSwappingCode(io::Printer* p) const {
if (is_oneof_) {
if (is_oneof()) {
// Don't print any swapping code. Swapping the union will swap this field.
return;
}
if (!inlined_) {
if (!is_inlined()) {
p->Emit(R"cc(
::_pbi::ArenaStringPtr::InternalSwap(&$field_$, lhs_arena,
&other->$field_$, rhs_arena);
@ -577,8 +573,8 @@ void SingularString::GenerateSwappingCode(io::Printer* p) const {
}
void SingularString::GenerateConstructorCode(io::Printer* p) const {
if ((inlined_ && EmptyDefault()) || is_oneof_) return;
ABSL_DCHECK(!inlined_);
if ((is_inlined() && EmptyDefault()) || is_oneof()) return;
ABSL_DCHECK(!is_inlined());
p->Emit(R"cc(
$field_$.InitDefault();
@ -596,7 +592,7 @@ void SingularString::GenerateConstructorCode(io::Printer* p) const {
void SingularString::GenerateCopyConstructorCode(io::Printer* p) const {
GenerateConstructorCode(p);
if (inlined_) {
if (is_inlined()) {
p->Emit(R"cc(
new (&_this->$field_$)::_pbi::InlinedStringField;
)cc");
@ -613,7 +609,7 @@ void SingularString::GenerateCopyConstructorCode(io::Printer* p) const {
}},
{"set_args",
[&] {
if (!inlined_) {
if (!is_inlined()) {
p->Emit("_this->GetArenaForAllocation()");
} else {
p->Emit(
@ -630,17 +626,17 @@ void SingularString::GenerateCopyConstructorCode(io::Printer* p) const {
}
void SingularString::GenerateDestructorCode(io::Printer* p) const {
if (inlined_) {
if (is_inlined()) {
// Explicitly calls ~InlinedStringField as its automatic call is disabled.
// Destructor has been implicitly skipped as a union.
ABSL_DCHECK(!ShouldSplit(field_, *opts_));
ABSL_DCHECK(!should_split());
p->Emit(R"cc(
$field_$.~InlinedStringField();
)cc");
return;
}
if (ShouldSplit(field_, *opts_)) {
if (should_split()) {
p->Emit(R"cc(
$cached_split_ptr$->$name$_.Destroy();
)cc");
@ -669,7 +665,7 @@ void SingularString::GenerateSerializeWithCachedSizesToArray(
void SingularString::GenerateConstexprAggregateInitializer(
io::Printer* p) const {
if (inlined_) {
if (is_inlined()) {
p->Emit(R"cc(
/*decltype($field_$)*/ {nullptr, false},
)cc");
@ -684,12 +680,12 @@ void SingularString::GenerateConstexprAggregateInitializer(
}
void SingularString::GenerateAggregateInitializer(io::Printer* p) const {
if (ShouldSplit(field_, options_)) {
ABSL_CHECK(!inlined_);
if (should_split()) {
ABSL_CHECK(!is_inlined());
p->Emit(R"cc(
decltype(Impl_::Split::$name$_){},
)cc");
} else if (!inlined_) {
} else if (!is_inlined()) {
p->Emit(R"cc(
decltype($field_$){},
)cc");
@ -702,8 +698,9 @@ void SingularString::GenerateAggregateInitializer(io::Printer* p) const {
class RepeatedString : public FieldGeneratorBase {
public:
RepeatedString(const FieldDescriptor* field, const Options& opts)
: FieldGeneratorBase(field, opts), field_(field), opts_(&opts) {}
RepeatedString(const FieldDescriptor* field, const Options& opts,
MessageSCCAnalyzer* scc)
: FieldGeneratorBase(field, opts, scc), field_(field), opts_(&opts) {}
~RepeatedString() override = default;
std::vector<Sub> MakeVars() const override { return Vars(field_, *opts_); }
@ -991,13 +988,13 @@ void RepeatedString::GenerateSerializeWithCachedSizesToArray(
std::unique_ptr<FieldGeneratorBase> MakeSinguarStringGenerator(
const FieldDescriptor* desc, const Options& options,
MessageSCCAnalyzer* scc) {
return absl::make_unique<SingularString>(desc, options);
return absl::make_unique<SingularString>(desc, options, scc);
}
std::unique_ptr<FieldGeneratorBase> MakeRepeatedStringGenerator(
const FieldDescriptor* desc, const Options& options,
MessageSCCAnalyzer* scc) {
return absl::make_unique<RepeatedString>(desc, options);
return absl::make_unique<RepeatedString>(desc, options, scc);
}
} // namespace cpp

Loading…
Cancel
Save