|
|
|
@ -35,10 +35,12 @@ |
|
|
|
|
#include <memory> |
|
|
|
|
#include <string> |
|
|
|
|
#include <tuple> |
|
|
|
|
#include <vector> |
|
|
|
|
|
|
|
|
|
#include "absl/container/flat_hash_map.h" |
|
|
|
|
#include "absl/log/absl_check.h" |
|
|
|
|
#include "absl/memory/memory.h" |
|
|
|
|
#include "absl/strings/substitute.h" |
|
|
|
|
#include "google/protobuf/compiler/cpp/field.h" |
|
|
|
|
#include "google/protobuf/compiler/cpp/field_generators/generators.h" |
|
|
|
|
#include "google/protobuf/compiler/cpp/helpers.h" |
|
|
|
@ -49,475 +51,418 @@ namespace protobuf { |
|
|
|
|
namespace compiler { |
|
|
|
|
namespace cpp { |
|
|
|
|
namespace { |
|
|
|
|
void SetEnumVariables( |
|
|
|
|
const FieldDescriptor* descriptor, |
|
|
|
|
absl::flat_hash_map<absl::string_view, std::string>* variables, |
|
|
|
|
const Options& options) { |
|
|
|
|
const EnumValueDescriptor* default_value = descriptor->default_value_enum(); |
|
|
|
|
(*variables)["type"] = QualifiedClassName(descriptor->enum_type(), options); |
|
|
|
|
(*variables)["default"] = Int32ToString(default_value->number()); |
|
|
|
|
(*variables)["full_name"] = descriptor->full_name(); |
|
|
|
|
(*variables)["cached_byte_size_name"] = MakeVarintCachedSizeName(descriptor); |
|
|
|
|
bool cold = ShouldSplit(descriptor, options); |
|
|
|
|
(*variables)["cached_byte_size_field"] = |
|
|
|
|
MakeVarintCachedSizeFieldName(descriptor, cold); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
class EnumFieldGenerator : public FieldGeneratorBase { |
|
|
|
|
public: |
|
|
|
|
EnumFieldGenerator(const FieldDescriptor* descriptor, const Options& options); |
|
|
|
|
~EnumFieldGenerator() override = default; |
|
|
|
|
|
|
|
|
|
void GeneratePrivateMembers(io::Printer* printer) const override; |
|
|
|
|
void GenerateAccessorDeclarations(io::Printer* printer) const override; |
|
|
|
|
void GenerateInlineAccessorDefinitions(io::Printer* printer) const override; |
|
|
|
|
void GenerateClearingCode(io::Printer* printer) const override; |
|
|
|
|
void GenerateMergingCode(io::Printer* printer) const override; |
|
|
|
|
void GenerateSwappingCode(io::Printer* printer) const override; |
|
|
|
|
void GenerateConstructorCode(io::Printer* printer) const override {} |
|
|
|
|
void GenerateCopyConstructorCode(io::Printer* printer) const override; |
|
|
|
|
void GenerateSerializeWithCachedSizesToArray( |
|
|
|
|
io::Printer* printer) const override; |
|
|
|
|
void GenerateByteSize(io::Printer* printer) const override; |
|
|
|
|
void GenerateConstexprAggregateInitializer( |
|
|
|
|
io::Printer* printer) const override; |
|
|
|
|
void GenerateAggregateInitializer(io::Printer* printer) const override; |
|
|
|
|
void GenerateCopyAggregateInitializer(io::Printer* printer) const override; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
class EnumOneofFieldGenerator : public EnumFieldGenerator { |
|
|
|
|
using Sub = ::google::protobuf::io::Printer::Sub; |
|
|
|
|
|
|
|
|
|
std::vector<Sub> Vars(const FieldDescriptor* field, const Options& opts) { |
|
|
|
|
const EnumValueDescriptor* default_value = field->default_value_enum(); |
|
|
|
|
bool split = ShouldSplit(field, opts); |
|
|
|
|
bool is_open = internal::cpp::HasPreservingUnknownEnumSemantics(field); |
|
|
|
|
auto enum_name = QualifiedClassName(field->enum_type(), opts); |
|
|
|
|
return { |
|
|
|
|
{"Enum", enum_name}, |
|
|
|
|
{"kDefault", Int32ToString(default_value->number())}, |
|
|
|
|
Sub("assert_valid", |
|
|
|
|
is_open ? "" |
|
|
|
|
: absl::Substitute("assert($0_IsValid(value));", enum_name)) |
|
|
|
|
.WithSuffix(";"), |
|
|
|
|
|
|
|
|
|
{"cached_size_name", MakeVarintCachedSizeName(field)}, |
|
|
|
|
{"cached_size_", MakeVarintCachedSizeFieldName(field, split)}, |
|
|
|
|
}; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
class SingularEnum : public FieldGeneratorBase { |
|
|
|
|
public: |
|
|
|
|
EnumOneofFieldGenerator(const FieldDescriptor* descriptor, |
|
|
|
|
const Options& options); |
|
|
|
|
~EnumOneofFieldGenerator() override = default; |
|
|
|
|
|
|
|
|
|
void GenerateInlineAccessorDefinitions(io::Printer* printer) const override; |
|
|
|
|
void GenerateClearingCode(io::Printer* printer) const override; |
|
|
|
|
void GenerateSwappingCode(io::Printer* printer) const override; |
|
|
|
|
void GenerateConstructorCode(io::Printer* printer) const override; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
class RepeatedEnumFieldGenerator : public FieldGeneratorBase { |
|
|
|
|
public: |
|
|
|
|
RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor, |
|
|
|
|
const Options& options); |
|
|
|
|
~RepeatedEnumFieldGenerator() override = default; |
|
|
|
|
|
|
|
|
|
// implements FieldGeneratorBase ---------------------------------------
|
|
|
|
|
void GeneratePrivateMembers(io::Printer* printer) const override; |
|
|
|
|
void GenerateAccessorDeclarations(io::Printer* printer) const override; |
|
|
|
|
void GenerateInlineAccessorDefinitions(io::Printer* printer) const override; |
|
|
|
|
void GenerateClearingCode(io::Printer* printer) const override; |
|
|
|
|
void GenerateMergingCode(io::Printer* printer) const override; |
|
|
|
|
void GenerateSwappingCode(io::Printer* printer) const override; |
|
|
|
|
void GenerateConstructorCode(io::Printer* printer) const override; |
|
|
|
|
void GenerateCopyConstructorCode(io::Printer* /*printer*/) const override { |
|
|
|
|
ABSL_CHECK(!ShouldSplit(descriptor_, options_)); |
|
|
|
|
SingularEnum(const FieldDescriptor* field, const Options& opts) |
|
|
|
|
: FieldGeneratorBase(field, opts), |
|
|
|
|
field_(field), |
|
|
|
|
opts_(&opts), |
|
|
|
|
is_oneof_(field->real_containing_oneof() != nullptr) {} |
|
|
|
|
~SingularEnum() override = default; |
|
|
|
|
|
|
|
|
|
std::vector<Sub> MakeVars() const override { return Vars(field_, *opts_); } |
|
|
|
|
|
|
|
|
|
void GeneratePrivateMembers(io::Printer* p) const override { |
|
|
|
|
p->Emit(R"cc( |
|
|
|
|
int $name$_; |
|
|
|
|
)cc"); |
|
|
|
|
} |
|
|
|
|
void GenerateDestructorCode(io::Printer* printer) const override; |
|
|
|
|
void GenerateSerializeWithCachedSizesToArray( |
|
|
|
|
io::Printer* printer) const override; |
|
|
|
|
void GenerateByteSize(io::Printer* printer) const override; |
|
|
|
|
void GenerateConstexprAggregateInitializer( |
|
|
|
|
io::Printer* printer) const override; |
|
|
|
|
void GenerateAggregateInitializer(io::Printer* printer) const override; |
|
|
|
|
void GenerateCopyAggregateInitializer(io::Printer* printer) const override; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
// ===================================================================
|
|
|
|
|
|
|
|
|
|
EnumFieldGenerator::EnumFieldGenerator(const FieldDescriptor* descriptor, |
|
|
|
|
const Options& options) |
|
|
|
|
: FieldGeneratorBase(descriptor, options) { |
|
|
|
|
SetEnumVariables(descriptor, &variables_, options); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void EnumFieldGenerator::GeneratePrivateMembers(io::Printer* printer) const { |
|
|
|
|
Formatter format(printer, variables_); |
|
|
|
|
format("int $name$_;\n"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void EnumFieldGenerator::GenerateAccessorDeclarations( |
|
|
|
|
io::Printer* printer) const { |
|
|
|
|
Formatter format(printer, variables_); |
|
|
|
|
format("$deprecated_attr$$type$ ${1$$name$$}$() const;\n", descriptor_); |
|
|
|
|
format("$deprecated_attr$void ${1$set_$name$$}$($type$ value);\n", |
|
|
|
|
std::make_tuple(descriptor_, GeneratedCodeInfo::Annotation::SET)); |
|
|
|
|
format( |
|
|
|
|
"private:\n" |
|
|
|
|
"$type$ ${1$_internal_$name$$}$() const;\n" |
|
|
|
|
"void ${1$_internal_set_$name$$}$($type$ value);\n" |
|
|
|
|
"public:\n", |
|
|
|
|
descriptor_); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void EnumFieldGenerator::GenerateInlineAccessorDefinitions( |
|
|
|
|
io::Printer* printer) const { |
|
|
|
|
Formatter format(printer, variables_); |
|
|
|
|
format( |
|
|
|
|
"inline $type$ $classname$::_internal_$name$() const {\n" |
|
|
|
|
" return static_cast< $type$ >($field$);\n" |
|
|
|
|
"}\n" |
|
|
|
|
"inline $type$ $classname$::$name$() const {\n" |
|
|
|
|
"$annotate_get$" |
|
|
|
|
" // @@protoc_insertion_point(field_get:$full_name$)\n" |
|
|
|
|
" return _internal_$name$();\n" |
|
|
|
|
"}\n" |
|
|
|
|
"inline void $classname$::_internal_set_$name$($type$ value) {\n"); |
|
|
|
|
if (!internal::cpp::HasPreservingUnknownEnumSemantics(descriptor_)) { |
|
|
|
|
format(" assert($type$_IsValid(value));\n"); |
|
|
|
|
void GenerateClearingCode(io::Printer* p) const override { |
|
|
|
|
p->Emit(R"cc( |
|
|
|
|
$field_$ = $kDefault$; |
|
|
|
|
)cc"); |
|
|
|
|
} |
|
|
|
|
format( |
|
|
|
|
" $set_hasbit$\n" |
|
|
|
|
" $field$ = value;\n" |
|
|
|
|
"}\n" |
|
|
|
|
"inline void $classname$::set_$name$($type$ value) {\n" |
|
|
|
|
"$maybe_prepare_split_message$" |
|
|
|
|
" _internal_set_$name$(value);\n" |
|
|
|
|
"$annotate_set$" |
|
|
|
|
" // @@protoc_insertion_point(field_set:$full_name$)\n" |
|
|
|
|
"}\n"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void EnumFieldGenerator::GenerateClearingCode(io::Printer* printer) const { |
|
|
|
|
Formatter format(printer, variables_); |
|
|
|
|
format("$field$ = $default$;\n"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void EnumFieldGenerator::GenerateMergingCode(io::Printer* printer) const { |
|
|
|
|
Formatter format(printer, variables_); |
|
|
|
|
format("_this->_internal_set_$name$(from._internal_$name$());\n"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void EnumFieldGenerator::GenerateSwappingCode(io::Printer* printer) const { |
|
|
|
|
Formatter format(printer, variables_); |
|
|
|
|
format("swap($field$, other->$field$);\n"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void EnumFieldGenerator::GenerateCopyConstructorCode( |
|
|
|
|
io::Printer* printer) const { |
|
|
|
|
Formatter format(printer, variables_); |
|
|
|
|
format("_this->$field$ = from.$field$;\n"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void EnumFieldGenerator::GenerateSerializeWithCachedSizesToArray( |
|
|
|
|
io::Printer* printer) const { |
|
|
|
|
Formatter format(printer, variables_); |
|
|
|
|
format( |
|
|
|
|
"target = stream->EnsureSpace(target);\n" |
|
|
|
|
"target = ::_pbi::WireFormatLite::WriteEnumToArray(\n" |
|
|
|
|
" $number$, this->_internal_$name$(), target);\n"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void EnumFieldGenerator::GenerateByteSize(io::Printer* printer) const { |
|
|
|
|
Formatter format(printer, variables_); |
|
|
|
|
format( |
|
|
|
|
"total_size += $tag_size$ +\n" |
|
|
|
|
" ::_pbi::WireFormatLite::EnumSize(this->_internal_$name$());\n"); |
|
|
|
|
} |
|
|
|
|
void GenerateMergingCode(io::Printer* p) const override { |
|
|
|
|
p->Emit(R"cc( |
|
|
|
|
_this->_internal_set_$name$(from._internal_$name$()); |
|
|
|
|
)cc"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void EnumFieldGenerator::GenerateConstexprAggregateInitializer( |
|
|
|
|
io::Printer* printer) const { |
|
|
|
|
Formatter format(printer, variables_); |
|
|
|
|
format("/*decltype($field$)*/$default$"); |
|
|
|
|
} |
|
|
|
|
void GenerateSwappingCode(io::Printer* p) const override { |
|
|
|
|
if (is_oneof_) return; |
|
|
|
|
|
|
|
|
|
void EnumFieldGenerator::GenerateAggregateInitializer( |
|
|
|
|
io::Printer* printer) const { |
|
|
|
|
Formatter format(printer, variables_); |
|
|
|
|
if (ShouldSplit(descriptor_, options_)) { |
|
|
|
|
format("decltype(Impl_::Split::$name$_){$default$}"); |
|
|
|
|
return; |
|
|
|
|
p->Emit(R"cc( |
|
|
|
|
swap($field_$, other->$field_$); |
|
|
|
|
)cc"); |
|
|
|
|
} |
|
|
|
|
format("decltype($field$){$default$}"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void EnumFieldGenerator::GenerateCopyAggregateInitializer( |
|
|
|
|
io::Printer* printer) const { |
|
|
|
|
Formatter format(printer, variables_); |
|
|
|
|
format("decltype($field$){}"); |
|
|
|
|
} |
|
|
|
|
void GenerateConstructorCode(io::Printer* p) const override { |
|
|
|
|
if (!is_oneof_) return; |
|
|
|
|
p->Emit(R"cc( |
|
|
|
|
$ns$::_$Msg$_default_instance_.$field_$ = $kDefault$; |
|
|
|
|
)cc"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// ===================================================================
|
|
|
|
|
void GenerateCopyConstructorCode(io::Printer* p) const override { |
|
|
|
|
p->Emit(R"cc( |
|
|
|
|
_this->$field_$ = from.$field_$; |
|
|
|
|
)cc"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
EnumOneofFieldGenerator::EnumOneofFieldGenerator( |
|
|
|
|
const FieldDescriptor* descriptor, const Options& options) |
|
|
|
|
: EnumFieldGenerator(descriptor, options) { |
|
|
|
|
} |
|
|
|
|
void GenerateSerializeWithCachedSizesToArray(io::Printer* p) const override { |
|
|
|
|
p->Emit(R"cc( |
|
|
|
|
target = stream->EnsureSpace(target); |
|
|
|
|
target = ::_pbi::WireFormatLite::WriteEnumToArray( |
|
|
|
|
$number$, this->_internal_$name$(), target); |
|
|
|
|
)cc"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void EnumOneofFieldGenerator::GenerateInlineAccessorDefinitions( |
|
|
|
|
io::Printer* printer) const { |
|
|
|
|
Formatter format(printer, variables_); |
|
|
|
|
format( |
|
|
|
|
"inline $type$ $classname$::_internal_$name$() const {\n" |
|
|
|
|
" if ($has_field$) {\n" |
|
|
|
|
" return static_cast< $type$ >($field$);\n" |
|
|
|
|
" }\n" |
|
|
|
|
" return static_cast< $type$ >($default$);\n" |
|
|
|
|
"}\n" |
|
|
|
|
"inline $type$ $classname$::$name$() const {\n" |
|
|
|
|
"$annotate_get$" |
|
|
|
|
" // @@protoc_insertion_point(field_get:$full_name$)\n" |
|
|
|
|
" return _internal_$name$();\n" |
|
|
|
|
"}\n" |
|
|
|
|
"inline void $classname$::_internal_set_$name$($type$ value) {\n"); |
|
|
|
|
if (!internal::cpp::HasPreservingUnknownEnumSemantics(descriptor_)) { |
|
|
|
|
format(" assert($type$_IsValid(value));\n"); |
|
|
|
|
void GenerateByteSize(io::Printer* p) const override { |
|
|
|
|
p->Emit(R"cc( |
|
|
|
|
total_size += $kTagBytes$ + |
|
|
|
|
::_pbi::WireFormatLite::EnumSize(this->_internal_$name$()); |
|
|
|
|
)cc"); |
|
|
|
|
} |
|
|
|
|
format( |
|
|
|
|
" if ($not_has_field$) {\n" |
|
|
|
|
" clear_$oneof_name$();\n" |
|
|
|
|
" set_has_$name$();\n" |
|
|
|
|
" }\n" |
|
|
|
|
" $field$ = value;\n" |
|
|
|
|
"}\n" |
|
|
|
|
"inline void $classname$::set_$name$($type$ value) {\n" |
|
|
|
|
" _internal_set_$name$(value);\n" |
|
|
|
|
"$annotate_set$" |
|
|
|
|
" // @@protoc_insertion_point(field_set:$full_name$)\n" |
|
|
|
|
"}\n"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void EnumOneofFieldGenerator::GenerateClearingCode(io::Printer* printer) const { |
|
|
|
|
Formatter format(printer, variables_); |
|
|
|
|
format("$field$ = $default$;\n"); |
|
|
|
|
} |
|
|
|
|
void GenerateConstexprAggregateInitializer(io::Printer* p) const override { |
|
|
|
|
p->Emit(R"cc( |
|
|
|
|
/*decltype($field_$)*/ $kDefault$ |
|
|
|
|
)cc"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void EnumOneofFieldGenerator::GenerateSwappingCode(io::Printer* printer) const { |
|
|
|
|
// Don't print any swapping code. Swapping the union will swap this field.
|
|
|
|
|
} |
|
|
|
|
void GenerateAggregateInitializer(io::Printer* p) const override { |
|
|
|
|
if (ShouldSplit(descriptor_, options_)) { |
|
|
|
|
p->Emit(R"cc( |
|
|
|
|
decltype(Impl_::Split::$name$_) { $kDefault$ } |
|
|
|
|
)cc"); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
p->Emit(R"cc( |
|
|
|
|
decltype($field_$) { $kDefault$ } |
|
|
|
|
)cc"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void EnumOneofFieldGenerator::GenerateConstructorCode( |
|
|
|
|
io::Printer* printer) const { |
|
|
|
|
Formatter format(printer, variables_); |
|
|
|
|
format("$ns$::_$classname$_default_instance_.$field$ = $default$;\n"); |
|
|
|
|
} |
|
|
|
|
void GenerateCopyAggregateInitializer(io::Printer* p) const override { |
|
|
|
|
p->Emit(R"cc( |
|
|
|
|
decltype($field_$) {} |
|
|
|
|
)cc"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// ===================================================================
|
|
|
|
|
void GenerateAccessorDeclarations(io::Printer* p) const override; |
|
|
|
|
void GenerateInlineAccessorDefinitions(io::Printer* p) const override; |
|
|
|
|
|
|
|
|
|
RepeatedEnumFieldGenerator::RepeatedEnumFieldGenerator( |
|
|
|
|
const FieldDescriptor* descriptor, const Options& options) |
|
|
|
|
: FieldGeneratorBase(descriptor, options) { |
|
|
|
|
SetEnumVariables(descriptor, &variables_, options); |
|
|
|
|
} |
|
|
|
|
private: |
|
|
|
|
const FieldDescriptor* field_; |
|
|
|
|
const Options* opts_; |
|
|
|
|
bool is_oneof_; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
void RepeatedEnumFieldGenerator::GeneratePrivateMembers( |
|
|
|
|
io::Printer* printer) const { |
|
|
|
|
Formatter format(printer, variables_); |
|
|
|
|
format("::$proto_ns$::RepeatedField<int> $name$_;\n"); |
|
|
|
|
if (descriptor_->is_packed() && |
|
|
|
|
HasGeneratedMethods(descriptor_->file(), options_)) { |
|
|
|
|
format( |
|
|
|
|
"mutable ::$proto_ns$::internal::CachedSize " |
|
|
|
|
"$cached_byte_size_name$;\n"); |
|
|
|
|
void SingularEnum::GenerateAccessorDeclarations(io::Printer* p) const { |
|
|
|
|
auto v = p->WithVars( |
|
|
|
|
AnnotatedAccessors(field_, {"", "set_", "_internal_", "_internal_set_"})); |
|
|
|
|
p->Emit(R"cc( |
|
|
|
|
$DEPRECATED$ $Enum$ $name$() const; |
|
|
|
|
$DEPRECATED$ void $set_name$($Enum$ value); |
|
|
|
|
|
|
|
|
|
private: |
|
|
|
|
$Enum$ $_internal_name$() const; |
|
|
|
|
void $_internal_set_name$($Enum$ value); |
|
|
|
|
|
|
|
|
|
public: |
|
|
|
|
)cc"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void SingularEnum::GenerateInlineAccessorDefinitions(io::Printer* p) const { |
|
|
|
|
p->Emit(R"cc( |
|
|
|
|
inline $Enum$ $Msg$::$name$() const { |
|
|
|
|
$annotate_get$; |
|
|
|
|
// @@protoc_insertion_point(field_get:$pkg.Msg.field$)
|
|
|
|
|
return _internal_$name$(); |
|
|
|
|
} |
|
|
|
|
inline void $Msg$::set_$name$($Enum$ value) { |
|
|
|
|
$maybe_prepare_split_message$ _internal_set_$name$(value); |
|
|
|
|
$annotate_set$; |
|
|
|
|
// @@protoc_insertion_point(field_set:$pkg.Msg.field$)
|
|
|
|
|
} |
|
|
|
|
)cc"); |
|
|
|
|
|
|
|
|
|
if (is_oneof_) { |
|
|
|
|
p->Emit(R"cc( |
|
|
|
|
inline $Enum$ $Msg$::_internal_$name$() const { |
|
|
|
|
if ($has_field$) { |
|
|
|
|
return static_cast<$Enum$>($field_$); |
|
|
|
|
} |
|
|
|
|
return static_cast<$Enum$>($kDefault$); |
|
|
|
|
} |
|
|
|
|
inline void $Msg$::_internal_set_$name$($Enum$ value) { |
|
|
|
|
$assert_valid$; |
|
|
|
|
if ($not_has_field$) { |
|
|
|
|
clear_$oneof_name$(); |
|
|
|
|
set_has_$name$(); |
|
|
|
|
} |
|
|
|
|
$field_$ = value; |
|
|
|
|
} |
|
|
|
|
)cc"); |
|
|
|
|
} else { |
|
|
|
|
p->Emit(R"cc( |
|
|
|
|
inline $Enum$ $Msg$::_internal_$name$() const { |
|
|
|
|
return static_cast<$Enum$>($field_$); |
|
|
|
|
} |
|
|
|
|
inline void $Msg$::_internal_set_$name$($Enum$ value) { |
|
|
|
|
$assert_valid$; |
|
|
|
|
$set_hasbit$; |
|
|
|
|
$field_$ = value; |
|
|
|
|
} |
|
|
|
|
)cc"); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void RepeatedEnumFieldGenerator::GenerateAccessorDeclarations( |
|
|
|
|
io::Printer* printer) const { |
|
|
|
|
Formatter format(printer, variables_); |
|
|
|
|
format( |
|
|
|
|
"private:\n" |
|
|
|
|
"$type$ ${1$_internal_$name$$}$(int index) const;\n" |
|
|
|
|
"void ${1$_internal_add_$name$$}$($type$ value);\n" |
|
|
|
|
"::$proto_ns$::RepeatedField<int>* " |
|
|
|
|
"${1$_internal_mutable_$name$$}$();\n" |
|
|
|
|
"public:\n" |
|
|
|
|
"$deprecated_attr$$type$ ${1$$name$$}$(int index) const;\n" |
|
|
|
|
"$deprecated_attr$void ${1$set_$name$$}$(int index, $type$ value);\n" |
|
|
|
|
"$deprecated_attr$void ${1$add_$name$$}$($type$ value);\n" |
|
|
|
|
"$deprecated_attr$const ::$proto_ns$::RepeatedField<int>& " |
|
|
|
|
"${1$$name$$}$() const;\n" |
|
|
|
|
"$deprecated_attr$::$proto_ns$::RepeatedField<int>* " |
|
|
|
|
"${1$mutable_$name$$}$();\n", |
|
|
|
|
descriptor_); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void RepeatedEnumFieldGenerator::GenerateInlineAccessorDefinitions( |
|
|
|
|
io::Printer* printer) const { |
|
|
|
|
Formatter format(printer, variables_); |
|
|
|
|
format( |
|
|
|
|
"inline $type$ $classname$::_internal_$name$(int index) const {\n" |
|
|
|
|
" return static_cast< $type$ >($field$.Get(index));\n" |
|
|
|
|
"}\n" |
|
|
|
|
"inline $type$ $classname$::$name$(int index) const {\n" |
|
|
|
|
"$annotate_get$" |
|
|
|
|
" // @@protoc_insertion_point(field_get:$full_name$)\n" |
|
|
|
|
" return _internal_$name$(index);\n" |
|
|
|
|
"}\n" |
|
|
|
|
"inline void $classname$::set_$name$(int index, $type$ value) {\n"); |
|
|
|
|
if (!internal::cpp::HasPreservingUnknownEnumSemantics(descriptor_)) { |
|
|
|
|
format(" assert($type$_IsValid(value));\n"); |
|
|
|
|
} |
|
|
|
|
format( |
|
|
|
|
" $field$.Set(index, value);\n" |
|
|
|
|
"$annotate_set$" |
|
|
|
|
" // @@protoc_insertion_point(field_set:$full_name$)\n" |
|
|
|
|
"}\n" |
|
|
|
|
"inline void $classname$::_internal_add_$name$($type$ value) {\n"); |
|
|
|
|
if (!internal::cpp::HasPreservingUnknownEnumSemantics(descriptor_)) { |
|
|
|
|
format(" assert($type$_IsValid(value));\n"); |
|
|
|
|
class RepeatedEnum : public FieldGeneratorBase { |
|
|
|
|
public: |
|
|
|
|
RepeatedEnum(const FieldDescriptor* field, const Options& opts) |
|
|
|
|
: FieldGeneratorBase(field, opts), |
|
|
|
|
field_(field), |
|
|
|
|
opts_(&opts), |
|
|
|
|
has_cached_size_(field_->is_packed() && |
|
|
|
|
HasGeneratedMethods(field_->file(), opts)) {} |
|
|
|
|
~RepeatedEnum() override = default; |
|
|
|
|
|
|
|
|
|
std::vector<Sub> MakeVars() const override { return Vars(field_, *opts_); } |
|
|
|
|
|
|
|
|
|
void GeneratePrivateMembers(io::Printer* p) const override { |
|
|
|
|
p->Emit(R"cc( |
|
|
|
|
$pb$::RepeatedField<int> $name$_; |
|
|
|
|
)cc"); |
|
|
|
|
|
|
|
|
|
if (has_cached_size_) { |
|
|
|
|
p->Emit(R"cc( |
|
|
|
|
mutable $pbi$::CachedSize $cached_size_name$; |
|
|
|
|
)cc"); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
format( |
|
|
|
|
" $field$.Add(value);\n" |
|
|
|
|
"}\n" |
|
|
|
|
"inline void $classname$::add_$name$($type$ value) {\n" |
|
|
|
|
" _internal_add_$name$(value);\n" |
|
|
|
|
"$annotate_add$" |
|
|
|
|
" // @@protoc_insertion_point(field_add:$full_name$)\n" |
|
|
|
|
"}\n" |
|
|
|
|
"inline const ::$proto_ns$::RepeatedField<int>&\n" |
|
|
|
|
"$classname$::$name$() const {\n" |
|
|
|
|
"$annotate_list$" |
|
|
|
|
" // @@protoc_insertion_point(field_list:$full_name$)\n" |
|
|
|
|
" return $field$;\n" |
|
|
|
|
"}\n" |
|
|
|
|
"inline ::$proto_ns$::RepeatedField<int>*\n" |
|
|
|
|
"$classname$::_internal_mutable_$name$() {\n" |
|
|
|
|
" return &$field$;\n" |
|
|
|
|
"}\n" |
|
|
|
|
"inline ::$proto_ns$::RepeatedField<int>*\n" |
|
|
|
|
"$classname$::mutable_$name$() {\n" |
|
|
|
|
"$annotate_mutable_list$" |
|
|
|
|
" // @@protoc_insertion_point(field_mutable_list:$full_name$)\n" |
|
|
|
|
" return _internal_mutable_$name$();\n" |
|
|
|
|
"}\n"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void RepeatedEnumFieldGenerator::GenerateClearingCode( |
|
|
|
|
io::Printer* printer) const { |
|
|
|
|
Formatter format(printer, variables_); |
|
|
|
|
format("$field$.Clear();\n"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void RepeatedEnumFieldGenerator::GenerateMergingCode( |
|
|
|
|
io::Printer* printer) const { |
|
|
|
|
Formatter format(printer, variables_); |
|
|
|
|
format("_this->$field$.MergeFrom(from.$field$);\n"); |
|
|
|
|
} |
|
|
|
|
void GenerateClearingCode(io::Printer* p) const override { |
|
|
|
|
p->Emit(R"cc( |
|
|
|
|
$field_$.Clear(); |
|
|
|
|
)cc"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void RepeatedEnumFieldGenerator::GenerateSwappingCode( |
|
|
|
|
io::Printer* printer) const { |
|
|
|
|
Formatter format(printer, variables_); |
|
|
|
|
format("$field$.InternalSwap(&other->$field$);\n"); |
|
|
|
|
} |
|
|
|
|
void GenerateMergingCode(io::Printer* p) const override { |
|
|
|
|
p->Emit(R"cc( |
|
|
|
|
_this->$field_$.MergeFrom(from.$field_$); |
|
|
|
|
)cc"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void RepeatedEnumFieldGenerator::GenerateConstructorCode( |
|
|
|
|
io::Printer* printer) const { |
|
|
|
|
// Not needed for repeated fields.
|
|
|
|
|
} |
|
|
|
|
void GenerateSwappingCode(io::Printer* p) const override { |
|
|
|
|
p->Emit(R"cc( |
|
|
|
|
$field_$.InternalSwap(&other->$field_$); |
|
|
|
|
)cc"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void RepeatedEnumFieldGenerator::GenerateDestructorCode( |
|
|
|
|
io::Printer* printer) const { |
|
|
|
|
Formatter format(printer, variables_); |
|
|
|
|
format("$field$.~RepeatedField();\n"); |
|
|
|
|
} |
|
|
|
|
void GenerateDestructorCode(io::Printer* p) const override { |
|
|
|
|
p->Emit(R"cc( |
|
|
|
|
$field_$.~RepeatedField(); |
|
|
|
|
)cc"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void RepeatedEnumFieldGenerator::GenerateSerializeWithCachedSizesToArray( |
|
|
|
|
io::Printer* printer) const { |
|
|
|
|
Formatter format(printer, variables_); |
|
|
|
|
if (descriptor_->is_packed()) { |
|
|
|
|
// Write the tag and the size.
|
|
|
|
|
format( |
|
|
|
|
"{\n" |
|
|
|
|
" int byte_size = " |
|
|
|
|
"$cached_byte_size_field$.Get();\n" |
|
|
|
|
" if (byte_size > 0) {\n" |
|
|
|
|
" target = stream->WriteEnumPacked(\n" |
|
|
|
|
" $number$, $field$, byte_size, target);\n" |
|
|
|
|
" }\n" |
|
|
|
|
"}\n"); |
|
|
|
|
} else { |
|
|
|
|
format( |
|
|
|
|
"for (int i = 0, n = this->_internal_$name$_size(); i < n; i++) {\n" |
|
|
|
|
" target = stream->EnsureSpace(target);\n" |
|
|
|
|
" target = ::_pbi::WireFormatLite::WriteEnumToArray(\n" |
|
|
|
|
" $number$, this->_internal_$name$(i), target);\n" |
|
|
|
|
"}\n"); |
|
|
|
|
void GenerateConstexprAggregateInitializer(io::Printer* p) const override { |
|
|
|
|
p->Emit(R"cc( |
|
|
|
|
/*decltype($field_$)*/ {} |
|
|
|
|
)cc"); |
|
|
|
|
if (has_cached_size_) { |
|
|
|
|
p->Emit(R"cc( |
|
|
|
|
, /*decltype($cached_size_$)*/ { 0 } |
|
|
|
|
)cc"); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void RepeatedEnumFieldGenerator::GenerateByteSize(io::Printer* printer) const { |
|
|
|
|
Formatter format(printer, variables_); |
|
|
|
|
format( |
|
|
|
|
"{\n" |
|
|
|
|
" ::size_t data_size = 0;\n" |
|
|
|
|
" unsigned int count = static_cast<unsigned " |
|
|
|
|
"int>(this->_internal_$name$_size());"); |
|
|
|
|
format.Indent(); |
|
|
|
|
format( |
|
|
|
|
"for (unsigned int i = 0; i < count; i++) {\n" |
|
|
|
|
" data_size += ::_pbi::WireFormatLite::EnumSize(\n" |
|
|
|
|
" this->_internal_$name$(static_cast<int>(i)));\n" |
|
|
|
|
"}\n"); |
|
|
|
|
|
|
|
|
|
if (descriptor_->is_packed()) { |
|
|
|
|
format( |
|
|
|
|
"if (data_size > 0) {\n" |
|
|
|
|
" total_size += $tag_size$ +\n" |
|
|
|
|
" " |
|
|
|
|
"::_pbi::WireFormatLite::Int32Size(static_cast<$int32$>(data_size));\n" |
|
|
|
|
"}\n" |
|
|
|
|
"int cached_size = ::_pbi::ToCachedSize(data_size);\n" |
|
|
|
|
"$cached_byte_size_field$.Set(cached_size);\n" |
|
|
|
|
"total_size += data_size;\n"); |
|
|
|
|
} else { |
|
|
|
|
format("total_size += ($tag_size$UL * count) + data_size;\n"); |
|
|
|
|
void GenerateAggregateInitializer(io::Printer* p) const override { |
|
|
|
|
p->Emit(R"cc( |
|
|
|
|
decltype($field_$) { arena } |
|
|
|
|
)cc"); |
|
|
|
|
if (has_cached_size_) { |
|
|
|
|
// std::atomic has no copy constructor, which prevents explicit aggregate
|
|
|
|
|
// initialization pre-C++17.
|
|
|
|
|
p->Emit(R"cc( |
|
|
|
|
, /*decltype($cached_size_$)*/ { 0 } |
|
|
|
|
)cc"); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
format.Outdent(); |
|
|
|
|
format("}\n"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void RepeatedEnumFieldGenerator::GenerateConstexprAggregateInitializer( |
|
|
|
|
io::Printer* printer) const { |
|
|
|
|
Formatter format(printer, variables_); |
|
|
|
|
format("/*decltype($field$)*/{}"); |
|
|
|
|
if (descriptor_->is_packed() && |
|
|
|
|
HasGeneratedMethods(descriptor_->file(), options_)) { |
|
|
|
|
format("\n, /*decltype($cached_byte_size_field$)*/{0}"); |
|
|
|
|
void GenerateCopyAggregateInitializer(io::Printer* p) const override { |
|
|
|
|
p->Emit(R"cc( |
|
|
|
|
decltype($field_$) { from.$field_$ })cc"); |
|
|
|
|
if (has_cached_size_) { |
|
|
|
|
// std::atomic has no copy constructor.
|
|
|
|
|
p->Emit(R"cc( |
|
|
|
|
, /*decltype($cached_size_$)*/ { 0 } |
|
|
|
|
)cc"); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void RepeatedEnumFieldGenerator::GenerateAggregateInitializer( |
|
|
|
|
io::Printer* printer) const { |
|
|
|
|
Formatter format(printer, variables_); |
|
|
|
|
format("decltype($field$){arena}"); |
|
|
|
|
if (descriptor_->is_packed() && |
|
|
|
|
HasGeneratedMethods(descriptor_->file(), options_)) { |
|
|
|
|
// std::atomic has no copy constructor, which prevents explicit aggregate
|
|
|
|
|
// initialization pre-C++17.
|
|
|
|
|
format("\n, /*decltype($cached_byte_size_field$)*/{0}"); |
|
|
|
|
void GenerateCopyConstructorCode(io::Printer* p) const override { |
|
|
|
|
ABSL_CHECK(!ShouldSplit(field_, *opts_)); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void RepeatedEnumFieldGenerator::GenerateCopyAggregateInitializer( |
|
|
|
|
io::Printer* printer) const { |
|
|
|
|
Formatter format(printer, variables_); |
|
|
|
|
format("decltype($field$){from.$field$}"); |
|
|
|
|
if (descriptor_->is_packed() && |
|
|
|
|
HasGeneratedMethods(descriptor_->file(), options_)) { |
|
|
|
|
// std::atomic has no copy constructor.
|
|
|
|
|
format("\n, /*decltype($cached_byte_size_field$)*/{0}"); |
|
|
|
|
void GenerateConstructorCode(io::Printer* p) const override {} |
|
|
|
|
|
|
|
|
|
void GenerateAccessorDeclarations(io::Printer* p) const override; |
|
|
|
|
void GenerateInlineAccessorDefinitions(io::Printer* p) const override; |
|
|
|
|
void GenerateSerializeWithCachedSizesToArray(io::Printer* p) const override; |
|
|
|
|
void GenerateByteSize(io::Printer* p) const override; |
|
|
|
|
|
|
|
|
|
private: |
|
|
|
|
const FieldDescriptor* field_; |
|
|
|
|
const Options* opts_; |
|
|
|
|
bool has_cached_size_; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
void RepeatedEnum::GenerateAccessorDeclarations(io::Printer* p) const { |
|
|
|
|
auto v = p->WithVars( |
|
|
|
|
AnnotatedAccessors(field_, {"", "set_", "add_", "mutable_", "_internal_", |
|
|
|
|
"_internal_add_", "_internal_mutable_"})); |
|
|
|
|
|
|
|
|
|
p->Emit(R"cc( |
|
|
|
|
public: |
|
|
|
|
$DEPRECATED$ $Enum$ $name$(int index) const; |
|
|
|
|
$DEPRECATED$ void $set_name$(int index, $Enum$ value); |
|
|
|
|
$DEPRECATED$ void $add_name$($Enum$ value); |
|
|
|
|
$DEPRECATED$ const $pb$::RepeatedField<int>& $name$() const; |
|
|
|
|
$DEPRECATED$ $pb$::RepeatedField<int>* $mutable_name$(); |
|
|
|
|
|
|
|
|
|
private: |
|
|
|
|
$Enum$ $_internal_name$(int index) const; |
|
|
|
|
void $_internal_add_name$($Enum$ value); |
|
|
|
|
$pb$::RepeatedField<int>* $_internal_mutable_name$(); |
|
|
|
|
|
|
|
|
|
public: |
|
|
|
|
)cc"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void RepeatedEnum::GenerateInlineAccessorDefinitions(io::Printer* p) const { |
|
|
|
|
p->Emit(R"cc( |
|
|
|
|
inline $Enum$ $Msg$::$name$(int index) const { |
|
|
|
|
$annotate_get$; |
|
|
|
|
// @@protoc_insertion_point(field_get:$pkg.Msg.field$)
|
|
|
|
|
return _internal_$name$(index); |
|
|
|
|
} |
|
|
|
|
inline void $Msg$::set_$name$(int index, $Enum$ value) { |
|
|
|
|
$assert_valid$; |
|
|
|
|
$field_$.Set(index, value); |
|
|
|
|
$annotate_set$ |
|
|
|
|
// @@protoc_insertion_point(field_set:$pkg.Msg.field$)
|
|
|
|
|
} |
|
|
|
|
inline void $Msg$::add_$name$($Enum$ value) { |
|
|
|
|
_internal_add_$name$(value); |
|
|
|
|
$annotate_add$ |
|
|
|
|
// @@protoc_insertion_point(field_add:$pkg.Msg.field$)
|
|
|
|
|
} |
|
|
|
|
inline const $pb$::RepeatedField<int>& $Msg$::$name$() const { |
|
|
|
|
$annotate_list$; |
|
|
|
|
// @@protoc_insertion_point(field_list:$pkg.Msg.field$)
|
|
|
|
|
return $field_$; |
|
|
|
|
} |
|
|
|
|
inline $pb$::RepeatedField<int>* $Msg$::mutable_$name$() { |
|
|
|
|
$annotate_mutable_list$; |
|
|
|
|
// @@protoc_insertion_point(field_mutable_list:$pkg.Msg.field$)
|
|
|
|
|
return _internal_mutable_$name$(); |
|
|
|
|
} |
|
|
|
|
inline $Enum$ $Msg$::_internal_$name$(int index) const { |
|
|
|
|
return static_cast<$Enum$>($field_$.Get(index)); |
|
|
|
|
} |
|
|
|
|
inline void $Msg$::_internal_add_$name$($Enum$ value) { |
|
|
|
|
$assert_valid$; |
|
|
|
|
$field_$.Add(value); |
|
|
|
|
} |
|
|
|
|
inline $pb$::RepeatedField<int>* $Msg$::_internal_mutable_$name$() { |
|
|
|
|
return &$field_$; |
|
|
|
|
} |
|
|
|
|
)cc"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void RepeatedEnum::GenerateSerializeWithCachedSizesToArray( |
|
|
|
|
io::Printer* p) const { |
|
|
|
|
if (field_->is_packed()) { |
|
|
|
|
p->Emit(R"cc( |
|
|
|
|
{ |
|
|
|
|
int byte_size = $cached_size_$.Get(); |
|
|
|
|
if (byte_size > 0) { |
|
|
|
|
target = stream->WriteEnumPacked($number$, $field_$, byte_size, target); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
)cc"); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
p->Emit(R"cc( |
|
|
|
|
for (int i = 0, n = this->_internal_$name$_size(); i < n; ++i) { |
|
|
|
|
target = stream->EnsureSpace(target); |
|
|
|
|
target = ::_pbi::WireFormatLite::WriteEnumToArray( |
|
|
|
|
$number$, this->_internal_$name$(i), target); |
|
|
|
|
} |
|
|
|
|
)cc"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void RepeatedEnum::GenerateByteSize(io::Printer* p) const { |
|
|
|
|
p->Emit( |
|
|
|
|
{ |
|
|
|
|
{"add_to_size", |
|
|
|
|
[&] { |
|
|
|
|
if (!field_->is_packed()) { |
|
|
|
|
p->Emit(R"cc( |
|
|
|
|
total_size += std::size_t{$kTagBytes$} * count; |
|
|
|
|
)cc"); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
p->Emit(R"cc( |
|
|
|
|
if (data_size > 0) { |
|
|
|
|
total_size += $kTagBytes$; |
|
|
|
|
total_size += ::_pbi::WireFormatLite::Int32Size( |
|
|
|
|
static_cast<int32_t>(data_size)); |
|
|
|
|
} |
|
|
|
|
$cached_size_$.Set(::_pbi::ToCachedSize(data_size)); |
|
|
|
|
)cc"); |
|
|
|
|
}}, |
|
|
|
|
}, |
|
|
|
|
R"cc( |
|
|
|
|
{ |
|
|
|
|
std::size_t data_size = 0; |
|
|
|
|
auto count = static_cast<std::size_t>(this->_internal_$name$_size()); |
|
|
|
|
|
|
|
|
|
for (std::size_t i = 0; i < count; ++i) { |
|
|
|
|
data_size += ::_pbi::WireFormatLite::EnumSize( |
|
|
|
|
this->_internal_$name$(static_cast<int>(i))); |
|
|
|
|
} |
|
|
|
|
total_size += data_size; |
|
|
|
|
$add_to_size$; |
|
|
|
|
} |
|
|
|
|
)cc"); |
|
|
|
|
} |
|
|
|
|
} // namespace
|
|
|
|
|
|
|
|
|
|
std::unique_ptr<FieldGeneratorBase> MakeSinguarEnumGenerator( |
|
|
|
|
const FieldDescriptor* desc, const Options& options, |
|
|
|
|
MessageSCCAnalyzer* scc) { |
|
|
|
|
return absl::make_unique<EnumFieldGenerator>(desc, options); |
|
|
|
|
return absl::make_unique<SingularEnum>(desc, options); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
std::unique_ptr<FieldGeneratorBase> MakeRepeatedEnumGenerator( |
|
|
|
|
const FieldDescriptor* desc, const Options& options, |
|
|
|
|
MessageSCCAnalyzer* scc) { |
|
|
|
|
return absl::make_unique<RepeatedEnumFieldGenerator>(desc, options); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
std::unique_ptr<FieldGeneratorBase> MakeOneofEnumGenerator( |
|
|
|
|
const FieldDescriptor* desc, const Options& options, |
|
|
|
|
MessageSCCAnalyzer* scc) { |
|
|
|
|
return absl::make_unique<EnumOneofFieldGenerator>(desc, options); |
|
|
|
|
return absl::make_unique<RepeatedEnum>(desc, options); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} // namespace cpp
|
|
|
|
|