|
|
@ -268,13 +268,6 @@ void CollectMapInfo(const Options& options, const Descriptor* descriptor, |
|
|
|
"TYPE_" + ToUpper(DeclaredTypeMethodName(key->type())); |
|
|
|
"TYPE_" + ToUpper(DeclaredTypeMethodName(key->type())); |
|
|
|
vars["val_wire_type"] = |
|
|
|
vars["val_wire_type"] = |
|
|
|
"TYPE_" + ToUpper(DeclaredTypeMethodName(val->type())); |
|
|
|
"TYPE_" + ToUpper(DeclaredTypeMethodName(val->type())); |
|
|
|
if (descriptor->file()->syntax() != FileDescriptor::SYNTAX_PROTO3 && |
|
|
|
|
|
|
|
val->type() == FieldDescriptor::TYPE_ENUM) { |
|
|
|
|
|
|
|
const EnumValueDescriptor* default_value = val->default_value_enum(); |
|
|
|
|
|
|
|
vars["default_enum_value"] = Int32ToString(default_value->number()); |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
vars["default_enum_value"] = "0"; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Does the given field have a private (internal helper only) has_$name$()
|
|
|
|
// Does the given field have a private (internal helper only) has_$name$()
|
|
|
@ -323,6 +316,17 @@ bool ShouldMarkNewAsFinal(const Descriptor* descriptor, |
|
|
|
options.opensource_runtime; |
|
|
|
options.opensource_runtime; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Returns true to make the message serialize in order, decided by the following
|
|
|
|
|
|
|
|
// factors in the order of precedence.
|
|
|
|
|
|
|
|
// --options().message_set_wire_format() == true
|
|
|
|
|
|
|
|
// --the message is in the allowlist (true)
|
|
|
|
|
|
|
|
// --GOOGLE_PROTOBUF_SHUFFLE_SERIALIZE is defined (false)
|
|
|
|
|
|
|
|
// --a ranage of message names that are allowed to stay in order (true)
|
|
|
|
|
|
|
|
bool ShouldSerializeInOrder(const Descriptor* descriptor, |
|
|
|
|
|
|
|
const Options& options) { |
|
|
|
|
|
|
|
return true; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
bool TableDrivenParsingEnabled(const Descriptor* descriptor, |
|
|
|
bool TableDrivenParsingEnabled(const Descriptor* descriptor, |
|
|
|
const Options& options) { |
|
|
|
const Options& options) { |
|
|
|
if (!options.table_driven_parsing) { |
|
|
|
if (!options.table_driven_parsing) { |
|
|
@ -591,7 +595,7 @@ MessageGenerator::MessageGenerator( |
|
|
|
// Compute optimized field order to be used for layout and initialization
|
|
|
|
// Compute optimized field order to be used for layout and initialization
|
|
|
|
// purposes.
|
|
|
|
// purposes.
|
|
|
|
for (auto field : FieldRange(descriptor_)) { |
|
|
|
for (auto field : FieldRange(descriptor_)) { |
|
|
|
if (!IsFieldUsed(field, options_)) { |
|
|
|
if (IsFieldStripped(field, options_)) { |
|
|
|
continue; |
|
|
|
continue; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -631,16 +635,7 @@ MessageGenerator::MessageGenerator( |
|
|
|
MessageGenerator::~MessageGenerator() = default; |
|
|
|
MessageGenerator::~MessageGenerator() = default; |
|
|
|
|
|
|
|
|
|
|
|
size_t MessageGenerator::HasBitsSize() const { |
|
|
|
size_t MessageGenerator::HasBitsSize() const { |
|
|
|
size_t sizeof_has_bits = (max_has_bit_index_ + 31) / 32 * 4; |
|
|
|
return (max_has_bit_index_ + 31) / 32; |
|
|
|
if (sizeof_has_bits == 0) { |
|
|
|
|
|
|
|
// Zero-size arrays aren't technically allowed, and MSVC in particular
|
|
|
|
|
|
|
|
// doesn't like them. We still need to declare these arrays to make
|
|
|
|
|
|
|
|
// other code compile. Since this is an uncommon case, we'll just declare
|
|
|
|
|
|
|
|
// them with size 1 and waste some space. Oh well.
|
|
|
|
|
|
|
|
sizeof_has_bits = 4; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return sizeof_has_bits; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int MessageGenerator::HasBitIndex(const FieldDescriptor* field) const { |
|
|
|
int MessageGenerator::HasBitIndex(const FieldDescriptor* field) const { |
|
|
@ -689,7 +684,7 @@ void MessageGenerator::GenerateFieldAccessorDeclarations(io::Printer* printer) { |
|
|
|
optimized_order_.end()); |
|
|
|
optimized_order_.end()); |
|
|
|
for (auto field : FieldRange(descriptor_)) { |
|
|
|
for (auto field : FieldRange(descriptor_)) { |
|
|
|
if (!field->real_containing_oneof() && !field->options().weak() && |
|
|
|
if (!field->real_containing_oneof() && !field->options().weak() && |
|
|
|
IsFieldUsed(field, options_)) { |
|
|
|
!IsFieldStripped(field, options_)) { |
|
|
|
continue; |
|
|
|
continue; |
|
|
|
} |
|
|
|
} |
|
|
|
ordered_fields.push_back(field); |
|
|
|
ordered_fields.push_back(field); |
|
|
@ -718,8 +713,8 @@ void MessageGenerator::GenerateFieldAccessorDeclarations(io::Printer* printer) { |
|
|
|
|
|
|
|
|
|
|
|
if (field->is_repeated()) { |
|
|
|
if (field->is_repeated()) { |
|
|
|
format("$deprecated_attr$int ${1$$name$_size$}$() const$2$\n", field, |
|
|
|
format("$deprecated_attr$int ${1$$name$_size$}$() const$2$\n", field, |
|
|
|
IsFieldUsed(field, options_) ? ";" : " {__builtin_trap();}"); |
|
|
|
!IsFieldStripped(field, options_) ? ";" : " {__builtin_trap();}"); |
|
|
|
if (IsFieldUsed(field, options_)) { |
|
|
|
if (!IsFieldStripped(field, options_)) { |
|
|
|
format( |
|
|
|
format( |
|
|
|
"private:\n" |
|
|
|
"private:\n" |
|
|
|
"int ${1$_internal_$name$_size$}$() const;\n" |
|
|
|
"int ${1$_internal_$name$_size$}$() const;\n" |
|
|
@ -728,15 +723,15 @@ void MessageGenerator::GenerateFieldAccessorDeclarations(io::Printer* printer) { |
|
|
|
} |
|
|
|
} |
|
|
|
} else if (HasHasMethod(field)) { |
|
|
|
} else if (HasHasMethod(field)) { |
|
|
|
format("$deprecated_attr$bool ${1$has_$name$$}$() const$2$\n", field, |
|
|
|
format("$deprecated_attr$bool ${1$has_$name$$}$() const$2$\n", field, |
|
|
|
IsFieldUsed(field, options_) ? ";" : " {__builtin_trap();}"); |
|
|
|
!IsFieldStripped(field, options_) ? ";" : " {__builtin_trap();}"); |
|
|
|
if (IsFieldUsed(field, options_)) { |
|
|
|
if (!IsFieldStripped(field, options_)) { |
|
|
|
format( |
|
|
|
format( |
|
|
|
"private:\n" |
|
|
|
"private:\n" |
|
|
|
"bool _internal_has_$name$() const;\n" |
|
|
|
"bool _internal_has_$name$() const;\n" |
|
|
|
"public:\n"); |
|
|
|
"public:\n"); |
|
|
|
} |
|
|
|
} |
|
|
|
} else if (HasPrivateHasMethod(field)) { |
|
|
|
} else if (HasPrivateHasMethod(field)) { |
|
|
|
if (IsFieldUsed(field, options_)) { |
|
|
|
if (!IsFieldStripped(field, options_)) { |
|
|
|
format( |
|
|
|
format( |
|
|
|
"private:\n" |
|
|
|
"private:\n" |
|
|
|
"bool ${1$_internal_has_$name$$}$() const;\n" |
|
|
|
"bool ${1$_internal_has_$name$$}$() const;\n" |
|
|
@ -745,7 +740,7 @@ void MessageGenerator::GenerateFieldAccessorDeclarations(io::Printer* printer) { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
format("$deprecated_attr$void ${1$clear_$name$$}$()$2$\n", field, |
|
|
|
format("$deprecated_attr$void ${1$clear_$name$$}$()$2$\n", field, |
|
|
|
IsFieldUsed(field, options_) ? ";" : "{__builtin_trap();}"); |
|
|
|
!IsFieldStripped(field, options_) ? ";" : "{__builtin_trap();}"); |
|
|
|
|
|
|
|
|
|
|
|
// Generate type-specific accessor declarations.
|
|
|
|
// Generate type-specific accessor declarations.
|
|
|
|
field_generators_.get(field).GenerateAccessorDeclarations(printer); |
|
|
|
field_generators_.get(field).GenerateAccessorDeclarations(printer); |
|
|
@ -780,7 +775,7 @@ void MessageGenerator::GenerateFieldAccessorDeclarations(io::Printer* printer) { |
|
|
|
|
|
|
|
|
|
|
|
void MessageGenerator::GenerateSingularFieldHasBits( |
|
|
|
void MessageGenerator::GenerateSingularFieldHasBits( |
|
|
|
const FieldDescriptor* field, Formatter format) { |
|
|
|
const FieldDescriptor* field, Formatter format) { |
|
|
|
if (!IsFieldUsed(field, options_)) { |
|
|
|
if (IsFieldStripped(field, options_)) { |
|
|
|
format( |
|
|
|
format( |
|
|
|
"inline bool $classname$::has_$name$() const { " |
|
|
|
"inline bool $classname$::has_$name$() const { " |
|
|
|
"__builtin_trap(); }\n"); |
|
|
|
"__builtin_trap(); }\n"); |
|
|
@ -861,7 +856,7 @@ void MessageGenerator::GenerateOneofHasBits(io::Printer* printer) { |
|
|
|
|
|
|
|
|
|
|
|
void MessageGenerator::GenerateOneofMemberHasBits(const FieldDescriptor* field, |
|
|
|
void MessageGenerator::GenerateOneofMemberHasBits(const FieldDescriptor* field, |
|
|
|
const Formatter& format) { |
|
|
|
const Formatter& format) { |
|
|
|
if (!IsFieldUsed(field, options_)) { |
|
|
|
if (IsFieldStripped(field, options_)) { |
|
|
|
if (HasHasMethod(field)) { |
|
|
|
if (HasHasMethod(field)) { |
|
|
|
format( |
|
|
|
format( |
|
|
|
"inline bool $classname$::has_$name$() const { " |
|
|
|
"inline bool $classname$::has_$name$() const { " |
|
|
@ -906,7 +901,7 @@ void MessageGenerator::GenerateOneofMemberHasBits(const FieldDescriptor* field, |
|
|
|
|
|
|
|
|
|
|
|
void MessageGenerator::GenerateFieldClear(const FieldDescriptor* field, |
|
|
|
void MessageGenerator::GenerateFieldClear(const FieldDescriptor* field, |
|
|
|
bool is_inline, Formatter format) { |
|
|
|
bool is_inline, Formatter format) { |
|
|
|
if (!IsFieldUsed(field, options_)) { |
|
|
|
if (IsFieldStripped(field, options_)) { |
|
|
|
format("void $classname$::clear_$name$() { __builtin_trap(); }\n"); |
|
|
|
format("void $classname$::clear_$name$() { __builtin_trap(); }\n"); |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
@ -952,7 +947,7 @@ void MessageGenerator::GenerateFieldAccessorDefinitions(io::Printer* printer) { |
|
|
|
for (auto field : FieldRange(descriptor_)) { |
|
|
|
for (auto field : FieldRange(descriptor_)) { |
|
|
|
PrintFieldComment(format, field); |
|
|
|
PrintFieldComment(format, field); |
|
|
|
|
|
|
|
|
|
|
|
if (!IsFieldUsed(field, options_)) { |
|
|
|
if (IsFieldStripped(field, options_)) { |
|
|
|
continue; |
|
|
|
continue; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -964,7 +959,7 @@ void MessageGenerator::GenerateFieldAccessorDefinitions(io::Printer* printer) { |
|
|
|
|
|
|
|
|
|
|
|
// Generate has_$name$() or $name$_size().
|
|
|
|
// Generate has_$name$() or $name$_size().
|
|
|
|
if (field->is_repeated()) { |
|
|
|
if (field->is_repeated()) { |
|
|
|
if (!IsFieldUsed(field, options_)) { |
|
|
|
if (IsFieldStripped(field, options_)) { |
|
|
|
format( |
|
|
|
format( |
|
|
|
"inline int $classname$::$name$_size() const { " |
|
|
|
"inline int $classname$::$name$_size() const { " |
|
|
|
"__builtin_trap(); }\n"); |
|
|
|
"__builtin_trap(); }\n"); |
|
|
@ -998,7 +993,7 @@ void MessageGenerator::GenerateFieldAccessorDefinitions(io::Printer* printer) { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Generate type-specific accessors.
|
|
|
|
// Generate type-specific accessors.
|
|
|
|
if (IsFieldUsed(field, options_)) { |
|
|
|
if (!IsFieldStripped(field, options_)) { |
|
|
|
field_generators_.get(field).GenerateInlineAccessorDefinitions(printer); |
|
|
|
field_generators_.get(field).GenerateInlineAccessorDefinitions(printer); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -1026,14 +1021,13 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { |
|
|
|
"::$proto_ns$::internal::MapEntry$lite$<$classname$, \n" |
|
|
|
"::$proto_ns$::internal::MapEntry$lite$<$classname$, \n" |
|
|
|
" $key_cpp$, $val_cpp$,\n" |
|
|
|
" $key_cpp$, $val_cpp$,\n" |
|
|
|
" ::$proto_ns$::internal::WireFormatLite::$key_wire_type$,\n" |
|
|
|
" ::$proto_ns$::internal::WireFormatLite::$key_wire_type$,\n" |
|
|
|
" ::$proto_ns$::internal::WireFormatLite::$val_wire_type$,\n" |
|
|
|
" ::$proto_ns$::internal::WireFormatLite::$val_wire_type$> {\n" |
|
|
|
" $default_enum_value$ > {\n" |
|
|
|
|
|
|
|
"public:\n" |
|
|
|
"public:\n" |
|
|
|
" typedef ::$proto_ns$::internal::MapEntry$lite$<$classname$, \n" |
|
|
|
" typedef ::$proto_ns$::internal::MapEntry$lite$<$classname$, \n" |
|
|
|
" $key_cpp$, $val_cpp$,\n" |
|
|
|
" $key_cpp$, $val_cpp$,\n" |
|
|
|
" ::$proto_ns$::internal::WireFormatLite::$key_wire_type$,\n" |
|
|
|
" ::$proto_ns$::internal::WireFormatLite::$key_wire_type$,\n" |
|
|
|
" ::$proto_ns$::internal::WireFormatLite::$val_wire_type$,\n" |
|
|
|
" ::$proto_ns$::internal::WireFormatLite::$val_wire_type$> " |
|
|
|
" $default_enum_value$ > SuperType;\n" |
|
|
|
"SuperType;\n" |
|
|
|
" $classname$();\n" |
|
|
|
" $classname$();\n" |
|
|
|
" explicit $classname$(::$proto_ns$::Arena* arena);\n" |
|
|
|
" explicit $classname$(::$proto_ns$::Arena* arena);\n" |
|
|
|
" void MergeFrom(const $classname$& other);\n" |
|
|
|
" void MergeFrom(const $classname$& other);\n" |
|
|
@ -1122,13 +1116,8 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { |
|
|
|
format(" public:\n"); |
|
|
|
format(" public:\n"); |
|
|
|
format.Indent(); |
|
|
|
format.Indent(); |
|
|
|
|
|
|
|
|
|
|
|
if (SupportsArenas(descriptor_)) { |
|
|
|
|
|
|
|
format("inline $classname$() : $classname$(nullptr) {}\n"); |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
format("$classname$();\n"); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
format( |
|
|
|
format( |
|
|
|
|
|
|
|
"inline $classname$() : $classname$(nullptr) {}\n" |
|
|
|
"virtual ~$classname$();\n" |
|
|
|
"virtual ~$classname$();\n" |
|
|
|
"\n" |
|
|
|
"\n" |
|
|
|
"$classname$(const $classname$& from);\n" |
|
|
|
"$classname$(const $classname$& from);\n" |
|
|
@ -1224,7 +1213,6 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { |
|
|
|
|
|
|
|
|
|
|
|
// TODO(gerbens) make this private, while still granting other protos access.
|
|
|
|
// TODO(gerbens) make this private, while still granting other protos access.
|
|
|
|
format( |
|
|
|
format( |
|
|
|
"static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY\n" |
|
|
|
|
|
|
|
"static inline const $classname$* internal_default_instance() {\n" |
|
|
|
"static inline const $classname$* internal_default_instance() {\n" |
|
|
|
" return reinterpret_cast<const $classname$*>(\n" |
|
|
|
" return reinterpret_cast<const $classname$*>(\n" |
|
|
|
" &_$classname$_default_instance_);\n" |
|
|
|
" &_$classname$_default_instance_);\n" |
|
|
@ -1244,7 +1232,8 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { |
|
|
|
" _any_metadata_.PackFrom(message);\n" |
|
|
|
" _any_metadata_.PackFrom(message);\n" |
|
|
|
"}\n" |
|
|
|
"}\n" |
|
|
|
"void PackFrom(const ::$proto_ns$::Message& message,\n" |
|
|
|
"void PackFrom(const ::$proto_ns$::Message& message,\n" |
|
|
|
" const std::string& type_url_prefix) {\n" |
|
|
|
" ::PROTOBUF_NAMESPACE_ID::ConstStringParam " |
|
|
|
|
|
|
|
"type_url_prefix) {\n" |
|
|
|
" _any_metadata_.PackFrom(message, type_url_prefix);\n" |
|
|
|
" _any_metadata_.PackFrom(message, type_url_prefix);\n" |
|
|
|
"}\n" |
|
|
|
"}\n" |
|
|
|
"bool UnpackTo(::$proto_ns$::Message* message) const {\n" |
|
|
|
"bool UnpackTo(::$proto_ns$::Message* message) const {\n" |
|
|
@ -1264,7 +1253,8 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { |
|
|
|
"!std::is_convertible<T, const ::$proto_ns$::Message&>" |
|
|
|
"!std::is_convertible<T, const ::$proto_ns$::Message&>" |
|
|
|
"::value>::type>\n" |
|
|
|
"::value>::type>\n" |
|
|
|
"void PackFrom(const T& message,\n" |
|
|
|
"void PackFrom(const T& message,\n" |
|
|
|
" const std::string& type_url_prefix) {\n" |
|
|
|
" ::PROTOBUF_NAMESPACE_ID::ConstStringParam " |
|
|
|
|
|
|
|
"type_url_prefix) {\n" |
|
|
|
" _any_metadata_.PackFrom<T>(message, type_url_prefix);" |
|
|
|
" _any_metadata_.PackFrom<T>(message, type_url_prefix);" |
|
|
|
"}\n" |
|
|
|
"}\n" |
|
|
|
"template <typename T, class = typename std::enable_if<" |
|
|
|
"template <typename T, class = typename std::enable_if<" |
|
|
@ -1281,7 +1271,8 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { |
|
|
|
"}\n" |
|
|
|
"}\n" |
|
|
|
"template <typename T>\n" |
|
|
|
"template <typename T>\n" |
|
|
|
"void PackFrom(const T& message,\n" |
|
|
|
"void PackFrom(const T& message,\n" |
|
|
|
" const std::string& type_url_prefix) {\n" |
|
|
|
" ::PROTOBUF_NAMESPACE_ID::ConstStringParam " |
|
|
|
|
|
|
|
"type_url_prefix) {\n" |
|
|
|
" _any_metadata_.PackFrom(message, type_url_prefix);\n" |
|
|
|
" _any_metadata_.PackFrom(message, type_url_prefix);\n" |
|
|
|
"}\n" |
|
|
|
"}\n" |
|
|
|
"template <typename T>\n" |
|
|
|
"template <typename T>\n" |
|
|
@ -1293,7 +1284,8 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { |
|
|
|
"template<typename T> bool Is() const {\n" |
|
|
|
"template<typename T> bool Is() const {\n" |
|
|
|
" return _any_metadata_.Is<T>();\n" |
|
|
|
" return _any_metadata_.Is<T>();\n" |
|
|
|
"}\n" |
|
|
|
"}\n" |
|
|
|
"static bool ParseAnyTypeUrl(const string& type_url,\n" |
|
|
|
"static bool ParseAnyTypeUrl(::PROTOBUF_NAMESPACE_ID::ConstStringParam " |
|
|
|
|
|
|
|
"type_url,\n" |
|
|
|
" std::string* full_type_name);\n"); |
|
|
|
" std::string* full_type_name);\n"); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -1303,31 +1295,21 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { |
|
|
|
format( |
|
|
|
format( |
|
|
|
"friend void swap($classname$& a, $classname$& b) {\n" |
|
|
|
"friend void swap($classname$& a, $classname$& b) {\n" |
|
|
|
" a.Swap(&b);\n" |
|
|
|
" a.Swap(&b);\n" |
|
|
|
|
|
|
|
"}\n" |
|
|
|
|
|
|
|
"inline void Swap($classname$* other) {\n" |
|
|
|
|
|
|
|
" if (other == this) return;\n" |
|
|
|
|
|
|
|
" if (GetArena() == other->GetArena()) {\n" |
|
|
|
|
|
|
|
" InternalSwap(other);\n" |
|
|
|
|
|
|
|
" } else {\n" |
|
|
|
|
|
|
|
" ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);\n" |
|
|
|
|
|
|
|
" }\n" |
|
|
|
|
|
|
|
"}\n" |
|
|
|
|
|
|
|
"void UnsafeArenaSwap($classname$* other) {\n" |
|
|
|
|
|
|
|
" if (other == this) return;\n" |
|
|
|
|
|
|
|
" $DCHK$(GetArena() == other->GetArena());\n" |
|
|
|
|
|
|
|
" InternalSwap(other);\n" |
|
|
|
"}\n"); |
|
|
|
"}\n"); |
|
|
|
|
|
|
|
|
|
|
|
if (SupportsArenas(descriptor_)) { |
|
|
|
|
|
|
|
format( |
|
|
|
|
|
|
|
"inline void Swap($classname$* other) {\n" |
|
|
|
|
|
|
|
" if (other == this) return;\n" |
|
|
|
|
|
|
|
" if (GetArena() == other->GetArena()) {\n" |
|
|
|
|
|
|
|
" InternalSwap(other);\n" |
|
|
|
|
|
|
|
" } else {\n" |
|
|
|
|
|
|
|
" ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);\n" |
|
|
|
|
|
|
|
" }\n" |
|
|
|
|
|
|
|
"}\n" |
|
|
|
|
|
|
|
"void UnsafeArenaSwap($classname$* other) {\n" |
|
|
|
|
|
|
|
" if (other == this) return;\n" |
|
|
|
|
|
|
|
" $DCHK$(GetArena() == other->GetArena());\n" |
|
|
|
|
|
|
|
" InternalSwap(other);\n" |
|
|
|
|
|
|
|
"}\n"); |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
format( |
|
|
|
|
|
|
|
"inline void Swap($classname$* other) {\n" |
|
|
|
|
|
|
|
" if (other == this) return;\n" |
|
|
|
|
|
|
|
" InternalSwap(other);\n" |
|
|
|
|
|
|
|
"}\n"); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
format( |
|
|
|
format( |
|
|
|
"\n" |
|
|
|
"\n" |
|
|
|
"// implements Message ----------------------------------------------\n" |
|
|
|
"// implements Message ----------------------------------------------\n" |
|
|
@ -1400,17 +1382,15 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { |
|
|
|
options_.opensource_runtime ? "::PROTOBUF_NAMESPACE_ID::StringPiece" |
|
|
|
options_.opensource_runtime ? "::PROTOBUF_NAMESPACE_ID::StringPiece" |
|
|
|
: "::StringPiece"); |
|
|
|
: "::StringPiece"); |
|
|
|
|
|
|
|
|
|
|
|
if (SupportsArenas(descriptor_)) { |
|
|
|
format( |
|
|
|
format( |
|
|
|
// TODO(gerbens) Make this private! Currently people are deriving from
|
|
|
|
// TODO(gerbens) Make this private! Currently people are deriving from
|
|
|
|
// protos to give access to this constructor, breaking the invariants
|
|
|
|
// protos to give access to this constructor, breaking the invariants
|
|
|
|
// we rely on.
|
|
|
|
// we rely on.
|
|
|
|
"protected:\n" |
|
|
|
"protected:\n" |
|
|
|
"explicit $classname$(::$proto_ns$::Arena* arena);\n" |
|
|
|
"explicit $classname$(::$proto_ns$::Arena* arena);\n" |
|
|
|
"private:\n" |
|
|
|
"private:\n" |
|
|
|
"static void ArenaDtor(void* object);\n" |
|
|
|
"static void ArenaDtor(void* object);\n" |
|
|
|
"inline void RegisterArenaDtor(::$proto_ns$::Arena* arena);\n"); |
|
|
|
"inline void RegisterArenaDtor(::$proto_ns$::Arena* arena);\n"); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
format( |
|
|
|
format( |
|
|
|
"public:\n" |
|
|
|
"public:\n" |
|
|
@ -1515,10 +1495,9 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { |
|
|
|
|
|
|
|
|
|
|
|
const size_t sizeof_has_bits = HasBitsSize(); |
|
|
|
const size_t sizeof_has_bits = HasBitsSize(); |
|
|
|
const std::string has_bits_decl = |
|
|
|
const std::string has_bits_decl = |
|
|
|
sizeof_has_bits == 0 |
|
|
|
sizeof_has_bits == 0 ? "" |
|
|
|
? "" |
|
|
|
: StrCat("::$proto_ns$::internal::HasBits<", |
|
|
|
: StrCat("::$proto_ns$::internal::HasBits<", |
|
|
|
sizeof_has_bits, "> _has_bits_;\n"); |
|
|
|
sizeof_has_bits / 4, "> _has_bits_;\n"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// To minimize padding, data members are divided into three sections:
|
|
|
|
// To minimize padding, data members are divided into three sections:
|
|
|
|
// (1) members assumed to align to 8 bytes
|
|
|
|
// (1) members assumed to align to 8 bytes
|
|
|
@ -1534,13 +1513,11 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { |
|
|
|
"\n"); |
|
|
|
"\n"); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (SupportsArenas(descriptor_)) { |
|
|
|
format( |
|
|
|
format( |
|
|
|
"template <typename T> friend class " |
|
|
|
"template <typename T> friend class " |
|
|
|
"::$proto_ns$::Arena::InternalHelper;\n" |
|
|
|
"::$proto_ns$::Arena::InternalHelper;\n" |
|
|
|
"typedef void InternalArenaConstructable_;\n" |
|
|
|
"typedef void InternalArenaConstructable_;\n" |
|
|
|
"typedef void DestructorSkippable_;\n"); |
|
|
|
"typedef void DestructorSkippable_;\n"); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!has_bit_indices_.empty()) { |
|
|
|
if (!has_bit_indices_.empty()) { |
|
|
|
// _has_bits_ is frequently accessed, so to reduce code size and improve
|
|
|
|
// _has_bits_ is frequently accessed, so to reduce code size and improve
|
|
|
@ -1572,14 +1549,14 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { |
|
|
|
camel_oneof_name); |
|
|
|
camel_oneof_name); |
|
|
|
format.Indent(); |
|
|
|
format.Indent(); |
|
|
|
for (auto field : FieldRange(oneof)) { |
|
|
|
for (auto field : FieldRange(oneof)) { |
|
|
|
if (IsFieldUsed(field, options_)) { |
|
|
|
if (!IsFieldStripped(field, options_)) { |
|
|
|
field_generators_.get(field).GeneratePrivateMembers(printer); |
|
|
|
field_generators_.get(field).GeneratePrivateMembers(printer); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
format.Outdent(); |
|
|
|
format.Outdent(); |
|
|
|
format("} $1$_;\n", oneof->name()); |
|
|
|
format("} $1$_;\n", oneof->name()); |
|
|
|
for (auto field : FieldRange(oneof)) { |
|
|
|
for (auto field : FieldRange(oneof)) { |
|
|
|
if (IsFieldUsed(field, options_)) { |
|
|
|
if (!IsFieldStripped(field, options_)) { |
|
|
|
field_generators_.get(field).GenerateStaticMembers(printer); |
|
|
|
field_generators_.get(field).GenerateStaticMembers(printer); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -1637,30 +1614,6 @@ void MessageGenerator::GenerateInlineMethods(io::Printer* printer) { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void MessageGenerator::GenerateExtraDefaultFields(io::Printer* printer) { |
|
|
|
|
|
|
|
// Generate oneof default instance and weak field instances for reflection
|
|
|
|
|
|
|
|
// usage.
|
|
|
|
|
|
|
|
Formatter format(printer, variables_); |
|
|
|
|
|
|
|
for (auto oneof : OneOfRange(descriptor_)) { |
|
|
|
|
|
|
|
for (auto field : FieldRange(oneof)) { |
|
|
|
|
|
|
|
if (!IsFieldUsed(field, options_)) { |
|
|
|
|
|
|
|
continue; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE || |
|
|
|
|
|
|
|
(field->cpp_type() == FieldDescriptor::CPPTYPE_STRING && |
|
|
|
|
|
|
|
EffectiveStringCType(field, options_) != FieldOptions::STRING)) { |
|
|
|
|
|
|
|
format("const "); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
field_generators_.get(field).GeneratePrivateMembers(printer); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
for (auto field : FieldRange(descriptor_)) { |
|
|
|
|
|
|
|
if (field->options().weak() && IsFieldUsed(field, options_)) { |
|
|
|
|
|
|
|
format(" const ::$proto_ns$::Message* $1$_;\n", FieldName(field)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool MessageGenerator::GenerateParseTable(io::Printer* printer, size_t offset, |
|
|
|
bool MessageGenerator::GenerateParseTable(io::Printer* printer, size_t offset, |
|
|
|
size_t aux_offset) { |
|
|
|
size_t aux_offset) { |
|
|
|
Formatter format(printer, variables_); |
|
|
|
Formatter format(printer, variables_); |
|
|
@ -1952,66 +1905,6 @@ void MessageGenerator::GenerateFieldDefaultInstances(io::Printer* printer) { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void MessageGenerator::GenerateDefaultInstanceInitializer( |
|
|
|
|
|
|
|
io::Printer* printer) { |
|
|
|
|
|
|
|
Formatter format(printer, variables_); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// The default instance needs all of its embedded message pointers
|
|
|
|
|
|
|
|
// cross-linked to other default instances. We can't do this initialization
|
|
|
|
|
|
|
|
// in the constructor because some other default instances may not have been
|
|
|
|
|
|
|
|
// constructed yet at that time.
|
|
|
|
|
|
|
|
// TODO(kenton): Maybe all message fields (even for non-default messages)
|
|
|
|
|
|
|
|
// should be initialized to point at default instances rather than NULL?
|
|
|
|
|
|
|
|
for (auto field : FieldRange(descriptor_)) { |
|
|
|
|
|
|
|
if (!IsFieldUsed(field, options_)) { |
|
|
|
|
|
|
|
continue; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
Formatter::SaveState saver(&format); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!field->is_repeated() && !IsLazy(field, options_) && |
|
|
|
|
|
|
|
field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE && |
|
|
|
|
|
|
|
(!field->real_containing_oneof() || |
|
|
|
|
|
|
|
HasDescriptorMethods(descriptor_->file(), options_))) { |
|
|
|
|
|
|
|
std::string name; |
|
|
|
|
|
|
|
if (field->real_containing_oneof() || field->options().weak()) { |
|
|
|
|
|
|
|
name = "_" + classname_ + "_default_instance_."; |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
name = |
|
|
|
|
|
|
|
"_" + classname_ + "_default_instance_._instance.get_mutable()->"; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
name += FieldName(field); |
|
|
|
|
|
|
|
format.Set("name", name); |
|
|
|
|
|
|
|
if (IsWeak(field, options_)) { |
|
|
|
|
|
|
|
format( |
|
|
|
|
|
|
|
"$package_ns$::$name$_ = reinterpret_cast<const " |
|
|
|
|
|
|
|
"::$proto_ns$::Message*>(&$1$);\n" |
|
|
|
|
|
|
|
"if ($package_ns$::$name$_ == nullptr) {\n" |
|
|
|
|
|
|
|
" $package_ns$::$name$_ = " |
|
|
|
|
|
|
|
"::$proto_ns$::Empty::internal_default_instance();\n" |
|
|
|
|
|
|
|
"}\n", |
|
|
|
|
|
|
|
QualifiedDefaultInstanceName(field->message_type(), |
|
|
|
|
|
|
|
options_)); // 1
|
|
|
|
|
|
|
|
continue; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (IsImplicitWeakField(field, options_, scc_analyzer_)) { |
|
|
|
|
|
|
|
format( |
|
|
|
|
|
|
|
"$package_ns$::$name$_ = reinterpret_cast<$1$*>(\n" |
|
|
|
|
|
|
|
" $2$);\n", |
|
|
|
|
|
|
|
FieldMessageTypeName(field, options_), |
|
|
|
|
|
|
|
QualifiedDefaultInstancePtr(field->message_type(), options_)); |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
format( |
|
|
|
|
|
|
|
"$package_ns$::$name$_ = const_cast< $1$*>(\n" |
|
|
|
|
|
|
|
" $1$::internal_default_instance());\n", |
|
|
|
|
|
|
|
FieldMessageTypeName(field, options_)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} else if (field->real_containing_oneof() && |
|
|
|
|
|
|
|
HasDescriptorMethods(descriptor_->file(), options_)) { |
|
|
|
|
|
|
|
field_generators_.get(field).GenerateConstructorCode(printer); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void MessageGenerator::GenerateClassMethods(io::Printer* printer) { |
|
|
|
void MessageGenerator::GenerateClassMethods(io::Printer* printer) { |
|
|
|
Formatter format(printer, variables_); |
|
|
|
Formatter format(printer, variables_); |
|
|
|
if (IsMapEntryMessage(descriptor_)) { |
|
|
|
if (IsMapEntryMessage(descriptor_)) { |
|
|
@ -2037,14 +1930,6 @@ void MessageGenerator::GenerateClassMethods(io::Printer* printer) { |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// TODO(gerbens) Remove this function. With a little bit of cleanup and
|
|
|
|
|
|
|
|
// refactoring this is superfluous.
|
|
|
|
|
|
|
|
format("void $classname$::InitAsDefaultInstance() {\n"); |
|
|
|
|
|
|
|
format.Indent(); |
|
|
|
|
|
|
|
GenerateDefaultInstanceInitializer(printer); |
|
|
|
|
|
|
|
format.Outdent(); |
|
|
|
|
|
|
|
format("}\n"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (IsAnyMessage(descriptor_, options_)) { |
|
|
|
if (IsAnyMessage(descriptor_, options_)) { |
|
|
|
if (HasDescriptorMethods(descriptor_->file(), options_)) { |
|
|
|
if (HasDescriptorMethods(descriptor_->file(), options_)) { |
|
|
|
format( |
|
|
|
format( |
|
|
@ -2057,8 +1942,9 @@ void MessageGenerator::GenerateClassMethods(io::Printer* printer) { |
|
|
|
"}\n"); |
|
|
|
"}\n"); |
|
|
|
} |
|
|
|
} |
|
|
|
format( |
|
|
|
format( |
|
|
|
"bool $classname$::ParseAnyTypeUrl(const string& type_url,\n" |
|
|
|
"bool $classname$::ParseAnyTypeUrl(\n" |
|
|
|
" std::string* full_type_name) {\n" |
|
|
|
" ::PROTOBUF_NAMESPACE_ID::ConstStringParam type_url,\n" |
|
|
|
|
|
|
|
" std::string* full_type_name) {\n" |
|
|
|
" return ::$proto_ns$::internal::ParseAnyTypeUrl(type_url,\n" |
|
|
|
" return ::$proto_ns$::internal::ParseAnyTypeUrl(type_url,\n" |
|
|
|
" full_type_name);\n" |
|
|
|
" full_type_name);\n" |
|
|
|
"}\n" |
|
|
|
"}\n" |
|
|
@ -2075,7 +1961,7 @@ void MessageGenerator::GenerateClassMethods(io::Printer* printer) { |
|
|
|
} |
|
|
|
} |
|
|
|
for (auto field : FieldRange(descriptor_)) { |
|
|
|
for (auto field : FieldRange(descriptor_)) { |
|
|
|
field_generators_.get(field).GenerateInternalAccessorDeclarations(printer); |
|
|
|
field_generators_.get(field).GenerateInternalAccessorDeclarations(printer); |
|
|
|
if (!IsFieldUsed(field, options_)) { |
|
|
|
if (IsFieldStripped(field, options_)) { |
|
|
|
continue; |
|
|
|
continue; |
|
|
|
} |
|
|
|
} |
|
|
|
if (HasHasbit(field)) { |
|
|
|
if (HasHasbit(field)) { |
|
|
@ -2101,14 +1987,14 @@ void MessageGenerator::GenerateClassMethods(io::Printer* printer) { |
|
|
|
format.Outdent(); |
|
|
|
format.Outdent(); |
|
|
|
format("};\n\n"); |
|
|
|
format("};\n\n"); |
|
|
|
for (auto field : FieldRange(descriptor_)) { |
|
|
|
for (auto field : FieldRange(descriptor_)) { |
|
|
|
if (IsFieldUsed(field, options_)) { |
|
|
|
if (!IsFieldStripped(field, options_)) { |
|
|
|
field_generators_.get(field).GenerateInternalAccessorDefinitions(printer); |
|
|
|
field_generators_.get(field).GenerateInternalAccessorDefinitions(printer); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Generate non-inline field definitions.
|
|
|
|
// Generate non-inline field definitions.
|
|
|
|
for (auto field : FieldRange(descriptor_)) { |
|
|
|
for (auto field : FieldRange(descriptor_)) { |
|
|
|
if (!IsFieldUsed(field, options_)) { |
|
|
|
if (IsFieldStripped(field, options_)) { |
|
|
|
continue; |
|
|
|
continue; |
|
|
|
} |
|
|
|
} |
|
|
|
field_generators_.get(field).GenerateNonInlineAccessorDefinitions(printer); |
|
|
|
field_generators_.get(field).GenerateNonInlineAccessorDefinitions(printer); |
|
|
@ -2413,13 +2299,16 @@ std::pair<size_t, size_t> MessageGenerator::GenerateOffsets( |
|
|
|
descriptor_->real_oneof_decl_count(); |
|
|
|
descriptor_->real_oneof_decl_count(); |
|
|
|
size_t entries = offsets; |
|
|
|
size_t entries = offsets; |
|
|
|
for (auto field : FieldRange(descriptor_)) { |
|
|
|
for (auto field : FieldRange(descriptor_)) { |
|
|
|
if (!IsFieldUsed(field, options_)) { |
|
|
|
if (IsFieldStripped(field, options_)) { |
|
|
|
format("~0u, // stripped\n"); |
|
|
|
format("~0u, // stripped\n"); |
|
|
|
continue; |
|
|
|
continue; |
|
|
|
} |
|
|
|
} |
|
|
|
if (field->real_containing_oneof() || field->options().weak()) { |
|
|
|
// TODO(sbenza): We should not have an entry in the offset table for fields
|
|
|
|
format("offsetof($classtype$DefaultTypeInternal, $1$_)", |
|
|
|
// that do not use them.
|
|
|
|
FieldName(field)); |
|
|
|
if (field->options().weak() || field->real_containing_oneof()) { |
|
|
|
|
|
|
|
// Mark the field to prevent unintentional access through reflection.
|
|
|
|
|
|
|
|
// Don't use the top bit because that is for unused fields.
|
|
|
|
|
|
|
|
format("::$proto_ns$::internal::kInvalidFieldOffsetTag"); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
format("PROTOBUF_FIELD_OFFSET($classtype$, $1$_)", FieldName(field)); |
|
|
|
format("PROTOBUF_FIELD_OFFSET($classtype$, $1$_)", FieldName(field)); |
|
|
|
} |
|
|
|
} |
|
|
@ -2429,7 +2318,11 @@ std::pair<size_t, size_t> MessageGenerator::GenerateOffsets( |
|
|
|
format(" | $1$", tag); |
|
|
|
format(" | $1$", tag); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
format(",\n"); |
|
|
|
if (!IsFieldUsed(field, options_)) { |
|
|
|
|
|
|
|
format(" | 0x80000000u, // unused\n"); |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
format(",\n"); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int count = 0; |
|
|
|
int count = 0; |
|
|
@ -2483,9 +2376,7 @@ void MessageGenerator::GenerateSharedDestructorCode(io::Printer* printer) { |
|
|
|
|
|
|
|
|
|
|
|
format("void $classname$::SharedDtor() {\n"); |
|
|
|
format("void $classname$::SharedDtor() {\n"); |
|
|
|
format.Indent(); |
|
|
|
format.Indent(); |
|
|
|
if (SupportsArenas(descriptor_)) { |
|
|
|
format("$DCHK$(GetArena() == nullptr);\n"); |
|
|
|
format("$DCHK$(GetArena() == nullptr);\n"); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
// Write the destructors for each field except oneof members.
|
|
|
|
// Write the destructors for each field except oneof members.
|
|
|
|
// optimized_order_ does not contain oneof fields.
|
|
|
|
// optimized_order_ does not contain oneof fields.
|
|
|
|
for (auto field : optimized_order_) { |
|
|
|
for (auto field : optimized_order_) { |
|
|
@ -2541,7 +2432,7 @@ void MessageGenerator::GenerateArenaDestructorCode(io::Printer* printer) { |
|
|
|
// and returns false for oneof fields.
|
|
|
|
// and returns false for oneof fields.
|
|
|
|
for (auto oneof : OneOfRange(descriptor_)) { |
|
|
|
for (auto oneof : OneOfRange(descriptor_)) { |
|
|
|
for (auto field : FieldRange(oneof)) { |
|
|
|
for (auto field : FieldRange(oneof)) { |
|
|
|
if (IsFieldUsed(field, options_) && |
|
|
|
if (!IsFieldStripped(field, options_) && |
|
|
|
field_generators_.get(field).GenerateArenaDestructorCode(printer)) { |
|
|
|
field_generators_.get(field).GenerateArenaDestructorCode(printer)) { |
|
|
|
need_registration = true; |
|
|
|
need_registration = true; |
|
|
|
} |
|
|
|
} |
|
|
@ -2644,7 +2535,7 @@ void MessageGenerator::GenerateStructors(io::Printer* printer) { |
|
|
|
|
|
|
|
|
|
|
|
// Initialize member variables with arena constructor.
|
|
|
|
// Initialize member variables with arena constructor.
|
|
|
|
for (auto field : optimized_order_) { |
|
|
|
for (auto field : optimized_order_) { |
|
|
|
GOOGLE_DCHECK(IsFieldUsed(field, options_)); |
|
|
|
GOOGLE_DCHECK(!IsFieldStripped(field, options_)); |
|
|
|
bool has_arena_constructor = field->is_repeated(); |
|
|
|
bool has_arena_constructor = field->is_repeated(); |
|
|
|
if (!field->real_containing_oneof() && |
|
|
|
if (!field->real_containing_oneof() && |
|
|
|
(IsLazy(field, options_) || IsStringPiece(field, options_))) { |
|
|
|
(IsLazy(field, options_) || IsStringPiece(field, options_))) { |
|
|
@ -2671,24 +2562,14 @@ void MessageGenerator::GenerateStructors(io::Printer* printer) { |
|
|
|
initializer_null += ", _weak_field_map_(nullptr)"; |
|
|
|
initializer_null += ", _weak_field_map_(nullptr)"; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (SupportsArenas(descriptor_)) { |
|
|
|
format( |
|
|
|
format( |
|
|
|
"$classname$::$classname$(::$proto_ns$::Arena* arena)\n" |
|
|
|
"$classname$::$classname$(::$proto_ns$::Arena* arena)\n" |
|
|
|
" : $1$ {\n" |
|
|
|
" : $1$ {\n" |
|
|
|
" SharedCtor();\n" |
|
|
|
" SharedCtor();\n" |
|
|
|
" RegisterArenaDtor(arena);\n" |
|
|
|
" RegisterArenaDtor(arena);\n" |
|
|
|
" // @@protoc_insertion_point(arena_constructor:$full_name$)\n" |
|
|
|
" // @@protoc_insertion_point(arena_constructor:$full_name$)\n" |
|
|
|
"}\n", |
|
|
|
"}\n", |
|
|
|
initializer_with_arena); |
|
|
|
initializer_with_arena); |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
format( |
|
|
|
|
|
|
|
"$classname$::$classname$()\n" |
|
|
|
|
|
|
|
" : $1$ {\n" |
|
|
|
|
|
|
|
" SharedCtor();\n" |
|
|
|
|
|
|
|
" // @@protoc_insertion_point(constructor:$full_name$)\n" |
|
|
|
|
|
|
|
"}\n", |
|
|
|
|
|
|
|
initializer_null); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::map<std::string, std::string> vars; |
|
|
|
std::map<std::string, std::string> vars; |
|
|
|
SetUnknkownFieldsVariable(descriptor_, options_, &vars); |
|
|
|
SetUnknkownFieldsVariable(descriptor_, options_, &vars); |
|
|
@ -2760,7 +2641,7 @@ void MessageGenerator::GenerateStructors(io::Printer* printer) { |
|
|
|
for (auto field : FieldRange(oneof)) { |
|
|
|
for (auto field : FieldRange(oneof)) { |
|
|
|
format("case k$1$: {\n", UnderscoresToCamelCase(field->name(), true)); |
|
|
|
format("case k$1$: {\n", UnderscoresToCamelCase(field->name(), true)); |
|
|
|
format.Indent(); |
|
|
|
format.Indent(); |
|
|
|
if (IsFieldUsed(field, options_)) { |
|
|
|
if (!IsFieldStripped(field, options_)) { |
|
|
|
field_generators_.get(field).GenerateMergingCode(printer); |
|
|
|
field_generators_.get(field).GenerateMergingCode(printer); |
|
|
|
} |
|
|
|
} |
|
|
|
format("break;\n"); |
|
|
|
format("break;\n"); |
|
|
@ -2799,9 +2680,7 @@ void MessageGenerator::GenerateStructors(io::Printer* printer) { |
|
|
|
GenerateSharedDestructorCode(printer); |
|
|
|
GenerateSharedDestructorCode(printer); |
|
|
|
|
|
|
|
|
|
|
|
// Generate the arena-specific destructor code.
|
|
|
|
// Generate the arena-specific destructor code.
|
|
|
|
if (SupportsArenas(descriptor_)) { |
|
|
|
GenerateArenaDestructorCode(printer); |
|
|
|
GenerateArenaDestructorCode(printer); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Generate SetCachedSize.
|
|
|
|
// Generate SetCachedSize.
|
|
|
|
format( |
|
|
|
format( |
|
|
@ -2824,9 +2703,8 @@ void MessageGenerator::GenerateSourceInProto2Namespace(io::Printer* printer) { |
|
|
|
"template<> " |
|
|
|
"template<> " |
|
|
|
"PROTOBUF_NOINLINE " |
|
|
|
"PROTOBUF_NOINLINE " |
|
|
|
"$classtype$* Arena::CreateMaybeMessage< $classtype$ >(Arena* arena) {\n" |
|
|
|
"$classtype$* Arena::CreateMaybeMessage< $classtype$ >(Arena* arena) {\n" |
|
|
|
" return Arena::$1$Internal< $classtype$ >(arena);\n" |
|
|
|
" return Arena::CreateMessageInternal< $classtype$ >(arena);\n" |
|
|
|
"}\n", |
|
|
|
"}\n"); |
|
|
|
MessageCreateFunction(descriptor_)); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void MessageGenerator::GenerateClear(io::Printer* printer) { |
|
|
|
void MessageGenerator::GenerateClear(io::Printer* printer) { |
|
|
@ -3018,7 +2896,7 @@ void MessageGenerator::GenerateOneofClear(io::Printer* printer) { |
|
|
|
format("case k$1$: {\n", UnderscoresToCamelCase(field->name(), true)); |
|
|
|
format("case k$1$: {\n", UnderscoresToCamelCase(field->name(), true)); |
|
|
|
format.Indent(); |
|
|
|
format.Indent(); |
|
|
|
// We clear only allocated objects in oneofs
|
|
|
|
// We clear only allocated objects in oneofs
|
|
|
|
if (!IsStringOrMessage(field) || !IsFieldUsed(field, options_)) { |
|
|
|
if (!IsStringOrMessage(field) || IsFieldStripped(field, options_)) { |
|
|
|
format("// No need to clear\n"); |
|
|
|
format("// No need to clear\n"); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
field_generators_.get(field).GenerateClearingCode(printer); |
|
|
|
field_generators_.get(field).GenerateClearingCode(printer); |
|
|
@ -3065,7 +2943,7 @@ void MessageGenerator::GenerateSwap(io::Printer* printer) { |
|
|
|
"metadata_);\n"); |
|
|
|
"metadata_);\n"); |
|
|
|
|
|
|
|
|
|
|
|
if (!has_bit_indices_.empty()) { |
|
|
|
if (!has_bit_indices_.empty()) { |
|
|
|
for (int i = 0; i < HasBitsSize() / 4; ++i) { |
|
|
|
for (int i = 0; i < HasBitsSize(); ++i) { |
|
|
|
format("swap(_has_bits_[$1$], other->_has_bits_[$1$]);\n", i); |
|
|
|
format("swap(_has_bits_[$1$], other->_has_bits_[$1$]);\n", i); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -3307,7 +3185,7 @@ void MessageGenerator::GenerateClassSpecificMergeFrom(io::Printer* printer) { |
|
|
|
for (auto field : FieldRange(oneof)) { |
|
|
|
for (auto field : FieldRange(oneof)) { |
|
|
|
format("case k$1$: {\n", UnderscoresToCamelCase(field->name(), true)); |
|
|
|
format("case k$1$: {\n", UnderscoresToCamelCase(field->name(), true)); |
|
|
|
format.Indent(); |
|
|
|
format.Indent(); |
|
|
|
if (IsFieldUsed(field, options_)) { |
|
|
|
if (!IsFieldStripped(field, options_)) { |
|
|
|
field_generators_.get(field).GenerateMergingCode(printer); |
|
|
|
field_generators_.get(field).GenerateMergingCode(printer); |
|
|
|
} |
|
|
|
} |
|
|
|
format("break;\n"); |
|
|
|
format("break;\n"); |
|
|
@ -3527,8 +3405,26 @@ void MessageGenerator::GenerateSerializeWithCachedSizesToArray( |
|
|
|
|
|
|
|
|
|
|
|
format("// @@protoc_insertion_point(serialize_to_array_start:$full_name$)\n"); |
|
|
|
format("// @@protoc_insertion_point(serialize_to_array_start:$full_name$)\n"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!ShouldSerializeInOrder(descriptor_, options_)) { |
|
|
|
|
|
|
|
format.Outdent(); |
|
|
|
|
|
|
|
format("#ifdef NDEBUG\n"); |
|
|
|
|
|
|
|
format.Indent(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
GenerateSerializeWithCachedSizesBody(printer); |
|
|
|
GenerateSerializeWithCachedSizesBody(printer); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!ShouldSerializeInOrder(descriptor_, options_)) { |
|
|
|
|
|
|
|
format.Outdent(); |
|
|
|
|
|
|
|
format("#else // NDEBUG\n"); |
|
|
|
|
|
|
|
format.Indent(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
GenerateSerializeWithCachedSizesBodyShuffled(printer); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
format.Outdent(); |
|
|
|
|
|
|
|
format("#endif // !NDEBUG\n"); |
|
|
|
|
|
|
|
format.Indent(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
format("// @@protoc_insertion_point(serialize_to_array_end:$full_name$)\n"); |
|
|
|
format("// @@protoc_insertion_point(serialize_to_array_end:$full_name$)\n"); |
|
|
|
|
|
|
|
|
|
|
|
format.Outdent(); |
|
|
|
format.Outdent(); |
|
|
@ -3643,11 +3539,14 @@ void MessageGenerator::GenerateSerializeWithCachedSizesBody( |
|
|
|
(i < descriptor_->field_count() && |
|
|
|
(i < descriptor_->field_count() && |
|
|
|
ordered_fields[i]->number() < sorted_extensions[j]->start)) { |
|
|
|
ordered_fields[i]->number() < sorted_extensions[j]->start)) { |
|
|
|
const FieldDescriptor* field = ordered_fields[i++]; |
|
|
|
const FieldDescriptor* field = ordered_fields[i++]; |
|
|
|
if (!IsFieldUsed(field, options_)) { |
|
|
|
if (IsFieldStripped(field, options_)) { |
|
|
|
continue; |
|
|
|
continue; |
|
|
|
} |
|
|
|
} |
|
|
|
if (field->options().weak()) { |
|
|
|
if (field->options().weak()) { |
|
|
|
last_weak_field = field; |
|
|
|
if (last_weak_field == nullptr || |
|
|
|
|
|
|
|
last_weak_field->number() < field->number()) { |
|
|
|
|
|
|
|
last_weak_field = field; |
|
|
|
|
|
|
|
} |
|
|
|
PrintFieldComment(format, field); |
|
|
|
PrintFieldComment(format, field); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
if (last_weak_field != nullptr) { |
|
|
|
if (last_weak_field != nullptr) { |
|
|
@ -3690,6 +3589,115 @@ void MessageGenerator::GenerateSerializeWithCachedSizesBody( |
|
|
|
format("}\n"); |
|
|
|
format("}\n"); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void MessageGenerator::GenerateSerializeWithCachedSizesBodyShuffled( |
|
|
|
|
|
|
|
io::Printer* printer) { |
|
|
|
|
|
|
|
Formatter format(printer, variables_); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::vector<const FieldDescriptor*> ordered_fields = |
|
|
|
|
|
|
|
SortFieldsByNumber(descriptor_); |
|
|
|
|
|
|
|
ordered_fields.erase( |
|
|
|
|
|
|
|
std::remove_if(ordered_fields.begin(), ordered_fields.end(), |
|
|
|
|
|
|
|
[this](const FieldDescriptor* f) { |
|
|
|
|
|
|
|
return !IsFieldUsed(f, options_); |
|
|
|
|
|
|
|
}), |
|
|
|
|
|
|
|
ordered_fields.end()); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::vector<const Descriptor::ExtensionRange*> sorted_extensions; |
|
|
|
|
|
|
|
sorted_extensions.reserve(descriptor_->extension_range_count()); |
|
|
|
|
|
|
|
for (int i = 0; i < descriptor_->extension_range_count(); ++i) { |
|
|
|
|
|
|
|
sorted_extensions.push_back(descriptor_->extension_range(i)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
std::sort(sorted_extensions.begin(), sorted_extensions.end(), |
|
|
|
|
|
|
|
ExtensionRangeSorter()); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int num_fields = ordered_fields.size() + sorted_extensions.size(); |
|
|
|
|
|
|
|
constexpr int kLargePrime = 1000003; |
|
|
|
|
|
|
|
GOOGLE_CHECK_LT(num_fields, kLargePrime) |
|
|
|
|
|
|
|
<< "Prime offset must be greater than the number of fields to ensure " |
|
|
|
|
|
|
|
"those are coprime."; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (num_weak_fields_) { |
|
|
|
|
|
|
|
format( |
|
|
|
|
|
|
|
"::$proto_ns$::internal::WeakFieldMap::FieldWriter field_writer(" |
|
|
|
|
|
|
|
"_weak_field_map_);\n"); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
format( |
|
|
|
|
|
|
|
"static const int kStart = GetInvariantPerBuild($1$UL) % $2$;\n" |
|
|
|
|
|
|
|
"bool first_pass = true;\n" |
|
|
|
|
|
|
|
"for (int i = kStart; i != kStart || first_pass; i = ((i + $3$) % $2$)) " |
|
|
|
|
|
|
|
"{\n", |
|
|
|
|
|
|
|
0, |
|
|
|
|
|
|
|
num_fields, kLargePrime); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
format.Indent(); |
|
|
|
|
|
|
|
format("switch(i) {\n"); |
|
|
|
|
|
|
|
format.Indent(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool first_pass_set = false; |
|
|
|
|
|
|
|
int index = 0; |
|
|
|
|
|
|
|
for (const auto* f : ordered_fields) { |
|
|
|
|
|
|
|
format("case $1$: {\n", index++); |
|
|
|
|
|
|
|
format.Indent(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!first_pass_set) { |
|
|
|
|
|
|
|
first_pass_set = true; |
|
|
|
|
|
|
|
format("first_pass = false;\n"); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
GenerateSerializeOneField(printer, f, -1); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
format("break;\n"); |
|
|
|
|
|
|
|
format.Outdent(); |
|
|
|
|
|
|
|
format("}\n"); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (const auto* r : sorted_extensions) { |
|
|
|
|
|
|
|
format("case $1$: {\n", index++); |
|
|
|
|
|
|
|
format.Indent(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!first_pass_set) { |
|
|
|
|
|
|
|
first_pass_set = true; |
|
|
|
|
|
|
|
format("first_pass = false;\n"); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
GenerateSerializeOneExtensionRange(printer, r); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
format("break;\n"); |
|
|
|
|
|
|
|
format.Outdent(); |
|
|
|
|
|
|
|
format("}\n"); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
format( |
|
|
|
|
|
|
|
"default: {\n" |
|
|
|
|
|
|
|
" $DCHK$(false) << \"Unexpected index: \" << i;\n" |
|
|
|
|
|
|
|
"}\n"); |
|
|
|
|
|
|
|
format.Outdent(); |
|
|
|
|
|
|
|
format("}\n"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
format.Outdent(); |
|
|
|
|
|
|
|
format("}\n"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::map<std::string, std::string> vars; |
|
|
|
|
|
|
|
SetUnknkownFieldsVariable(descriptor_, options_, &vars); |
|
|
|
|
|
|
|
format.AddMap(vars); |
|
|
|
|
|
|
|
format("if (PROTOBUF_PREDICT_FALSE($have_unknown_fields$)) {\n"); |
|
|
|
|
|
|
|
format.Indent(); |
|
|
|
|
|
|
|
if (UseUnknownFieldSet(descriptor_->file(), options_)) { |
|
|
|
|
|
|
|
format( |
|
|
|
|
|
|
|
"target = " |
|
|
|
|
|
|
|
"::$proto_ns$::internal::WireFormat::" |
|
|
|
|
|
|
|
"InternalSerializeUnknownFieldsToArray(\n" |
|
|
|
|
|
|
|
" $unknown_fields$, target, stream);\n"); |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
format( |
|
|
|
|
|
|
|
"target = stream->WriteRaw($unknown_fields$.data(),\n" |
|
|
|
|
|
|
|
" static_cast<int>($unknown_fields$.size()), target);\n"); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
format.Outdent(); |
|
|
|
|
|
|
|
format("}\n"); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
std::vector<uint32> MessageGenerator::RequiredFieldsBitMask() const { |
|
|
|
std::vector<uint32> MessageGenerator::RequiredFieldsBitMask() const { |
|
|
|
const int array_size = HasBitsSize(); |
|
|
|
const int array_size = HasBitsSize(); |
|
|
|
std::vector<uint32> masks(array_size, 0); |
|
|
|
std::vector<uint32> masks(array_size, 0); |
|
|
@ -3911,7 +3919,7 @@ void MessageGenerator::GenerateByteSize(io::Printer* printer) { |
|
|
|
PrintFieldComment(format, field); |
|
|
|
PrintFieldComment(format, field); |
|
|
|
format("case k$1$: {\n", UnderscoresToCamelCase(field->name(), true)); |
|
|
|
format("case k$1$: {\n", UnderscoresToCamelCase(field->name(), true)); |
|
|
|
format.Indent(); |
|
|
|
format.Indent(); |
|
|
|
if (IsFieldUsed(field, options_)) { |
|
|
|
if (!IsFieldStripped(field, options_)) { |
|
|
|
field_generators_.get(field).GenerateByteSize(printer); |
|
|
|
field_generators_.get(field).GenerateByteSize(printer); |
|
|
|
} |
|
|
|
} |
|
|
|
format("break;\n"); |
|
|
|
format("break;\n"); |
|
|
@ -4039,7 +4047,7 @@ void MessageGenerator::GenerateIsInitialized(io::Printer* printer) { |
|
|
|
format("case k$1$: {\n", UnderscoresToCamelCase(field->name(), true)); |
|
|
|
format("case k$1$: {\n", UnderscoresToCamelCase(field->name(), true)); |
|
|
|
format.Indent(); |
|
|
|
format.Indent(); |
|
|
|
|
|
|
|
|
|
|
|
if (IsFieldUsed(field, options_) && |
|
|
|
if (!IsFieldStripped(field, options_) && |
|
|
|
field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE && |
|
|
|
field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE && |
|
|
|
!ShouldIgnoreRequiredFieldCheck(field, options_) && |
|
|
|
!ShouldIgnoreRequiredFieldCheck(field, options_) && |
|
|
|
scc_analyzer_->HasRequiredFields(field->message_type())) { |
|
|
|
scc_analyzer_->HasRequiredFields(field->message_type())) { |
|
|
|