Rename `DynamicCastToGenerated`/`DownCastToGenerated` to

`DynamicCastMessage`/`DownCastMessage`.
The target does not necessarily need to be a generated type. For example, it
also supports `Message` itself. This makes the API friendlier to generic code and less verbose.

Replace all uses of dynamic_cast/down_cast/**ToGenerated with the new names.
Also, remove checks for RTTI in tests where we only need the casts to work. They don't need RTTI anymore.

PiperOrigin-RevId: 638278948
pull/16958/head
Protobuf Team Bot 8 months ago committed by Copybara-Service
parent 01ec3fab1f
commit 18da465815
  1. 3
      python/google/protobuf/pyext/descriptor_database.cc
  2. 2
      src/google/protobuf/arena.h
  3. 2
      src/google/protobuf/arena_align.h
  4. 6
      src/google/protobuf/arena_unittest.cc
  5. 5
      src/google/protobuf/compiler/cpp/service.cc
  6. 14
      src/google/protobuf/compiler/cpp/unittest.inc
  7. 1
      src/google/protobuf/compiler/objectivec/BUILD.bazel
  8. 2
      src/google/protobuf/compiler/objectivec/line_consumer_unittest.cc
  9. 5
      src/google/protobuf/compiler/parser.cc
  10. 2
      src/google/protobuf/descriptor.cc
  11. 3
      src/google/protobuf/extension_set_heavy.cc
  12. 6
      src/google/protobuf/extension_set_unittest.cc
  13. 4
      src/google/protobuf/generated_message_tctable_full.cc
  14. 1
      src/google/protobuf/io/zero_copy_stream_impl_lite.h
  15. 43
      src/google/protobuf/lite_unittest.cc
  16. 30
      src/google/protobuf/map_test.inc
  17. 13
      src/google/protobuf/message.cc
  18. 50
      src/google/protobuf/message.h
  19. 118
      src/google/protobuf/message_lite.h
  20. 49
      src/google/protobuf/message_unittest.inc
  21. 10
      src/google/protobuf/port_def.inc
  22. 1
      src/google/protobuf/port_undef.inc
  23. 11
      src/google/protobuf/reflection_visit_field_info.h
  24. 4
      src/google/protobuf/reflection_visit_fields.h
  25. 12
      src/google/protobuf/repeated_field_reflection_unittest.inc
  26. 14
      src/google/protobuf/repeated_ptr_field.cc
  27. 1
      src/google/protobuf/util/BUILD.bazel
  28. 2
      src/google/protobuf/util/message_differencer.h

@ -17,6 +17,7 @@
#include "google/protobuf/descriptor.pb.h"
#include "absl/log/absl_log.h"
#include "google/protobuf/message.h"
#include "google/protobuf/message_lite.h"
#include "google/protobuf/pyext/message.h"
#include "google/protobuf/pyext/scoped_pyobject_ptr.h"
@ -55,7 +56,7 @@ static bool GetFileDescriptorProto(PyObject* py_descriptor,
message->message->GetDescriptor() == filedescriptor_descriptor) {
// Fast path: Just use the pointer.
FileDescriptorProto* file_proto =
google::protobuf::DownCastToGenerated<FileDescriptorProto>(message->message);
google::protobuf::DownCastMessage<FileDescriptorProto>(message->message);
*output = *file_proto;
return true;
} else {

@ -28,7 +28,7 @@ using type_info = ::type_info;
#endif
#include "absl/base/attributes.h"
#include "google/protobuf/stubs/common.h"
#include "absl/base/macros.h"
#include "absl/log/absl_check.h"
#include "absl/utility/internal/if_constexpr.h"
#include "google/protobuf/arena_align.h"

@ -55,7 +55,7 @@
#include <cstddef>
#include <cstdint>
#include "google/protobuf/stubs/common.h"
#include "absl/base/macros.h"
#include "absl/log/absl_check.h"
#include "absl/numeric/bits.h"

@ -879,7 +879,7 @@ TEST(ArenaTest, ReleaseFromArenaMessageUsingReflectionMakesCopy) {
const Reflection* r = arena_message->GetReflection();
const FieldDescriptor* f = arena_message->GetDescriptor()->FindFieldByName(
"optional_nested_message");
nested_msg = DownCastToGenerated<TestAllTypes::NestedMessage>(
nested_msg = DownCastMessage<TestAllTypes::NestedMessage>(
r->ReleaseMessage(arena_message, f));
}
EXPECT_EQ(42, nested_msg->bb());
@ -1491,7 +1491,7 @@ TEST(ArenaTest, MutableMessageReflection) {
const Descriptor* d = message->GetDescriptor();
const FieldDescriptor* field = d->FindFieldByName("optional_nested_message");
TestAllTypes::NestedMessage* submessage =
DownCastToGenerated<TestAllTypes::NestedMessage>(
DownCastMessage<TestAllTypes::NestedMessage>(
r->MutableMessage(message, field));
TestAllTypes::NestedMessage* submessage_expected =
message->mutable_optional_nested_message();
@ -1501,7 +1501,7 @@ TEST(ArenaTest, MutableMessageReflection) {
const FieldDescriptor* oneof_field =
d->FindFieldByName("oneof_nested_message");
submessage = DownCastToGenerated<TestAllTypes::NestedMessage>(
submessage = DownCastMessage<TestAllTypes::NestedMessage>(
r->MutableMessage(message, oneof_field));
submessage_expected = message->mutable_oneof_nested_message();

@ -255,9 +255,8 @@ void ServiceGenerator::GenerateCallMethodCases(io::Printer* printer) {
},
R"cc(
case $index$:
$name$(controller,
::$proto_ns$::DownCastToGenerated<$input$>(request),
::$proto_ns$::DownCastToGenerated<$output$>(response), done);
$name$(controller, ::$proto_ns$::DownCastMessage<$input$>(request),
::$proto_ns$::DownCastMessage<$output$>(response), done);
break;
)cc");
}

@ -1310,17 +1310,17 @@ TEST_F(GENERATED_SERVICE_TEST_NAME, CallMethod) {
TEST_F(GENERATED_SERVICE_TEST_NAME, CallMethodTypeFailure) {
// Verify death if we call Foo() with Bar's message types.
#if PROTOBUF_RTTI && GTEST_HAS_DEATH_TEST // death tests do not work on Windows yet
#if GTEST_HAS_DEATH_TEST // death tests do not work on Windows yet
EXPECT_DEBUG_DEATH(
mock_service_.CallMethod(foo_, &mock_controller_,
&foo_request_, &bar_response_, done_.get()),
"DynamicCastToGenerated");
mock_service_.CallMethod(foo_, &mock_controller_, &foo_request_,
&bar_response_, done_.get()),
"DynamicCastMessage");
mock_service_.Reset();
EXPECT_DEBUG_DEATH(
mock_service_.CallMethod(foo_, &mock_controller_,
&bar_request_, &foo_response_, done_.get()),
"DynamicCastToGenerated");
mock_service_.CallMethod(foo_, &mock_controller_, &bar_request_,
&foo_response_, done_.get()),
"DynamicCastMessage");
#endif // GTEST_HAS_DEATH_TEST
}

@ -125,6 +125,7 @@ cc_test(
":line_consumer",
"//src/google/protobuf/io",
"//src/google/protobuf/stubs",
"@com_google_absl//absl/base:core_headers",
"@com_google_absl//absl/strings",
"@com_google_googletest//:gtest",
"@com_google_googletest//:gtest_main",

@ -13,7 +13,7 @@
#include <vector>
#include <gtest/gtest.h>
#include "google/protobuf/stubs/common.h"
#include "absl/base/macros.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "google/protobuf/io/zero_copy_stream_impl_lite.h"

@ -1565,9 +1565,8 @@ bool Parser::ParseOption(Message* options,
}
UninterpretedOption* uninterpreted_option =
DownCastToGenerated<UninterpretedOption>(
options->GetReflection()->AddMessage(options,
uninterpreted_option_field));
DownCastMessage<UninterpretedOption>(options->GetReflection()->AddMessage(
options, uninterpreted_option_field));
// Parse dot-separated name.
{

@ -8584,7 +8584,7 @@ bool DescriptorBuilder::OptionInterpreter::InterpretOptionsImpl(
*original_options, original_uninterpreted_options_field);
for (int i = 0; i < num_uninterpreted_options; ++i) {
src_path.push_back(i);
uninterpreted_option_ = DownCastToGenerated<UninterpretedOption>(
uninterpreted_option_ = DownCastMessage<UninterpretedOption>(
&original_options->GetReflection()->GetRepeatedMessage(
*original_options, original_uninterpreted_options_field, i));
if (!InterpretSingleOption(options, src_path,

@ -406,7 +406,8 @@ size_t ExtensionSet::Extension::SpaceUsedExcludingSelfLong() const {
if (is_lazy) {
total_size += lazymessage_value->SpaceUsedLong();
} else {
total_size += DownCastToMessage(message_value)->SpaceUsedLong();
total_size +=
DownCastMessage<Message>(message_value)->SpaceUsedLong();
}
break;
default:

@ -1323,11 +1323,7 @@ TEST(ExtensionSetTest, DynamicExtensions) {
const Message& sub_message =
message.GetReflection()->GetMessage(message, message_extension);
const unittest::ForeignMessage* typed_sub_message =
#if PROTOBUF_RTTI
dynamic_cast<const unittest::ForeignMessage*>(&sub_message);
#else
static_cast<const unittest::ForeignMessage*>(&sub_message);
#endif
google::protobuf::DynamicCastMessage<unittest::ForeignMessage>(&sub_message);
ASSERT_TRUE(typed_sub_message != nullptr);
EXPECT_EQ(456, typed_sub_message->c());
}

@ -63,7 +63,7 @@ const char* TcParser::ReflectionFallback(PROTOBUF_TC_PARAM_DECL) {
return ptr;
}
auto* full_msg = DownCastToMessage(msg);
auto* full_msg = DownCastMessage<Message>(msg);
auto* descriptor = full_msg->GetDescriptor();
auto* reflection = full_msg->GetReflection();
int field_number = WireFormatLite::GetTagFieldNumber(tag);
@ -87,7 +87,7 @@ const char* TcParser::ReflectionParseLoop(PROTOBUF_TC_PARAM_DECL) {
(void)table;
(void)hasbits;
// Call into the wire format reflective parse loop.
return WireFormat::_InternalParse(DownCastToMessage(msg), ptr, ctx);
return WireFormat::_InternalParse(DownCastMessage<Message>(msg), ptr, ctx);
}
const char* TcParser::MessageSetWireFormatParseLoop(

@ -29,6 +29,7 @@
#include "google/protobuf/stubs/callback.h"
#include "google/protobuf/stubs/common.h"
#include "absl/base/attributes.h"
#include "absl/base/macros.h"
#include "absl/strings/cord.h"
#include "absl/strings/cord_buffer.h"
#include "google/protobuf/io/zero_copy_stream.h"

@ -1330,83 +1330,80 @@ TEST(LiteBasicTest, CodedInputStreamRollback) {
using CastType1 = protobuf_unittest::TestAllTypesLite;
using CastType2 = protobuf_unittest::TestPackedTypesLite;
TEST(LiteTest, DynamicCastToGenerated) {
TEST(LiteTest, DynamicCastMessage) {
CastType1 test_type_1;
MessageLite* test_type_1_pointer = &test_type_1;
EXPECT_EQ(&test_type_1,
DynamicCastToGenerated<CastType1>(test_type_1_pointer));
EXPECT_EQ(nullptr, DynamicCastToGenerated<CastType2>(test_type_1_pointer));
EXPECT_EQ(&test_type_1, DynamicCastMessage<CastType1>(test_type_1_pointer));
EXPECT_EQ(nullptr, DynamicCastMessage<CastType2>(test_type_1_pointer));
const MessageLite* test_type_1_pointer_const = &test_type_1;
EXPECT_EQ(&test_type_1,
DynamicCastToGenerated<const CastType1>(test_type_1_pointer_const));
DynamicCastMessage<const CastType1>(test_type_1_pointer_const));
EXPECT_EQ(nullptr,
DynamicCastToGenerated<const CastType2>(test_type_1_pointer_const));
DynamicCastMessage<const CastType2>(test_type_1_pointer_const));
MessageLite* test_type_1_pointer_nullptr = nullptr;
EXPECT_EQ(nullptr,
DynamicCastToGenerated<CastType1>(test_type_1_pointer_nullptr));
DynamicCastMessage<CastType1>(test_type_1_pointer_nullptr));
MessageLite& test_type_1_pointer_ref = test_type_1;
EXPECT_EQ(&test_type_1,
&DynamicCastToGenerated<CastType1>(test_type_1_pointer_ref));
&DynamicCastMessage<CastType1>(test_type_1_pointer_ref));
const MessageLite& test_type_1_pointer_const_ref = test_type_1;
EXPECT_EQ(&test_type_1,
&DynamicCastToGenerated<CastType1>(test_type_1_pointer_const_ref));
&DynamicCastMessage<CastType1>(test_type_1_pointer_const_ref));
}
#if GTEST_HAS_DEATH_TEST
TEST(LiteTest, DynamicCastToGeneratedInvalidReferenceType) {
TEST(LiteTest, DynamicCastMessageInvalidReferenceType) {
CastType1 test_type_1;
const MessageLite& test_type_1_pointer_const_ref = test_type_1;
ASSERT_DEATH(DynamicCastToGenerated<CastType2>(test_type_1_pointer_const_ref),
ASSERT_DEATH(DynamicCastMessage<CastType2>(test_type_1_pointer_const_ref),
"Cannot downcast " + test_type_1.GetTypeName() + " to " +
CastType2::default_instance().GetTypeName());
}
#endif // GTEST_HAS_DEATH_TEST
TEST(LiteTest, DownCastToGeneratedValidType) {
TEST(LiteTest, DownCastMessageValidType) {
CastType1 test_type_1;
MessageLite* test_type_1_pointer = &test_type_1;
EXPECT_EQ(&test_type_1, DownCastToGenerated<CastType1>(test_type_1_pointer));
EXPECT_EQ(&test_type_1, DownCastMessage<CastType1>(test_type_1_pointer));
const MessageLite* test_type_1_pointer_const = &test_type_1;
EXPECT_EQ(&test_type_1,
DownCastToGenerated<const CastType1>(test_type_1_pointer_const));
DownCastMessage<const CastType1>(test_type_1_pointer_const));
MessageLite* test_type_1_pointer_nullptr = nullptr;
EXPECT_EQ(nullptr,
DownCastToGenerated<CastType1>(test_type_1_pointer_nullptr));
EXPECT_EQ(nullptr, DownCastMessage<CastType1>(test_type_1_pointer_nullptr));
MessageLite& test_type_1_pointer_ref = test_type_1;
EXPECT_EQ(&test_type_1,
&DownCastToGenerated<CastType1>(test_type_1_pointer_ref));
EXPECT_EQ(&test_type_1, &DownCastMessage<CastType1>(test_type_1_pointer_ref));
const MessageLite& test_type_1_pointer_const_ref = test_type_1;
EXPECT_EQ(&test_type_1,
&DownCastToGenerated<CastType1>(test_type_1_pointer_const_ref));
&DownCastMessage<CastType1>(test_type_1_pointer_const_ref));
}
#if GTEST_HAS_DEATH_TEST
TEST(LiteTest, DownCastToGeneratedInvalidPointerType) {
TEST(LiteTest, DownCastMessageInvalidPointerType) {
CastType1 test_type_1;
MessageLite* test_type_1_pointer = &test_type_1;
ASSERT_DEBUG_DEATH(DownCastToGenerated<CastType2>(test_type_1_pointer),
ASSERT_DEBUG_DEATH(DownCastMessage<CastType2>(test_type_1_pointer),
"Cannot downcast " + test_type_1.GetTypeName() + " to " +
CastType2::default_instance().GetTypeName());
}
TEST(LiteTest, DownCastToGeneratedInvalidReferenceType) {
TEST(LiteTest, DownCastMessageInvalidReferenceType) {
CastType1 test_type_1;
MessageLite& test_type_1_pointer = test_type_1;
ASSERT_DEBUG_DEATH(DownCastToGenerated<CastType2>(test_type_1_pointer),
ASSERT_DEBUG_DEATH(DownCastMessage<CastType2>(test_type_1_pointer),
"Cannot downcast " + test_type_1.GetTypeName() + " to " +
CastType2::default_instance().GetTypeName());
}

@ -1578,7 +1578,7 @@ TEST_F(MapFieldReflectionTest, RegularFields) {
message_int32_message.GetReflection()->GetInt32(
message_int32_message, fd_map_int32_foreign_message_key);
const ForeignMessage& value_int32_message =
DownCastToGenerated<ForeignMessage>(
DownCastMessage<ForeignMessage>(
message_int32_message.GetReflection()->GetMessage(
message_int32_message, fd_map_int32_foreign_message_value));
EXPECT_EQ(value_int32_message.c(), Func(key_int32_message, 6));
@ -1615,7 +1615,7 @@ TEST_F(MapFieldReflectionTest, RegularFields) {
message_int32_message.GetReflection()->GetInt32(
message_int32_message, fd_map_int32_foreign_message_key);
const ForeignMessage& value_int32_message =
DownCastToGenerated<ForeignMessage>(
DownCastMessage<ForeignMessage>(
message_int32_message.GetReflection()->GetMessage(
message_int32_message, fd_map_int32_foreign_message_value));
EXPECT_EQ(value_int32_message.c(), Func(key_int32_message, 6));
@ -1652,7 +1652,7 @@ TEST_F(MapFieldReflectionTest, RegularFields) {
int32_t key_int32_message =
message_int32_message->GetReflection()->GetInt32(
*message_int32_message, fd_map_int32_foreign_message_key);
ForeignMessage* value_int32_message = DownCastToGenerated<ForeignMessage>(
ForeignMessage* value_int32_message = DownCastMessage<ForeignMessage>(
message_int32_message->GetReflection()->MutableMessage(
message_int32_message, fd_map_int32_foreign_message_value));
value_int32_message->set_c(Func(key_int32_message, -6));
@ -1808,7 +1808,7 @@ TEST_F(MapFieldReflectionTest, RepeatedFieldRefForRegularFields) {
message_int32_message.GetReflection()->GetInt32(
message_int32_message, fd_map_int32_foreign_message_key);
const ForeignMessage& value_int32_message =
DownCastToGenerated<ForeignMessage>(
DownCastMessage<ForeignMessage>(
message_int32_message.GetReflection()->GetMessage(
message_int32_message, fd_map_int32_foreign_message_value));
EXPECT_EQ(value_int32_message.c(), Func(key_int32_message, 6));
@ -1849,7 +1849,7 @@ TEST_F(MapFieldReflectionTest, RepeatedFieldRefForRegularFields) {
message_int32_message.GetReflection()->GetInt32(
message_int32_message, fd_map_int32_foreign_message_key);
const ForeignMessage& value_int32_message =
DownCastToGenerated<ForeignMessage>(
DownCastMessage<ForeignMessage>(
message_int32_message.GetReflection()->GetMessage(
message_int32_message, fd_map_int32_foreign_message_value));
EXPECT_EQ(value_int32_message.c(), Func(key_int32_message, 6));
@ -1966,8 +1966,8 @@ TEST_F(MapFieldReflectionTest, RepeatedFieldRefForRegularFields) {
const Message& message = *it;
int32_t key = message.GetReflection()->GetInt32(
message, fd_map_int32_foreign_message_key);
const ForeignMessage& sub_message = DownCastToGenerated<ForeignMessage>(
message.GetReflection()->GetMessage(
const ForeignMessage& sub_message =
DownCastMessage<ForeignMessage>(message.GetReflection()->GetMessage(
message, fd_map_int32_foreign_message_value));
result[key].MergeFrom(sub_message);
++index;
@ -2120,14 +2120,14 @@ TEST_F(MapFieldReflectionTest, RepeatedFieldRefForRegularFields) {
{
const Message& message0a =
mmf_int32_foreign_message.Get(0, entry_int32_foreign_message.get());
const ForeignMessage& sub_message0a = DownCastToGenerated<ForeignMessage>(
message0a.GetReflection()->GetMessage(
const ForeignMessage& sub_message0a =
DownCastMessage<ForeignMessage>(message0a.GetReflection()->GetMessage(
message0a, fd_map_int32_foreign_message_value));
int32_t int32_value0a = sub_message0a.c();
const Message& message9a =
mmf_int32_foreign_message.Get(9, entry_int32_foreign_message.get());
const ForeignMessage& sub_message9a = DownCastToGenerated<ForeignMessage>(
message9a.GetReflection()->GetMessage(
const ForeignMessage& sub_message9a =
DownCastMessage<ForeignMessage>(message9a.GetReflection()->GetMessage(
message9a, fd_map_int32_foreign_message_value));
int32_t int32_value9a = sub_message9a.c();
@ -2135,14 +2135,14 @@ TEST_F(MapFieldReflectionTest, RepeatedFieldRefForRegularFields) {
const Message& message0b =
mmf_int32_foreign_message.Get(0, entry_int32_foreign_message.get());
const ForeignMessage& sub_message0b = DownCastToGenerated<ForeignMessage>(
message0b.GetReflection()->GetMessage(
const ForeignMessage& sub_message0b =
DownCastMessage<ForeignMessage>(message0b.GetReflection()->GetMessage(
message0b, fd_map_int32_foreign_message_value));
int32_t int32_value0b = sub_message0b.c();
const Message& message9b =
mmf_int32_foreign_message.Get(9, entry_int32_foreign_message.get());
const ForeignMessage& sub_message9b = DownCastToGenerated<ForeignMessage>(
message9b.GetReflection()->GetMessage(
const ForeignMessage& sub_message9b =
DownCastMessage<ForeignMessage>(message9b.GetReflection()->GetMessage(
message9b, fd_map_int32_foreign_message_value));
int32_t int32_value9b = sub_message9b.c();

@ -67,7 +67,8 @@ using internal::ReflectionOps;
using internal::WireFormat;
void Message::MergeImpl(MessageLite& to, const MessageLite& from) {
ReflectionOps::Merge(DownCastToMessage(from), DownCastToMessage(&to));
ReflectionOps::Merge(DownCastMessage<Message>(from),
DownCastMessage<Message>(&to));
}
void Message::MergeFrom(const Message& from) {
@ -108,7 +109,7 @@ void Message::CopyFrom(const Message& from) {
void Message::Clear() { ReflectionOps::Clear(this); }
bool Message::IsInitializedImpl(const MessageLite& msg) {
return ReflectionOps::IsInitialized(DownCastToMessage(msg));
return ReflectionOps::IsInitialized(DownCastMessage<Message>(msg));
}
void Message::FindInitializationErrors(std::vector<std::string>* errors) const {
@ -184,20 +185,20 @@ size_t Message::SpaceUsedLong() const {
}
static std::string GetTypeNameImpl(const MessageLite& msg) {
return DownCastToMessage(msg).GetDescriptor()->full_name();
return DownCastMessage<Message>(msg).GetDescriptor()->full_name();
}
static std::string InitializationErrorStringImpl(const MessageLite& msg) {
return DownCastToMessage(msg).InitializationErrorString();
return DownCastMessage<Message>(msg).InitializationErrorString();
}
const internal::TcParseTableBase* Message::GetTcParseTableImpl(
const MessageLite& msg) {
return DownCastToMessage(msg).GetReflection()->GetTcParseTable();
return DownCastMessage<Message>(msg).GetReflection()->GetTcParseTable();
}
size_t Message::SpaceUsedLongImpl(const MessageLite& msg_lite) {
auto& msg = DownCastToMessage(msg_lite);
auto& msg = DownCastMessage<Message>(msg_lite);
return msg.GetReflection()->SpaceUsedLong(msg);
}

@ -96,7 +96,7 @@
#include "absl/base/attributes.h"
#include "absl/base/call_once.h"
#include "google/protobuf/stubs/common.h"
#include "absl/base/macros.h"
#include "absl/log/absl_check.h"
#include "absl/memory/memory.h"
#include "absl/strings/cord.h"
@ -1448,45 +1448,19 @@ void LinkMessageReflection() {
internal::StrongReferenceToType<T>();
}
// Tries to downcast this message from MessageLite to Message. Returns nullptr
// if this class is not an instance of Message. eg if the message was defined
// with optimized_for=LITE_RUNTIME. This works even if RTTI is disabled.
inline const Message* DynamicCastToMessage(const MessageLite* lite) {
return lite == nullptr || internal::GetClassData(*lite)->is_lite
// Specializations to handle cast to `Message`. We can check the `is_lite` bit
// in the class data.
template <>
inline const Message* DynamicCastMessage(const MessageLite* from) {
return from == nullptr || internal::GetClassData(*from)->is_lite
? nullptr
: static_cast<const Message*>(lite);
}
inline Message* DynamicCastToMessage(MessageLite* lite) {
return const_cast<Message*>(
DynamicCastToMessage(static_cast<const MessageLite*>(lite)));
}
inline const Message& DynamicCastToMessage(const MessageLite& lite) {
auto* res = DynamicCastToMessage(&lite);
ABSL_CHECK(res != nullptr)
<< "Cannot to `Message` type " << lite.GetTypeName();
return *res;
: static_cast<const Message*>(from);
}
inline Message& DynamicCastToMessage(MessageLite& lite) {
return const_cast<Message&>(
DynamicCastToMessage(static_cast<const MessageLite&>(lite)));
}
// A lightweight function for downcasting a MessageLite to Message. It should
// only be used when the caller is certain that the argument is a Message
// object.
inline const Message* DownCastToMessage(const MessageLite* lite) {
ABSL_CHECK(lite == nullptr || DynamicCastToMessage(lite) != nullptr);
return static_cast<const Message*>(lite);
}
inline Message* DownCastToMessage(MessageLite* lite) {
return const_cast<Message*>(
DownCastToMessage(static_cast<const MessageLite*>(lite)));
}
inline const Message& DownCastToMessage(const MessageLite& lite) {
return *DownCastToMessage(&lite);
}
inline Message& DownCastToMessage(MessageLite& lite) {
return *DownCastToMessage(&lite);
template <>
inline const Message* DownCastMessage(const MessageLite* from) {
ABSL_DCHECK(DynamicCastMessage<Message>(from) == from)
<< "Cannot downcast " << from->GetTypeName() << " to Message";
return static_cast<const Message*>(from);
}
// =============================================================================

@ -727,7 +727,7 @@ class PROTOBUF_EXPORT MessageLite {
namespace internal {
// A typeinfo equivalent for protobuf message types. Used for
// DynamicCastToGenerated.
// DynamicCastMessage.
// We might make this class public later on to have an alternative to
// `std::type_info` that works when RTTI is disabled.
class TypeId {
@ -862,18 +862,26 @@ inline void AssertDownCast(const MessageLite& from, const MessageLite& to) {
std::string ShortFormat(const MessageLite& message_lite);
std::string Utf8Format(const MessageLite& message_lite);
// Tries to downcast this message to a generated message type. Returns nullptr
// if this class is not an instance of T. This works even if RTTI is disabled.
// Cast functions for message pointer/references.
// This is the supported API to cast from a Message/MessageLite to derived
// types. These work even when RTTI is disabled on message types.
//
// This also has the effect of creating a strong reference to T that will
// prevent the linker from stripping it out at link time. This can be important
// if you are using a DynamicMessageFactory that delegates to the generated
// factory.
// The template parameter is simplified and the return type is inferred from the
// input. Eg just `DynamicCastMessage<Foo>(x)` instead of
// `DynamicCastMessage<const Foo*>(x)`.
//
// `DynamicCastMessage` is similar to `dynamic_cast`, returns `nullptr` when the
// input is not an instance of `T`. The overloads that take a reference will
// terminate on mismatch.
//
// `DownCastMessage` is a lightweight function for downcasting base
// `MessageLite` pointer to derived type, where it only does type checking if
// !NDEBUG. It should only be used when the caller is certain that the input
// message is of instance `T`.
template <typename T>
const T* DynamicCastToGenerated(const MessageLite* from) {
const T* DynamicCastMessage(const MessageLite* from) {
static_assert(std::is_base_of<MessageLite, T>::value, "");
internal::StrongReferenceToType<T>();
// We might avoid the call to T::GetClassData() altogether if T were to
// expose the class data pointer.
if (from == nullptr ||
@ -885,20 +893,14 @@ const T* DynamicCastToGenerated(const MessageLite* from) {
}
template <typename T>
const T* DynamicCastToGenerated(const MessageLite* from);
template <typename T>
T* DynamicCastToGenerated(MessageLite* from) {
T* DynamicCastMessage(MessageLite* from) {
return const_cast<T*>(
DynamicCastToGenerated<T>(static_cast<const MessageLite*>(from)));
DynamicCastMessage<T>(static_cast<const MessageLite*>(from)));
}
// An overloaded version of DynamicCastToGenerated for downcasting references to
// base Message class. If the argument is not an instance of T, it terminates
// with an error.
template <typename T>
const T& DynamicCastToGenerated(const MessageLite& from) {
const T* destination_message = DynamicCastToGenerated<T>(&from);
const T& DynamicCastMessage(const MessageLite& from) {
const T* destination_message = DynamicCastMessage<T>(&from);
ABSL_CHECK(destination_message != nullptr)
<< "Cannot downcast " << from.GetTypeName() << " to "
<< T::default_instance().GetTypeName();
@ -906,37 +908,93 @@ const T& DynamicCastToGenerated(const MessageLite& from) {
}
template <typename T>
T& DynamicCastToGenerated(MessageLite& from) {
T& DynamicCastMessage(MessageLite& from) {
return const_cast<T&>(
DynamicCastToGenerated<T>(static_cast<const MessageLite&>(from)));
DynamicCastMessage<T>(static_cast<const MessageLite&>(from)));
}
// A lightweight function for downcasting base MessageLite pointer to derived
// type. It should only be used when the caller is certain that the argument is
// of instance T and T is a generated message type.
template <typename T>
const T* DownCastToGenerated(const MessageLite* from) {
const T* DownCastMessage(const MessageLite* from) {
internal::StrongReferenceToType<T>();
ABSL_DCHECK(DynamicCastToGenerated<T>(from) == from)
ABSL_DCHECK(DynamicCastMessage<T>(from) == from)
<< "Cannot downcast " << from->GetTypeName() << " to "
<< T::default_instance().GetTypeName();
return static_cast<const T*>(from);
}
template <typename T>
T* DownCastToGenerated(MessageLite* from) {
T* DownCastMessage(MessageLite* from) {
return const_cast<T*>(
DownCastToGenerated<T>(static_cast<const MessageLite*>(from)));
DownCastMessage<T>(static_cast<const MessageLite*>(from)));
}
template <typename T>
const T& DownCastMessage(const MessageLite& from) {
return *DownCastMessage<T>(&from);
}
template <typename T>
T& DownCastMessage(MessageLite& from) {
return *DownCastMessage<T>(&from);
}
template <>
inline const MessageLite* DynamicCastMessage(const MessageLite* from) {
return from;
}
template <>
inline const MessageLite* DownCastMessage(const MessageLite* from) {
return from;
}
// Deprecated names for the cast functions.
// Prefer the ones above.
template <typename T>
PROTOBUF_DEPRECATE_AND_INLINE()
const T* DynamicCastToGenerated(const MessageLite* from) {
return DynamicCastMessage<T>(from);
}
template <typename T>
PROTOBUF_DEPRECATE_AND_INLINE()
T* DynamicCastToGenerated(MessageLite* from) {
return DynamicCastMessage<T>(from);
}
template <typename T>
PROTOBUF_DEPRECATE_AND_INLINE()
const T& DynamicCastToGenerated(const MessageLite& from) {
return DynamicCastMessage<T>(from);
}
template <typename T>
PROTOBUF_DEPRECATE_AND_INLINE()
T& DynamicCastToGenerated(MessageLite& from) {
return DynamicCastMessage<T>(from);
}
template <typename T>
PROTOBUF_DEPRECATE_AND_INLINE()
const T* DownCastToGenerated(const MessageLite* from) {
return DownCastMessage<T>(from);
}
template <typename T>
PROTOBUF_DEPRECATE_AND_INLINE()
T* DownCastToGenerated(MessageLite* from) {
return DownCastMessage<T>(from);
}
template <typename T>
PROTOBUF_DEPRECATE_AND_INLINE()
const T& DownCastToGenerated(const MessageLite& from) {
return *DownCastToGenerated<T>(&from);
return DownCastMessage<T>(from);
}
template <typename T>
PROTOBUF_DEPRECATE_AND_INLINE()
T& DownCastToGenerated(MessageLite& from) {
return *DownCastToGenerated<T>(&from);
return DownCastMessage<T>(from);
}
} // namespace protobuf

@ -750,86 +750,85 @@ TEST(MESSAGE_TEST_NAME, InitializationErrorString) {
EXPECT_EQ("a, b, c", message.InitializationErrorString());
}
TEST(MESSAGE_TEST_NAME, DynamicCastToGenerated) {
TEST(MESSAGE_TEST_NAME, DynamicCastMessage) {
UNITTEST::TestAllTypes test_all_types;
MessageLite* test_all_types_pointer = &test_all_types;
EXPECT_EQ(&test_all_types, DynamicCastToGenerated<UNITTEST::TestAllTypes>(
test_all_types_pointer));
EXPECT_EQ(nullptr, DynamicCastToGenerated<UNITTEST::TestRequired>(
test_all_types_pointer));
EXPECT_EQ(&test_all_types,
DynamicCastMessage<UNITTEST::TestAllTypes>(test_all_types_pointer));
EXPECT_EQ(nullptr,
DynamicCastMessage<UNITTEST::TestRequired>(test_all_types_pointer));
const MessageLite* test_all_types_pointer_const = &test_all_types;
EXPECT_EQ(&test_all_types,
DynamicCastToGenerated<const UNITTEST::TestAllTypes>(
test_all_types_pointer_const));
EXPECT_EQ(nullptr, DynamicCastToGenerated<const UNITTEST::TestRequired>(
EXPECT_EQ(&test_all_types, DynamicCastMessage<const UNITTEST::TestAllTypes>(
test_all_types_pointer_const));
EXPECT_EQ(nullptr, DynamicCastMessage<const UNITTEST::TestRequired>(
test_all_types_pointer_const));
MessageLite* test_all_types_pointer_nullptr = nullptr;
EXPECT_EQ(nullptr, DynamicCastToGenerated<UNITTEST::TestAllTypes>(
EXPECT_EQ(nullptr, DynamicCastMessage<UNITTEST::TestAllTypes>(
test_all_types_pointer_nullptr));
MessageLite& test_all_types_pointer_ref = test_all_types;
EXPECT_EQ(&test_all_types, &DynamicCastToGenerated<UNITTEST::TestAllTypes>(
EXPECT_EQ(&test_all_types, &DynamicCastMessage<UNITTEST::TestAllTypes>(
test_all_types_pointer_ref));
const MessageLite& test_all_types_pointer_const_ref = test_all_types;
EXPECT_EQ(&test_all_types, &DynamicCastToGenerated<UNITTEST::TestAllTypes>(
EXPECT_EQ(&test_all_types, &DynamicCastMessage<UNITTEST::TestAllTypes>(
test_all_types_pointer_const_ref));
}
TEST(MESSAGE_TEST_NAME, DynamicCastToGeneratedInvalidReferenceType) {
TEST(MESSAGE_TEST_NAME, DynamicCastMessageInvalidReferenceType) {
UNITTEST::TestAllTypes test_all_types;
const MessageLite& test_all_types_pointer_const_ref = test_all_types;
ASSERT_DEATH(DynamicCastToGenerated<UNITTEST::TestRequired>(
ASSERT_DEATH(DynamicCastMessage<UNITTEST::TestRequired>(
test_all_types_pointer_const_ref),
"Cannot downcast " + test_all_types.GetTypeName() + " to " +
UNITTEST::TestRequired::default_instance().GetTypeName());
}
TEST(MESSAGE_TEST_NAME, DownCastToGeneratedValidType) {
TEST(MESSAGE_TEST_NAME, DownCastMessageValidType) {
UNITTEST::TestAllTypes test_all_types;
MessageLite* test_all_types_pointer = &test_all_types;
EXPECT_EQ(&test_all_types, DownCastToGenerated<UNITTEST::TestAllTypes>(
test_all_types_pointer));
EXPECT_EQ(&test_all_types,
DownCastMessage<UNITTEST::TestAllTypes>(test_all_types_pointer));
const MessageLite* test_all_types_pointer_const = &test_all_types;
EXPECT_EQ(&test_all_types, DownCastToGenerated<const UNITTEST::TestAllTypes>(
EXPECT_EQ(&test_all_types, DownCastMessage<const UNITTEST::TestAllTypes>(
test_all_types_pointer_const));
MessageLite* test_all_types_pointer_nullptr = nullptr;
EXPECT_EQ(nullptr, DownCastToGenerated<UNITTEST::TestAllTypes>(
EXPECT_EQ(nullptr, DownCastMessage<UNITTEST::TestAllTypes>(
test_all_types_pointer_nullptr));
MessageLite& test_all_types_pointer_ref = test_all_types;
EXPECT_EQ(&test_all_types, &DownCastToGenerated<UNITTEST::TestAllTypes>(
EXPECT_EQ(&test_all_types, &DownCastMessage<UNITTEST::TestAllTypes>(
test_all_types_pointer_ref));
const MessageLite& test_all_types_pointer_const_ref = test_all_types;
EXPECT_EQ(&test_all_types, &DownCastToGenerated<UNITTEST::TestAllTypes>(
EXPECT_EQ(&test_all_types, &DownCastMessage<UNITTEST::TestAllTypes>(
test_all_types_pointer_const_ref));
}
TEST(MESSAGE_TEST_NAME, DownCastToGeneratedInvalidPointerType) {
TEST(MESSAGE_TEST_NAME, DownCastMessageInvalidPointerType) {
UNITTEST::TestAllTypes test_all_types;
MessageLite* test_all_types_pointer = &test_all_types;
ASSERT_DEBUG_DEATH(
DownCastToGenerated<UNITTEST::TestRequired>(test_all_types_pointer),
DownCastMessage<UNITTEST::TestRequired>(test_all_types_pointer),
"Cannot downcast " + test_all_types.GetTypeName() + " to " +
UNITTEST::TestRequired::default_instance().GetTypeName());
}
TEST(MESSAGE_TEST_NAME, DownCastToGeneratedInvalidReferenceType) {
TEST(MESSAGE_TEST_NAME, DownCastMessageInvalidReferenceType) {
UNITTEST::TestAllTypes test_all_types;
MessageLite& test_all_types_pointer = test_all_types;
ASSERT_DEBUG_DEATH(
DownCastToGenerated<UNITTEST::TestRequired>(test_all_types_pointer),
DownCastMessage<UNITTEST::TestRequired>(test_all_types_pointer),
"Cannot downcast " + test_all_types.GetTypeName() + " to " +
UNITTEST::TestRequired::default_instance().GetTypeName());
}

@ -32,6 +32,7 @@
#define PROTOBUF_PORT_
#include "absl/base/attributes.h"
#include "absl/base/config.h"
#include "absl/base/macros.h"
// The definitions in this file are intended to be portable across Clang,
// GCC, and MSVC. Function-like macros are usable without an #ifdef guard.
@ -959,3 +960,12 @@ namespace internal {
#endif // !NDEBUG
#endif // has_builtin(__builtin_assume)
#ifdef PROTOBUF_DEPRECATE_AND_INLINE
#error PROTOBUF_DEPRECATE_AND_INLINE was previously defined
#endif
#if defined(ABSL_DEPRECATE_AND_INLINE)
#define PROTOBUF_DEPRECATE_AND_INLINE() ABSL_DEPRECATE_AND_INLINE()
#else
#define PROTOBUF_DEPRECATE_AND_INLINE() [[deprecated]]
#endif

@ -48,6 +48,7 @@
#undef PROTOBUF_FORCE_ALLOCATION_ON_CONSTRUCTION
#undef PROTOBUF_UNUSED
#undef PROTOBUF_ASSUME
#undef PROTOBUF_DEPRECATE_AND_INLINE
#undef PROTOBUF_EXPORT_TEMPLATE_DECLARE
#undef PROTOBUF_EXPORT_TEMPLATE_DEFINE
#undef PROTOBUF_ALIGNAS

@ -18,6 +18,7 @@
#include "google/protobuf/inlined_string_field.h"
#include "google/protobuf/map_field.h"
#include "google/protobuf/message.h"
#include "google/protobuf/message_lite.h"
#include "google/protobuf/port.h"
#include "google/protobuf/wire_format_lite.h"
@ -200,10 +201,10 @@ struct DynamicExtensionInfoHelper {
}
static const Message& GetMessage(const Extension& ext) {
return DownCastToMessage(*ext.message_value);
return DownCastMessage<Message>(*ext.message_value);
}
static Message& MutableMessage(Extension& ext) {
return DownCastToMessage(*ext.message_value);
return DownCastMessage<Message>(*ext.message_value);
}
static void ClearMessage(Extension& ext) {
ext.is_cleared = true;
@ -212,18 +213,18 @@ struct DynamicExtensionInfoHelper {
static const Message& GetLazyMessage(const Extension& ext,
const Message& prototype, Arena* arena) {
return DownCastToMessage(
return DownCastMessage<Message>(
ext.lazymessage_value->GetMessage(prototype, arena));
}
static const Message& GetLazyMessageIgnoreUnparsed(const Extension& ext,
const Message& prototype,
Arena* arena) {
return DownCastToMessage(
return DownCastMessage<Message>(
ext.lazymessage_value->GetMessageIgnoreUnparsed(prototype, arena));
}
static Message& MutableLazyMessage(Extension& ext, const Message& prototype,
Arena* arena) {
return DownCastToMessage(
return DownCastMessage<Message>(
*ext.lazymessage_value->MutableMessage(prototype, arena));
}
static void ClearLazyMessage(Extension& ext) {

@ -422,7 +422,7 @@ void ReflectionVisit::VisitMessageFields(const Message& message,
FieldDescriptor::CPPTYPE_MESSAGE) {
if constexpr (info.is_repeated) {
for (const auto& it : info.Get()) {
func(DownCastToMessage(it));
func(DownCastMessage<Message>(it));
}
} else {
func(info.Get());
@ -452,7 +452,7 @@ void ReflectionVisit::VisitMessageFields(Message& message, CallbackFn&& func) {
FieldDescriptor::CPPTYPE_MESSAGE) {
if constexpr (info.is_repeated) {
for (auto& it : info.Mutable()) {
func(DownCastToMessage(it));
func(DownCastMessage<Message>(it));
}
} else {
func(info.Mutable());

@ -91,7 +91,7 @@ TEST(REFLECTION_TEST, RegularFields) {
EXPECT_EQ(rf_double.Get(i), Func(i, 2));
EXPECT_EQ(rpf_string.Get(i), StrFunc(i, 5));
EXPECT_EQ(rpf_foreign_message.Get(i).c(), Func(i, 6));
EXPECT_EQ(DownCastToGenerated<ForeignMessage>(&rpf_message.Get(i))->c(),
EXPECT_EQ(DownCastMessage<ForeignMessage>(&rpf_message.Get(i))->c(),
Func(i, 6));
// Check gets through mutable objects.
@ -99,7 +99,7 @@ TEST(REFLECTION_TEST, RegularFields) {
EXPECT_EQ(mrf_double->Get(i), Func(i, 2));
EXPECT_EQ(mrpf_string->Get(i), StrFunc(i, 5));
EXPECT_EQ(mrpf_foreign_message->Get(i).c(), Func(i, 6));
EXPECT_EQ(DownCastToGenerated<ForeignMessage>(&mrpf_message->Get(i))->c(),
EXPECT_EQ(DownCastMessage<ForeignMessage>(&mrpf_message->Get(i))->c(),
Func(i, 6));
// Check sets through mutable objects.
@ -111,7 +111,7 @@ TEST(REFLECTION_TEST, RegularFields) {
EXPECT_EQ(message.repeated_double(i), Func(i, -2));
EXPECT_EQ(message.repeated_string(i), StrFunc(i, -5));
EXPECT_EQ(message.repeated_foreign_message(i).c(), Func(i, -6));
DownCastToGenerated<ForeignMessage>(mrpf_message->Mutable(i))
DownCastMessage<ForeignMessage>(mrpf_message->Mutable(i))
->set_c(Func(i, 7));
EXPECT_EQ(message.repeated_foreign_message(i).c(), Func(i, 7));
}
@ -272,8 +272,7 @@ TEST(REFLECTION_TEST, RepeatedFieldRefForRegularFields) {
ForeignMessage scratch_space;
EXPECT_EQ(rf_foreign_message.Get(i, &scratch_space).c(), Func(i, 6));
EXPECT_EQ(
DownCastToGenerated<ForeignMessage>(rf_message.Get(i, &scratch_space))
.c(),
DownCastMessage<ForeignMessage>(rf_message.Get(i, &scratch_space)).c(),
Func(i, 6));
// Check gets through mutable objects.
@ -282,8 +281,7 @@ TEST(REFLECTION_TEST, RepeatedFieldRefForRegularFields) {
EXPECT_EQ(mrf_string.Get(i), StrFunc(i, 5));
EXPECT_EQ(mrf_foreign_message.Get(i, &scratch_space).c(), Func(i, 6));
EXPECT_EQ(
DownCastToGenerated<ForeignMessage>(mrf_message.Get(i, &scratch_space))
.c(),
DownCastMessage<ForeignMessage>(mrf_message.Get(i, &scratch_space)).c(),
Func(i, 6));
// Check sets through mutable objects.

@ -200,11 +200,8 @@ int RepeatedPtrFieldBase::MergeIntoClearedMessages(
int count = std::min(ClearedCount(), from.current_size_);
for (int i = 0; i < count; ++i) {
ABSL_DCHECK(src[i] != nullptr);
#if PROTOBUF_RTTI
// TODO: remove or replace with a cleaner check.
ABSL_DCHECK(typeid(*src[i]) == typeid(*src[0]))
<< typeid(*src[i]).name() << " vs " << typeid(*src[0]).name();
#endif
ABSL_DCHECK(TypeId::Get(*src[i]) == TypeId::Get(*src[0]))
<< src[i]->GetTypeName() << " vs " << src[0]->GetTypeName();
dst[i]->CheckTypeAndMergeFrom(*src[i]);
}
return count;
@ -251,11 +248,8 @@ void RepeatedPtrFieldBase::MergeFrom<MessageLite>(
Arena* arena = GetArena();
for (; src < end; ++src, ++dst) {
ABSL_DCHECK(*src != nullptr);
#if PROTOBUF_RTTI
// TODO: remove or replace with a cleaner check.
ABSL_DCHECK(typeid(**src) == typeid(*prototype))
<< typeid(**src).name() << " vs " << typeid(*prototype).name();
#endif
ABSL_DCHECK(TypeId::Get(**src) == TypeId::Get(*prototype))
<< (**src).GetTypeName() << " vs " << prototype->GetTypeName();
*dst = prototype->New(arena);
(*dst)->CheckTypeAndMergeFrom(**src);
}

@ -55,6 +55,7 @@ cc_library(
"//src/google/protobuf/io",
"//src/google/protobuf/io:printer",
"//src/google/protobuf/stubs",
"@com_google_absl//absl/base:core_headers",
"@com_google_absl//absl/container:fixed_array",
"@com_google_absl//absl/container:flat_hash_map",
"@com_google_absl//absl/container:flat_hash_set",

@ -25,7 +25,7 @@
#include <string>
#include <vector>
#include "google/protobuf/stubs/common.h"
#include "absl/base/macros.h"
#include "absl/container/fixed_array.h"
#include "absl/container/flat_hash_map.h"
#include "absl/container/flat_hash_set.h"

Loading…
Cancel
Save