// Protocol Buffers - Google's data interchange format // Copyright 2008 Google Inc. All rights reserved. // https://developers.google.com/protocol-buffers/ // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // Author: kenton@google.com (Kenton Varda) // Based on original Protocol Buffers design by // Sanjay Ghemawat, Jeff Dean, and others. // // To test GeneratedMessageReflection, we actually let the protocol compiler // generate a full protocol message implementation and then test its // reflection interface. This is much easier and more maintainable than // trying to create our own Message class for GeneratedMessageReflection // to wrap. // // The tests here closely mirror some of the tests in // compiler/cpp/unittest, except using the reflection interface // rather than generated accessors. #include #include #include #include #include #include #include #include #include #include #include #include #include #include // Must be included last. #include namespace google { namespace protobuf { class GeneratedMessageReflectionTestHelper { public: static void UnsafeShallowSwapFields( Message* lhs, Message* rhs, const std::vector& fields) { lhs->GetReflection()->UnsafeShallowSwapFields(lhs, rhs, fields); } static bool IsLazyExtension(const Message& msg, const FieldDescriptor* ext) { return msg.GetReflection()->IsLazyExtension(msg, ext); } static bool IsLazyField(const Message& msg, const FieldDescriptor* field) { return msg.GetReflection()->IsLazyField(field); } static bool IsEagerlyVerifiedLazyField(const Message& msg, const FieldDescriptor* field) { return msg.GetReflection()->IsEagerlyVerifiedLazyField(field); } static bool IsLazilyVerifiedLazyField(const Message& msg, const FieldDescriptor* field) { return msg.GetReflection()->IsLazilyVerifiedLazyField(field); } }; namespace { // Shorthand to get a FieldDescriptor for a field of unittest::TestAllTypes. const FieldDescriptor* F(const std::string& name) { const FieldDescriptor* result = unittest::TestAllTypes::descriptor()->FindFieldByName(name); GOOGLE_CHECK(result != nullptr); return result; } TEST(GeneratedMessageReflectionTest, Defaults) { // Check that all default values are set correctly in the initial message. unittest::TestAllTypes message; TestUtil::ReflectionTester reflection_tester( unittest::TestAllTypes::descriptor()); reflection_tester.ExpectClearViaReflection(message); const Reflection* reflection = message.GetReflection(); // Messages should return pointers to default instances until first use. // (This is not checked by ExpectClear() since it is not actually true after // the fields have been set and then cleared.) EXPECT_EQ(&unittest::TestAllTypes::OptionalGroup::default_instance(), &reflection->GetMessage(message, F("optionalgroup"))); EXPECT_EQ(&unittest::TestAllTypes::NestedMessage::default_instance(), &reflection->GetMessage(message, F("optional_nested_message"))); EXPECT_EQ(&unittest::ForeignMessage::default_instance(), &reflection->GetMessage(message, F("optional_foreign_message"))); EXPECT_EQ(&unittest_import::ImportMessage::default_instance(), &reflection->GetMessage(message, F("optional_import_message"))); } TEST(GeneratedMessageReflectionTest, Accessors) { // Set every field to a unique value then go back and check all those // values. unittest::TestAllTypes message; TestUtil::ReflectionTester reflection_tester( unittest::TestAllTypes::descriptor()); reflection_tester.SetAllFieldsViaReflection(&message); TestUtil::ExpectAllFieldsSet(message); reflection_tester.ExpectAllFieldsSetViaReflection(message); reflection_tester.ModifyRepeatedFieldsViaReflection(&message); TestUtil::ExpectRepeatedFieldsModified(message); } TEST(GeneratedMessageReflectionTest, GetStringReference) { // Test that GetStringReference() returns the underlying string when it // is a normal string field. unittest::TestAllTypes message; message.set_optional_string("foo"); message.add_repeated_string("foo"); const Reflection* reflection = message.GetReflection(); std::string scratch; EXPECT_EQ( &message.optional_string(), &reflection->GetStringReference(message, F("optional_string"), &scratch)) << "For simple string fields, GetStringReference() should return a " "reference to the underlying string."; EXPECT_EQ(&message.repeated_string(0), &reflection->GetRepeatedStringReference( message, F("repeated_string"), 0, &scratch)) << "For simple string fields, GetRepeatedStringReference() should " "return " "a reference to the underlying string."; } class GeneratedMessageReflectionSwapTest : public testing::TestWithParam { protected: void Swap(const Reflection* reflection, Message* lhs, Message* rhs) { if (GetParam()) { reflection->UnsafeArenaSwap(lhs, rhs); } else { reflection->Swap(lhs, rhs); } } void SwapFields(const Reflection* reflection, Message* lhs, Message* rhs, const std::vector& fields) { if (GetParam()) { reflection->UnsafeArenaSwapFields(lhs, rhs, fields); } else { reflection->SwapFields(lhs, rhs, fields); } } }; // unsafe_shallow_swap: true -> UnsafeArena* API. INSTANTIATE_TEST_SUITE_P(ReflectionSwap, GeneratedMessageReflectionSwapTest, testing::Bool()); TEST_P(GeneratedMessageReflectionSwapTest, LhsSet) { unittest::TestAllTypes lhs; unittest::TestAllTypes rhs; TestUtil::SetAllFields(&lhs); Swap(lhs.GetReflection(), &lhs, &rhs); TestUtil::ExpectClear(lhs); TestUtil::ExpectAllFieldsSet(rhs); } TEST_P(GeneratedMessageReflectionSwapTest, BothSet) { unittest::TestAllTypes lhs; unittest::TestAllTypes rhs; TestUtil::SetAllFields(&lhs); TestUtil::SetAllFields(&rhs); TestUtil::ModifyRepeatedFields(&rhs); const Reflection* reflection = lhs.GetReflection(); Swap(reflection, &lhs, &rhs); TestUtil::ExpectRepeatedFieldsModified(lhs); TestUtil::ExpectAllFieldsSet(rhs); lhs.set_optional_int32(532819); Swap(reflection, &lhs, &rhs); EXPECT_EQ(532819, rhs.optional_int32()); } TEST_P(GeneratedMessageReflectionSwapTest, LhsCleared) { unittest::TestAllTypes lhs; unittest::TestAllTypes rhs; TestUtil::SetAllFields(&lhs); // For proto2 message, for message field, Clear only reset hasbits, but // doesn't delete the underlying field. lhs.Clear(); Swap(lhs.GetReflection(), &lhs, &rhs); TestUtil::ExpectClear(rhs); } TEST_P(GeneratedMessageReflectionSwapTest, RhsCleared) { unittest::TestAllTypes lhs; unittest::TestAllTypes rhs; TestUtil::SetAllFields(&rhs); // For proto2 message, for message field, Clear only reset hasbits, but // doesn't delete the underlying field. rhs.Clear(); Swap(lhs.GetReflection(), &lhs, &rhs); TestUtil::ExpectClear(lhs); } TEST_P(GeneratedMessageReflectionSwapTest, Extensions) { unittest::TestAllExtensions lhs; unittest::TestAllExtensions rhs; TestUtil::SetAllExtensions(&lhs); Swap(lhs.GetReflection(), &lhs, &rhs); TestUtil::ExpectExtensionsClear(lhs); TestUtil::ExpectAllExtensionsSet(rhs); } TEST_P(GeneratedMessageReflectionSwapTest, Unknown) { unittest::TestEmptyMessage lhs, rhs; lhs.mutable_unknown_fields()->AddVarint(1234, 1); EXPECT_EQ(1, lhs.unknown_fields().field_count()); EXPECT_EQ(0, rhs.unknown_fields().field_count()); Swap(lhs.GetReflection(), &lhs, &rhs); EXPECT_EQ(0, lhs.unknown_fields().field_count()); EXPECT_EQ(1, rhs.unknown_fields().field_count()); } TEST_P(GeneratedMessageReflectionSwapTest, Oneof) { unittest::TestOneof2 lhs, rhs; TestUtil::SetOneof1(&lhs); Swap(lhs.GetReflection(), &lhs, &rhs); TestUtil::ExpectOneofClear(lhs); TestUtil::ExpectOneofSet1(rhs); } TEST_P(GeneratedMessageReflectionSwapTest, OneofBothSet) { unittest::TestOneof2 lhs, rhs; TestUtil::SetOneof1(&lhs); TestUtil::SetOneof2(&rhs); Swap(lhs.GetReflection(), &lhs, &rhs); TestUtil::ExpectOneofSet2(lhs); TestUtil::ExpectOneofSet1(rhs); } TEST_P(GeneratedMessageReflectionSwapTest, SwapFields) { std::unique_ptr lhs( Arena::CreateMessage(nullptr)); std::unique_ptr rhs( Arena::CreateMessage(nullptr)); lhs->set_optional_double(12.3); lhs->mutable_repeated_int32()->Add(10); lhs->mutable_repeated_int32()->Add(20); rhs->set_optional_string("hello"); rhs->mutable_repeated_int64()->Add(30); std::vector fields; const Descriptor* descriptor = lhs->GetDescriptor(); fields.push_back(descriptor->FindFieldByName("optional_double")); fields.push_back(descriptor->FindFieldByName("repeated_int32")); fields.push_back(descriptor->FindFieldByName("optional_string")); fields.push_back(descriptor->FindFieldByName("optional_uint64")); SwapFields(lhs->GetReflection(), lhs.get(), rhs.get(), fields); EXPECT_FALSE(lhs->has_optional_double()); EXPECT_EQ(0, lhs->repeated_int32_size()); EXPECT_TRUE(lhs->has_optional_string()); EXPECT_EQ("hello", lhs->optional_string()); EXPECT_EQ(0, lhs->repeated_int64_size()); EXPECT_FALSE(lhs->has_optional_uint64()); EXPECT_TRUE(rhs->has_optional_double()); EXPECT_EQ(12.3, rhs->optional_double()); EXPECT_EQ(2, rhs->repeated_int32_size()); EXPECT_EQ(10, rhs->repeated_int32(0)); EXPECT_EQ(20, rhs->repeated_int32(1)); EXPECT_FALSE(rhs->has_optional_string()); EXPECT_EQ(1, rhs->repeated_int64_size()); EXPECT_FALSE(rhs->has_optional_uint64()); } TEST_P(GeneratedMessageReflectionSwapTest, SwapFieldsAll) { std::unique_ptr lhs( Arena::CreateMessage(nullptr)); std::unique_ptr rhs( Arena::CreateMessage(nullptr)); TestUtil::SetAllFields(rhs.get()); std::vector fields; const Reflection* reflection = lhs->GetReflection(); reflection->ListFields(*rhs, &fields); SwapFields(reflection, lhs.get(), rhs.get(), fields); TestUtil::ExpectAllFieldsSet(*lhs); TestUtil::ExpectClear(*rhs); } TEST(GeneratedMessageReflectionTest, SwapFieldsAllOnDifferentArena) { Arena arena1, arena2; auto* message1 = Arena::CreateMessage(&arena1); auto* message2 = Arena::CreateMessage(&arena2); TestUtil::SetAllFields(message2); std::vector fields; const Reflection* reflection = message1->GetReflection(); reflection->ListFields(*message2, &fields); reflection->SwapFields(message1, message2, fields); TestUtil::ExpectAllFieldsSet(*message1); TestUtil::ExpectClear(*message2); } TEST(GeneratedMessageReflectionTest, SwapFieldsAllOnArenaHeap) { Arena arena; auto* message1 = Arena::CreateMessage(&arena); std::unique_ptr message2( Arena::CreateMessage(nullptr)); TestUtil::SetAllFields(message2.get()); std::vector fields; const Reflection* reflection = message1->GetReflection(); reflection->ListFields(*message2, &fields); reflection->SwapFields(message1, message2.get(), fields); TestUtil::ExpectAllFieldsSet(*message1); TestUtil::ExpectClear(*message2); } TEST(GeneratedMessageReflectionTest, SwapFieldsAllExtension) { unittest::TestAllExtensions message1; unittest::TestAllExtensions message2; TestUtil::SetAllExtensions(&message1); std::vector fields; const Reflection* reflection = message1.GetReflection(); reflection->ListFields(message1, &fields); reflection->SwapFields(&message1, &message2, fields); TestUtil::ExpectExtensionsClear(message1); TestUtil::ExpectAllExtensionsSet(message2); } TEST(GeneratedMessageReflectionTest, SwapFieldsAllExtensionArenaHeap) { Arena arena; std::unique_ptr message1( Arena::CreateMessage(nullptr)); auto* message2 = Arena::CreateMessage(&arena); TestUtil::SetAllExtensions(message1.get()); std::vector fields; const Reflection* reflection = message1->GetReflection(); reflection->ListFields(*message1, &fields); reflection->SwapFields(message1.get(), message2, fields); TestUtil::ExpectExtensionsClear(*message1); TestUtil::ExpectAllExtensionsSet(*message2); } TEST(GeneratedMessageReflectionTest, UnsafeShallowSwapFieldsAll) { Arena arena; auto* message1 = Arena::CreateMessage(&arena); auto* message2 = Arena::CreateMessage(&arena); TestUtil::SetAllFields(message2); auto* kept_nested_message_ptr = message2->mutable_optional_nested_message(); auto* kept_foreign_message_ptr = message2->mutable_optional_foreign_message(); auto* kept_repeated_nested_message_ptr = message2->mutable_repeated_nested_message(0); auto* kept_repeated_foreign_message_ptr = message2->mutable_repeated_foreign_message(0); std::vector fields; const Reflection* reflection = message1->GetReflection(); reflection->ListFields(*message2, &fields); GeneratedMessageReflectionTestHelper::UnsafeShallowSwapFields( message1, message2, fields); TestUtil::ExpectAllFieldsSet(*message1); TestUtil::ExpectClear(*message2); // Expects the swap to be shallow. Expects pointer stability to the element of // the repeated fields (not the container). EXPECT_EQ(kept_nested_message_ptr, message1->mutable_optional_nested_message()); EXPECT_EQ(kept_foreign_message_ptr, message1->mutable_optional_foreign_message()); EXPECT_EQ(kept_repeated_nested_message_ptr, message1->mutable_repeated_nested_message(0)); EXPECT_EQ(kept_repeated_foreign_message_ptr, message1->mutable_repeated_foreign_message(0)); } TEST(GeneratedMessageReflectionTest, UnsafeShallowSwapFieldsMap) { Arena arena; auto* message1 = Arena::CreateMessage(&arena); auto* message2 = Arena::CreateMessage(&arena); MapTestUtil::SetMapFields(message2); auto* kept_map_int32_fm_ptr = &(*message2->mutable_map_int32_foreign_message())[0]; std::vector fields; const Reflection* reflection = message1->GetReflection(); reflection->ListFields(*message2, &fields); GeneratedMessageReflectionTestHelper::UnsafeShallowSwapFields( message1, message2, fields); MapTestUtil::ExpectMapFieldsSet(*message1); MapTestUtil::ExpectClear(*message2); // Expects the swap to be shallow. EXPECT_EQ(kept_map_int32_fm_ptr, &(*message1->mutable_map_int32_foreign_message())[0]); } TEST(GeneratedMessageReflectionTest, UnsafeShallowSwapFieldsAllExtension) { Arena arena; auto* message1 = Arena::CreateMessage(&arena); auto* message2 = Arena::CreateMessage(&arena); TestUtil::SetAllExtensions(message1); auto* kept_nested_message_ext_ptr = message1->MutableExtension(unittest::optional_nested_message_extension); auto* kept_foreign_message_ext_ptr = message1->MutableExtension(unittest::optional_foreign_message_extension); auto* kept_repeated_nested_message_ext_ptr = message1->MutableRepeatedExtension( unittest::repeated_nested_message_extension); auto* kept_repeated_foreign_message_ext_ptr = message1->MutableRepeatedExtension( unittest::repeated_foreign_message_extension); std::vector fields; const Reflection* reflection = message1->GetReflection(); reflection->ListFields(*message1, &fields); GeneratedMessageReflectionTestHelper::UnsafeShallowSwapFields( message1, message2, fields); TestUtil::ExpectExtensionsClear(*message1); TestUtil::ExpectAllExtensionsSet(*message2); // Expects the swap to be shallow. EXPECT_EQ( kept_nested_message_ext_ptr, message2->MutableExtension(unittest::optional_nested_message_extension)); EXPECT_EQ( kept_foreign_message_ext_ptr, message2->MutableExtension(unittest::optional_foreign_message_extension)); EXPECT_EQ(kept_repeated_nested_message_ext_ptr, message2->MutableRepeatedExtension( unittest::repeated_nested_message_extension)); EXPECT_EQ(kept_repeated_foreign_message_ext_ptr, message2->MutableRepeatedExtension( unittest::repeated_foreign_message_extension)); } TEST(GeneratedMessageReflectionTest, SwapFieldsOneof) { unittest::TestOneof2 message1, message2; TestUtil::SetOneof1(&message1); std::vector fields; const Descriptor* descriptor = message1.GetDescriptor(); for (int i = 0; i < descriptor->field_count(); i++) { fields.push_back(descriptor->field(i)); } const Reflection* reflection = message1.GetReflection(); reflection->SwapFields(&message1, &message2, fields); TestUtil::ExpectOneofClear(message1); TestUtil::ExpectOneofSet1(message2); } TEST(GeneratedMessageReflectionTest, UnsafeShallowSwapFieldsOneof) { Arena arena; auto* message1 = Arena::CreateMessage(&arena); auto* message2 = Arena::CreateMessage(&arena); TestUtil::SetOneof1(message1); std::vector fields; const Descriptor* descriptor = message1->GetDescriptor(); for (int i = 0; i < descriptor->field_count(); i++) { fields.push_back(descriptor->field(i)); } GeneratedMessageReflectionTestHelper::UnsafeShallowSwapFields( message1, message2, fields); TestUtil::ExpectOneofClear(*message1); TestUtil::ExpectOneofSet1(*message2); } TEST(GeneratedMessageReflectionTest, UnsafeShallowSwapFieldsOneofExpectShallow) { Arena arena; auto* message1 = Arena::CreateMessage(&arena); auto* message2 = Arena::CreateMessage(&arena); TestUtil::SetOneof1(message1); message1->mutable_foo_message()->set_moo_int(1000); auto* kept_foo_ptr = message1->mutable_foo_message(); std::vector fields; const Descriptor* descriptor = message1->GetDescriptor(); for (int i = 0; i < descriptor->field_count(); i++) { fields.push_back(descriptor->field(i)); } GeneratedMessageReflectionTestHelper::UnsafeShallowSwapFields( message1, message2, fields); EXPECT_TRUE(message2->has_foo_message()); EXPECT_EQ(message2->foo_message().moo_int(), 1000); EXPECT_EQ(kept_foo_ptr, message2->mutable_foo_message()); } TEST(GeneratedMessageReflectionTest, RemoveLast) { unittest::TestAllTypes message; TestUtil::ReflectionTester reflection_tester( unittest::TestAllTypes::descriptor()); TestUtil::SetAllFields(&message); reflection_tester.RemoveLastRepeatedsViaReflection(&message); TestUtil::ExpectLastRepeatedsRemoved(message); } TEST(GeneratedMessageReflectionTest, RemoveLastExtensions) { unittest::TestAllExtensions message; TestUtil::ReflectionTester reflection_tester( unittest::TestAllExtensions::descriptor()); TestUtil::SetAllExtensions(&message); reflection_tester.RemoveLastRepeatedsViaReflection(&message); TestUtil::ExpectLastRepeatedExtensionsRemoved(message); } TEST(GeneratedMessageReflectionTest, ReleaseLast) { unittest::TestAllTypes message; const Descriptor* descriptor = message.GetDescriptor(); TestUtil::ReflectionTester reflection_tester(descriptor); TestUtil::SetAllFields(&message); reflection_tester.ReleaseLastRepeatedsViaReflection(&message, false); TestUtil::ExpectLastRepeatedsReleased(message); // Now test that we actually release the right message. message.Clear(); TestUtil::SetAllFields(&message); ASSERT_EQ(2, message.repeated_foreign_message_size()); const protobuf_unittest::ForeignMessage* expected = message.mutable_repeated_foreign_message(1); (void)expected; // unused in somce configurations std::unique_ptr released(message.GetReflection()->ReleaseLast( &message, descriptor->FindFieldByName("repeated_foreign_message"))); EXPECT_EQ(expected, released.get()); } TEST(GeneratedMessageReflectionTest, ReleaseLastExtensions) { unittest::TestAllExtensions message; const Descriptor* descriptor = message.GetDescriptor(); TestUtil::ReflectionTester reflection_tester(descriptor); TestUtil::SetAllExtensions(&message); reflection_tester.ReleaseLastRepeatedsViaReflection(&message, true); TestUtil::ExpectLastRepeatedExtensionsReleased(message); // Now test that we actually release the right message. message.Clear(); TestUtil::SetAllExtensions(&message); ASSERT_EQ( 2, message.ExtensionSize(unittest::repeated_foreign_message_extension)); const protobuf_unittest::ForeignMessage* expected = message.MutableExtension(unittest::repeated_foreign_message_extension, 1); std::unique_ptr released(message.GetReflection()->ReleaseLast( &message, descriptor->file()->FindExtensionByName( "repeated_foreign_message_extension"))); EXPECT_EQ(expected, released.get()); } TEST(GeneratedMessageReflectionTest, SwapRepeatedElements) { unittest::TestAllTypes message; TestUtil::ReflectionTester reflection_tester( unittest::TestAllTypes::descriptor()); TestUtil::SetAllFields(&message); // Swap and test that fields are all swapped. reflection_tester.SwapRepeatedsViaReflection(&message); TestUtil::ExpectRepeatedsSwapped(message); // Swap back and test that fields are all back to original values. reflection_tester.SwapRepeatedsViaReflection(&message); TestUtil::ExpectAllFieldsSet(message); } TEST(GeneratedMessageReflectionTest, SwapRepeatedElementsExtension) { unittest::TestAllExtensions message; TestUtil::ReflectionTester reflection_tester( unittest::TestAllExtensions::descriptor()); TestUtil::SetAllExtensions(&message); // Swap and test that fields are all swapped. reflection_tester.SwapRepeatedsViaReflection(&message); TestUtil::ExpectRepeatedExtensionsSwapped(message); // Swap back and test that fields are all back to original values. reflection_tester.SwapRepeatedsViaReflection(&message); TestUtil::ExpectAllExtensionsSet(message); } TEST(GeneratedMessageReflectionTest, Extensions) { // Set every extension to a unique value then go back and check all those // values. unittest::TestAllExtensions message; TestUtil::ReflectionTester reflection_tester( unittest::TestAllExtensions::descriptor()); reflection_tester.SetAllFieldsViaReflection(&message); TestUtil::ExpectAllExtensionsSet(message); reflection_tester.ExpectAllFieldsSetViaReflection(message); reflection_tester.ModifyRepeatedFieldsViaReflection(&message); TestUtil::ExpectRepeatedExtensionsModified(message); } TEST(GeneratedMessageReflectionTest, FindExtensionTypeByNumber) { const Reflection* reflection = unittest::TestAllExtensions::default_instance().GetReflection(); const FieldDescriptor* extension1 = unittest::TestAllExtensions::descriptor()->file()->FindExtensionByName( "optional_int32_extension"); const FieldDescriptor* extension2 = unittest::TestAllExtensions::descriptor()->file()->FindExtensionByName( "repeated_string_extension"); EXPECT_EQ(extension1, reflection->FindKnownExtensionByNumber(extension1->number())); EXPECT_EQ(extension2, reflection->FindKnownExtensionByNumber(extension2->number())); // Non-existent extension. EXPECT_TRUE(reflection->FindKnownExtensionByNumber(62341) == nullptr); // Extensions of TestAllExtensions should not show up as extensions of // other types. EXPECT_TRUE(unittest::TestAllTypes::default_instance() .GetReflection() ->FindKnownExtensionByNumber(extension1->number()) == nullptr); } TEST(GeneratedMessageReflectionTest, FindKnownExtensionByName) { const Reflection* reflection = unittest::TestAllExtensions::default_instance().GetReflection(); const FieldDescriptor* extension1 = unittest::TestAllExtensions::descriptor()->file()->FindExtensionByName( "optional_int32_extension"); const FieldDescriptor* extension2 = unittest::TestAllExtensions::descriptor()->file()->FindExtensionByName( "repeated_string_extension"); EXPECT_EQ(extension1, reflection->FindKnownExtensionByName(extension1->full_name())); EXPECT_EQ(extension2, reflection->FindKnownExtensionByName(extension2->full_name())); // Non-existent extension. EXPECT_TRUE(reflection->FindKnownExtensionByName("no_such_ext") == nullptr); // Extensions of TestAllExtensions should not show up as extensions of // other types. EXPECT_TRUE(unittest::TestAllTypes::default_instance() .GetReflection() ->FindKnownExtensionByName(extension1->full_name()) == nullptr); } TEST(GeneratedMessageReflectionTest, SetAllocatedMessageTest) { unittest::TestAllTypes from_message1; unittest::TestAllTypes from_message2; unittest::TestAllTypes to_message; TestUtil::ReflectionTester reflection_tester( unittest::TestAllTypes::descriptor()); reflection_tester.SetAllFieldsViaReflection(&from_message1); reflection_tester.SetAllFieldsViaReflection(&from_message2); // Before moving fields, we expect the nested messages to be nullptr. reflection_tester.ExpectMessagesReleasedViaReflection( &to_message, TestUtil::ReflectionTester::IS_NULL); // After fields are moved we should get non-nullptr releases. reflection_tester.SetAllocatedOptionalMessageFieldsToMessageViaReflection( &from_message1, &to_message); reflection_tester.ExpectMessagesReleasedViaReflection( &to_message, TestUtil::ReflectionTester::NOT_NULL); // Another move to make sure that we can SetAllocated several times. reflection_tester.SetAllocatedOptionalMessageFieldsToMessageViaReflection( &from_message2, &to_message); reflection_tester.ExpectMessagesReleasedViaReflection( &to_message, TestUtil::ReflectionTester::NOT_NULL); // After SetAllocatedOptionalMessageFieldsToNullViaReflection() we expect the // releases to be nullptr again. reflection_tester.SetAllocatedOptionalMessageFieldsToNullViaReflection( &to_message); reflection_tester.ExpectMessagesReleasedViaReflection( &to_message, TestUtil::ReflectionTester::IS_NULL); } TEST(GeneratedMessageReflectionTest, SetAllocatedMessageOnArenaTest) { unittest::TestAllTypes from_message1; unittest::TestAllTypes from_message2; Arena arena; unittest::TestAllTypes* to_message = Arena::CreateMessage(&arena); TestUtil::ReflectionTester reflection_tester( unittest::TestAllTypes::descriptor()); reflection_tester.SetAllFieldsViaReflection(&from_message1); reflection_tester.SetAllFieldsViaReflection(&from_message2); // Before moving fields, we expect the nested messages to be nullptr. reflection_tester.ExpectMessagesReleasedViaReflection( to_message, TestUtil::ReflectionTester::IS_NULL); // After fields are moved we should get non-nullptr releases. reflection_tester.SetAllocatedOptionalMessageFieldsToMessageViaReflection( &from_message1, to_message); reflection_tester.ExpectMessagesReleasedViaReflection( to_message, TestUtil::ReflectionTester::NOT_NULL); // Another move to make sure that we can SetAllocated several times. reflection_tester.SetAllocatedOptionalMessageFieldsToMessageViaReflection( &from_message2, to_message); reflection_tester.ExpectMessagesReleasedViaReflection( to_message, TestUtil::ReflectionTester::NOT_NULL); // After SetAllocatedOptionalMessageFieldsToNullViaReflection() we expect the // releases to be nullptr again. reflection_tester.SetAllocatedOptionalMessageFieldsToNullViaReflection( to_message); reflection_tester.ExpectMessagesReleasedViaReflection( to_message, TestUtil::ReflectionTester::IS_NULL); } TEST(GeneratedMessageReflectionTest, SetAllocatedExtensionMessageTest) { unittest::TestAllExtensions from_message1; unittest::TestAllExtensions from_message2; unittest::TestAllExtensions to_message; TestUtil::ReflectionTester reflection_tester( unittest::TestAllExtensions::descriptor()); reflection_tester.SetAllFieldsViaReflection(&from_message1); reflection_tester.SetAllFieldsViaReflection(&from_message2); // Before moving fields, we expect the nested messages to be nullptr. reflection_tester.ExpectMessagesReleasedViaReflection( &to_message, TestUtil::ReflectionTester::IS_NULL); // After fields are moved we should get non-nullptr releases. reflection_tester.SetAllocatedOptionalMessageFieldsToMessageViaReflection( &from_message1, &to_message); reflection_tester.ExpectMessagesReleasedViaReflection( &to_message, TestUtil::ReflectionTester::NOT_NULL); // Another move to make sure that we can SetAllocated several times. reflection_tester.SetAllocatedOptionalMessageFieldsToMessageViaReflection( &from_message2, &to_message); reflection_tester.ExpectMessagesReleasedViaReflection( &to_message, TestUtil::ReflectionTester::NOT_NULL); // After SetAllocatedOptionalMessageFieldsToNullViaReflection() we expect the // releases to be nullptr again. reflection_tester.SetAllocatedOptionalMessageFieldsToNullViaReflection( &to_message); reflection_tester.ExpectMessagesReleasedViaReflection( &to_message, TestUtil::ReflectionTester::IS_NULL); } TEST(GeneratedMessageReflectionTest, SetAllocatedExtensionMessageOnArenaTest) { Arena arena; unittest::TestAllExtensions* to_message = Arena::CreateMessage(&arena); unittest::TestAllExtensions from_message1; unittest::TestAllExtensions from_message2; TestUtil::ReflectionTester reflection_tester( unittest::TestAllExtensions::descriptor()); reflection_tester.SetAllFieldsViaReflection(&from_message1); reflection_tester.SetAllFieldsViaReflection(&from_message2); // Before moving fields, we expect the nested messages to be nullptr. reflection_tester.ExpectMessagesReleasedViaReflection( to_message, TestUtil::ReflectionTester::IS_NULL); // After fields are moved we should get non-nullptr releases. reflection_tester.SetAllocatedOptionalMessageFieldsToMessageViaReflection( &from_message1, to_message); reflection_tester.ExpectMessagesReleasedViaReflection( to_message, TestUtil::ReflectionTester::NOT_NULL); // Another move to make sure that we can SetAllocated several times. reflection_tester.SetAllocatedOptionalMessageFieldsToMessageViaReflection( &from_message2, to_message); reflection_tester.ExpectMessagesReleasedViaReflection( to_message, TestUtil::ReflectionTester::NOT_NULL); // After SetAllocatedOptionalMessageFieldsToNullViaReflection() we expect the // releases to be nullptr again. reflection_tester.SetAllocatedOptionalMessageFieldsToNullViaReflection( to_message); reflection_tester.ExpectMessagesReleasedViaReflection( to_message, TestUtil::ReflectionTester::IS_NULL); } TEST(GeneratedMessageReflectionTest, AddRepeatedMessage) { unittest::TestAllTypes message; const Reflection* reflection = message.GetReflection(); const Reflection* nested_reflection = unittest::TestAllTypes::NestedMessage::default_instance().GetReflection(); const FieldDescriptor* nested_bb = unittest::TestAllTypes::NestedMessage::descriptor()->FindFieldByName( "bb"); Message* nested = reflection->AddMessage(&message, F("repeated_nested_message")); nested_reflection->SetInt32(nested, nested_bb, 11); EXPECT_EQ(11, message.repeated_nested_message(0).bb()); } TEST(GeneratedMessageReflectionTest, MutableRepeatedMessage) { unittest::TestAllTypes message; const Reflection* reflection = message.GetReflection(); const Reflection* nested_reflection = unittest::TestAllTypes::NestedMessage::default_instance().GetReflection(); const FieldDescriptor* nested_bb = unittest::TestAllTypes::NestedMessage::descriptor()->FindFieldByName( "bb"); message.add_repeated_nested_message()->set_bb(12); Message* nested = reflection->MutableRepeatedMessage( &message, F("repeated_nested_message"), 0); EXPECT_EQ(12, nested_reflection->GetInt32(*nested, nested_bb)); nested_reflection->SetInt32(nested, nested_bb, 13); EXPECT_EQ(13, message.repeated_nested_message(0).bb()); } TEST(GeneratedMessageReflectionTest, AddAllocatedMessage) { unittest::TestAllTypes message; const Reflection* reflection = message.GetReflection(); unittest::TestAllTypes::NestedMessage* nested = new unittest::TestAllTypes::NestedMessage(); nested->set_bb(11); reflection->AddAllocatedMessage(&message, F("repeated_nested_message"), nested); EXPECT_EQ(1, message.repeated_nested_message_size()); EXPECT_EQ(11, message.repeated_nested_message(0).bb()); } TEST(GeneratedMessageReflectionTest, ListFieldsOneOf) { unittest::TestOneof2 message; TestUtil::SetOneof1(&message); const Reflection* reflection = message.GetReflection(); std::vector fields; reflection->ListFields(message, &fields); EXPECT_EQ(4, fields.size()); } TEST(GeneratedMessageReflectionTest, Oneof) { unittest::TestOneof2 message; const Descriptor* descriptor = message.GetDescriptor(); const Reflection* reflection = message.GetReflection(); // Check default values. EXPECT_EQ( 0, reflection->GetInt32(message, descriptor->FindFieldByName("foo_int"))); EXPECT_EQ("", reflection->GetString( message, descriptor->FindFieldByName("foo_string"))); EXPECT_EQ("", reflection->GetString(message, descriptor->FindFieldByName("foo_cord"))); EXPECT_EQ("", reflection->GetString( message, descriptor->FindFieldByName("foo_string_piece"))); EXPECT_EQ("", reflection->GetString( message, descriptor->FindFieldByName("foo_bytes"))); EXPECT_EQ( unittest::TestOneof2::FOO, reflection->GetEnum(message, descriptor->FindFieldByName("foo_enum")) ->number()); EXPECT_EQ(&unittest::TestOneof2::NestedMessage::default_instance(), &reflection->GetMessage( message, descriptor->FindFieldByName("foo_message"))); EXPECT_EQ(&unittest::TestOneof2::FooGroup::default_instance(), &reflection->GetMessage(message, descriptor->FindFieldByName("foogroup"))); EXPECT_NE(&unittest::TestOneof2::FooGroup::default_instance(), &reflection->GetMessage( message, descriptor->FindFieldByName("foo_lazy_message"))); EXPECT_EQ( 5, reflection->GetInt32(message, descriptor->FindFieldByName("bar_int"))); EXPECT_EQ("STRING", reflection->GetString( message, descriptor->FindFieldByName("bar_string"))); EXPECT_EQ("CORD", reflection->GetString( message, descriptor->FindFieldByName("bar_cord"))); EXPECT_EQ("SPIECE", reflection->GetString( message, descriptor->FindFieldByName("bar_string_piece"))); EXPECT_EQ("BYTES", reflection->GetString( message, descriptor->FindFieldByName("bar_bytes"))); EXPECT_EQ( unittest::TestOneof2::BAR, reflection->GetEnum(message, descriptor->FindFieldByName("bar_enum")) ->number()); // Check Set functions. reflection->SetInt32(&message, descriptor->FindFieldByName("foo_int"), 123); EXPECT_EQ(123, reflection->GetInt32(message, descriptor->FindFieldByName("foo_int"))); reflection->SetString(&message, descriptor->FindFieldByName("foo_string"), "abc"); EXPECT_EQ("abc", reflection->GetString( message, descriptor->FindFieldByName("foo_string"))); reflection->SetString(&message, descriptor->FindFieldByName("foo_bytes"), "bytes"); EXPECT_EQ("bytes", reflection->GetString( message, descriptor->FindFieldByName("foo_bytes"))); reflection->SetString(&message, descriptor->FindFieldByName("bar_cord"), "change_cord"); EXPECT_EQ( "change_cord", reflection->GetString(message, descriptor->FindFieldByName("bar_cord"))); reflection->SetString(&message, descriptor->FindFieldByName("bar_string_piece"), "change_spiece"); EXPECT_EQ("change_spiece", reflection->GetString( message, descriptor->FindFieldByName("bar_string_piece"))); message.clear_foo(); message.clear_bar(); TestUtil::ExpectOneofClear(message); } TEST(GeneratedMessageReflectionTest, SetAllocatedOneofMessageTest) { unittest::TestOneof2 from_message1; unittest::TestOneof2 from_message2; unittest::TestOneof2 to_message; const Descriptor* descriptor = unittest::TestOneof2::descriptor(); const Reflection* reflection = to_message.GetReflection(); Message* released = reflection->ReleaseMessage( &to_message, descriptor->FindFieldByName("foo_lazy_message")); EXPECT_TRUE(released == nullptr); released = reflection->ReleaseMessage( &to_message, descriptor->FindFieldByName("foo_message")); EXPECT_TRUE(released == nullptr); TestUtil::ReflectionTester::SetOneofViaReflection(&from_message1); TestUtil::ReflectionTester::ExpectOneofSetViaReflection(from_message1); TestUtil::ReflectionTester:: SetAllocatedOptionalMessageFieldsToMessageViaReflection(&from_message1, &to_message); const Message& sub_message = reflection->GetMessage( to_message, descriptor->FindFieldByName("foo_lazy_message")); (void)sub_message; // unused in somce configurations released = reflection->ReleaseMessage( &to_message, descriptor->FindFieldByName("foo_lazy_message")); EXPECT_TRUE(released != nullptr); EXPECT_EQ(&sub_message, released); delete released; TestUtil::ReflectionTester::SetOneofViaReflection(&from_message2); reflection->MutableMessage(&from_message2, descriptor->FindFieldByName("foo_message")); TestUtil::ReflectionTester:: SetAllocatedOptionalMessageFieldsToMessageViaReflection(&from_message2, &to_message); const Message& sub_message2 = reflection->GetMessage( to_message, descriptor->FindFieldByName("foo_message")); (void)sub_message2; // unused in somce configurations released = reflection->ReleaseMessage( &to_message, descriptor->FindFieldByName("foo_message")); EXPECT_TRUE(released != nullptr); EXPECT_EQ(&sub_message2, released); delete released; } TEST(GeneratedMessageReflectionTest, SetAllocatedOneofMessageOnArenaTest) { unittest::TestOneof2 from_message1; unittest::TestOneof2 from_message2; Arena arena; unittest::TestOneof2* to_message = Arena::CreateMessage(&arena); const Descriptor* descriptor = unittest::TestOneof2::descriptor(); const Reflection* reflection = to_message->GetReflection(); Message* released = reflection->ReleaseMessage( to_message, descriptor->FindFieldByName("foo_lazy_message")); EXPECT_TRUE(released == nullptr); released = reflection->ReleaseMessage( to_message, descriptor->FindFieldByName("foo_message")); EXPECT_TRUE(released == nullptr); TestUtil::ReflectionTester::SetOneofViaReflection(&from_message1); TestUtil::ReflectionTester::ExpectOneofSetViaReflection(from_message1); TestUtil::ReflectionTester:: SetAllocatedOptionalMessageFieldsToMessageViaReflection(&from_message1, to_message); const Message& sub_message = reflection->GetMessage( *to_message, descriptor->FindFieldByName("foo_lazy_message")); released = reflection->ReleaseMessage( to_message, descriptor->FindFieldByName("foo_lazy_message")); EXPECT_TRUE(released != nullptr); // Since sub_message is arena allocated, releasing it results in copying it // into new heap-allocated memory. EXPECT_NE(&sub_message, released); delete released; TestUtil::ReflectionTester::SetOneofViaReflection(&from_message2); reflection->MutableMessage(&from_message2, descriptor->FindFieldByName("foo_message")); TestUtil::ReflectionTester:: SetAllocatedOptionalMessageFieldsToMessageViaReflection(&from_message2, to_message); const Message& sub_message2 = reflection->GetMessage( *to_message, descriptor->FindFieldByName("foo_message")); released = reflection->ReleaseMessage( to_message, descriptor->FindFieldByName("foo_message")); EXPECT_TRUE(released != nullptr); // Since sub_message2 is arena allocated, releasing it results in copying it // into new heap-allocated memory. EXPECT_NE(&sub_message2, released); delete released; } TEST(GeneratedMessageReflectionTest, ReleaseMessageTest) { unittest::TestAllTypes message; TestUtil::ReflectionTester reflection_tester( unittest::TestAllTypes::descriptor()); // When nothing is set, we expect all released messages to be nullptr. reflection_tester.ExpectMessagesReleasedViaReflection( &message, TestUtil::ReflectionTester::IS_NULL); // After fields are set we should get non-nullptr releases. reflection_tester.SetAllFieldsViaReflection(&message); reflection_tester.ExpectMessagesReleasedViaReflection( &message, TestUtil::ReflectionTester::NOT_NULL); // After Clear() we may or may not get a message from ReleaseMessage(). // This is implementation specific. reflection_tester.SetAllFieldsViaReflection(&message); message.Clear(); reflection_tester.ExpectMessagesReleasedViaReflection( &message, TestUtil::ReflectionTester::CAN_BE_NULL); // Test a different code path for setting after releasing. TestUtil::SetAllFields(&message); TestUtil::ExpectAllFieldsSet(message); } TEST(GeneratedMessageReflectionTest, ReleaseExtensionMessageTest) { unittest::TestAllExtensions message; TestUtil::ReflectionTester reflection_tester( unittest::TestAllExtensions::descriptor()); // When nothing is set, we expect all released messages to be nullptr. reflection_tester.ExpectMessagesReleasedViaReflection( &message, TestUtil::ReflectionTester::IS_NULL); // After fields are set we should get non-nullptr releases. reflection_tester.SetAllFieldsViaReflection(&message); reflection_tester.ExpectMessagesReleasedViaReflection( &message, TestUtil::ReflectionTester::NOT_NULL); // After Clear() we may or may not get a message from ReleaseMessage(). // This is implementation specific. reflection_tester.SetAllFieldsViaReflection(&message); message.Clear(); reflection_tester.ExpectMessagesReleasedViaReflection( &message, TestUtil::ReflectionTester::CAN_BE_NULL); // Test a different code path for setting after releasing. TestUtil::SetAllExtensions(&message); TestUtil::ExpectAllExtensionsSet(message); } TEST(GeneratedMessageReflectionTest, ReleaseOneofMessageTest) { unittest::TestOneof2 message; TestUtil::ReflectionTester::SetOneofViaReflection(&message); const Descriptor* descriptor = unittest::TestOneof2::descriptor(); const Reflection* reflection = message.GetReflection(); const Message& sub_message = reflection->GetMessage( message, descriptor->FindFieldByName("foo_lazy_message")); (void)sub_message; // unused in somce configurations Message* released = reflection->ReleaseMessage( &message, descriptor->FindFieldByName("foo_lazy_message")); EXPECT_TRUE(released != nullptr); EXPECT_EQ(&sub_message, released); delete released; released = reflection->ReleaseMessage( &message, descriptor->FindFieldByName("foo_lazy_message")); EXPECT_TRUE(released == nullptr); } TEST(GeneratedMessageReflectionTest, ArenaReleaseMessageTest) { Arena arena; unittest::TestAllTypes* message = Arena::CreateMessage(&arena); TestUtil::ReflectionTester reflection_tester( unittest::TestAllTypes::descriptor()); // When nothing is set, we expect all released messages to be nullptr. reflection_tester.ExpectMessagesReleasedViaReflection( message, TestUtil::ReflectionTester::IS_NULL); // After fields are set we should get non-nullptr releases. reflection_tester.SetAllFieldsViaReflection(message); reflection_tester.ExpectMessagesReleasedViaReflection( message, TestUtil::ReflectionTester::NOT_NULL); // After Clear() we may or may not get a message from ReleaseMessage(). // This is implementation specific. reflection_tester.SetAllFieldsViaReflection(message); message->Clear(); reflection_tester.ExpectMessagesReleasedViaReflection( message, TestUtil::ReflectionTester::CAN_BE_NULL); } TEST(GeneratedMessageReflectionTest, ArenaReleaseExtensionMessageTest) { Arena arena; unittest::TestAllExtensions* message = Arena::CreateMessage(&arena); TestUtil::ReflectionTester reflection_tester( unittest::TestAllExtensions::descriptor()); // When nothing is set, we expect all released messages to be nullptr. reflection_tester.ExpectMessagesReleasedViaReflection( message, TestUtil::ReflectionTester::IS_NULL); // After fields are set we should get non-nullptr releases. reflection_tester.SetAllFieldsViaReflection(message); reflection_tester.ExpectMessagesReleasedViaReflection( message, TestUtil::ReflectionTester::NOT_NULL); // After Clear() we may or may not get a message from ReleaseMessage(). // This is implementation specific. reflection_tester.SetAllFieldsViaReflection(message); message->Clear(); reflection_tester.ExpectMessagesReleasedViaReflection( message, TestUtil::ReflectionTester::CAN_BE_NULL); } TEST(GeneratedMessageReflectionTest, ArenaReleaseOneofMessageTest) { Arena arena; unittest::TestOneof2* message = Arena::CreateMessage(&arena); TestUtil::ReflectionTester::SetOneofViaReflection(message); const Descriptor* descriptor = unittest::TestOneof2::descriptor(); const Reflection* reflection = message->GetReflection(); Message* released = reflection->ReleaseMessage( message, descriptor->FindFieldByName("foo_lazy_message")); EXPECT_TRUE(released != nullptr); delete released; released = reflection->ReleaseMessage( message, descriptor->FindFieldByName("foo_lazy_message")); EXPECT_TRUE(released == nullptr); } #ifdef PROTOBUF_HAS_DEATH_TEST TEST(GeneratedMessageReflectionTest, UsageErrors) { unittest::TestAllTypes message; const Reflection* reflection = message.GetReflection(); const Descriptor* descriptor = message.GetDescriptor(); #define f(NAME) descriptor->FindFieldByName(NAME) // Testing every single failure mode would be too much work. Let's just // check a few. EXPECT_DEATH( reflection->GetInt32(message, descriptor->FindFieldByName("optional_int64")), "Protocol Buffer reflection usage error:\n" " Method : google::protobuf::Reflection::GetInt32\n" " Message type: protobuf_unittest\\.TestAllTypes\n" " Field : protobuf_unittest\\.TestAllTypes\\.optional_int64\n" " Problem : Field is not the right type for this message:\n" " Expected : CPPTYPE_INT32\n" " Field type: CPPTYPE_INT64"); EXPECT_DEATH(reflection->GetInt32( message, descriptor->FindFieldByName("repeated_int32")), "Protocol Buffer reflection usage error:\n" " Method : google::protobuf::Reflection::GetInt32\n" " Message type: protobuf_unittest.TestAllTypes\n" " Field : protobuf_unittest.TestAllTypes.repeated_int32\n" " Problem : Field is repeated; the method requires a " "singular field."); EXPECT_DEATH( reflection->GetInt32( message, unittest::ForeignMessage::descriptor()->FindFieldByName("c")), "Protocol Buffer reflection usage error:\n" " Method : google::protobuf::Reflection::GetInt32\n" " Message type: protobuf_unittest.TestAllTypes\n" " Field : protobuf_unittest.ForeignMessage.c\n" " Problem : Field does not match message type."); EXPECT_DEATH( reflection->HasField( message, unittest::ForeignMessage::descriptor()->FindFieldByName("c")), "Protocol Buffer reflection usage error:\n" " Method : google::protobuf::Reflection::HasField\n" " Message type: protobuf_unittest.TestAllTypes\n" " Field : protobuf_unittest.ForeignMessage.c\n" " Problem : Field does not match message type."); #undef f } #endif // PROTOBUF_HAS_DEATH_TEST using internal::IsDescendant; TEST(GeneratedMessageReflection, IsDescendantMessage) { unittest::TestAllTypes msg1, msg2; TestUtil::SetAllFields(&msg1); msg2 = msg1; EXPECT_TRUE(IsDescendant(msg1, msg1.optional_nested_message())); EXPECT_TRUE(IsDescendant(msg1, msg1.repeated_foreign_message(0))); EXPECT_FALSE(IsDescendant(msg1, msg2.optional_nested_message())); EXPECT_FALSE(IsDescendant(msg1, msg2.repeated_foreign_message(0))); } TEST(GeneratedMessageReflection, IsDescendantMap) { unittest::TestMap msg1, msg2; (*msg1.mutable_map_int32_foreign_message())[0].set_c(100); TestUtil::SetAllFields(&(*msg1.mutable_map_int32_all_types())[0]); msg2 = msg1; EXPECT_TRUE(IsDescendant(msg1, msg1.map_int32_foreign_message().at(0))); EXPECT_TRUE(IsDescendant(msg1, msg1.map_int32_all_types().at(0))); EXPECT_FALSE(IsDescendant(msg1, msg2.map_int32_foreign_message().at(0))); EXPECT_FALSE(IsDescendant(msg1, msg2.map_int32_all_types().at(0))); } TEST(GeneratedMessageReflection, IsDescendantExtension) { unittest::TestAllExtensions msg1, msg2; TestUtil::SetAllExtensions(&msg1); msg2 = msg1; EXPECT_TRUE(IsDescendant( msg1, msg1.GetExtension(unittest::optional_nested_message_extension))); EXPECT_TRUE(IsDescendant( msg1, msg1.GetExtension(unittest::repeated_foreign_message_extension, 0))); EXPECT_FALSE(IsDescendant( msg1, msg2.GetExtension(unittest::optional_nested_message_extension))); EXPECT_FALSE(IsDescendant( msg1, msg2.GetExtension(unittest::repeated_foreign_message_extension, 0))); } TEST(GeneratedMessageReflection, IsDescendantOneof) { unittest::TestOneof msg1, msg2; TestUtil::SetAllFields(msg1.mutable_foo_message()); msg2 = msg1; EXPECT_TRUE(IsDescendant(msg1, msg1.foo_message().optional_nested_message())); EXPECT_TRUE( IsDescendant(msg1, msg1.foo_message().repeated_foreign_message(0))); EXPECT_FALSE( IsDescendant(msg1, msg2.foo_message().optional_nested_message())); EXPECT_FALSE( IsDescendant(msg1, msg2.foo_message().repeated_foreign_message(0))); } } // namespace } // namespace protobuf } // namespace google