From 6ef984af4b0c63c1c33127a12dcfc8e6359f0c9e Mon Sep 17 00:00:00 2001 From: Feng Xiao Date: Mon, 10 Nov 2014 17:34:54 -0800 Subject: Down-integrate from internal code base. --- .../protobuf/repeated_field_reflection_unittest.cc | 518 ++++++++++++++++++++- 1 file changed, 513 insertions(+), 5 deletions(-) (limited to 'src/google/protobuf/repeated_field_reflection_unittest.cc') diff --git a/src/google/protobuf/repeated_field_reflection_unittest.cc b/src/google/protobuf/repeated_field_reflection_unittest.cc index 62833aab..98c864d3 100644 --- a/src/google/protobuf/repeated_field_reflection_unittest.cc +++ b/src/google/protobuf/repeated_field_reflection_unittest.cc @@ -33,10 +33,12 @@ // Test reflection methods for aggregate access to Repeated[Ptr]Fields. // This test proto2 methods on a proto2 layout. -#include +#include #include +#include #include #include +#include #include namespace google { @@ -58,7 +60,6 @@ static string StrFunc(int i, int j) { return str; } - TEST(RepeatedFieldReflectionTest, RegularFields) { TestAllTypes message; const Reflection* refl = message.GetReflection(); @@ -113,7 +114,7 @@ TEST(RepeatedFieldReflectionTest, RegularFields) { refl->MutableRepeatedPtrField( &message, fd_repeated_foreign_message); - // Make sure we can do get and sets through the Repeated[Ptr]Field objects. + // 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)); @@ -158,8 +159,6 @@ TEST(RepeatedFieldReflectionTest, RegularFields) { } - - TEST(RepeatedFieldReflectionTest, ExtensionFields) { TestAllExtensions extended_message; const Reflection* refl = extended_message.GetReflection(); @@ -190,6 +189,515 @@ TEST(RepeatedFieldReflectionTest, ExtensionFields) { } } +template +void TestRepeatedFieldRefIterator( + 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) { + ValueType value = static_cast(*it); + EXPECT_EQ((message.*GetFunc)(index), value); + ++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(down_cast( + 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(down_cast( + 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. + TestRepeatedFieldRefIterator(rf_int32, message, + &TestAllTypes::repeated_int32); + TestRepeatedFieldRefIterator(rf_double, message, + &TestAllTypes::repeated_double); + TestRepeatedFieldRefIterator(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 ususally 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::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()); + + // 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), ""); +} + +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)); + } + + TestRepeatedFieldRefIterator(enum_ref, message, + &TestAllTypes::repeated_nested_enum); + TestRepeatedFieldRefIterator(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"); + GOOGLE_CHECK(fd_repeated_int64_extension != NULL); + + 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; + scoped_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 -- cgit v1.2.3