text:
// 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: tgs@google.com (Tom Szymanski)
//
// Test reflection methods for aggregate access to Repeated[Ptr]Fields.
// This test proto2 methods on a proto2 layout.

#include <google/protobuf/stubs/casts.h>
#include <google/protobuf/stubs/stringprintf.h>
#include <google/protobuf/dynamic_message.h>
#include <google/protobuf/unittest.pb.h>
#include <google/protobuf/test_util.h>
#include <google/protobuf/reflection.h>
#include <gtest/gtest.h>

namespace google {
namespace protobuf {

using unittest::ForeignMessage;
using unittest::TestAllTypes;
using unittest::TestAllExtensions;

namespace {

static int Func(int i, int j) {
  return i * j;
}

static string StrFunc(int i, int j) {
  string str;
  SStringPrintf(&str, "%d", Func(i, 4));
  return str;
}

TEST(RepeatedFieldReflectionTest, RegularFields) {
  TestAllTypes message;
  const Reflection* refl = message.GetReflection();
  const Descriptor* desc = message.GetDescriptor();

  for (int i = 0; i < 10; ++i) {
    message.add_repeated_int32(Func(i, 1));
    message.add_repeated_double(Func(i, 2));
    message.add_repeated_string(StrFunc(i, 5));
    message.add_repeated_foreign_message()->set_c(Func(i, 6));
  }

  // Get FieldDescriptors for all the fields of interest.
  const FieldDescriptor* fd_repeated_int32 =
      desc->FindFieldByName("repeated_int32");
  const FieldDescriptor* fd_repeated_double =
      desc->FindFieldByName("repeated_double");
  const FieldDescriptor* fd_repeated_string =
      desc->FindFieldByName("repeated_string");
  const FieldDescriptor* fd_repeated_foreign_message =
      desc->FindFieldByName("repeated_foreign_message");

  // Get RepeatedField objects for all fields of interest.
  const RepeatedField<int32>& rf_int32 =
      refl->GetRepeatedField<int32>(message, fd_repeated_int32);
  const RepeatedField<double>& rf_double =
      refl->GetRepeatedField<double>(message, fd_repeated_double);

  // Get mutable RepeatedField objects for all fields of interest.
  RepeatedField<int32>* mrf_int32 =
      refl->MutableRepeatedField<int32>(&message, fd_repeated_int32);
  RepeatedField<double>* mrf_double =
      refl->MutableRepeatedField<double>(&message, fd_repeated_double);

  // Get RepeatedPtrField objects for all fields of interest.
  const RepeatedPtrField<string>& rpf_string =
      refl->GetRepeatedPtrField<string>(message, fd_repeated_string);
  const RepeatedPtrField<ForeignMessage>& rpf_foreign_message =
      refl->GetRepeatedPtrField<ForeignMessage>(
          message, fd_repeated_foreign_message);
  const RepeatedPtrField<Message>& rpf_message =
      refl->GetRepeatedPtrField<Message>(
          message, fd_repeated_foreign_message);

  // Get mutable RepeatedPtrField objects for all fields of interest.
  RepeatedPtrField<string>* mrpf_string =
      refl->MutableRepeatedPtrField<string>(&message, fd_repeated_string);
  RepeatedPtrField<ForeignMessage>* mrpf_foreign_message =
      refl->MutableRepeatedPtrField<ForeignMessage>(
          &message, fd_repeated_foreign_message);
  RepeatedPtrField<Message>* mrpf_message =
      refl->MutableRepeatedPtrField<Message>(
          &message, fd_repeated_foreign_message);

  // Make sure we can do gets and sets through the Repeated[Ptr]Field objects.
  for (int i = 0; i < 10; ++i) {
    // Check gets through const objects.
    EXPECT_EQ(rf_int32.Get(i), Func(i, 1));
    EXPECT_EQ(rf_double.Get(i), Func(i, 2));
    EXPECT_EQ(rpf_string.Get(i), StrFunc(i, 5));
    EXPECT_EQ(rpf_foreign_message.Get(i).c(), Func(i, 6));
    EXPECT_EQ(down_cast<const ForeignMessage*>(&rpf_message.Get(i))->c(),
              Func(i, 6));

    // Check gets through mutable objects.
    EXPECT_EQ(mrf_int32->Get(i), Func(i, 1));
    EXPECT_EQ(mrf_double->Get(i), Func(i, 2));
    EXPECT_EQ(mrpf_string->Get(i), StrFunc(i, 5));
    EXPECT_EQ(mrpf_foreign_message->Get(i).c(), Func(i, 6));
    EXPECT_EQ(down_cast<const ForeignMessage*>(&mrpf_message->Get(i))->c(),
              Func(i, 6));

    // Check sets through mutable objects.
    mrf_int32->Set(i, Func(i, -1));
    mrf_double->Set(i, Func(i, -2));
    mrpf_string->Mutable(i)->assign(StrFunc(i, -5));
    mrpf_foreign_message->Mutable(i)->set_c(Func(i, -6));
    EXPECT_EQ(message.repeated_int32(i), Func(i, -1));
    EXPECT_EQ(message.repeated_double(i), Func(i, -2));
    EXPECT_EQ(message.repeated_string(i), StrFunc(i, -5));
    EXPECT_EQ(message.repeated_foreign_message(i).c(), Func(i, -6));
    down_cast<ForeignMessage*>(mrpf_message->Mutable(i))->set_c(Func(i, 7));
    EXPECT_EQ(message.repeated_foreign_message(i).c(), Func(i, 7));
  }

#ifdef PROTOBUF_HAS_DEATH_TEST
  // Make sure types are checked correctly at runtime.
  const FieldDescriptor* fd_optional_int32 =
      desc->FindFieldByName("optional_int32");
  EXPECT_DEATH(refl->GetRepeatedField<int32>(
      message, fd_optional_int32), "requires a repeated field");
  EXPECT_DEATH(refl->GetRepeatedField<double>(
      message, fd_repeated_int32), "not the right type");
  EXPECT_DEATH(refl->GetRepeatedPtrField<TestAllTypes>(
      message, fd_repeated_foreign_message), "wrong submessage type");
#endif  // PROTOBUF_HAS_DEATH_TEST
}

TEST(RepeatedFieldReflectionTest, ExtensionFields) {
  TestAllExtensions extended_message;
  const Reflection* refl = extended_message.GetReflection();
  const Descriptor* desc = extended_message.GetDescriptor();

  for (int i = 0; i < 10; ++i) {
    extended_message.AddExtension(
        unittest::repeated_int64_extension, Func(i, 1));
  }

  const FieldDescriptor* fd_repeated_int64_extension =
      desc->file()->FindExtensionByName("repeated_int64_extension");
  GOOGLE_CHECK(fd_repeated_int64_extension != NULL);

  const RepeatedField<int64>& rf_int64_extension =
      refl->GetRepeatedField<int64>(extended_message,
                                    fd_repeated_int64_extension);

  RepeatedField<int64>* mrf_int64_extension =
      refl->MutableRepeatedField<int64>(&extended_message,
                                        fd_repeated_int64_extension);

  for (int i = 0; i < 10; ++i) {
    EXPECT_EQ(Func(i, 1), rf_int64_extension.Get(i));
    mrf_int64_extension->Set(i, Func(i, -1));
    EXPECT_EQ(Func(i, -1),
        extended_message.GetExtension(unittest::repeated_int64_extension, i));
  }
}

template <typename Ref, typename MessageType, typename ValueType>
void TestRepeatedFieldRefIteratorForPrimitive(
    const Ref& handle, const MessageType& message,
    ValueType (MessageType::*GetFunc)(int) const) {
  int index = 0;
  for (typename Ref::const_iterator it = handle.begin();
       it != handle.end(); ++it) {
    EXPECT_EQ((message.*GetFunc)(index), *it);
    ++index;
  }
  EXPECT_EQ(handle.size(), index);
}

template <typename MessageType, typename ValueType>
void TestRepeatedFieldRefIteratorForString(
    const RepeatedFieldRef<string>& handle, const MessageType& message,
    ValueType (MessageType::*GetFunc)(int) const) {
  int index = 0;
  for (typename RepeatedFieldRef<string>::const_iterator it = handle.begin();
       it != handle.end(); ++it) {
    // Test both operator* and operator->
    EXPECT_EQ((message.*GetFunc)(index), *it);
    EXPECT_EQ((message.*GetFunc)(index).size(), it->size());
    ++index;
  }
  EXPECT_EQ(handle.size(), index);
}

TEST(RepeatedFieldReflectionTest, RepeatedFieldRefForRegularFields) {
  TestAllTypes message;
  const Reflection* refl = message.GetReflection();
  const Descriptor* desc = message.GetDescriptor();

  for (int i = 0; i < 10; ++i) {
    message.add_repeated_int32(Func(i, 1));
    message.add_repeated_double(Func(i, 2));
    message.add_repeated_string(StrFunc(i, 5));
    message.add_repeated_foreign_message()->set_c(Func(i, 6));
  }

  // Get FieldDescriptors for all the fields of interest.
  const FieldDescriptor* fd_repeated_int32 =
      desc->FindFieldByName("repeated_int32");
  const FieldDescriptor* fd_repeated_double =
      desc->FindFieldByName("repeated_double");
  const FieldDescriptor* fd_repeated_string =
      desc->FindFieldByName("repeated_string");
  const FieldDescriptor* fd_repeated_foreign_message =
      desc->FindFieldByName("repeated_foreign_message");

  // Get RepeatedFieldRef objects for all fields of interest.
  const RepeatedFieldRef<int32> rf_int32 =
      refl->GetRepeatedFieldRef<int32>(message, fd_repeated_int32);
  const RepeatedFieldRef<double> rf_double =
      refl->GetRepeatedFieldRef<double>(message, fd_repeated_double);
  const RepeatedFieldRef<string> rf_string =
      refl->GetRepeatedFieldRef<string>(message, fd_repeated_string);
  const RepeatedFieldRef<ForeignMessage> rf_foreign_message =
      refl->GetRepeatedFieldRef<ForeignMessage>(
          message, fd_repeated_foreign_message);
  const RepeatedFieldRef<Message> rf_message =
      refl->GetRepeatedFieldRef<Message>(
          message, fd_repeated_foreign_message);

  // Get MutableRepeatedFieldRef objects for all fields of interest.
  const MutableRepeatedFieldRef<int32> mrf_int32 =
      refl->GetMutableRepeatedFieldRef<int32>(&message, fd_repeated_int32);
  const MutableRepeatedFieldRef<double> mrf_double =
      refl->GetMutableRepeatedFieldRef<double>(&message, fd_repeated_double);
  const MutableRepeatedFieldRef<string> mrf_string =
      refl->GetMutableRepeatedFieldRef<string>(&message, fd_repeated_string);
  const MutableRepeatedFieldRef<ForeignMessage> mrf_foreign_message =
      refl->GetMutableRepeatedFieldRef<ForeignMessage>(
          &message, fd_repeated_foreign_message);
  const MutableRepeatedFieldRef<Message> mrf_message =
      refl->GetMutableRepeatedFieldRef<Message>(
          &message, fd_repeated_foreign_message);

  EXPECT_EQ(message.repeated_int32_size(), rf_int32.size());
  EXPECT_EQ(message.repeated_int32_size(), mrf_int32.size());
  EXPECT_EQ(message.repeated_double_size(), rf_double.size());
  EXPECT_EQ(message.repeated_double_size(), mrf_double.size());
  EXPECT_EQ(message.repeated_string_size(), rf_string.size());
  EXPECT_EQ(message.repeated_string_size(), mrf_string.size());
  EXPECT_EQ(message.repeated_foreign_message_size(),
            rf_foreign_message.size());
  EXPECT_EQ(message.repeated_foreign_message_size(),
            mrf_foreign_message.size());
  EXPECT_EQ(message.repeated_foreign_message_size(), rf_message.size());
  EXPECT_EQ(message.repeated_foreign_message_size(), mrf_message.size());

  EXPECT_FALSE(rf_int32.empty());
  EXPECT_FALSE(mrf_int32.empty());
  EXPECT_FALSE(rf_double.empty());
  EXPECT_FALSE(mrf_double.empty());
  EXPECT_FALSE(rf_string.empty());
  EXPECT_FALSE(mrf_string.empty());
  EXPECT_FALSE(rf_foreign_message.empty());
  EXPECT_FALSE(mrf_foreign_message.empty());
  EXPECT_FALSE(rf_message.empty());
  EXPECT_FALSE(mrf_message.empty());

  // Make sure we can do gets and sets through the RepeatedFieldRef objects.
  for (int i = 0; i < 10; ++i) {
    // Check gets through const objects.
    EXPECT_EQ(rf_int32.Get(i), Func(i, 1));
    EXPECT_EQ(rf_double.Get(i), Func(i, 2));
    EXPECT_EQ(rf_string.Get(i), StrFunc(i, 5));
    ForeignMessage scratch_space;
    EXPECT_EQ(rf_foreign_message.Get(i, &scratch_space).c(), Func(i, 6));
    EXPECT_EQ(down_cast<const ForeignMessage&>(
        rf_message.Get(i, &scratch_space)).c(), Func(i, 6));

    // Check gets through mutable objects.
    EXPECT_EQ(mrf_int32.Get(i), Func(i, 1));
    EXPECT_EQ(mrf_double.Get(i), Func(i, 2));
    EXPECT_EQ(mrf_string.Get(i), StrFunc(i, 5));
    EXPECT_EQ(mrf_foreign_message.Get(i, &scratch_space).c(), Func(i, 6));
    EXPECT_EQ(down_cast<const ForeignMessage&>(
        mrf_message.Get(i, &scratch_space)).c(), Func(i, 6));

    // Check sets through mutable objects.
    mrf_int32.Set(i, Func(i, -1));
    mrf_double.Set(i, Func(i, -2));
    mrf_string.Set(i, StrFunc(i, -5));
    ForeignMessage foreign_message;
    foreign_message.set_c(Func(i, -6));
    mrf_foreign_message.Set(i, foreign_message);
    EXPECT_EQ(message.repeated_int32(i), Func(i, -1));
    EXPECT_EQ(message.repeated_double(i), Func(i, -2));
    EXPECT_EQ(message.repeated_string(i), StrFunc(i, -5));
    EXPECT_EQ(message.repeated_foreign_message(i).c(), Func(i, -6));
    foreign_message.set_c(Func(i, 7));
    mrf_message.Set(i, foreign_message);
    EXPECT_EQ(message.repeated_foreign_message(i).c(), Func(i, 7));
  }

  // Test iterators.
  TestRepeatedFieldRefIteratorForPrimitive(rf_int32, message,
                                           &TestAllTypes::repeated_int32);
  TestRepeatedFieldRefIteratorForPrimitive(rf_double, message,
                                           &TestAllTypes::repeated_double);
  TestRepeatedFieldRefIteratorForString(rf_string, message,
                                        &TestAllTypes::repeated_string);

  // Test iterators for message fields.
  typedef RepeatedFieldRef<ForeignMessage>::iterator MessageIterator;
  int index = 0;
  for (MessageIterator it = rf_foreign_message.begin();
       it != rf_foreign_message.end(); ++it) {
    EXPECT_EQ(message.repeated_foreign_message(index).c(), it->c());
    ++index;
  }
  EXPECT_EQ(10, index);

  // Test iterator operators that are not ususally used in regular for-loops.
  // Including: post increment, assign, ==.
  MessageIterator old_it = rf_foreign_message.begin();
  MessageIterator new_it = old_it++;
  EXPECT_FALSE(old_it == new_it);
  // Check that old_it++ increments old_it once.
  for (index = 1; old_it != rf_foreign_message.end(); ++old_it, ++index) {
    EXPECT_EQ(message.repeated_foreign_message(index).c(), old_it->c());
  }
  EXPECT_EQ(10, index);
  // Test assign operator.
  old_it = new_it;
  for (index = 0; old_it != rf_foreign_message.end(); ++old_it, ++index) {
    EXPECT_EQ(message.repeated_foreign_message(index).c(), old_it->c());
  }
  EXPECT_EQ(10, index);
  // Check that the returned value of old_it++ is the one before increment.
  for (index = 0; new_it != rf_foreign_message.end(); ++new_it, ++index) {
    EXPECT_EQ(message.repeated_foreign_message(index).c(), new_it->c());
  }
  EXPECT_EQ(10, index);

  // Test MutableRepeatedFieldRef::Add()
  mrf_int32.Add(1234);
  mrf_double.Add(1234.0);
  mrf_string.Add("1234");
  ForeignMessage foreign_message;
  foreign_message.set_c(1234);
  mrf_foreign_message.Add(foreign_message);
  EXPECT_EQ(1234, message.repeated_int32(10));
  EXPECT_EQ(1234.0, message.repeated_double(10));
  EXPECT_EQ("1234", message.repeated_string(10));
  EXPECT_EQ(1234, message.repeated_foreign_message(10).c());

  // Test MutableRepeatedFieldRef::RemoveLast()
  mrf_int32.RemoveLast();
  mrf_double.RemoveLast();
  mrf_string.RemoveLast();
  mrf_foreign_message.RemoveLast();
  EXPECT_EQ(10, message.repeated_int32_size());
  EXPECT_EQ(10, message.repeated_double_size());
  EXPECT_EQ(10, message.repeated_string_size());
  EXPECT_EQ(10, message.repeated_foreign_message_size());

  // Test MutableRepeatedFieldRef::SwapElements()
  mrf_int32.SwapElements(0, 9);
  mrf_double.SwapElements(0, 9);
  mrf_string.SwapElements(0, 9);
  mrf_foreign_message.SwapElements(0, 9);
  EXPECT_EQ(Func(9, -1), message.repeated_int32(0));
  EXPECT_EQ(Func(0, -1), message.repeated_int32(9));
  EXPECT_EQ(Func(9, -2), message.repeated_double(0));
  EXPECT_EQ(Func(0, -2), message.repeated_double(9));
  EXPECT_EQ(StrFunc(9, -5), message.repeated_string(0));
  EXPECT_EQ(StrFunc(0, -5), message.repeated_string(9));
  EXPECT_EQ(Func(9, 7), message.repeated_foreign_message(0).c());
  EXPECT_EQ(Func(0, 7), message.repeated_foreign_message(9).c());

  // Test MutableRepeatedFieldRef::Clear()
  mrf_int32.Clear();
  mrf_double.Clear();
  mrf_string.Clear();
  mrf_foreign_message.Clear();
  EXPECT_EQ(0, message.repeated_int32_size());
  EXPECT_EQ(0, message.repeated_double_size());
  EXPECT_EQ(0, message.repeated_string_size());
  EXPECT_EQ(0, message.repeated_foreign_message_size());

  // Test (Mutable)RepeatedFieldRef::empty()
  EXPECT_TRUE(rf_int32.empty());
  EXPECT_TRUE(mrf_int32.empty());
  EXPECT_TRUE(rf_double.empty());
  EXPECT_TRUE(mrf_double.empty());
  EXPECT_TRUE(rf_string.empty());
  EXPECT_TRUE(mrf_string.empty());
  EXPECT_TRUE(rf_foreign_message.empty());
  EXPECT_TRUE(mrf_foreign_message.empty());
  EXPECT_TRUE(rf_message.empty());
  EXPECT_TRUE(mrf_message.empty());

#ifdef PROTOBUF_HAS_DEATH_TEST

  // Make sure types are checked correctly at runtime.
  const FieldDescriptor* fd_optional_int32 =
      desc->FindFieldByName("optional_int32");
  EXPECT_DEATH(refl->GetRepeatedFieldRef<int32>(
      message, fd_optional_int32), "");
  EXPECT_DEATH(refl->GetRepeatedFieldRef<double>(
      message, fd_repeated_int32), "");
  EXPECT_DEATH(refl->GetRepeatedFieldRef<TestAllTypes>(
      message, fd_repeated_foreign_message), "");

#endif  // PROTOBUF_HAS_DEATH_TEST
}

TEST(RepeatedFieldReflectionTest, RepeatedFieldRefForEnums) {
  TestAllTypes message;
  const Reflection* refl = message.GetReflection();
  const Descriptor* desc = message.GetDescriptor();

  for (int i = 0; i < 10; ++i) {
    message.add_repeated_nested_enum(TestAllTypes::BAR);
  }

  const FieldDescriptor* fd_repeated_nested_enum =
      desc->FindFieldByName("repeated_nested_enum");
  const RepeatedFieldRef<TestAllTypes::NestedEnum> enum_ref =
      refl->GetRepeatedFieldRef<TestAllTypes::NestedEnum>(
          message, fd_repeated_nested_enum);
  const MutableRepeatedFieldRef<TestAllTypes::NestedEnum>
  mutable_enum_ref =
      refl->GetMutableRepeatedFieldRef<TestAllTypes::NestedEnum>(
          &message, fd_repeated_nested_enum);
  const RepeatedFieldRef<int32> int32_ref =
      refl->GetRepeatedFieldRef<int32>(
          message, fd_repeated_nested_enum);
  const MutableRepeatedFieldRef<int32> mutable_int32_ref =
      refl->GetMutableRepeatedFieldRef<int32>(
          &message, fd_repeated_nested_enum);

  EXPECT_EQ(message.repeated_nested_enum_size(), enum_ref.size());
  EXPECT_EQ(message.repeated_nested_enum_size(), mutable_enum_ref.size());
  EXPECT_EQ(message.repeated_nested_enum_size(), int32_ref.size());
  EXPECT_EQ(message.repeated_nested_enum_size(), mutable_int32_ref.size());

  EXPECT_FALSE(enum_ref.empty());
  EXPECT_FALSE(mutable_enum_ref.empty());
  EXPECT_FALSE(int32_ref.empty());
  EXPECT_FALSE(mutable_int32_ref.empty());

  for (int i = 0; i < 10; ++i) {
    EXPECT_EQ(TestAllTypes::BAR, enum_ref.Get(i));
    EXPECT_EQ(TestAllTypes::BAR, mutable_enum_ref.Get(i));
    mutable_enum_ref.Set(i, TestAllTypes::BAZ);
    EXPECT_EQ(TestAllTypes::BAZ, enum_ref.Get(i));
    EXPECT_EQ(TestAllTypes::BAZ, message.repeated_nested_enum(i));

    message.set_repeated_nested_enum(i, TestAllTypes::BAR);
    EXPECT_EQ(TestAllTypes::BAR, int32_ref.Get(i));
    EXPECT_EQ(TestAllTypes::BAR, mutable_int32_ref.Get(i));
    mutable_int32_ref.Set(i, TestAllTypes::BAZ);
    EXPECT_EQ(TestAllTypes::BAZ, int32_ref.Get(i));
    EXPECT_EQ(TestAllTypes::BAZ, message.repeated_nested_enum(i));
  }

  TestRepeatedFieldRefIteratorForPrimitive(enum_ref, message,
                                           &TestAllTypes::repeated_nested_enum);
  TestRepeatedFieldRefIteratorForPrimitive(int32_ref, message,
                                           &TestAllTypes::repeated_nested_enum);

  // Test Add()
  mutable_enum_ref.Add(TestAllTypes::FOO);
  EXPECT_EQ(TestAllTypes::FOO, message.repeated_nested_enum(10));
  mutable_int32_ref.Add(TestAllTypes::BAR);
  EXPECT_EQ(TestAllTypes::BAR, message.repeated_nested_enum(11));

  // Test RemoveLast()
  mutable_enum_ref.RemoveLast();
  EXPECT_EQ(11, message.repeated_nested_enum_size());
  mutable_int32_ref.RemoveLast();
  EXPECT_EQ(10, message.repeated_nested_enum_size());

  // Test SwapElements()
  mutable_enum_ref.Set(0, TestAllTypes::BAR);
  mutable_enum_ref.Set(9, TestAllTypes::BAZ);
  mutable_enum_ref.SwapElements(0, 9);
  EXPECT_EQ(TestAllTypes::BAZ, enum_ref.Get(0));
  EXPECT_EQ(TestAllTypes::BAR, enum_ref.Get(9));
  mutable_int32_ref.SwapElements(0, 9);
  EXPECT_EQ(TestAllTypes::BAR, enum_ref.Get(0));
  EXPECT_EQ(TestAllTypes::BAZ, enum_ref.Get(9));

  // Test Clear()
  mutable_enum_ref.Clear();
  EXPECT_EQ(0, message.repeated_nested_enum_size());
  mutable_enum_ref.Add(TestAllTypes::FOO);
  EXPECT_EQ(1, message.repeated_nested_enum_size());
  mutable_int32_ref.Clear();
  EXPECT_EQ(0, message.repeated_nested_enum_size());

  // Test empty()
  EXPECT_TRUE(enum_ref.empty());
  EXPECT_TRUE(mutable_enum_ref.empty());
  EXPECT_TRUE(int32_ref.empty());
  EXPECT_TRUE(mutable_int32_ref.empty());
}

TEST(RepeatedFieldReflectionTest, RepeatedFieldRefForExtensionFields) {
  TestAllExtensions extended_message;
  const Reflection* refl = extended_message.GetReflection();
  const Descriptor* desc = extended_message.GetDescriptor();

  for (int i = 0; i < 10; ++i) {
    extended_message.AddExtension(
        unittest::repeated_int64_extension, Func(i, 1));
  }

  const FieldDescriptor* fd_repeated_int64_extension =
      desc->file()->FindExtensionByName("repeated_int64_extension");
  GOOGLE_CHECK(fd_repeated_int64_extension != NULL);

  const RepeatedFieldRef<int64> rf_int64_extension =
      refl->GetRepeatedFieldRef<int64>(extended_message,
                                          fd_repeated_int64_extension);

  const MutableRepeatedFieldRef<int64> mrf_int64_extension =
      refl->GetMutableRepeatedFieldRef<int64>(&extended_message,
                                                 fd_repeated_int64_extension);

  for (int i = 0; i < 10; ++i) {
    EXPECT_EQ(Func(i, 1), rf_int64_extension.Get(i));
    mrf_int64_extension.Set(i, Func(i, -1));
    EXPECT_EQ(Func(i, -1),
        extended_message.GetExtension(unittest::repeated_int64_extension, i));
  }
}

TEST(RepeatedFieldReflectionTest, RepeatedFieldRefMergeFromAndSwap) {
  // Set-up message content.
  TestAllTypes m0, m1, m2;
  for (int i = 0; i < 10; ++i) {
    m0.add_repeated_int32(Func(i, 1));
    m0.add_repeated_double(Func(i, 2));
    m0.add_repeated_string(StrFunc(i, 5));
    m0.add_repeated_foreign_message()->set_c(Func(i, 6));
    m0.add_repeated_nested_enum(TestAllTypes::FOO);
    m1.add_repeated_int32(Func(i, 11));
    m1.add_repeated_double(Func(i, 12));
    m1.add_repeated_string(StrFunc(i, 15));
    m1.add_repeated_foreign_message()->set_c(Func(i, 16));
    m1.add_repeated_nested_enum(TestAllTypes::BAR);
    m2.add_repeated_int32(Func(i, 21));
    m2.add_repeated_double(Func(i, 22));
    m2.add_repeated_string(StrFunc(i, 25));
    m2.add_repeated_foreign_message()->set_c(Func(i, 26));
    m2.add_repeated_nested_enum(TestAllTypes::BAZ);
  }

  const Reflection* refl = m0.GetReflection();
  const Descriptor* desc = m0.GetDescriptor();

  // Get FieldDescriptors for all the fields of interest.
  const FieldDescriptor* fd_repeated_int32 =
      desc->FindFieldByName("repeated_int32");
  const FieldDescriptor* fd_repeated_double =
      desc->FindFieldByName("repeated_double");
  const FieldDescriptor* fd_repeated_string =
      desc->FindFieldByName("repeated_string");
  const FieldDescriptor* fd_repeated_foreign_message =
      desc->FindFieldByName("repeated_foreign_message");
  const FieldDescriptor* fd_repeated_nested_enum =
      desc->FindFieldByName("repeated_nested_enum");

  // Get MutableRepeatedFieldRef objects for all fields of interest.
  const MutableRepeatedFieldRef<int32> mrf_int32 =
      refl->GetMutableRepeatedFieldRef<int32>(&m0, fd_repeated_int32);
  const MutableRepeatedFieldRef<double> mrf_double =
      refl->GetMutableRepeatedFieldRef<double>(&m0, fd_repeated_double);
  const MutableRepeatedFieldRef<string> mrf_string =
      refl->GetMutableRepeatedFieldRef<string>(&m0, fd_repeated_string);
  const MutableRepeatedFieldRef<ForeignMessage> mrf_foreign_message =
      refl->GetMutableRepeatedFieldRef<ForeignMessage>(
          &m0, fd_repeated_foreign_message);
  const MutableRepeatedFieldRef<TestAllTypes::NestedEnum>
  mrf_nested_enum =
      refl->GetMutableRepeatedFieldRef<TestAllTypes::NestedEnum>(
          &m0, fd_repeated_nested_enum);

  // Test MutableRepeatedRef::CopyFrom
  mrf_int32.CopyFrom(
      refl->GetRepeatedFieldRef<int32>(m1, fd_repeated_int32));
  mrf_double.CopyFrom(
      refl->GetRepeatedFieldRef<double>(m1, fd_repeated_double));
  mrf_string.CopyFrom(
      refl->GetRepeatedFieldRef<string>(m1, fd_repeated_string));
  mrf_foreign_message.CopyFrom(
      refl->GetRepeatedFieldRef<ForeignMessage>(
          m1, fd_repeated_foreign_message));
  mrf_nested_enum.CopyFrom(
      refl->GetRepeatedFieldRef<TestAllTypes::NestedEnum>(
          m1, fd_repeated_nested_enum));
  for (int i = 0; i < 10; ++i) {
    EXPECT_EQ(Func(i, 11), m0.repeated_int32(i));
    EXPECT_EQ(Func(i, 12), m0.repeated_double(i));
    EXPECT_EQ(StrFunc(i, 15), m0.repeated_string(i));
    EXPECT_EQ(Func(i, 16), m0.repeated_foreign_message(i).c());
    EXPECT_EQ(TestAllTypes::BAR, m0.repeated_nested_enum(i));
  }

  // Test MutableRepeatedRef::MergeFrom
  mrf_int32.MergeFrom(
      refl->GetRepeatedFieldRef<int32>(m2, fd_repeated_int32));
  mrf_double.MergeFrom(
      refl->GetRepeatedFieldRef<double>(m2, fd_repeated_double));
  mrf_string.MergeFrom(
      refl->GetRepeatedFieldRef<string>(m2, fd_repeated_string));
  mrf_foreign_message.MergeFrom(
      refl->GetRepeatedFieldRef<ForeignMessage>(
          m2, fd_repeated_foreign_message));
  mrf_nested_enum.MergeFrom(
      refl->GetRepeatedFieldRef<TestAllTypes::NestedEnum>(
          m2, fd_repeated_nested_enum));
  for (int i = 0; i < 10; ++i) {
    EXPECT_EQ(Func(i, 21), m0.repeated_int32(i + 10));
    EXPECT_EQ(Func(i, 22), m0.repeated_double(i + 10));
    EXPECT_EQ(StrFunc(i, 25), m0.repeated_string(i + 10));
    EXPECT_EQ(Func(i, 26), m0.repeated_foreign_message(i + 10).c());
    EXPECT_EQ(TestAllTypes::BAZ, m0.repeated_nested_enum(i + 10));
  }

  // Test MutableRepeatedRef::Swap
  // Swap between m0 and m2.
  mrf_int32.Swap(
      refl->GetMutableRepeatedFieldRef<int32>(&m2, fd_repeated_int32));
  mrf_double.Swap(
      refl->GetMutableRepeatedFieldRef<double>(&m2, fd_repeated_double));
  mrf_string.Swap(
      refl->GetMutableRepeatedFieldRef<string>(&m2, fd_repeated_string));
  mrf_foreign_message.Swap(
      refl->GetMutableRepeatedFieldRef<ForeignMessage>(
          &m2, fd_repeated_foreign_message));
  mrf_nested_enum.Swap(
      refl->GetMutableRepeatedFieldRef<TestAllTypes::NestedEnum>(
          &m2, fd_repeated_nested_enum));
  for (int i = 0; i < 10; ++i) {
    // Check the content of m0.
    EXPECT_EQ(Func(i, 21), m0.repeated_int32(i));
    EXPECT_EQ(Func(i, 22), m0.repeated_double(i));
    EXPECT_EQ(StrFunc(i, 25), m0.repeated_string(i));
    EXPECT_EQ(Func(i, 26), m0.repeated_foreign_message(i).c());
    EXPECT_EQ(TestAllTypes::BAZ, m0.repeated_nested_enum(i));

    // Check the content of m2.
    EXPECT_EQ(Func(i, 11), m2.repeated_int32(i));
    EXPECT_EQ(Func(i, 12), m2.repeated_double(i));
    EXPECT_EQ(StrFunc(i, 15), m2.repeated_string(i));
    EXPECT_EQ(Func(i, 16), m2.repeated_foreign_message(i).c());
    EXPECT_EQ(TestAllTypes::BAR, m2.repeated_nested_enum(i));
    EXPECT_EQ(Func(i, 21), m2.repeated_int32(i + 10));
    EXPECT_EQ(Func(i, 22), m2.repeated_double(i + 10));
    EXPECT_EQ(StrFunc(i, 25), m2.repeated_string(i + 10));
    EXPECT_EQ(Func(i, 26), m2.repeated_foreign_message(i + 10).c());
    EXPECT_EQ(TestAllTypes::BAZ, m2.repeated_nested_enum(i + 10));
  }
}

// Test that GetRepeatedFieldRef/MutableRepeatedFieldRef works with
// DynamicMessage.
TEST(RepeatedFieldReflectionTest, RepeatedFieldRefDynamicMessage) {
  // DynamicMessage shares the same memory layout as generated message
  // and use the same GeneratedMessageReflection code for reflection.
  // All code paths should already be covered by the other tests for
  // generated messages. Here we just test one field.

  const Descriptor* desc = TestAllTypes::descriptor();
  const FieldDescriptor* fd_repeated_int32 =
      desc->FindFieldByName("repeated_int32");

  DynamicMessageFactory factory;
  google::protobuf::scoped_ptr<Message> dynamic_message(factory.GetPrototype(desc)->New());
  const Reflection* refl = dynamic_message->GetReflection();

  MutableRepeatedFieldRef<int32> rf_int32 =
      refl->GetMutableRepeatedFieldRef<int32>(
          dynamic_message.get(), fd_repeated_int32);
  rf_int32.Add(1234);
  EXPECT_EQ(1, refl->FieldSize(*dynamic_message, fd_repeated_int32));
  EXPECT_EQ(1234, refl->GetRepeatedInt32(*dynamic_message,
                                         fd_repeated_int32, 0));
}

}  // namespace
}  // namespace protobuf
}  // namespace google


text:
// 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.

#ifndef GOOGLE_PROTOBUF_HAS_BITS_H__
#define GOOGLE_PROTOBUF_HAS_BITS_H__

#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/port.h>

namespace google {
namespace protobuf {
namespace internal {

template<size_t doublewords>
class HasBits {
 public:
  HasBits() GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE { Clear(); }

  void Clear() GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE {
    memset(has_bits_, 0, sizeof(has_bits_));
  }

  ::google::protobuf::uint32& operator[](int index) GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE {
    return has_bits_[index];
  }

  const ::google::protobuf::uint32& operator[](int index) const
  GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE {
    return has_bits_[index];
  }

  bool operator==(const HasBits<doublewords>& rhs) const {
    return memcmp(has_bits_, rhs.has_bits_, sizeof(has_bits_)) == 0;
  }

  bool operator!=(const HasBits<doublewords>& rhs) const {
    return !(*this == rhs);
  }

  bool empty() const;

 private:
  ::google::protobuf::uint32 has_bits_[doublewords];
};

template <>
inline bool HasBits<1>::empty() const {
  return !has_bits_[0];
}

template <>
inline bool HasBits<2>::empty() const {
  return !(has_bits_[0] | has_bits_[1]);
}

template <>
inline bool HasBits<3>::empty() const {
  return !(has_bits_[0] | has_bits_[1] | has_bits_[2]);
}

template <>
inline bool HasBits<4>::empty() const {
  return !(has_bits_[0] | has_bits_[1] | has_bits_[2] | has_bits_[3]);
}

template <size_t doublewords>
inline bool HasBits<doublewords>::empty() const {
  for (size_t i = 0; i < doublewords; ++i) {
    if (has_bits_[i]) return false;
  }
  return true;
}

}  // namespace internal
}  // namespace protobuf

}  // namespace google
#endif  // GOOGLE_PROTOBUF_HAS_BITS_H__

mime_type: text/plain


text:
// 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.

// Authors: wink@google.com (Wink Saville),
//          kenton@google.com (Kenton Varda)
//  Based on original Protocol Buffers design by
//  Sanjay Ghemawat, Jeff Dean, and others.

#include <climits>

#include <google/protobuf/arena.h>
#include <google/protobuf/generated_message_util.h>
#include <google/protobuf/message_lite.h>
#include <google/protobuf/repeated_field.h>
#include <string>
#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
#include <google/protobuf/stubs/stl_util.h>

namespace google {
namespace protobuf {

string MessageLite::InitializationErrorString() const {
  return "(cannot determine missing fields for lite message)";
}

namespace {

// When serializing, we first compute the byte size, then serialize the message.
// If serialization produces a different number of bytes than expected, we
// call this function, which crashes.  The problem could be due to a bug in the
// protobuf implementation but is more likely caused by concurrent modification
// of the message.  This function attempts to distinguish between the two and
// provide a useful error message.
void ByteSizeConsistencyError(size_t byte_size_before_serialization,
                              size_t byte_size_after_serialization,
                              size_t bytes_produced_by_serialization,
                              const MessageLite& message) {
  GOOGLE_CHECK_EQ(byte_size_before_serialization, byte_size_after_serialization)
      << message.GetTypeName()
      << " was modified concurrently during serialization.";
  GOOGLE_CHECK_EQ(bytes_produced_by_serialization, byte_size_before_serialization)
      << "Byte size calculation and serialization were inconsistent.  This "
         "may indicate a bug in protocol buffers or it may be caused by "
         "concurrent modification of " << message.GetTypeName() << ".";
  GOOGLE_LOG(FATAL) << "This shouldn't be called if all the sizes are equal.";
}

string InitializationErrorMessage(const char* action,
                                  const MessageLite& message) {
  // Note:  We want to avoid depending on strutil in the lite library, otherwise
  //   we'd use:
  //
  // return strings::Substitute(
  //   "Can't $0 message of type \"$1\" because it is missing required "
  //   "fields: $2",
  //   action, message.GetTypeName(),
  //   message.InitializationErrorString());

  string result;
  result += "Can't ";
  result += action;
  result += " message of type \"";
  result += message.GetTypeName();
  result += "\" because it is missing required fields: ";
  result += message.InitializationErrorString();
  return result;
}

// Several of the Parse methods below just do one thing and then call another
// method.  In a naive implementation, we might have ParseFromString() call
// ParseFromArray() which would call ParseFromZeroCopyStream() which would call
// ParseFromCodedStream() which would call MergeFromCodedStream() which would
// call MergePartialFromCodedStream().  However, when parsing very small
// messages, every function call introduces significant overhead.  To avoid
// this without reproducing code, we use these forced-inline helpers.
GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE bool InlineMergeFromCodedStream(
    io::CodedInputStream* input, MessageLite* message);
GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE bool InlineParseFromCodedStream(
    io::CodedInputStream* input, MessageLite* message);
GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE bool InlineParsePartialFromCodedStream(
    io::CodedInputStream* input, MessageLite* message);
GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE bool InlineParseFromArray(
    const void* data, int size, MessageLite* message);
GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE bool InlineParsePartialFromArray(
    const void* data, int size, MessageLite* message);

inline bool InlineMergeFromCodedStream(io::CodedInputStream* input,
                                       MessageLite* message) {
  if (!message->MergePartialFromCodedStream(input)) return false;
  if (!message->IsInitialized()) {
    GOOGLE_LOG(ERROR) << InitializationErrorMessage("parse", *message);
    return false;
  }
  return true;
}

inline bool InlineParseFromCodedStream(io::CodedInputStream* input,
                                       MessageLite* message) {
  message->Clear();
  return InlineMergeFromCodedStream(input, message);
}

inline bool InlineParsePartialFromCodedStream(io::CodedInputStream* input,
                                              MessageLite* message) {
  message->Clear();
  return message->MergePartialFromCodedStream(input);
}

inline bool InlineParseFromArray(
    const void* data, int size, MessageLite* message) {
  io::CodedInputStream input(reinterpret_cast<const uint8*>(data), size);
  return InlineParseFromCodedStream(&input, message) &&
         input.ConsumedEntireMessage();
}

inline bool InlineParsePartialFromArray(
    const void* data, int size, MessageLite* message) {
  io::CodedInputStream input(reinterpret_cast<const uint8*>(data), size);
  return InlineParsePartialFromCodedStream(&input, message) &&
         input.ConsumedEntireMessage();
}

}  // namespace

MessageLite* MessageLite::New(::google::protobuf::Arena* arena) const {
  MessageLite* message = New();
  if (arena != NULL) {
    arena->Own(message);
  }
  return message;
}

bool MessageLite::MergeFromCodedStream(io::CodedInputStream* input) {
  return InlineMergeFromCodedStream(input, this);
}

bool MessageLite::ParseFromCodedStream(io::CodedInputStream* input) {
  return InlineParseFromCodedStream(input, this);
}

bool MessageLite::ParsePartialFromCodedStream(io::CodedInputStream* input) {
  return InlineParsePartialFromCodedStream(input, this);
}

bool MessageLite::ParseFromZeroCopyStream(io::ZeroCopyInputStream* input) {
  io::CodedInputStream decoder(input);
  return ParseFromCodedStream(&decoder) && decoder.ConsumedEntireMessage();
}

bool MessageLite::ParsePartialFromZeroCopyStream(
    io::ZeroCopyInputStream* input) {
  io::CodedInputStream decoder(input);
  return ParsePartialFromCodedStream(&decoder) &&
         decoder.ConsumedEntireMessage();
}

bool MessageLite::ParseFromBoundedZeroCopyStream(
    io::ZeroCopyInputStream* input, int size) {
  io::CodedInputStream decoder(input);
  decoder.PushLimit(size);
  return ParseFromCodedStream(&decoder) &&
         decoder.ConsumedEntireMessage() &&
         decoder.BytesUntilLimit() == 0;
}

bool MessageLite::ParsePartialFromBoundedZeroCopyStream(
    io::ZeroCopyInputStream* input, int size) {
  io::CodedInputStream decoder(input);
  decoder.PushLimit(size);
  return ParsePartialFromCodedStream(&decoder) &&
         decoder.ConsumedEntireMessage() &&
         decoder.BytesUntilLimit() == 0;
}

bool MessageLite::ParseFromString(const string& data) {
  return InlineParseFromArray(data.data(), data.size(), this);
}

bool MessageLite::ParsePartialFromString(const string& data) {
  return InlineParsePartialFromArray(data.data(), data.size(), this);
}

bool MessageLite::ParseFromArray(const void* data, int size) {
  return InlineParseFromArray(data, size, this);
}

bool MessageLite::ParsePartialFromArray(const void* data, int size) {
  return InlineParsePartialFromArray(data, size, this);
}

// ===================================================================

uint8* MessageLite::SerializeWithCachedSizesToArray(uint8* target) const {
  return InternalSerializeWithCachedSizesToArray(
      io::CodedOutputStream::IsDefaultSerializationDeterministic(), target);
}

bool MessageLite::SerializeToCodedStream(io::CodedOutputStream* output) const {
  GOOGLE_DCHECK(IsInitialized()) << InitializationErrorMessage("serialize", *this);
  return SerializePartialToCodedStream(output);
}

bool MessageLite::SerializePartialToCodedStream(
    io::CodedOutputStream* output) const {
  const size_t size = ByteSizeLong();  // Force size to be cached.
  if (size > INT_MAX) {
    GOOGLE_LOG(ERROR) << "Exceeded maximum protobuf size of 2GB: " << size;
    return false;
  }

  uint8* buffer = output->GetDirectBufferForNBytesAndAdvance(size);
  if (buffer != NULL) {
    uint8* end = InternalSerializeWithCachedSizesToArray(
        output->IsSerializationDeterministic(), buffer);
    if (end - buffer != size) {
      ByteSizeConsistencyError(size, ByteSizeLong(), end - buffer, *this);
    }
    return true;
  } else {
    int original_byte_count = output->ByteCount();
    SerializeWithCachedSizes(output);
    if (output->HadError()) {
      return false;
    }
    int final_byte_count = output->ByteCount();

    if (final_byte_count - original_byte_count != size) {
      ByteSizeConsistencyError(size, ByteSizeLong(),
                               final_byte_count - original_byte_count, *this);
    }

    return true;
  }
}

bool MessageLite::SerializeToZeroCopyStream(
    io::ZeroCopyOutputStream* output) const {
  io::CodedOutputStream encoder(output);
  return SerializeToCodedStream(&encoder);
}

bool MessageLite::SerializePartialToZeroCopyStream(
    io::ZeroCopyOutputStream* output) const {
  io::CodedOutputStream encoder(output);
  return SerializePartialToCodedStream(&encoder);
}

bool MessageLite::AppendToString(string* output) const {
  GOOGLE_DCHECK(IsInitialized()) << InitializationErrorMessage("serialize", *this);
  return AppendPartialToString(output);
}

bool MessageLite::AppendPartialToString(string* output) const {
  size_t old_size = output->size();
  size_t byte_size = ByteSizeLong();
  if (byte_size > INT_MAX) {
    GOOGLE_LOG(ERROR) << "Exceeded maximum protobuf size of 2GB: " << byte_size;
    return false;
  }

  STLStringResizeUninitialized(output, old_size + byte_size);
  uint8* start =
      reinterpret_cast<uint8*>(io::mutable_string_data(output) + old_size);
  uint8* end = SerializeWithCachedSizesToArray(start);
  if (end - start != byte_size) {
    ByteSizeConsistencyError(byte_size, ByteSizeLong(), end - start, *this);
  }
  return true;
}

bool MessageLite::SerializeToString(string* output) const {
  output->clear();
  return AppendToString(output);
}

bool MessageLite::SerializePartialToString(string* output) const {
  output->clear();
  return AppendPartialToString(output);
}

bool MessageLite::SerializeToArray(void* data, int size) const {
  GOOGLE_DCHECK(IsInitialized()) << InitializationErrorMessage("serialize", *this);
  return SerializePartialToArray(data, size);
}

bool MessageLite::SerializePartialToArray(void* data, int size) const {
  int byte_size = ByteSizeLong();
  if (size < byte_size) return false;
  uint8* start = reinterpret_cast<uint8*>(data);
  uint8* end = SerializeWithCachedSizesToArray(start);
  if (end - start != byte_size) {
    ByteSizeConsistencyError(byte_size, ByteSizeLong(), end - start, *this);
  }
  return true;
}

string MessageLite::SerializeAsString() const {
  // If the compiler implements the (Named) Return Value Optimization,
  // the local variable 'output' will not actually reside on the stack
  // of this function, but will be overlaid with the object that the
  // caller supplied for the return value to be constructed in.
  string output;
  if (!AppendToString(&output))
    output.clear();
  return output;
}

string MessageLite::SerializePartialAsString() const {
  string output;
  if (!AppendPartialToString(&output))
    output.clear();
  return output;
}

void MessageLite::SerializeWithCachedSizes(
    io::CodedOutputStream* output) const {
  GOOGLE_DCHECK(InternalGetTable());
  internal::TableSerialize(
      *this,
      static_cast<const internal::SerializationTable*>(InternalGetTable()),
      output);
}

// The table driven code optimizes the case that the CodedOutputStream buffer
// is large enough to serialize into it directly.
// If the proto is optimized for speed, this method will be overridden by
// generated code for maximum speed. If the proto is optimized for size or
// is lite, then we need to specialize this to avoid infinite recursion.
uint8* MessageLite::InternalSerializeWithCachedSizesToArray(
    bool deterministic, uint8* target) const {
  const internal::SerializationTable* table =
      static_cast<const internal::SerializationTable*>(InternalGetTable());
  if (table == NULL) {
    // We only optimize this when using optimize_for = SPEED.  In other cases
    // we just use the CodedOutputStream path.
    int size = GetCachedSize();
    io::ArrayOutputStream out(target, size);
    io::CodedOutputStream coded_out(&out);
    coded_out.SetSerializationDeterministic(deterministic);
    SerializeWithCachedSizes(&coded_out);
    GOOGLE_CHECK(!coded_out.HadError());
    return target + size;
  } else {
    return internal::TableSerializeToArray(*this, table, deterministic, target);
  }
}

namespace internal {
template<>
MessageLite* GenericTypeHandler<MessageLite>::NewFromPrototype(
    const MessageLite* prototype, google::protobuf::Arena* arena) {
  return prototype->New(arena);
}
template <>
void GenericTypeHandler<MessageLite>::Merge(const MessageLite& from,
                                            MessageLite* to) {
  to->CheckTypeAndMergeFrom(from);
}
template<>
void GenericTypeHandler<string>::Merge(const string& from,
                                              string* to) {
  *to = from;
}

bool proto3_preserve_unknown_ = true;

void SetProto3PreserveUnknownsDefault(bool preserve) {
  proto3_preserve_unknown_ = preserve;
}

}  // namespace internal

}  // namespace protobuf
}  // namespace google


text:
// 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: liujisi@google.com (Pherl Liu)

syntax = "proto3";

package protobuf_unittest_import;

option java_package = "com.google.protobuf.test";
option csharp_namespace = "Google.Protobuf.TestProtos";

message PublicImportMessage {
 int32 e = 1;
}


text:
// 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.
//
// Test schema for proto2 messages.  This test schema is used by:
//
// - conformance tests
//

syntax = "proto2";

package protobuf_test_messages.proto2;
option java_package = "com.google.protobuf_test_messages.proto2";

// This is the default, but we specify it here explicitly.
option optimize_for = SPEED;

option cc_enable_arenas = true;

// This proto includes every type of field in both singular and repeated
// forms.
//
// Also, crucially, all messages and enums in this file are eventually
// submessages of this message.  So for example, a fuzz test of TestAllTypes
// could trigger bugs that occur in any message type in this file.  We verify
// this stays true in a unit test.
message TestAllTypesProto2 {
  message NestedMessage {
    optional int32 a = 1;
    optional TestAllTypesProto2 corecursive = 2;
  }

  enum NestedEnum {
    FOO = 0;
    BAR = 1;
    BAZ = 2;
    NEG = -1;  // Intentionally negative.
  }

  // Singular
  optional int32 optional_int32    =  1;
  optional int64 optional_int64    =  2;
  optional uint32 optional_uint32   =  3;
  optional uint64 optional_uint64   =  4;
  optional sint32 optional_sint32   =  5;
  optional sint64 optional_sint64   =  6;
  optional fixed32 optional_fixed32  =  7;
  optional fixed64 optional_fixed64  =  8;
  optional sfixed32 optional_sfixed32 =  9;
  optional sfixed64 optional_sfixed64 = 10;
  optional float optional_float    = 11;
  optional double optional_double   = 12;
  optional bool optional_bool     = 13;
  optional string optional_string   = 14;
  optional bytes optional_bytes    = 15;

  optional NestedMessage                        optional_nested_message  = 18;
  optional ForeignMessageProto2                 optional_foreign_message = 19;

  optional NestedEnum                           optional_nested_enum     = 21;
  optional ForeignEnumProto2                    optional_foreign_enum    = 22;

  optional string optional_string_piece = 24 [ctype=STRING_PIECE];
  optional string optional_cord = 25 [ctype=CORD];

  optional TestAllTypesProto2 recursive_message = 27;

  // Repeated
  repeated    int32 repeated_int32    = 31;
  repeated    int64 repeated_int64    = 32;
  repeated   uint32 repeated_uint32   = 33;
  repeated   uint64 repeated_uint64   = 34;
  repeated   sint32 repeated_sint32   = 35;
  repeated   sint64 repeated_sint64   = 36;
  repeated  fixed32 repeated_fixed32  = 37;
  repeated  fixed64 repeated_fixed64  = 38;
  repeated sfixed32 repeated_sfixed32 = 39;
  repeated sfixed64 repeated_sfixed64 = 40;
  repeated    float repeated_float    = 41;
  repeated   double repeated_double   = 42;
  repeated     bool repeated_bool     = 43;
  repeated   string repeated_string   = 44;
  repeated    bytes repeated_bytes    = 45;

  repeated NestedMessage       repeated_nested_message  = 48;
  repeated ForeignMessageProto2      repeated_foreign_message = 49;

  repeated NestedEnum          repeated_nested_enum     = 51;
  repeated ForeignEnumProto2         repeated_foreign_enum    = 52;

  repeated string repeated_string_piece = 54 [ctype=STRING_PIECE];
  repeated string repeated_cord = 55 [ctype=CORD];

  // Map
  map <   int32, int32>    map_int32_int32 = 56;
  map <   int64, int64>    map_int64_int64 = 57;
  map <  uint32, uint32>   map_uint32_uint32 = 58;
  map <  uint64, uint64>   map_uint64_uint64 = 59;
  map <  sint32, sint32>   map_sint32_sint32 = 60;
  map <  sint64, sint64>   map_sint64_sint64 = 61;
  map < fixed32, fixed32>  map_fixed32_fixed32 = 62;
  map < fixed64, fixed64>  map_fixed64_fixed64 = 63;
  map <sfixed32, sfixed32> map_sfixed32_sfixed32 = 64;
  map <sfixed64, sfixed64> map_sfixed64_sfixed64 = 65;
  map <   int32, float>    map_int32_float = 66;
  map <   int32, double>   map_int32_double = 67;
  map <    bool, bool>     map_bool_bool = 68;
  map <  string, string>   map_string_string = 69;
  map <  string, bytes>    map_string_bytes = 70;
  map <  string, NestedMessage>  map_string_nested_message = 71;
  map <  string, ForeignMessageProto2> map_string_foreign_message = 72;
  map <  string, NestedEnum>     map_string_nested_enum = 73;
  map <  string, ForeignEnumProto2>    map_string_foreign_enum = 74;

  oneof oneof_field {
    uint32 oneof_uint32 = 111;
    NestedMessage oneof_nested_message = 112;
    string oneof_string = 113;
    bytes oneof_bytes = 114;
    bool oneof_bool = 115;
    uint64 oneof_uint64 = 116;
    float oneof_float = 117;
    double oneof_double = 118;
    NestedEnum oneof_enum = 119;
  }

  // extensions
  extensions 120 to 200;

  // groups
  optional group Data = 201 {
    optional int32 group_int32 = 202;
    optional uint32 group_uint32 = 203;
  };

  // Test field-name-to-JSON-name convention.
  // (protobuf says names can be any valid C/C++ identifier.)
  optional int32 fieldname1 = 401;
  optional int32 field_name2 = 402;
  optional int32 _field_name3 = 403;
  optional int32 field__name4_ = 404;
  optional int32 field0name5 = 405;
  optional int32 field_0_name6 = 406;
  optional int32 fieldName7 = 407;
  optional int32 FieldName8 = 408;
  optional int32 field_Name9 = 409;
  optional int32 Field_Name10 = 410;
  optional int32 FIELD_NAME11 = 411;
  optional int32 FIELD_name12 = 412;
  optional int32 __field_name13 = 413;
  optional int32 __Field_name14 = 414;
  optional int32 field__name15 = 415;
  optional int32 field__Name16 = 416;
  optional int32 field_name17__ = 417;
  optional int32 Field_name18__ = 418;

  // message_set test case.
  message MessageSetCorrect {
    option message_set_wire_format = true;
    extensions 4 to max;
  }

  message MessageSetCorrectExtension1 {
    extend MessageSetCorrect {
      optional MessageSetCorrectExtension1 message_set_extension = 1547769;
    }
    optional string str = 25;
  }

  message MessageSetCorrectExtension2 {
    extend MessageSetCorrect {
      optional MessageSetCorrectExtension2 message_set_extension = 4135312;
    }
    optional int32 i = 9;
  }
}

message ForeignMessageProto2 {
  optional int32 c = 1;
}

enum ForeignEnumProto2 {
  FOREIGN_FOO = 0;
  FOREIGN_BAR = 1;
  FOREIGN_BAZ = 2;
}

extend TestAllTypesProto2 {
  optional int32 extension_int32 = 120;
}


text:
// 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.

syntax = "proto3";

package google.protobuf;

option csharp_namespace = "Google.Protobuf.WellKnownTypes";
option go_package = "github.com/golang/protobuf/ptypes/any";
option java_package = "com.google.protobuf";
option java_outer_classname = "AnyProto";
option java_multiple_files = true;
option objc_class_prefix = "GPB";

// `Any` contains an arbitrary serialized protocol buffer message along with a
// URL that describes the type of the serialized message.
//
// Protobuf library provides support to pack/unpack Any values in the form
// of utility functions or additional generated methods of the Any type.
//
// Example 1: Pack and unpack a message in C++.
//
//     Foo foo = ...;
//     Any any;
//     any.PackFrom(foo);
//     ...
//     if (any.UnpackTo(&foo)) {
//       ...
//     }
//
// Example 2: Pack and unpack a message in Java.
//
//     Foo foo = ...;
//     Any any = Any.pack(foo);
//     ...
//     if (any.is(Foo.class)) {
//       foo = any.unpack(Foo.class);
//     }
//
//  Example 3: Pack and unpack a message in Python.
//
//     foo = Foo(...)
//     any = Any()
//     any.Pack(foo)
//     ...
//     if any.Is(Foo.DESCRIPTOR):
//       any.Unpack(foo)
//       ...
//
//  Example 4: Pack and unpack a message in Go
//
//      foo := &pb.Foo{...}
//      any, err := ptypes.MarshalAny(foo)
//      ...
//      foo := &pb.Foo{}
//      if err := ptypes.UnmarshalAny(any, foo); err != nil {
//        ...
//      }
//
// The pack methods provided by protobuf library will by default use
// 'type.googleapis.com/full.type.name' as the type URL and the unpack
// methods only use the fully qualified type name after the last '/'
// in the type URL, for example "foo.bar.com/x/y.z" will yield type
// name "y.z".
//
//
// JSON
// ====
// The JSON representation of an `Any` value uses the regular
// representation of the deserialized, embedded message, with an
// additional field `@type` which contains the type URL. Example:
//
//     package google.profile;
//     message Person {
//       string first_name = 1;
//       string last_name = 2;
//     }
//
//     {
//       "@type": "type.googleapis.com/google.profile.Person",
//       "firstName": <string>,
//       "lastName": <string>
//     }
//
// If the embedded message type is well-known and has a custom JSON
// representation, that representation will be embedded adding a field
// `value` which holds the custom JSON in addition to the `@type`
// field. Example (for message [google.protobuf.Duration][]):
//
//     {
//       "@type": "type.googleapis.com/google.protobuf.Duration",
//       "value": "1.212s"
//     }
//
message Any {
  // A URL/resource name whose content describes the type of the
  // serialized protocol buffer message.
  //
  // For URLs which use the scheme `http`, `https`, or no scheme, the
  // following restrictions and interpretations apply:
  //
  // * If no scheme is provided, `https` is assumed.
  // * The last segment of the URL's path must represent the fully
  //   qualified name of the type (as in `path/google.protobuf.Duration`).
  //   The name should be in a canonical form (e.g., leading "." is
  //   not accepted).
  // * An HTTP GET on the URL must yield a [google.protobuf.Type][]
  //   value in binary format, or produce an error.
  // * Applications are allowed to cache lookup results based on the
  //   URL, or have them precompiled into a binary to avoid any
  //   lookup. Therefore, binary compatibility needs to be preserved
  //   on changes to types. (Use versioned type names to manage
  //   breaking changes.)
  //
  // Schemes other than `http`, `https` (or the empty scheme) might be
  // used with implementation specific semantics.
  //
  string type_url = 1;

  // Must be a valid serialized protocol buffer of the above specified type.
  bytes value = 2;
}


text:
// 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.

#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/arena_test_util.h>

#define EXPECT_EQ GOOGLE_CHECK_EQ

namespace google {
namespace protobuf {
namespace internal {

NoHeapChecker::~NoHeapChecker() {
  capture_alloc.Unhook();
  EXPECT_EQ(0, capture_alloc.alloc_count());
  EXPECT_EQ(0, capture_alloc.free_count());
}

}  // namespace internal
}  // namespace protobuf
}  // namespace google


text:
// 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.

syntax = "proto3";

package google.protobuf;

option csharp_namespace = "Google.Protobuf.WellKnownTypes";
option java_package = "com.google.protobuf";
option java_outer_classname = "SourceContextProto";
option java_multiple_files = true;
option objc_class_prefix = "GPB";
option go_package = "google.golang.org/genproto/protobuf/source_context;source_context";

// `SourceContext` represents information about the source of a
// protobuf element, like the file in which it is defined.
message SourceContext {
  // The path-qualified name of the .proto file that contained the associated
  // protobuf element.  For example: `"google/protobuf/source_context.proto"`.
  string file_name = 1;
}