|
|
|
@ -201,10 +201,11 @@ RunMap FindRuns(const std::vector<const FieldDescriptor*>& fields, |
|
|
|
|
// Emits an if-statement with a condition that evaluates to true if |field| is
|
|
|
|
|
// considered non-default (will be sent over the wire), for message types
|
|
|
|
|
// without true field presence. Should only be called if
|
|
|
|
|
// !HasFieldPresence(message_descriptor).
|
|
|
|
|
// !HasHasbit(field).
|
|
|
|
|
bool EmitFieldNonDefaultCondition(io::Printer* printer, |
|
|
|
|
const std::string& prefix, |
|
|
|
|
const FieldDescriptor* field) { |
|
|
|
|
GOOGLE_CHECK(!HasHasbit(field)); |
|
|
|
|
Formatter format(printer); |
|
|
|
|
format.Set("prefix", prefix); |
|
|
|
|
format.Set("name", FieldName(field)); |
|
|
|
@ -225,7 +226,7 @@ bool EmitFieldNonDefaultCondition(io::Printer* printer, |
|
|
|
|
} |
|
|
|
|
format.Indent(); |
|
|
|
|
return true; |
|
|
|
|
} else if (field->containing_oneof()) { |
|
|
|
|
} else if (InRealOneof(field)) { |
|
|
|
|
format("if (_internal_has_$name$()) {\n"); |
|
|
|
|
format.Indent(); |
|
|
|
|
return true; |
|
|
|
@ -281,8 +282,7 @@ void CollectMapInfo(const Options& options, const Descriptor* descriptor, |
|
|
|
|
bool HasPrivateHasMethod(const FieldDescriptor* field) { |
|
|
|
|
// Only for oneofs in message types with no field presence. has_$name$(),
|
|
|
|
|
// based on the oneof case, is still useful internally for generated code.
|
|
|
|
|
return (!HasFieldPresence(field->file()) && |
|
|
|
|
field->containing_oneof() != NULL); |
|
|
|
|
return (!HasFieldPresence(field->file()) && InRealOneof(field)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// TODO(ckennelly): Cull these exclusions if/when these protos do not have
|
|
|
|
@ -597,7 +597,7 @@ MessageGenerator::MessageGenerator( |
|
|
|
|
|
|
|
|
|
if (IsWeak(field, options_)) { |
|
|
|
|
num_weak_fields_++; |
|
|
|
|
} else if (!field->containing_oneof()) { |
|
|
|
|
} else if (!InRealOneof(field)) { |
|
|
|
|
optimized_order_.push_back(field); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -677,7 +677,7 @@ void MessageGenerator::AddGenerators( |
|
|
|
|
void MessageGenerator::GenerateFieldAccessorDeclarations(io::Printer* printer) { |
|
|
|
|
Formatter format(printer, variables_); |
|
|
|
|
// optimized_fields_ does not contain fields where
|
|
|
|
|
// field->containing_oneof() != NULL
|
|
|
|
|
// InRealOneof(field) == true
|
|
|
|
|
// so we need to iterate over those as well.
|
|
|
|
|
//
|
|
|
|
|
// We place the non-oneof fields in optimized_order_, as that controls the
|
|
|
|
@ -689,7 +689,7 @@ void MessageGenerator::GenerateFieldAccessorDeclarations(io::Printer* printer) { |
|
|
|
|
ordered_fields.insert(ordered_fields.begin(), optimized_order_.begin(), |
|
|
|
|
optimized_order_.end()); |
|
|
|
|
for (auto field : FieldRange(descriptor_)) { |
|
|
|
|
if (field->containing_oneof() == nullptr && !field->options().weak() && |
|
|
|
|
if (!InRealOneof(field) && !field->options().weak() && |
|
|
|
|
IsFieldUsed(field, options_)) { |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
@ -922,7 +922,7 @@ void MessageGenerator::GenerateFieldClear(const FieldDescriptor* field, |
|
|
|
|
|
|
|
|
|
format.Indent(); |
|
|
|
|
|
|
|
|
|
if (field->containing_oneof()) { |
|
|
|
|
if (InRealOneof(field)) { |
|
|
|
|
// Clear this field only if it is the active field in this oneof,
|
|
|
|
|
// otherwise ignore
|
|
|
|
|
format("if (_internal_has_$name$()) {\n"); |
|
|
|
@ -983,7 +983,7 @@ void MessageGenerator::GenerateFieldAccessorDefinitions(io::Printer* printer) { |
|
|
|
|
? ".weak" |
|
|
|
|
: ""); |
|
|
|
|
} |
|
|
|
|
} else if (field->containing_oneof()) { |
|
|
|
|
} else if (InRealOneof(field)) { |
|
|
|
|
format.Set("field_name", UnderscoresToCamelCase(field->name(), true)); |
|
|
|
|
format.Set("oneof_name", field->containing_oneof()->name()); |
|
|
|
|
format.Set("oneof_index", |
|
|
|
@ -1485,7 +1485,7 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { |
|
|
|
|
for (auto field : FieldRange(descriptor_)) { |
|
|
|
|
// set_has_***() generated in all oneofs.
|
|
|
|
|
if (!field->is_repeated() && !field->options().weak() && |
|
|
|
|
field->containing_oneof()) { |
|
|
|
|
InRealOneof(field)) { |
|
|
|
|
format("void set_has_$1$();\n", FieldName(field)); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -1594,11 +1594,12 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Generate _oneof_case_.
|
|
|
|
|
if (descriptor_->oneof_decl_count() > 0) { |
|
|
|
|
int count = RealOneofCount(descriptor_); |
|
|
|
|
if (count > 0) { |
|
|
|
|
format( |
|
|
|
|
"$uint32$ _oneof_case_[$1$];\n" |
|
|
|
|
"\n", |
|
|
|
|
descriptor_->oneof_decl_count()); |
|
|
|
|
count); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (num_weak_fields_) { |
|
|
|
@ -1642,24 +1643,22 @@ void MessageGenerator::GenerateExtraDefaultFields(io::Printer* printer) { |
|
|
|
|
// Generate oneof default instance and weak field instances for reflection
|
|
|
|
|
// usage.
|
|
|
|
|
Formatter format(printer, variables_); |
|
|
|
|
if (descriptor_->oneof_decl_count() > 0 || num_weak_fields_ > 0) { |
|
|
|
|
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 oneof : OneOfRange(descriptor_)) { |
|
|
|
|
for (auto field : FieldRange(oneof)) { |
|
|
|
|
if (!IsFieldUsed(field, options_)) { |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
for (auto field : FieldRange(descriptor_)) { |
|
|
|
|
if (field->options().weak() && IsFieldUsed(field, options_)) { |
|
|
|
|
format(" const ::$proto_ns$::Message* $1$_;\n", FieldName(field)); |
|
|
|
|
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)); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -1696,7 +1695,7 @@ bool MessageGenerator::GenerateParseTable(io::Printer* printer, size_t offset, |
|
|
|
|
format("PROTOBUF_FIELD_OFFSET($classtype$, _has_bits_),\n"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (descriptor_->oneof_decl_count() > 0) { |
|
|
|
|
if (RealOneofCount(descriptor_) > 0) { |
|
|
|
|
format("PROTOBUF_FIELD_OFFSET($classtype$, _oneof_case_),\n"); |
|
|
|
|
} else { |
|
|
|
|
format("-1, // no _oneof_case_\n"); |
|
|
|
@ -1755,17 +1754,17 @@ uint32 CalcFieldNum(const FieldGenerator& generator, |
|
|
|
|
type = internal::FieldMetadata::kStringPieceType; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if (field->containing_oneof()) { |
|
|
|
|
|
|
|
|
|
if (InRealOneof(field)) { |
|
|
|
|
return internal::FieldMetadata::CalculateType( |
|
|
|
|
type, internal::FieldMetadata::kOneOf); |
|
|
|
|
} |
|
|
|
|
if (field->is_packed()) { |
|
|
|
|
} else if (field->is_packed()) { |
|
|
|
|
return internal::FieldMetadata::CalculateType( |
|
|
|
|
type, internal::FieldMetadata::kPacked); |
|
|
|
|
} else if (field->is_repeated()) { |
|
|
|
|
return internal::FieldMetadata::CalculateType( |
|
|
|
|
type, internal::FieldMetadata::kRepeated); |
|
|
|
|
} else if (HasHasbit(field) || field->containing_oneof() || is_a_map) { |
|
|
|
|
} else if (HasHasbit(field) || InRealOneof(field) || is_a_map) { |
|
|
|
|
return internal::FieldMetadata::CalculateType( |
|
|
|
|
type, internal::FieldMetadata::kPresence); |
|
|
|
|
} else { |
|
|
|
@ -1860,7 +1859,7 @@ int MessageGenerator::GenerateFieldMetadata(io::Printer* printer) { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
std::string classfieldname = FieldName(field); |
|
|
|
|
if (field->containing_oneof()) { |
|
|
|
|
if (InRealOneof(field)) { |
|
|
|
|
classfieldname = field->containing_oneof()->name(); |
|
|
|
|
} |
|
|
|
|
format.Set("field_name", classfieldname); |
|
|
|
@ -1896,7 +1895,7 @@ int MessageGenerator::GenerateFieldMetadata(io::Printer* printer) { |
|
|
|
|
type = internal::FieldMetadata::kSpecial; |
|
|
|
|
ptr = "reinterpret_cast<const void*>(::" + variables_["proto_ns"] + |
|
|
|
|
"::internal::LazyFieldSerializer"; |
|
|
|
|
if (field->containing_oneof()) { |
|
|
|
|
if (InRealOneof(field)) { |
|
|
|
|
ptr += "OneOf"; |
|
|
|
|
} else if (!HasHasbit(field)) { |
|
|
|
|
ptr += "NoPresence"; |
|
|
|
@ -1913,7 +1912,7 @@ int MessageGenerator::GenerateFieldMetadata(io::Printer* printer) { |
|
|
|
|
"reinterpret_cast<const " |
|
|
|
|
"void*>(::$proto_ns$::internal::WeakFieldSerializer)},\n", |
|
|
|
|
tag); |
|
|
|
|
} else if (field->containing_oneof()) { |
|
|
|
|
} else if (InRealOneof(field)) { |
|
|
|
|
format.Set("oneofoffset", |
|
|
|
|
sizeof(uint32) * field->containing_oneof()->index()); |
|
|
|
|
format( |
|
|
|
@ -1973,10 +1972,10 @@ void MessageGenerator::GenerateDefaultInstanceInitializer( |
|
|
|
|
|
|
|
|
|
if (!field->is_repeated() && !IsLazy(field, options_) && |
|
|
|
|
field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE && |
|
|
|
|
(field->containing_oneof() == NULL || |
|
|
|
|
(!InRealOneof(field) || |
|
|
|
|
HasDescriptorMethods(descriptor_->file(), options_))) { |
|
|
|
|
std::string name; |
|
|
|
|
if (field->containing_oneof() || field->options().weak()) { |
|
|
|
|
if (InRealOneof(field) || field->options().weak()) { |
|
|
|
|
name = "_" + classname_ + "_default_instance_."; |
|
|
|
|
} else { |
|
|
|
|
name = |
|
|
|
@ -2008,7 +2007,7 @@ void MessageGenerator::GenerateDefaultInstanceInitializer( |
|
|
|
|
" $1$::internal_default_instance());\n", |
|
|
|
|
FieldMessageTypeName(field, options_)); |
|
|
|
|
} |
|
|
|
|
} else if (field->containing_oneof() && |
|
|
|
|
} else if (InRealOneof(field) && |
|
|
|
|
HasDescriptorMethods(descriptor_->file(), options_)) { |
|
|
|
|
field_generators_.get(field).GenerateConstructorCode(printer); |
|
|
|
|
} |
|
|
|
@ -2083,6 +2082,7 @@ void MessageGenerator::GenerateClassMethods(io::Printer* printer) { |
|
|
|
|
} |
|
|
|
|
if (HasHasbit(field)) { |
|
|
|
|
int has_bit_index = HasBitIndex(field); |
|
|
|
|
GOOGLE_CHECK_NE(has_bit_index, kNoHasbit) << field->full_name(); |
|
|
|
|
format( |
|
|
|
|
"static void set_has_$1$(HasBits* has_bits) {\n" |
|
|
|
|
" (*has_bits)[$2$] |= $3$u;\n" |
|
|
|
@ -2118,7 +2118,7 @@ void MessageGenerator::GenerateClassMethods(io::Printer* printer) { |
|
|
|
|
Formatter::SaveState saver(&format); |
|
|
|
|
std::map<std::string, std::string> vars; |
|
|
|
|
SetCommonFieldVariables(field, &vars, options_); |
|
|
|
|
if (field->containing_oneof()) { |
|
|
|
|
if (InRealOneof(field)) { |
|
|
|
|
SetCommonOneofFieldVariables(field, &vars); |
|
|
|
|
} |
|
|
|
|
format.AddMap(vars); |
|
|
|
@ -2129,7 +2129,7 @@ void MessageGenerator::GenerateClassMethods(io::Printer* printer) { |
|
|
|
|
GenerateStructors(printer); |
|
|
|
|
format("\n"); |
|
|
|
|
|
|
|
|
|
if (descriptor_->oneof_decl_count() > 0) { |
|
|
|
|
if (RealOneofCount(descriptor_) > 0) { |
|
|
|
|
GenerateOneofClear(printer); |
|
|
|
|
format("\n"); |
|
|
|
|
} |
|
|
|
@ -2258,8 +2258,8 @@ size_t MessageGenerator::GenerateParseOffsets(io::Printer* printer) { |
|
|
|
|
|
|
|
|
|
processing_type |= static_cast<unsigned>( |
|
|
|
|
field->is_repeated() ? internal::kRepeatedMask : 0); |
|
|
|
|
processing_type |= static_cast<unsigned>( |
|
|
|
|
field->containing_oneof() ? internal::kOneofMask : 0); |
|
|
|
|
processing_type |= |
|
|
|
|
static_cast<unsigned>(InRealOneof(field) ? internal::kOneofMask : 0); |
|
|
|
|
|
|
|
|
|
if (field->is_map()) { |
|
|
|
|
processing_type = internal::TYPE_MAP; |
|
|
|
@ -2269,7 +2269,7 @@ size_t MessageGenerator::GenerateParseOffsets(io::Printer* printer) { |
|
|
|
|
WireFormat::TagSize(field->number(), field->type()); |
|
|
|
|
|
|
|
|
|
std::map<std::string, std::string> vars; |
|
|
|
|
if (field->containing_oneof() != NULL) { |
|
|
|
|
if (InRealOneof(field)) { |
|
|
|
|
vars["name"] = field->containing_oneof()->name(); |
|
|
|
|
vars["presence"] = StrCat(field->containing_oneof()->index()); |
|
|
|
|
} else { |
|
|
|
@ -2400,7 +2400,7 @@ std::pair<size_t, size_t> MessageGenerator::GenerateOffsets( |
|
|
|
|
} else { |
|
|
|
|
format("~0u, // no _extensions_\n"); |
|
|
|
|
} |
|
|
|
|
if (descriptor_->oneof_decl_count() > 0) { |
|
|
|
|
if (RealOneofCount(descriptor_) > 0) { |
|
|
|
|
format("PROTOBUF_FIELD_OFFSET($classtype$, _oneof_case_[0]),\n"); |
|
|
|
|
} else { |
|
|
|
|
format("~0u, // no _oneof_case_\n"); |
|
|
|
@ -2418,13 +2418,13 @@ std::pair<size_t, size_t> MessageGenerator::GenerateOffsets( |
|
|
|
|
} |
|
|
|
|
const int kNumGenericOffsets = 5; // the number of fixed offsets above
|
|
|
|
|
const size_t offsets = kNumGenericOffsets + descriptor_->field_count() + |
|
|
|
|
descriptor_->oneof_decl_count() - num_stripped; |
|
|
|
|
RealOneofCount(descriptor_) - num_stripped; |
|
|
|
|
size_t entries = offsets; |
|
|
|
|
for (auto field : FieldRange(descriptor_)) { |
|
|
|
|
if (!IsFieldUsed(field, options_)) { |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
if (field->containing_oneof() || field->options().weak()) { |
|
|
|
|
if (InRealOneof(field) || field->options().weak()) { |
|
|
|
|
format("offsetof($classtype$DefaultTypeInternal, $1$_)", |
|
|
|
|
FieldName(field)); |
|
|
|
|
} else { |
|
|
|
@ -2439,9 +2439,12 @@ std::pair<size_t, size_t> MessageGenerator::GenerateOffsets( |
|
|
|
|
format(",\n"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int count = 0; |
|
|
|
|
for (auto oneof : OneOfRange(descriptor_)) { |
|
|
|
|
format("PROTOBUF_FIELD_OFFSET($classtype$, $1$_),\n", oneof->name()); |
|
|
|
|
count++; |
|
|
|
|
} |
|
|
|
|
GOOGLE_CHECK_EQ(count, RealOneofCount(descriptor_)); |
|
|
|
|
|
|
|
|
|
if (IsMapEntryMessage(descriptor_)) { |
|
|
|
|
entries += 2; |
|
|
|
@ -2653,7 +2656,7 @@ void MessageGenerator::GenerateStructors(io::Printer* printer) { |
|
|
|
|
for (auto field : optimized_order_) { |
|
|
|
|
GOOGLE_DCHECK(IsFieldUsed(field, options_)); |
|
|
|
|
bool has_arena_constructor = field->is_repeated(); |
|
|
|
|
if (field->containing_oneof() == NULL && |
|
|
|
|
if (!InRealOneof(field) && |
|
|
|
|
(IsLazy(field, options_) || IsStringPiece(field, options_))) { |
|
|
|
|
has_arena_constructor = true; |
|
|
|
|
} |
|
|
|
@ -3010,8 +3013,8 @@ void MessageGenerator::GenerateClear(io::Printer* printer) { |
|
|
|
|
|
|
|
|
|
void MessageGenerator::GenerateOneofClear(io::Printer* printer) { |
|
|
|
|
// Generated function clears the active field and union case (e.g. foo_case_).
|
|
|
|
|
for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { |
|
|
|
|
auto oneof = descriptor_->oneof_decl(i); |
|
|
|
|
int i = 0; |
|
|
|
|
for (auto oneof : OneOfRange(descriptor_)) { |
|
|
|
|
Formatter format(printer, variables_); |
|
|
|
|
format.Set("oneofname", oneof->name()); |
|
|
|
|
|
|
|
|
@ -3048,6 +3051,7 @@ void MessageGenerator::GenerateOneofClear(io::Printer* printer) { |
|
|
|
|
format( |
|
|
|
|
"}\n" |
|
|
|
|
"\n"); |
|
|
|
|
i++; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -3118,7 +3122,8 @@ void MessageGenerator::GenerateSwap(io::Printer* printer) { |
|
|
|
|
format("swap($1$_, other->$1$_);\n", oneof->name()); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { |
|
|
|
|
int count = RealOneofCount(descriptor_); |
|
|
|
|
for (int i = 0; i < count; i++) { |
|
|
|
|
format("swap(_oneof_case_[$1$], other->_oneof_case_[$1$]);\n", i); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -3567,7 +3572,7 @@ void MessageGenerator::GenerateSerializeWithCachedSizesBody( |
|
|
|
|
if (eager_ || MustFlush(field)) { |
|
|
|
|
Flush(); |
|
|
|
|
} |
|
|
|
|
if (field->containing_oneof() == NULL) { |
|
|
|
|
if (!InRealOneof(field)) { |
|
|
|
|
// TODO(ckennelly): Defer non-oneof fields similarly to oneof fields.
|
|
|
|
|
|
|
|
|
|
if (!field->options().weak() && !field->is_repeated() && !eager_) { |
|
|
|
@ -4009,7 +4014,7 @@ void MessageGenerator::GenerateIsInitialized(io::Printer* printer) { |
|
|
|
|
} else if (field->options().weak()) { |
|
|
|
|
continue; |
|
|
|
|
} else { |
|
|
|
|
GOOGLE_CHECK(!field->containing_oneof()); |
|
|
|
|
GOOGLE_CHECK(!InRealOneof(field)); |
|
|
|
|
format( |
|
|
|
|
"if (_internal_has_$1$()) {\n" |
|
|
|
|
" if (!$1$_->IsInitialized()) return false;\n" |
|
|
|
@ -4049,7 +4054,7 @@ void MessageGenerator::GenerateIsInitialized(io::Printer* printer) { |
|
|
|
|
field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE && |
|
|
|
|
!ShouldIgnoreRequiredFieldCheck(field, options_) && |
|
|
|
|
scc_analyzer_->HasRequiredFields(field->message_type())) { |
|
|
|
|
GOOGLE_CHECK(!(field->options().weak() || !field->containing_oneof())); |
|
|
|
|
GOOGLE_CHECK(!(field->options().weak() || !InRealOneof(field))); |
|
|
|
|
if (field->options().weak()) { |
|
|
|
|
// Just skip.
|
|
|
|
|
} else { |
|
|
|
|