diff --git a/src/google/protobuf/compiler/cpp/message.cc b/src/google/protobuf/compiler/cpp/message.cc index de0392e555..3447fe24d6 100644 --- a/src/google/protobuf/compiler/cpp/message.cc +++ b/src/google/protobuf/compiler/cpp/message.cc @@ -4305,71 +4305,96 @@ void MessageGenerator::GenerateByteSize(io::Printer* p) { void MessageGenerator::GenerateIsInitialized(io::Printer* p) { if (HasSimpleBaseClass(descriptor_, options_)) return; - Formatter format(p); - format("PROTOBUF_NOINLINE bool $classname$::IsInitialized() const {\n"); - format.Indent(); - - if (descriptor_->extension_range_count() > 0) { - format( - "if (!$extensions$.IsInitialized(internal_default_instance())) {\n" - " return false;\n" - "}\n\n"); - } - - if (num_required_fields_ > 0) { - format( - "if (_Internal::MissingRequiredFields($has_bits$))" - " return false;\n"); - } - // Now check that all non-oneof embedded messages are initialized. - for (auto field : optimized_order_) { - field_generators_.get(field).GenerateIsInitialized(p); - } - if (num_weak_fields_) { - // For Weak fields. - format("if (!$weak_field_map$.IsInitialized()) return false;\n"); - } - // Go through the oneof fields, emitting a switch if any might have required - // fields. - for (auto oneof : OneOfRange(descriptor_)) { - bool has_required_fields = false; - for (auto field : FieldRange(oneof)) { + auto has_required_field = [&](const auto* oneof) { + for (const auto* field : FieldRange(oneof)) { if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE && !ShouldIgnoreRequiredFieldCheck(field, options_) && scc_analyzer_->HasRequiredFields(field->message_type())) { - has_required_fields = true; - break; + return true; } } + return false; + }; - if (!has_required_fields) { - continue; - } - - format("switch ($1$_case()) {\n", oneof->name()); - format.Indent(); - for (auto field : FieldRange(oneof)) { - format("case k$1$: {\n", UnderscoresToCamelCase(field->name(), true)); - format.Indent(); - field_generators_.get(field).GenerateIsInitialized(p); - format("break;\n"); - format.Outdent(); - format("}\n"); - } - format( - "case $1$_NOT_SET: {\n" - " break;\n" - "}\n", - absl::AsciiStrToUpper(oneof->name())); - format.Outdent(); - format("}\n"); - } - - format.Outdent(); - format( - " return true;\n" - "}\n"); + p->Emit( + { + {"test_extensions", + [&] { + if (descriptor_->extension_range_count() == 0) return; + p->Emit(R"cc( + if (!$extensions$.IsInitialized(internal_default_instance())) { + return false; + } + )cc"); + }}, + {"test_required_fields", + [&] { + if (num_required_fields_ == 0) return; + p->Emit(R"cc( + if (_Internal::MissingRequiredFields($has_bits$)) { + return false; + } + )cc"); + }}, + {"test_ordinary_fields", + [&] { + for (const auto* field : optimized_order_) { + field_generators_.get(field).GenerateIsInitialized(p); + } + }}, + {"test_weak_fields", + [&] { + if (num_weak_fields_ == 0) return; + p->Emit(R"cc( + if (!$weak_field_map$.IsInitialized()) return false; + )cc"); + }}, + {"test_oneof_fields", + [&] { + for (const auto* oneof : OneOfRange(descriptor_)) { + if (!has_required_field(oneof)) continue; + p->Emit({{"name", oneof->name()}, + {"NAME", absl::AsciiStrToUpper(oneof->name())}, + {"cases", + [&] { + for (const auto* field : FieldRange(oneof)) { + p->Emit({{"Name", UnderscoresToCamelCase( + field->name(), true)}, + {"body", + [&] { + field_generators_.get(field) + .GenerateIsInitialized(p); + }}}, + R"cc( + case k$Name$: { + $body$; + break; + } + )cc"); + } + }}}, + R"cc( + switch ($name$_case()) { + $cases$; + case $NAME$_NOT_SET: { + break; + } + } + )cc"); + } + }}, + }, + R"cc( + PROTOBUF_NOINLINE bool $classname$::IsInitialized() const { + $test_extensions$; + $test_required_fields$; + $test_ordinary_fields$; + $test_weak_fields$; + $test_oneof_fields$; + return true; + } + )cc"); } } // namespace cpp diff --git a/src/google/protobuf/descriptor.pb.cc b/src/google/protobuf/descriptor.pb.cc index 847afd8be6..dda90b8a1b 100644 --- a/src/google/protobuf/descriptor.pb.cc +++ b/src/google/protobuf/descriptor.pb.cc @@ -4405,7 +4405,6 @@ PROTOBUF_NOINLINE bool ExtensionRangeOptions::IsInitialized() const { if (!_impl_._extensions_.IsInitialized(internal_default_instance())) { return false; } - if (!::google::protobuf::internal::AllAreInitialized(_internal_uninterpreted_option())) return false; return true; @@ -7761,7 +7760,6 @@ PROTOBUF_NOINLINE bool FileOptions::IsInitialized() const { if (!_impl_._extensions_.IsInitialized(internal_default_instance())) { return false; } - if (!::google::protobuf::internal::AllAreInitialized(_internal_uninterpreted_option())) return false; return true; @@ -8133,7 +8131,6 @@ PROTOBUF_NOINLINE bool MessageOptions::IsInitialized() const { if (!_impl_._extensions_.IsInitialized(internal_default_instance())) { return false; } - if (!::google::protobuf::internal::AllAreInitialized(_internal_uninterpreted_option())) return false; return true; @@ -8664,7 +8661,6 @@ PROTOBUF_NOINLINE bool FieldOptions::IsInitialized() const { if (!_impl_._extensions_.IsInitialized(internal_default_instance())) { return false; } - if (!::google::protobuf::internal::AllAreInitialized(_internal_uninterpreted_option())) return false; return true; @@ -8865,7 +8861,6 @@ PROTOBUF_NOINLINE bool OneofOptions::IsInitialized() const { if (!_impl_._extensions_.IsInitialized(internal_default_instance())) { return false; } - if (!::google::protobuf::internal::AllAreInitialized(_internal_uninterpreted_option())) return false; return true; @@ -9159,7 +9154,6 @@ PROTOBUF_NOINLINE bool EnumOptions::IsInitialized() const { if (!_impl_._extensions_.IsInitialized(internal_default_instance())) { return false; } - if (!::google::protobuf::internal::AllAreInitialized(_internal_uninterpreted_option())) return false; return true; @@ -9396,7 +9390,6 @@ PROTOBUF_NOINLINE bool EnumValueOptions::IsInitialized() const { if (!_impl_._extensions_.IsInitialized(internal_default_instance())) { return false; } - if (!::google::protobuf::internal::AllAreInitialized(_internal_uninterpreted_option())) return false; return true; @@ -9629,7 +9622,6 @@ PROTOBUF_NOINLINE bool ServiceOptions::IsInitialized() const { if (!_impl_._extensions_.IsInitialized(internal_default_instance())) { return false; } - if (!::google::protobuf::internal::AllAreInitialized(_internal_uninterpreted_option())) return false; return true; @@ -9902,7 +9894,6 @@ PROTOBUF_NOINLINE bool MethodOptions::IsInitialized() const { if (!_impl_._extensions_.IsInitialized(internal_default_instance())) { return false; } - if (!::google::protobuf::internal::AllAreInitialized(_internal_uninterpreted_option())) return false; return true; @@ -10163,7 +10154,9 @@ void UninterpretedOption_NamePart::CopyFrom(const UninterpretedOption_NamePart& } PROTOBUF_NOINLINE bool UninterpretedOption_NamePart::IsInitialized() const { - if (_Internal::MissingRequiredFields(_impl_._has_bits_)) return false; + if (_Internal::MissingRequiredFields(_impl_._has_bits_)) { + return false; + } return true; }