diff --git a/src/google/protobuf/BUILD.bazel b/src/google/protobuf/BUILD.bazel index 1177d9e99d1a..5e7f5479c58e 100644 --- a/src/google/protobuf/BUILD.bazel +++ b/src/google/protobuf/BUILD.bazel @@ -897,6 +897,7 @@ cc_library( "map_test_util.inc", "message_unittest.inc", "reflection_tester.h", + "repeated_field_reflection_unittest.inc", "test_util.h", "test_util.inc", "test_util_lite.h", @@ -1377,7 +1378,10 @@ cc_test( cc_test( name = "repeated_field_reflection_unittest", - srcs = ["repeated_field_reflection_unittest.cc"], + srcs = [ + "repeated_field_reflection_unittest.cc", + "repeated_field_reflection_unittest.inc", + ], copts = COPTS + select({ "//build_defs:config_msvc": [], "//conditions:default": [ diff --git a/src/google/protobuf/repeated_field_reflection_unittest.cc b/src/google/protobuf/repeated_field_reflection_unittest.cc index 716df41c6008..d24efa7693f9 100644 --- a/src/google/protobuf/repeated_field_reflection_unittest.cc +++ b/src/google/protobuf/repeated_field_reflection_unittest.cc @@ -10,684 +10,15 @@ // Test reflection methods for aggregate access to Repeated[Ptr]Fields. // This test proto2 methods on a proto2 layout. -#include -#include "absl/base/casts.h" -#include "absl/strings/cord.h" -#include "google/protobuf/dynamic_message.h" -#include "google/protobuf/port.h" -#include "google/protobuf/reflection.h" -#include "google/protobuf/test_util.h" -#include "google/protobuf/unittest.pb.h" - -namespace google { -namespace protobuf { -namespace { - -using internal::DownCast; -using unittest::ForeignMessage; -using unittest::TestAllExtensions; -using unittest::TestAllTypes; - -static int Func(int i, int j) { return i * j; } - -static std::string StrFunc(int i, int j) { return absl::StrCat(Func(i, 4)); } - -TEST(RepeatedFieldReflectionTest, RegularFields) { - TestAllTypes message; - const Reflection* refl = message.GetReflection(); - const Descriptor* desc = message.GetDescriptor(); - - for (int i = 0; i < 10; ++i) { - message.add_repeated_int32(Func(i, 1)); - message.add_repeated_double(Func(i, 2)); - message.add_repeated_string(StrFunc(i, 5)); - message.add_repeated_foreign_message()->set_c(Func(i, 6)); - } - - // Get FieldDescriptors for all the fields of interest. - const FieldDescriptor* fd_repeated_int32 = - desc->FindFieldByName("repeated_int32"); - const FieldDescriptor* fd_repeated_double = - desc->FindFieldByName("repeated_double"); - const FieldDescriptor* fd_repeated_string = - desc->FindFieldByName("repeated_string"); - const FieldDescriptor* fd_repeated_foreign_message = - desc->FindFieldByName("repeated_foreign_message"); - - // Get RepeatedField objects for all fields of interest. - const RepeatedField& rf_int32 = - refl->GetRepeatedField(message, fd_repeated_int32); - const RepeatedField& rf_double = - refl->GetRepeatedField(message, fd_repeated_double); - - // Get mutable RepeatedField objects for all fields of interest. - RepeatedField* mrf_int32 = - refl->MutableRepeatedField(&message, fd_repeated_int32); - RepeatedField* mrf_double = - refl->MutableRepeatedField(&message, fd_repeated_double); - - // Get RepeatedPtrField objects for all fields of interest. - const RepeatedPtrField& rpf_string = - refl->GetRepeatedPtrField(message, fd_repeated_string); - const RepeatedPtrField& rpf_foreign_message = - refl->GetRepeatedPtrField(message, - fd_repeated_foreign_message); - const RepeatedPtrField& rpf_message = - refl->GetRepeatedPtrField(message, fd_repeated_foreign_message); - - // Get mutable RepeatedPtrField objects for all fields of interest. - RepeatedPtrField* mrpf_string = - refl->MutableRepeatedPtrField(&message, fd_repeated_string); - RepeatedPtrField* mrpf_foreign_message = - refl->MutableRepeatedPtrField( - &message, fd_repeated_foreign_message); - RepeatedPtrField* mrpf_message = - refl->MutableRepeatedPtrField(&message, - fd_repeated_foreign_message); - - // Make sure we can do gets and sets through the Repeated[Ptr]Field objects. - for (int i = 0; i < 10; ++i) { - // Check gets through const objects. - EXPECT_EQ(rf_int32.Get(i), Func(i, 1)); - 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(DownCast(&rpf_message.Get(i))->c(), - Func(i, 6)); - - // Check gets through mutable objects. - EXPECT_EQ(mrf_int32->Get(i), Func(i, 1)); - 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(DownCast(&mrpf_message->Get(i))->c(), - Func(i, 6)); - - // Check sets through mutable objects. - mrf_int32->Set(i, Func(i, -1)); - mrf_double->Set(i, Func(i, -2)); - mrpf_string->Mutable(i)->assign(StrFunc(i, -5)); - mrpf_foreign_message->Mutable(i)->set_c(Func(i, -6)); - EXPECT_EQ(message.repeated_int32(i), Func(i, -1)); - 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)); - DownCast(mrpf_message->Mutable(i))->set_c(Func(i, 7)); - EXPECT_EQ(message.repeated_foreign_message(i).c(), Func(i, 7)); - } - -#if GTEST_HAS_DEATH_TEST - // Make sure types are checked correctly at runtime. - const FieldDescriptor* fd_optional_int32 = - desc->FindFieldByName("optional_int32"); - EXPECT_DEATH(refl->GetRepeatedField(message, fd_optional_int32), - "requires a repeated field"); - EXPECT_DEATH(refl->GetRepeatedField(message, fd_repeated_int32), - "not the right type"); - EXPECT_DEATH(refl->GetRepeatedPtrField( - message, fd_repeated_foreign_message), - "wrong submessage type"); -#endif // GTEST_HAS_DEATH_TEST -} - - -TEST(RepeatedFieldReflectionTest, ExtensionFields) { - TestAllExtensions extended_message; - const Reflection* refl = extended_message.GetReflection(); - const Descriptor* desc = extended_message.GetDescriptor(); - - for (int i = 0; i < 10; ++i) { - extended_message.AddExtension(unittest::repeated_int64_extension, - Func(i, 1)); - } - - const FieldDescriptor* fd_repeated_int64_extension = - desc->file()->FindExtensionByName("repeated_int64_extension"); - ABSL_CHECK(fd_repeated_int64_extension != nullptr); - - const RepeatedField& rf_int64_extension = - refl->GetRepeatedField(extended_message, - fd_repeated_int64_extension); - - RepeatedField* mrf_int64_extension = - refl->MutableRepeatedField(&extended_message, - fd_repeated_int64_extension); - - for (int i = 0; i < 10; ++i) { - EXPECT_EQ(Func(i, 1), rf_int64_extension.Get(i)); - mrf_int64_extension->Set(i, Func(i, -1)); - EXPECT_EQ(Func(i, -1), extended_message.GetExtension( - unittest::repeated_int64_extension, i)); - } -} - -template -void TestRepeatedFieldRefIteratorForPrimitive( - const Ref& handle, const MessageType& message, - ValueType (MessageType::*GetFunc)(int) const) { - int index = 0; - for (typename Ref::const_iterator it = handle.begin(); it != handle.end(); - ++it) { - EXPECT_EQ((message.*GetFunc)(index), *it); - ++index; - } - EXPECT_EQ(handle.size(), index); -} - -template -void TestRepeatedFieldRefIteratorForString( - const RepeatedFieldRef& handle, const MessageType& message, - ValueType (MessageType::*GetFunc)(int) const) { - int index = 0; - for (typename RepeatedFieldRef::const_iterator it = - handle.begin(); - it != handle.end(); ++it) { - // Test both operator* and operator-> - EXPECT_EQ((message.*GetFunc)(index), *it); - EXPECT_EQ((message.*GetFunc)(index).size(), it->size()); - ++index; - } - EXPECT_EQ(handle.size(), index); -} - -TEST(RepeatedFieldReflectionTest, RepeatedFieldRefForRegularFields) { - TestAllTypes message; - const Reflection* refl = message.GetReflection(); - const Descriptor* desc = message.GetDescriptor(); - - for (int i = 0; i < 10; ++i) { - message.add_repeated_int32(Func(i, 1)); - message.add_repeated_double(Func(i, 2)); - message.add_repeated_string(StrFunc(i, 5)); - message.add_repeated_foreign_message()->set_c(Func(i, 6)); - } - - // Get FieldDescriptors for all the fields of interest. - const FieldDescriptor* fd_repeated_int32 = - desc->FindFieldByName("repeated_int32"); - const FieldDescriptor* fd_repeated_double = - desc->FindFieldByName("repeated_double"); - const FieldDescriptor* fd_repeated_string = - desc->FindFieldByName("repeated_string"); - const FieldDescriptor* fd_repeated_foreign_message = - desc->FindFieldByName("repeated_foreign_message"); - - // Get RepeatedFieldRef objects for all fields of interest. - const RepeatedFieldRef rf_int32 = - refl->GetRepeatedFieldRef(message, fd_repeated_int32); - const RepeatedFieldRef rf_double = - refl->GetRepeatedFieldRef(message, fd_repeated_double); - const RepeatedFieldRef rf_string = - refl->GetRepeatedFieldRef(message, fd_repeated_string); - const RepeatedFieldRef rf_foreign_message = - refl->GetRepeatedFieldRef(message, - fd_repeated_foreign_message); - const RepeatedFieldRef rf_message = - refl->GetRepeatedFieldRef(message, fd_repeated_foreign_message); - - // Get MutableRepeatedFieldRef objects for all fields of interest. - const MutableRepeatedFieldRef mrf_int32 = - refl->GetMutableRepeatedFieldRef(&message, fd_repeated_int32); - const MutableRepeatedFieldRef mrf_double = - refl->GetMutableRepeatedFieldRef(&message, fd_repeated_double); - const MutableRepeatedFieldRef mrf_string = - refl->GetMutableRepeatedFieldRef(&message, - fd_repeated_string); - const MutableRepeatedFieldRef mrf_foreign_message = - refl->GetMutableRepeatedFieldRef( - &message, fd_repeated_foreign_message); - const MutableRepeatedFieldRef mrf_message = - refl->GetMutableRepeatedFieldRef(&message, - fd_repeated_foreign_message); - - EXPECT_EQ(message.repeated_int32_size(), rf_int32.size()); - EXPECT_EQ(message.repeated_int32_size(), mrf_int32.size()); - EXPECT_EQ(message.repeated_double_size(), rf_double.size()); - EXPECT_EQ(message.repeated_double_size(), mrf_double.size()); - EXPECT_EQ(message.repeated_string_size(), rf_string.size()); - EXPECT_EQ(message.repeated_string_size(), mrf_string.size()); - EXPECT_EQ(message.repeated_foreign_message_size(), rf_foreign_message.size()); - EXPECT_EQ(message.repeated_foreign_message_size(), - mrf_foreign_message.size()); - EXPECT_EQ(message.repeated_foreign_message_size(), rf_message.size()); - EXPECT_EQ(message.repeated_foreign_message_size(), mrf_message.size()); - - EXPECT_FALSE(rf_int32.empty()); - EXPECT_FALSE(mrf_int32.empty()); - EXPECT_FALSE(rf_double.empty()); - EXPECT_FALSE(mrf_double.empty()); - EXPECT_FALSE(rf_string.empty()); - EXPECT_FALSE(mrf_string.empty()); - EXPECT_FALSE(rf_foreign_message.empty()); - EXPECT_FALSE(mrf_foreign_message.empty()); - EXPECT_FALSE(rf_message.empty()); - EXPECT_FALSE(mrf_message.empty()); - - // Make sure we can do gets and sets through the RepeatedFieldRef objects. - for (int i = 0; i < 10; ++i) { - // Check gets through const objects. - EXPECT_EQ(rf_int32.Get(i), Func(i, 1)); - EXPECT_EQ(rf_double.Get(i), Func(i, 2)); - EXPECT_EQ(rf_string.Get(i), StrFunc(i, 5)); - ForeignMessage scratch_space; - EXPECT_EQ(rf_foreign_message.Get(i, &scratch_space).c(), Func(i, 6)); - EXPECT_EQ( - DownCast(rf_message.Get(i, &scratch_space)).c(), - Func(i, 6)); - - // Check gets through mutable objects. - EXPECT_EQ(mrf_int32.Get(i), Func(i, 1)); - EXPECT_EQ(mrf_double.Get(i), Func(i, 2)); - EXPECT_EQ(mrf_string.Get(i), StrFunc(i, 5)); - EXPECT_EQ(mrf_foreign_message.Get(i, &scratch_space).c(), Func(i, 6)); - EXPECT_EQ( - DownCast(mrf_message.Get(i, &scratch_space)).c(), - Func(i, 6)); - - // Check sets through mutable objects. - mrf_int32.Set(i, Func(i, -1)); - mrf_double.Set(i, Func(i, -2)); - mrf_string.Set(i, StrFunc(i, -5)); - ForeignMessage foreign_message; - foreign_message.set_c(Func(i, -6)); - mrf_foreign_message.Set(i, foreign_message); - EXPECT_EQ(message.repeated_int32(i), Func(i, -1)); - 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)); - foreign_message.set_c(Func(i, 7)); - mrf_message.Set(i, foreign_message); - EXPECT_EQ(message.repeated_foreign_message(i).c(), Func(i, 7)); - } - - // Test iterators. - TestRepeatedFieldRefIteratorForPrimitive(rf_int32, message, - &TestAllTypes::repeated_int32); - TestRepeatedFieldRefIteratorForPrimitive(rf_double, message, - &TestAllTypes::repeated_double); - TestRepeatedFieldRefIteratorForString(rf_string, message, - &TestAllTypes::repeated_string); - - // Test iterators for message fields. - typedef RepeatedFieldRef::iterator MessageIterator; - int index = 0; - for (MessageIterator it = rf_foreign_message.begin(); - it != rf_foreign_message.end(); ++it) { - EXPECT_EQ(message.repeated_foreign_message(index).c(), it->c()); - ++index; - } - EXPECT_EQ(10, index); - - // Test iterator operators that are not usually used in regular for-loops. - // Including: post increment, assign, ==. - MessageIterator old_it = rf_foreign_message.begin(); - MessageIterator new_it = old_it++; - EXPECT_FALSE(old_it == new_it); - // Check that old_it++ increments old_it once. - for (index = 1; old_it != rf_foreign_message.end(); ++old_it, ++index) { - EXPECT_EQ(message.repeated_foreign_message(index).c(), old_it->c()); - } - EXPECT_EQ(10, index); - // Test assign operator. - old_it = new_it; - for (index = 0; old_it != rf_foreign_message.end(); ++old_it, ++index) { - EXPECT_EQ(message.repeated_foreign_message(index).c(), old_it->c()); - } - EXPECT_EQ(10, index); - // Check that the returned value of old_it++ is the one before increment. - for (index = 0; new_it != rf_foreign_message.end(); ++new_it, ++index) { - EXPECT_EQ(message.repeated_foreign_message(index).c(), new_it->c()); - } - EXPECT_EQ(10, index); - - // Test MutableRepeatedFieldRef::Reserve() - mrf_int32.Reserve(mrf_int32.size() + 1); - mrf_double.Reserve(mrf_double.size() + 1); - mrf_string.Reserve(mrf_string.size() + 1); - mrf_foreign_message.Reserve(mrf_foreign_message.size() + 1); - - // Test MutableRepeatedFieldRef::Add() - mrf_int32.Add(1234); - mrf_double.Add(1234.0); - mrf_string.Add("1234"); - ForeignMessage foreign_message; - foreign_message.set_c(1234); - mrf_foreign_message.Add(foreign_message); - EXPECT_EQ(1234, message.repeated_int32(10)); - EXPECT_EQ(1234.0, message.repeated_double(10)); - EXPECT_EQ("1234", message.repeated_string(10)); - EXPECT_EQ(1234, message.repeated_foreign_message(10).c()); - - // Test MutableRepeatedFieldRef::RemoveLast() - mrf_int32.RemoveLast(); - mrf_double.RemoveLast(); - mrf_string.RemoveLast(); - mrf_foreign_message.RemoveLast(); - EXPECT_EQ(10, message.repeated_int32_size()); - EXPECT_EQ(10, message.repeated_double_size()); - EXPECT_EQ(10, message.repeated_string_size()); - EXPECT_EQ(10, message.repeated_foreign_message_size()); - - // Test MutableRepeatedFieldRef::SwapElements() - mrf_int32.SwapElements(0, 9); - mrf_double.SwapElements(0, 9); - mrf_string.SwapElements(0, 9); - mrf_foreign_message.SwapElements(0, 9); - EXPECT_EQ(Func(9, -1), message.repeated_int32(0)); - EXPECT_EQ(Func(0, -1), message.repeated_int32(9)); - EXPECT_EQ(Func(9, -2), message.repeated_double(0)); - EXPECT_EQ(Func(0, -2), message.repeated_double(9)); - EXPECT_EQ(StrFunc(9, -5), message.repeated_string(0)); - EXPECT_EQ(StrFunc(0, -5), message.repeated_string(9)); - EXPECT_EQ(Func(9, 7), message.repeated_foreign_message(0).c()); - EXPECT_EQ(Func(0, 7), message.repeated_foreign_message(9).c()); - - // Test MutableRepeatedFieldRef::Clear() - mrf_int32.Clear(); - mrf_double.Clear(); - mrf_string.Clear(); - mrf_foreign_message.Clear(); - EXPECT_EQ(0, message.repeated_int32_size()); - EXPECT_EQ(0, message.repeated_double_size()); - EXPECT_EQ(0, message.repeated_string_size()); - EXPECT_EQ(0, message.repeated_foreign_message_size()); - - // Test (Mutable)RepeatedFieldRef::empty() - EXPECT_TRUE(rf_int32.empty()); - EXPECT_TRUE(mrf_int32.empty()); - EXPECT_TRUE(rf_double.empty()); - EXPECT_TRUE(mrf_double.empty()); - EXPECT_TRUE(rf_string.empty()); - EXPECT_TRUE(mrf_string.empty()); - EXPECT_TRUE(rf_foreign_message.empty()); - EXPECT_TRUE(mrf_foreign_message.empty()); - EXPECT_TRUE(rf_message.empty()); - EXPECT_TRUE(mrf_message.empty()); - -#if GTEST_HAS_DEATH_TEST - - // Make sure types are checked correctly at runtime. - const FieldDescriptor* fd_optional_int32 = - desc->FindFieldByName("optional_int32"); - EXPECT_DEATH(refl->GetRepeatedFieldRef(message, fd_optional_int32), - ""); - EXPECT_DEATH(refl->GetRepeatedFieldRef(message, fd_repeated_int32), - ""); - EXPECT_DEATH(refl->GetRepeatedFieldRef( - message, fd_repeated_foreign_message), - ""); - -#endif // GTEST_HAS_DEATH_TEST -} - -TEST(RepeatedFieldReflectionTest, RepeatedFieldRefForEnums) { - TestAllTypes message; - const Reflection* refl = message.GetReflection(); - const Descriptor* desc = message.GetDescriptor(); - - for (int i = 0; i < 10; ++i) { - message.add_repeated_nested_enum(TestAllTypes::BAR); - } - - const FieldDescriptor* fd_repeated_nested_enum = - desc->FindFieldByName("repeated_nested_enum"); - const RepeatedFieldRef enum_ref = - refl->GetRepeatedFieldRef( - message, fd_repeated_nested_enum); - const MutableRepeatedFieldRef mutable_enum_ref = - refl->GetMutableRepeatedFieldRef( - &message, fd_repeated_nested_enum); - const RepeatedFieldRef int32_ref = - refl->GetRepeatedFieldRef(message, fd_repeated_nested_enum); - const MutableRepeatedFieldRef mutable_int32_ref = - refl->GetMutableRepeatedFieldRef(&message, - fd_repeated_nested_enum); - - EXPECT_EQ(message.repeated_nested_enum_size(), enum_ref.size()); - EXPECT_EQ(message.repeated_nested_enum_size(), mutable_enum_ref.size()); - EXPECT_EQ(message.repeated_nested_enum_size(), int32_ref.size()); - EXPECT_EQ(message.repeated_nested_enum_size(), mutable_int32_ref.size()); - - EXPECT_FALSE(enum_ref.empty()); - EXPECT_FALSE(mutable_enum_ref.empty()); - EXPECT_FALSE(int32_ref.empty()); - EXPECT_FALSE(mutable_int32_ref.empty()); - - for (int i = 0; i < 10; ++i) { - EXPECT_EQ(TestAllTypes::BAR, enum_ref.Get(i)); - EXPECT_EQ(TestAllTypes::BAR, mutable_enum_ref.Get(i)); - mutable_enum_ref.Set(i, TestAllTypes::BAZ); - EXPECT_EQ(TestAllTypes::BAZ, enum_ref.Get(i)); - EXPECT_EQ(TestAllTypes::BAZ, message.repeated_nested_enum(i)); - - message.set_repeated_nested_enum(i, TestAllTypes::BAR); - EXPECT_EQ(TestAllTypes::BAR, int32_ref.Get(i)); - EXPECT_EQ(TestAllTypes::BAR, mutable_int32_ref.Get(i)); - mutable_int32_ref.Set(i, TestAllTypes::BAZ); - EXPECT_EQ(TestAllTypes::BAZ, int32_ref.Get(i)); - EXPECT_EQ(TestAllTypes::BAZ, message.repeated_nested_enum(i)); - } - - TestRepeatedFieldRefIteratorForPrimitive(enum_ref, message, - &TestAllTypes::repeated_nested_enum); - TestRepeatedFieldRefIteratorForPrimitive(int32_ref, message, - &TestAllTypes::repeated_nested_enum); - - // Test Add() - mutable_enum_ref.Add(TestAllTypes::FOO); - EXPECT_EQ(TestAllTypes::FOO, message.repeated_nested_enum(10)); - mutable_int32_ref.Add(TestAllTypes::BAR); - EXPECT_EQ(TestAllTypes::BAR, message.repeated_nested_enum(11)); - - // Test RemoveLast() - mutable_enum_ref.RemoveLast(); - EXPECT_EQ(11, message.repeated_nested_enum_size()); - mutable_int32_ref.RemoveLast(); - EXPECT_EQ(10, message.repeated_nested_enum_size()); - - // Test SwapElements() - mutable_enum_ref.Set(0, TestAllTypes::BAR); - mutable_enum_ref.Set(9, TestAllTypes::BAZ); - mutable_enum_ref.SwapElements(0, 9); - EXPECT_EQ(TestAllTypes::BAZ, enum_ref.Get(0)); - EXPECT_EQ(TestAllTypes::BAR, enum_ref.Get(9)); - mutable_int32_ref.SwapElements(0, 9); - EXPECT_EQ(TestAllTypes::BAR, enum_ref.Get(0)); - EXPECT_EQ(TestAllTypes::BAZ, enum_ref.Get(9)); - - // Test Clear() - mutable_enum_ref.Clear(); - EXPECT_EQ(0, message.repeated_nested_enum_size()); - mutable_enum_ref.Add(TestAllTypes::FOO); - EXPECT_EQ(1, message.repeated_nested_enum_size()); - mutable_int32_ref.Clear(); - EXPECT_EQ(0, message.repeated_nested_enum_size()); - - // Test empty() - EXPECT_TRUE(enum_ref.empty()); - EXPECT_TRUE(mutable_enum_ref.empty()); - EXPECT_TRUE(int32_ref.empty()); - EXPECT_TRUE(mutable_int32_ref.empty()); -} - -TEST(RepeatedFieldReflectionTest, RepeatedFieldRefForExtensionFields) { - TestAllExtensions extended_message; - const Reflection* refl = extended_message.GetReflection(); - const Descriptor* desc = extended_message.GetDescriptor(); - - for (int i = 0; i < 10; ++i) { - extended_message.AddExtension(unittest::repeated_int64_extension, - Func(i, 1)); - } - - const FieldDescriptor* fd_repeated_int64_extension = - desc->file()->FindExtensionByName("repeated_int64_extension"); - ABSL_CHECK(fd_repeated_int64_extension != nullptr); - - const RepeatedFieldRef rf_int64_extension = - refl->GetRepeatedFieldRef(extended_message, - fd_repeated_int64_extension); - - const MutableRepeatedFieldRef mrf_int64_extension = - refl->GetMutableRepeatedFieldRef(&extended_message, - fd_repeated_int64_extension); - - for (int i = 0; i < 10; ++i) { - EXPECT_EQ(Func(i, 1), rf_int64_extension.Get(i)); - mrf_int64_extension.Set(i, Func(i, -1)); - EXPECT_EQ(Func(i, -1), extended_message.GetExtension( - unittest::repeated_int64_extension, i)); - } -} - - -TEST(RepeatedFieldReflectionTest, RepeatedFieldRefMergeFromAndSwap) { - // Set-up message content. - TestAllTypes m0, m1, m2; - for (int i = 0; i < 10; ++i) { - m0.add_repeated_int32(Func(i, 1)); - m0.add_repeated_double(Func(i, 2)); - m0.add_repeated_string(StrFunc(i, 5)); - m0.add_repeated_foreign_message()->set_c(Func(i, 6)); - m0.add_repeated_nested_enum(TestAllTypes::FOO); - m1.add_repeated_int32(Func(i, 11)); - m1.add_repeated_double(Func(i, 12)); - m1.add_repeated_string(StrFunc(i, 15)); - m1.add_repeated_foreign_message()->set_c(Func(i, 16)); - m1.add_repeated_nested_enum(TestAllTypes::BAR); - m2.add_repeated_int32(Func(i, 21)); - m2.add_repeated_double(Func(i, 22)); - m2.add_repeated_string(StrFunc(i, 25)); - m2.add_repeated_foreign_message()->set_c(Func(i, 26)); - m2.add_repeated_nested_enum(TestAllTypes::BAZ); - } - - const Reflection* refl = m0.GetReflection(); - const Descriptor* desc = m0.GetDescriptor(); - - // Get FieldDescriptors for all the fields of interest. - const FieldDescriptor* fd_repeated_int32 = - desc->FindFieldByName("repeated_int32"); - const FieldDescriptor* fd_repeated_double = - desc->FindFieldByName("repeated_double"); - const FieldDescriptor* fd_repeated_string = - desc->FindFieldByName("repeated_string"); - const FieldDescriptor* fd_repeated_foreign_message = - desc->FindFieldByName("repeated_foreign_message"); - const FieldDescriptor* fd_repeated_nested_enum = - desc->FindFieldByName("repeated_nested_enum"); - - // Get MutableRepeatedFieldRef objects for all fields of interest. - const MutableRepeatedFieldRef mrf_int32 = - refl->GetMutableRepeatedFieldRef(&m0, fd_repeated_int32); - const MutableRepeatedFieldRef mrf_double = - refl->GetMutableRepeatedFieldRef(&m0, fd_repeated_double); - const MutableRepeatedFieldRef mrf_string = - refl->GetMutableRepeatedFieldRef(&m0, fd_repeated_string); - const MutableRepeatedFieldRef mrf_foreign_message = - refl->GetMutableRepeatedFieldRef( - &m0, fd_repeated_foreign_message); - const MutableRepeatedFieldRef mrf_nested_enum = - refl->GetMutableRepeatedFieldRef( - &m0, fd_repeated_nested_enum); - - // Test MutableRepeatedRef::CopyFrom - mrf_int32.CopyFrom(refl->GetRepeatedFieldRef(m1, fd_repeated_int32)); - mrf_double.CopyFrom( - refl->GetRepeatedFieldRef(m1, fd_repeated_double)); - mrf_string.CopyFrom( - refl->GetRepeatedFieldRef(m1, fd_repeated_string)); - mrf_foreign_message.CopyFrom(refl->GetRepeatedFieldRef( - m1, fd_repeated_foreign_message)); - mrf_nested_enum.CopyFrom(refl->GetRepeatedFieldRef( - m1, fd_repeated_nested_enum)); - for (int i = 0; i < 10; ++i) { - EXPECT_EQ(Func(i, 11), m0.repeated_int32(i)); - EXPECT_EQ(Func(i, 12), m0.repeated_double(i)); - EXPECT_EQ(StrFunc(i, 15), m0.repeated_string(i)); - EXPECT_EQ(Func(i, 16), m0.repeated_foreign_message(i).c()); - EXPECT_EQ(TestAllTypes::BAR, m0.repeated_nested_enum(i)); - } - - // Test MutableRepeatedRef::MergeFrom - mrf_int32.MergeFrom( - refl->GetRepeatedFieldRef(m2, fd_repeated_int32)); - mrf_double.MergeFrom( - refl->GetRepeatedFieldRef(m2, fd_repeated_double)); - mrf_string.MergeFrom( - refl->GetRepeatedFieldRef(m2, fd_repeated_string)); - mrf_foreign_message.MergeFrom(refl->GetRepeatedFieldRef( - m2, fd_repeated_foreign_message)); - mrf_nested_enum.MergeFrom(refl->GetRepeatedFieldRef( - m2, fd_repeated_nested_enum)); - for (int i = 0; i < 10; ++i) { - EXPECT_EQ(Func(i, 21), m0.repeated_int32(i + 10)); - EXPECT_EQ(Func(i, 22), m0.repeated_double(i + 10)); - EXPECT_EQ(StrFunc(i, 25), m0.repeated_string(i + 10)); - EXPECT_EQ(Func(i, 26), m0.repeated_foreign_message(i + 10).c()); - EXPECT_EQ(TestAllTypes::BAZ, m0.repeated_nested_enum(i + 10)); - } - - // Test MutableRepeatedRef::Swap - // Swap between m0 and m2. - mrf_int32.Swap( - refl->GetMutableRepeatedFieldRef(&m2, fd_repeated_int32)); - mrf_double.Swap( - refl->GetMutableRepeatedFieldRef(&m2, fd_repeated_double)); - mrf_string.Swap( - refl->GetMutableRepeatedFieldRef(&m2, fd_repeated_string)); - mrf_foreign_message.Swap(refl->GetMutableRepeatedFieldRef( - &m2, fd_repeated_foreign_message)); - mrf_nested_enum.Swap( - refl->GetMutableRepeatedFieldRef( - &m2, fd_repeated_nested_enum)); - for (int i = 0; i < 10; ++i) { - // Check the content of m0. - EXPECT_EQ(Func(i, 21), m0.repeated_int32(i)); - EXPECT_EQ(Func(i, 22), m0.repeated_double(i)); - EXPECT_EQ(StrFunc(i, 25), m0.repeated_string(i)); - EXPECT_EQ(Func(i, 26), m0.repeated_foreign_message(i).c()); - EXPECT_EQ(TestAllTypes::BAZ, m0.repeated_nested_enum(i)); - - // Check the content of m2. - EXPECT_EQ(Func(i, 11), m2.repeated_int32(i)); - EXPECT_EQ(Func(i, 12), m2.repeated_double(i)); - EXPECT_EQ(StrFunc(i, 15), m2.repeated_string(i)); - EXPECT_EQ(Func(i, 16), m2.repeated_foreign_message(i).c()); - EXPECT_EQ(TestAllTypes::BAR, m2.repeated_nested_enum(i)); - EXPECT_EQ(Func(i, 21), m2.repeated_int32(i + 10)); - EXPECT_EQ(Func(i, 22), m2.repeated_double(i + 10)); - EXPECT_EQ(StrFunc(i, 25), m2.repeated_string(i + 10)); - EXPECT_EQ(Func(i, 26), m2.repeated_foreign_message(i + 10).c()); - EXPECT_EQ(TestAllTypes::BAZ, m2.repeated_nested_enum(i + 10)); - } -} - -// Test that GetRepeatedFieldRef/MutableRepeatedFieldRef works with -// DynamicMessage. -TEST(RepeatedFieldReflectionTest, RepeatedFieldRefDynamicMessage) { - // DynamicMessage shares the same memory layout as generated message - // and use the same GeneratedMessageReflection code for reflection. - // All code paths should already be covered by the other tests for - // generated messages. Here we just test one field. - - const Descriptor* desc = TestAllTypes::descriptor(); - const FieldDescriptor* fd_repeated_int32 = - desc->FindFieldByName("repeated_int32"); - - DynamicMessageFactory factory; - std::unique_ptr dynamic_message(factory.GetPrototype(desc)->New()); - const Reflection* refl = dynamic_message->GetReflection(); - - MutableRepeatedFieldRef rf_int32 = - refl->GetMutableRepeatedFieldRef(dynamic_message.get(), - fd_repeated_int32); - rf_int32.Add(1234); - EXPECT_EQ(1, refl->FieldSize(*dynamic_message, fd_repeated_int32)); - EXPECT_EQ(1234, - refl->GetRepeatedInt32(*dynamic_message, fd_repeated_int32, 0)); -} - -} // namespace -} // namespace protobuf -} // namespace google +#include "google/protobuf/unittest.pb.h" // IWYU pragma: keep, used in UNITTEST + +#define REFLECTION_TEST RepeatedFieldReflectionTest +#define UNITTEST_PACKAGE_NAME "protobuf_unittest" +#define UNITTEST ::protobuf_unittest +#define UNITTEST_IMPORT ::protobuf_unittest_import + +// Must include after the above macros. +// clang-format off +#include "google/protobuf/test_util.inc" +#include "google/protobuf/repeated_field_reflection_unittest.inc" +// clang-format on diff --git a/src/google/protobuf/repeated_field_reflection_unittest.inc b/src/google/protobuf/repeated_field_reflection_unittest.inc new file mode 100644 index 000000000000..97d5c4128eae --- /dev/null +++ b/src/google/protobuf/repeated_field_reflection_unittest.inc @@ -0,0 +1,692 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd + +// Author: tgs@google.com (Tom Szymanski) +// +// Test reflection methods for aggregate access to Repeated[Ptr]Fields. +// This test proto2 methods on a proto2 layout. + +#include +#include "absl/base/casts.h" +#include "absl/strings/cord.h" +#include "google/protobuf/dynamic_message.h" +#include "google/protobuf/port.h" +#include "google/protobuf/reflection.h" + +namespace google { +namespace protobuf { +namespace { + + +using internal::DownCast; +using UNITTEST::ForeignMessage; +using UNITTEST::TestAllExtensions; +using UNITTEST::TestAllTypes; + +static int Func(int i, int j) { return i * j; } + +static std::string StrFunc(int i, int j) { return absl::StrCat(Func(i, 4)); } + +TEST(REFLECTION_TEST, RegularFields) { + TestAllTypes message; + const Reflection* refl = message.GetReflection(); + const Descriptor* desc = message.GetDescriptor(); + + for (int i = 0; i < 10; ++i) { + message.add_repeated_int32(Func(i, 1)); + message.add_repeated_double(Func(i, 2)); + message.add_repeated_string(StrFunc(i, 5)); + message.add_repeated_foreign_message()->set_c(Func(i, 6)); + } + + // Get FieldDescriptors for all the fields of interest. + const FieldDescriptor* fd_repeated_int32 = + desc->FindFieldByName("repeated_int32"); + const FieldDescriptor* fd_repeated_double = + desc->FindFieldByName("repeated_double"); + const FieldDescriptor* fd_repeated_string = + desc->FindFieldByName("repeated_string"); + const FieldDescriptor* fd_repeated_foreign_message = + desc->FindFieldByName("repeated_foreign_message"); + + // Get RepeatedField objects for all fields of interest. + const RepeatedField& rf_int32 = + refl->GetRepeatedField(message, fd_repeated_int32); + const RepeatedField& rf_double = + refl->GetRepeatedField(message, fd_repeated_double); + + // Get mutable RepeatedField objects for all fields of interest. + RepeatedField* mrf_int32 = + refl->MutableRepeatedField(&message, fd_repeated_int32); + RepeatedField* mrf_double = + refl->MutableRepeatedField(&message, fd_repeated_double); + + // Get RepeatedPtrField objects for all fields of interest. + const RepeatedPtrField& rpf_string = + refl->GetRepeatedPtrField(message, fd_repeated_string); + const RepeatedPtrField& rpf_foreign_message = + refl->GetRepeatedPtrField(message, + fd_repeated_foreign_message); + const RepeatedPtrField& rpf_message = + refl->GetRepeatedPtrField(message, fd_repeated_foreign_message); + + // Get mutable RepeatedPtrField objects for all fields of interest. + RepeatedPtrField* mrpf_string = + refl->MutableRepeatedPtrField(&message, fd_repeated_string); + RepeatedPtrField* mrpf_foreign_message = + refl->MutableRepeatedPtrField( + &message, fd_repeated_foreign_message); + RepeatedPtrField* mrpf_message = + refl->MutableRepeatedPtrField(&message, + fd_repeated_foreign_message); + + // Make sure we can do gets and sets through the Repeated[Ptr]Field objects. + for (int i = 0; i < 10; ++i) { + // Check gets through const objects. + EXPECT_EQ(rf_int32.Get(i), Func(i, 1)); + 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(DownCast(&rpf_message.Get(i))->c(), + Func(i, 6)); + + // Check gets through mutable objects. + EXPECT_EQ(mrf_int32->Get(i), Func(i, 1)); + 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(DownCast(&mrpf_message->Get(i))->c(), + Func(i, 6)); + + // Check sets through mutable objects. + mrf_int32->Set(i, Func(i, -1)); + mrf_double->Set(i, Func(i, -2)); + mrpf_string->Mutable(i)->assign(StrFunc(i, -5)); + mrpf_foreign_message->Mutable(i)->set_c(Func(i, -6)); + EXPECT_EQ(message.repeated_int32(i), Func(i, -1)); + 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)); + DownCast(mrpf_message->Mutable(i))->set_c(Func(i, 7)); + EXPECT_EQ(message.repeated_foreign_message(i).c(), Func(i, 7)); + } + +#if GTEST_HAS_DEATH_TEST + // Make sure types are checked correctly at runtime. + const FieldDescriptor* fd_optional_int32 = + desc->FindFieldByName("optional_int32"); + EXPECT_DEATH(refl->GetRepeatedField(message, fd_optional_int32), + "requires a repeated field"); + EXPECT_DEATH(refl->GetRepeatedField(message, fd_repeated_int32), + "not the right type"); + EXPECT_DEATH(refl->GetRepeatedPtrField( + message, fd_repeated_foreign_message), + "wrong submessage type"); +#endif // GTEST_HAS_DEATH_TEST +} + + +TEST(REFLECTION_TEST, ExtensionFields) { + TestAllExtensions extended_message; + const Reflection* refl = extended_message.GetReflection(); + const Descriptor* desc = extended_message.GetDescriptor(); + + for (int i = 0; i < 10; ++i) { + extended_message.AddExtension(UNITTEST::repeated_int64_extension, + Func(i, 1)); + } + + const FieldDescriptor* fd_repeated_int64_extension = + desc->file()->FindExtensionByName("repeated_int64_extension"); + ABSL_CHECK(fd_repeated_int64_extension != nullptr); + + const RepeatedField& rf_int64_extension = + refl->GetRepeatedField(extended_message, + fd_repeated_int64_extension); + + RepeatedField* mrf_int64_extension = + refl->MutableRepeatedField(&extended_message, + fd_repeated_int64_extension); + + for (int i = 0; i < 10; ++i) { + EXPECT_EQ(Func(i, 1), rf_int64_extension.Get(i)); + mrf_int64_extension->Set(i, Func(i, -1)); + EXPECT_EQ(Func(i, -1), extended_message.GetExtension( + UNITTEST::repeated_int64_extension, i)); + } +} + +template +void TestRepeatedFieldRefIteratorForPrimitive( + const Ref& handle, const MessageType& message, + ValueType (MessageType::*GetFunc)(int) const) { + int index = 0; + for (typename Ref::const_iterator it = handle.begin(); it != handle.end(); + ++it) { + EXPECT_EQ((message.*GetFunc)(index), *it); + ++index; + } + EXPECT_EQ(handle.size(), index); +} + +template +void TestRepeatedFieldRefIteratorForString( + const RepeatedFieldRef& handle, const MessageType& message, + ValueType (MessageType::*GetFunc)(int) const) { + int index = 0; + for (typename RepeatedFieldRef::const_iterator it = + handle.begin(); + it != handle.end(); ++it) { + // Test both operator* and operator-> + EXPECT_EQ((message.*GetFunc)(index), *it); + EXPECT_EQ((message.*GetFunc)(index).size(), it->size()); + ++index; + } + EXPECT_EQ(handle.size(), index); +} + +TEST(REFLECTION_TEST, RepeatedFieldRefForRegularFields) { + TestAllTypes message; + const Reflection* refl = message.GetReflection(); + const Descriptor* desc = message.GetDescriptor(); + + for (int i = 0; i < 10; ++i) { + message.add_repeated_int32(Func(i, 1)); + message.add_repeated_double(Func(i, 2)); + message.add_repeated_string(StrFunc(i, 5)); + message.add_repeated_foreign_message()->set_c(Func(i, 6)); + } + + // Get FieldDescriptors for all the fields of interest. + const FieldDescriptor* fd_repeated_int32 = + desc->FindFieldByName("repeated_int32"); + const FieldDescriptor* fd_repeated_double = + desc->FindFieldByName("repeated_double"); + const FieldDescriptor* fd_repeated_string = + desc->FindFieldByName("repeated_string"); + const FieldDescriptor* fd_repeated_foreign_message = + desc->FindFieldByName("repeated_foreign_message"); + + // Get RepeatedFieldRef objects for all fields of interest. + const RepeatedFieldRef rf_int32 = + refl->GetRepeatedFieldRef(message, fd_repeated_int32); + const RepeatedFieldRef rf_double = + refl->GetRepeatedFieldRef(message, fd_repeated_double); + const RepeatedFieldRef rf_string = + refl->GetRepeatedFieldRef(message, fd_repeated_string); + const RepeatedFieldRef rf_foreign_message = + refl->GetRepeatedFieldRef(message, + fd_repeated_foreign_message); + const RepeatedFieldRef rf_message = + refl->GetRepeatedFieldRef(message, fd_repeated_foreign_message); + + // Get MutableRepeatedFieldRef objects for all fields of interest. + const MutableRepeatedFieldRef mrf_int32 = + refl->GetMutableRepeatedFieldRef(&message, fd_repeated_int32); + const MutableRepeatedFieldRef mrf_double = + refl->GetMutableRepeatedFieldRef(&message, fd_repeated_double); + const MutableRepeatedFieldRef mrf_string = + refl->GetMutableRepeatedFieldRef(&message, + fd_repeated_string); + const MutableRepeatedFieldRef mrf_foreign_message = + refl->GetMutableRepeatedFieldRef( + &message, fd_repeated_foreign_message); + const MutableRepeatedFieldRef mrf_message = + refl->GetMutableRepeatedFieldRef(&message, + fd_repeated_foreign_message); + + EXPECT_EQ(message.repeated_int32_size(), rf_int32.size()); + EXPECT_EQ(message.repeated_int32_size(), mrf_int32.size()); + EXPECT_EQ(message.repeated_double_size(), rf_double.size()); + EXPECT_EQ(message.repeated_double_size(), mrf_double.size()); + EXPECT_EQ(message.repeated_string_size(), rf_string.size()); + EXPECT_EQ(message.repeated_string_size(), mrf_string.size()); + EXPECT_EQ(message.repeated_foreign_message_size(), rf_foreign_message.size()); + EXPECT_EQ(message.repeated_foreign_message_size(), + mrf_foreign_message.size()); + EXPECT_EQ(message.repeated_foreign_message_size(), rf_message.size()); + EXPECT_EQ(message.repeated_foreign_message_size(), mrf_message.size()); + + EXPECT_FALSE(rf_int32.empty()); + EXPECT_FALSE(mrf_int32.empty()); + EXPECT_FALSE(rf_double.empty()); + EXPECT_FALSE(mrf_double.empty()); + EXPECT_FALSE(rf_string.empty()); + EXPECT_FALSE(mrf_string.empty()); + EXPECT_FALSE(rf_foreign_message.empty()); + EXPECT_FALSE(mrf_foreign_message.empty()); + EXPECT_FALSE(rf_message.empty()); + EXPECT_FALSE(mrf_message.empty()); + + // Make sure we can do gets and sets through the RepeatedFieldRef objects. + for (int i = 0; i < 10; ++i) { + // Check gets through const objects. + EXPECT_EQ(rf_int32.Get(i), Func(i, 1)); + EXPECT_EQ(rf_double.Get(i), Func(i, 2)); + EXPECT_EQ(rf_string.Get(i), StrFunc(i, 5)); + ForeignMessage scratch_space; + EXPECT_EQ(rf_foreign_message.Get(i, &scratch_space).c(), Func(i, 6)); + EXPECT_EQ( + DownCast(rf_message.Get(i, &scratch_space)).c(), + Func(i, 6)); + + // Check gets through mutable objects. + EXPECT_EQ(mrf_int32.Get(i), Func(i, 1)); + EXPECT_EQ(mrf_double.Get(i), Func(i, 2)); + EXPECT_EQ(mrf_string.Get(i), StrFunc(i, 5)); + EXPECT_EQ(mrf_foreign_message.Get(i, &scratch_space).c(), Func(i, 6)); + EXPECT_EQ( + DownCast(mrf_message.Get(i, &scratch_space)).c(), + Func(i, 6)); + + // Check sets through mutable objects. + mrf_int32.Set(i, Func(i, -1)); + mrf_double.Set(i, Func(i, -2)); + mrf_string.Set(i, StrFunc(i, -5)); + ForeignMessage foreign_message; + foreign_message.set_c(Func(i, -6)); + mrf_foreign_message.Set(i, foreign_message); + EXPECT_EQ(message.repeated_int32(i), Func(i, -1)); + 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)); + foreign_message.set_c(Func(i, 7)); + mrf_message.Set(i, foreign_message); + EXPECT_EQ(message.repeated_foreign_message(i).c(), Func(i, 7)); + } + + // Test iterators. + TestRepeatedFieldRefIteratorForPrimitive(rf_int32, message, + &TestAllTypes::repeated_int32); + TestRepeatedFieldRefIteratorForPrimitive(rf_double, message, + &TestAllTypes::repeated_double); + TestRepeatedFieldRefIteratorForString(rf_string, message, + &TestAllTypes::repeated_string); + + // Test iterators for message fields. + typedef RepeatedFieldRef::iterator MessageIterator; + int index = 0; + for (MessageIterator it = rf_foreign_message.begin(); + it != rf_foreign_message.end(); ++it) { + EXPECT_EQ(message.repeated_foreign_message(index).c(), it->c()); + ++index; + } + EXPECT_EQ(10, index); + + // Test iterator operators that are not usually used in regular for-loops. + // Including: post increment, assign, ==. + MessageIterator old_it = rf_foreign_message.begin(); + MessageIterator new_it = old_it++; + EXPECT_FALSE(old_it == new_it); + // Check that old_it++ increments old_it once. + for (index = 1; old_it != rf_foreign_message.end(); ++old_it, ++index) { + EXPECT_EQ(message.repeated_foreign_message(index).c(), old_it->c()); + } + EXPECT_EQ(10, index); + // Test assign operator. + old_it = new_it; + for (index = 0; old_it != rf_foreign_message.end(); ++old_it, ++index) { + EXPECT_EQ(message.repeated_foreign_message(index).c(), old_it->c()); + } + EXPECT_EQ(10, index); + // Check that the returned value of old_it++ is the one before increment. + for (index = 0; new_it != rf_foreign_message.end(); ++new_it, ++index) { + EXPECT_EQ(message.repeated_foreign_message(index).c(), new_it->c()); + } + EXPECT_EQ(10, index); + + // Test MutableRepeatedFieldRef::Reserve() + mrf_int32.Reserve(mrf_int32.size() + 1); + mrf_double.Reserve(mrf_double.size() + 1); + mrf_string.Reserve(mrf_string.size() + 1); + mrf_foreign_message.Reserve(mrf_foreign_message.size() + 1); + + // Test MutableRepeatedFieldRef::Add() + mrf_int32.Add(1234); + mrf_double.Add(1234.0); + mrf_string.Add("1234"); + ForeignMessage foreign_message; + foreign_message.set_c(1234); + mrf_foreign_message.Add(foreign_message); + EXPECT_EQ(1234, message.repeated_int32(10)); + EXPECT_EQ(1234.0, message.repeated_double(10)); + EXPECT_EQ("1234", message.repeated_string(10)); + EXPECT_EQ(1234, message.repeated_foreign_message(10).c()); + + // Test MutableRepeatedFieldRef::RemoveLast() + mrf_int32.RemoveLast(); + mrf_double.RemoveLast(); + mrf_string.RemoveLast(); + mrf_foreign_message.RemoveLast(); + EXPECT_EQ(10, message.repeated_int32_size()); + EXPECT_EQ(10, message.repeated_double_size()); + EXPECT_EQ(10, message.repeated_string_size()); + EXPECT_EQ(10, message.repeated_foreign_message_size()); + + // Test MutableRepeatedFieldRef::SwapElements() + mrf_int32.SwapElements(0, 9); + mrf_double.SwapElements(0, 9); + mrf_string.SwapElements(0, 9); + mrf_foreign_message.SwapElements(0, 9); + EXPECT_EQ(Func(9, -1), message.repeated_int32(0)); + EXPECT_EQ(Func(0, -1), message.repeated_int32(9)); + EXPECT_EQ(Func(9, -2), message.repeated_double(0)); + EXPECT_EQ(Func(0, -2), message.repeated_double(9)); + EXPECT_EQ(StrFunc(9, -5), message.repeated_string(0)); + EXPECT_EQ(StrFunc(0, -5), message.repeated_string(9)); + EXPECT_EQ(Func(9, 7), message.repeated_foreign_message(0).c()); + EXPECT_EQ(Func(0, 7), message.repeated_foreign_message(9).c()); + + // Test MutableRepeatedFieldRef::Clear() + mrf_int32.Clear(); + mrf_double.Clear(); + mrf_string.Clear(); + mrf_foreign_message.Clear(); + EXPECT_EQ(0, message.repeated_int32_size()); + EXPECT_EQ(0, message.repeated_double_size()); + EXPECT_EQ(0, message.repeated_string_size()); + EXPECT_EQ(0, message.repeated_foreign_message_size()); + + // Test (Mutable)RepeatedFieldRef::empty() + EXPECT_TRUE(rf_int32.empty()); + EXPECT_TRUE(mrf_int32.empty()); + EXPECT_TRUE(rf_double.empty()); + EXPECT_TRUE(mrf_double.empty()); + EXPECT_TRUE(rf_string.empty()); + EXPECT_TRUE(mrf_string.empty()); + EXPECT_TRUE(rf_foreign_message.empty()); + EXPECT_TRUE(mrf_foreign_message.empty()); + EXPECT_TRUE(rf_message.empty()); + EXPECT_TRUE(mrf_message.empty()); + +#if GTEST_HAS_DEATH_TEST + + // Make sure types are checked correctly at runtime. + const FieldDescriptor* fd_optional_int32 = + desc->FindFieldByName("optional_int32"); + EXPECT_DEATH(refl->GetRepeatedFieldRef(message, fd_optional_int32), + ""); + EXPECT_DEATH(refl->GetRepeatedFieldRef(message, fd_repeated_int32), + ""); + EXPECT_DEATH(refl->GetRepeatedFieldRef( + message, fd_repeated_foreign_message), + ""); + +#endif // GTEST_HAS_DEATH_TEST +} + +TEST(REFLECTION_TEST, RepeatedFieldRefForEnums) { + TestAllTypes message; + const Reflection* refl = message.GetReflection(); + const Descriptor* desc = message.GetDescriptor(); + + for (int i = 0; i < 10; ++i) { + message.add_repeated_nested_enum(TestAllTypes::BAR); + } + + const FieldDescriptor* fd_repeated_nested_enum = + desc->FindFieldByName("repeated_nested_enum"); + const RepeatedFieldRef enum_ref = + refl->GetRepeatedFieldRef( + message, fd_repeated_nested_enum); + const MutableRepeatedFieldRef mutable_enum_ref = + refl->GetMutableRepeatedFieldRef( + &message, fd_repeated_nested_enum); + const RepeatedFieldRef int32_ref = + refl->GetRepeatedFieldRef(message, fd_repeated_nested_enum); + const MutableRepeatedFieldRef mutable_int32_ref = + refl->GetMutableRepeatedFieldRef(&message, + fd_repeated_nested_enum); + + EXPECT_EQ(message.repeated_nested_enum_size(), enum_ref.size()); + EXPECT_EQ(message.repeated_nested_enum_size(), mutable_enum_ref.size()); + EXPECT_EQ(message.repeated_nested_enum_size(), int32_ref.size()); + EXPECT_EQ(message.repeated_nested_enum_size(), mutable_int32_ref.size()); + + EXPECT_FALSE(enum_ref.empty()); + EXPECT_FALSE(mutable_enum_ref.empty()); + EXPECT_FALSE(int32_ref.empty()); + EXPECT_FALSE(mutable_int32_ref.empty()); + + for (int i = 0; i < 10; ++i) { + EXPECT_EQ(TestAllTypes::BAR, enum_ref.Get(i)); + EXPECT_EQ(TestAllTypes::BAR, mutable_enum_ref.Get(i)); + mutable_enum_ref.Set(i, TestAllTypes::BAZ); + EXPECT_EQ(TestAllTypes::BAZ, enum_ref.Get(i)); + EXPECT_EQ(TestAllTypes::BAZ, message.repeated_nested_enum(i)); + + message.set_repeated_nested_enum(i, TestAllTypes::BAR); + EXPECT_EQ(TestAllTypes::BAR, int32_ref.Get(i)); + EXPECT_EQ(TestAllTypes::BAR, mutable_int32_ref.Get(i)); + mutable_int32_ref.Set(i, TestAllTypes::BAZ); + EXPECT_EQ(TestAllTypes::BAZ, int32_ref.Get(i)); + EXPECT_EQ(TestAllTypes::BAZ, message.repeated_nested_enum(i)); + } + + TestRepeatedFieldRefIteratorForPrimitive(enum_ref, message, + &TestAllTypes::repeated_nested_enum); + TestRepeatedFieldRefIteratorForPrimitive(int32_ref, message, + &TestAllTypes::repeated_nested_enum); + + // Test Add() + mutable_enum_ref.Add(TestAllTypes::FOO); + EXPECT_EQ(TestAllTypes::FOO, message.repeated_nested_enum(10)); + mutable_int32_ref.Add(TestAllTypes::BAR); + EXPECT_EQ(TestAllTypes::BAR, message.repeated_nested_enum(11)); + + // Test RemoveLast() + mutable_enum_ref.RemoveLast(); + EXPECT_EQ(11, message.repeated_nested_enum_size()); + mutable_int32_ref.RemoveLast(); + EXPECT_EQ(10, message.repeated_nested_enum_size()); + + // Test SwapElements() + mutable_enum_ref.Set(0, TestAllTypes::BAR); + mutable_enum_ref.Set(9, TestAllTypes::BAZ); + mutable_enum_ref.SwapElements(0, 9); + EXPECT_EQ(TestAllTypes::BAZ, enum_ref.Get(0)); + EXPECT_EQ(TestAllTypes::BAR, enum_ref.Get(9)); + mutable_int32_ref.SwapElements(0, 9); + EXPECT_EQ(TestAllTypes::BAR, enum_ref.Get(0)); + EXPECT_EQ(TestAllTypes::BAZ, enum_ref.Get(9)); + + // Test Clear() + mutable_enum_ref.Clear(); + EXPECT_EQ(0, message.repeated_nested_enum_size()); + mutable_enum_ref.Add(TestAllTypes::FOO); + EXPECT_EQ(1, message.repeated_nested_enum_size()); + mutable_int32_ref.Clear(); + EXPECT_EQ(0, message.repeated_nested_enum_size()); + + // Test empty() + EXPECT_TRUE(enum_ref.empty()); + EXPECT_TRUE(mutable_enum_ref.empty()); + EXPECT_TRUE(int32_ref.empty()); + EXPECT_TRUE(mutable_int32_ref.empty()); +} + +TEST(REFLECTION_TEST, RepeatedFieldRefForExtensionFields) { + TestAllExtensions extended_message; + const Reflection* refl = extended_message.GetReflection(); + const Descriptor* desc = extended_message.GetDescriptor(); + + for (int i = 0; i < 10; ++i) { + extended_message.AddExtension(UNITTEST::repeated_int64_extension, + Func(i, 1)); + } + + const FieldDescriptor* fd_repeated_int64_extension = + desc->file()->FindExtensionByName("repeated_int64_extension"); + ABSL_CHECK(fd_repeated_int64_extension != nullptr); + + const RepeatedFieldRef rf_int64_extension = + refl->GetRepeatedFieldRef(extended_message, + fd_repeated_int64_extension); + + const MutableRepeatedFieldRef mrf_int64_extension = + refl->GetMutableRepeatedFieldRef(&extended_message, + fd_repeated_int64_extension); + + for (int i = 0; i < 10; ++i) { + EXPECT_EQ(Func(i, 1), rf_int64_extension.Get(i)); + mrf_int64_extension.Set(i, Func(i, -1)); + EXPECT_EQ(Func(i, -1), extended_message.GetExtension( + UNITTEST::repeated_int64_extension, i)); + } +} + + +TEST(REFLECTION_TEST, RepeatedFieldRefMergeFromAndSwap) { + // Set-up message content. + TestAllTypes m0, m1, m2; + for (int i = 0; i < 10; ++i) { + m0.add_repeated_int32(Func(i, 1)); + m0.add_repeated_double(Func(i, 2)); + m0.add_repeated_string(StrFunc(i, 5)); + m0.add_repeated_foreign_message()->set_c(Func(i, 6)); + m0.add_repeated_nested_enum(TestAllTypes::FOO); + m1.add_repeated_int32(Func(i, 11)); + m1.add_repeated_double(Func(i, 12)); + m1.add_repeated_string(StrFunc(i, 15)); + m1.add_repeated_foreign_message()->set_c(Func(i, 16)); + m1.add_repeated_nested_enum(TestAllTypes::BAR); + m2.add_repeated_int32(Func(i, 21)); + m2.add_repeated_double(Func(i, 22)); + m2.add_repeated_string(StrFunc(i, 25)); + m2.add_repeated_foreign_message()->set_c(Func(i, 26)); + m2.add_repeated_nested_enum(TestAllTypes::BAZ); + } + + const Reflection* refl = m0.GetReflection(); + const Descriptor* desc = m0.GetDescriptor(); + + // Get FieldDescriptors for all the fields of interest. + const FieldDescriptor* fd_repeated_int32 = + desc->FindFieldByName("repeated_int32"); + const FieldDescriptor* fd_repeated_double = + desc->FindFieldByName("repeated_double"); + const FieldDescriptor* fd_repeated_string = + desc->FindFieldByName("repeated_string"); + const FieldDescriptor* fd_repeated_foreign_message = + desc->FindFieldByName("repeated_foreign_message"); + const FieldDescriptor* fd_repeated_nested_enum = + desc->FindFieldByName("repeated_nested_enum"); + + // Get MutableRepeatedFieldRef objects for all fields of interest. + const MutableRepeatedFieldRef mrf_int32 = + refl->GetMutableRepeatedFieldRef(&m0, fd_repeated_int32); + const MutableRepeatedFieldRef mrf_double = + refl->GetMutableRepeatedFieldRef(&m0, fd_repeated_double); + const MutableRepeatedFieldRef mrf_string = + refl->GetMutableRepeatedFieldRef(&m0, fd_repeated_string); + const MutableRepeatedFieldRef mrf_foreign_message = + refl->GetMutableRepeatedFieldRef( + &m0, fd_repeated_foreign_message); + const MutableRepeatedFieldRef mrf_nested_enum = + refl->GetMutableRepeatedFieldRef( + &m0, fd_repeated_nested_enum); + + // Test MutableRepeatedRef::CopyFrom + mrf_int32.CopyFrom(refl->GetRepeatedFieldRef(m1, fd_repeated_int32)); + mrf_double.CopyFrom( + refl->GetRepeatedFieldRef(m1, fd_repeated_double)); + mrf_string.CopyFrom( + refl->GetRepeatedFieldRef(m1, fd_repeated_string)); + mrf_foreign_message.CopyFrom(refl->GetRepeatedFieldRef( + m1, fd_repeated_foreign_message)); + mrf_nested_enum.CopyFrom(refl->GetRepeatedFieldRef( + m1, fd_repeated_nested_enum)); + for (int i = 0; i < 10; ++i) { + EXPECT_EQ(Func(i, 11), m0.repeated_int32(i)); + EXPECT_EQ(Func(i, 12), m0.repeated_double(i)); + EXPECT_EQ(StrFunc(i, 15), m0.repeated_string(i)); + EXPECT_EQ(Func(i, 16), m0.repeated_foreign_message(i).c()); + EXPECT_EQ(TestAllTypes::BAR, m0.repeated_nested_enum(i)); + } + + // Test MutableRepeatedRef::MergeFrom + mrf_int32.MergeFrom( + refl->GetRepeatedFieldRef(m2, fd_repeated_int32)); + mrf_double.MergeFrom( + refl->GetRepeatedFieldRef(m2, fd_repeated_double)); + mrf_string.MergeFrom( + refl->GetRepeatedFieldRef(m2, fd_repeated_string)); + mrf_foreign_message.MergeFrom(refl->GetRepeatedFieldRef( + m2, fd_repeated_foreign_message)); + mrf_nested_enum.MergeFrom(refl->GetRepeatedFieldRef( + m2, fd_repeated_nested_enum)); + for (int i = 0; i < 10; ++i) { + EXPECT_EQ(Func(i, 21), m0.repeated_int32(i + 10)); + EXPECT_EQ(Func(i, 22), m0.repeated_double(i + 10)); + EXPECT_EQ(StrFunc(i, 25), m0.repeated_string(i + 10)); + EXPECT_EQ(Func(i, 26), m0.repeated_foreign_message(i + 10).c()); + EXPECT_EQ(TestAllTypes::BAZ, m0.repeated_nested_enum(i + 10)); + } + + // Test MutableRepeatedRef::Swap + // Swap between m0 and m2. + mrf_int32.Swap( + refl->GetMutableRepeatedFieldRef(&m2, fd_repeated_int32)); + mrf_double.Swap( + refl->GetMutableRepeatedFieldRef(&m2, fd_repeated_double)); + mrf_string.Swap( + refl->GetMutableRepeatedFieldRef(&m2, fd_repeated_string)); + mrf_foreign_message.Swap(refl->GetMutableRepeatedFieldRef( + &m2, fd_repeated_foreign_message)); + mrf_nested_enum.Swap( + refl->GetMutableRepeatedFieldRef( + &m2, fd_repeated_nested_enum)); + for (int i = 0; i < 10; ++i) { + // Check the content of m0. + EXPECT_EQ(Func(i, 21), m0.repeated_int32(i)); + EXPECT_EQ(Func(i, 22), m0.repeated_double(i)); + EXPECT_EQ(StrFunc(i, 25), m0.repeated_string(i)); + EXPECT_EQ(Func(i, 26), m0.repeated_foreign_message(i).c()); + EXPECT_EQ(TestAllTypes::BAZ, m0.repeated_nested_enum(i)); + + // Check the content of m2. + EXPECT_EQ(Func(i, 11), m2.repeated_int32(i)); + EXPECT_EQ(Func(i, 12), m2.repeated_double(i)); + EXPECT_EQ(StrFunc(i, 15), m2.repeated_string(i)); + EXPECT_EQ(Func(i, 16), m2.repeated_foreign_message(i).c()); + EXPECT_EQ(TestAllTypes::BAR, m2.repeated_nested_enum(i)); + EXPECT_EQ(Func(i, 21), m2.repeated_int32(i + 10)); + EXPECT_EQ(Func(i, 22), m2.repeated_double(i + 10)); + EXPECT_EQ(StrFunc(i, 25), m2.repeated_string(i + 10)); + EXPECT_EQ(Func(i, 26), m2.repeated_foreign_message(i + 10).c()); + EXPECT_EQ(TestAllTypes::BAZ, m2.repeated_nested_enum(i + 10)); + } +} + +// Test that GetRepeatedFieldRef/MutableRepeatedFieldRef works with +// DynamicMessage. +TEST(REFLECTION_TEST, RepeatedFieldRefDynamicMessage) { + // DynamicMessage shares the same memory layout as generated message + // and use the same GeneratedMessageReflection code for reflection. + // All code paths should already be covered by the other tests for + // generated messages. Here we just test one field. + + const Descriptor* desc = TestAllTypes::descriptor(); + const FieldDescriptor* fd_repeated_int32 = + desc->FindFieldByName("repeated_int32"); + + DynamicMessageFactory factory; + std::unique_ptr dynamic_message(factory.GetPrototype(desc)->New()); + const Reflection* refl = dynamic_message->GetReflection(); + + MutableRepeatedFieldRef rf_int32 = + refl->GetMutableRepeatedFieldRef(dynamic_message.get(), + fd_repeated_int32); + rf_int32.Add(1234); + EXPECT_EQ(1, refl->FieldSize(*dynamic_message, fd_repeated_int32)); + EXPECT_EQ(1234, + refl->GetRepeatedInt32(*dynamic_message, fd_repeated_int32, 0)); +} + +} // namespace +} // namespace protobuf +} // namespace google