// 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 "google/protobuf/generated_message_reflection.h"

#include <memory>

#include "google/protobuf/stubs/logging.h"
#include "google/protobuf/stubs/common.h"
#include "google/protobuf/map_unittest.pb.h"
#include "google/protobuf/unittest.pb.h"
#include "google/protobuf/unittest_mset.pb.h"
#include "google/protobuf/unittest_mset_wire_format.pb.h"
#include "google/protobuf/arena.h"
#include "google/protobuf/descriptor.h"
#include "google/protobuf/testing/googletest.h"
#include <gtest/gtest.h>
#include "absl/strings/cord.h"
#include "google/protobuf/map_test_util.h"
#include "google/protobuf/test_util.h"

// Must be included last.
#include "google/protobuf/port_def.inc"

namespace google {
namespace protobuf {

class GeneratedMessageReflectionTestHelper {
 public:
  static void UnsafeShallowSwapFields(
      Message* lhs, Message* rhs,
      const std::vector<const FieldDescriptor*>& 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<bool> {
 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<const FieldDescriptor*>& 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<unittest::TestAllTypes> lhs(
      Arena::CreateMessage<unittest::TestAllTypes>(nullptr));
  std::unique_ptr<unittest::TestAllTypes> rhs(
      Arena::CreateMessage<unittest::TestAllTypes>(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<const FieldDescriptor*> 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<unittest::TestAllTypes> lhs(
      Arena::CreateMessage<unittest::TestAllTypes>(nullptr));
  std::unique_ptr<unittest::TestAllTypes> rhs(
      Arena::CreateMessage<unittest::TestAllTypes>(nullptr));

  TestUtil::SetAllFields(rhs.get());

  std::vector<const FieldDescriptor*> 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<unittest::TestAllTypes>(&arena1);
  auto* message2 = Arena::CreateMessage<unittest::TestAllTypes>(&arena2);

  TestUtil::SetAllFields(message2);

  std::vector<const FieldDescriptor*> 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<unittest::TestAllTypes>(&arena);
  std::unique_ptr<unittest::TestAllTypes> message2(
      Arena::CreateMessage<unittest::TestAllTypes>(nullptr));

  TestUtil::SetAllFields(message2.get());

  std::vector<const FieldDescriptor*> 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<const FieldDescriptor*> 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<unittest::TestAllExtensions> message1(
      Arena::CreateMessage<unittest::TestAllExtensions>(nullptr));
  auto* message2 = Arena::CreateMessage<unittest::TestAllExtensions>(&arena);

  TestUtil::SetAllExtensions(message1.get());

  std::vector<const FieldDescriptor*> 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<unittest::TestAllTypes>(&arena);
  auto* message2 = Arena::CreateMessage<unittest::TestAllTypes>(&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<const FieldDescriptor*> 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<unittest::TestMap>(&arena);
  auto* message2 = Arena::CreateMessage<unittest::TestMap>(&arena);

  MapTestUtil::SetMapFields(message2);

  auto* kept_map_int32_fm_ptr =
      &(*message2->mutable_map_int32_foreign_message())[0];

  std::vector<const FieldDescriptor*> 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<unittest::TestAllExtensions>(&arena);
  auto* message2 = Arena::CreateMessage<unittest::TestAllExtensions>(&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<const FieldDescriptor*> 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<const FieldDescriptor*> 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<unittest::TestOneof2>(&arena);
  auto* message2 = Arena::CreateMessage<unittest::TestOneof2>(&arena);
  TestUtil::SetOneof1(message1);

  std::vector<const FieldDescriptor*> 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<unittest::TestOneof2>(&arena);
  auto* message2 = Arena::CreateMessage<unittest::TestOneof2>(&arena);
  TestUtil::SetOneof1(message1);
  message1->mutable_foo_message()->set_moo_int(1000);
  auto* kept_foo_ptr = message1->mutable_foo_message();

  std::vector<const FieldDescriptor*> 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<Message> 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<Message> 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<unittest::TestAllTypes>(&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<unittest::TestAllExtensions>(&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<const FieldDescriptor*> 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<unittest::TestOneof2>(&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<unittest::TestAllTypes>(&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<unittest::TestAllExtensions>(&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<unittest::TestOneof2>(&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();

  // 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.");
}

#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
