// 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.
//
// This test is testing a lot more than just the UnknownFieldSet class.  It
// tests handling of unknown fields throughout the system.

#include <google/protobuf/unknown_field_set.h>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/io/zero_copy_stream_impl.h>
#include <google/protobuf/wire_format.h>
#include <google/protobuf/unittest.pb.h>
#include <google/protobuf/test_util.h>

#include <google/protobuf/stubs/callback.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/mutex.h>
#include <google/protobuf/testing/googletest.h>
#include <gtest/gtest.h>

#include <google/protobuf/stubs/stl_util.h>

namespace google {
namespace protobuf {

using internal::WireFormat;

class UnknownFieldSetTest : public testing::Test {
 protected:
  virtual void SetUp() {
    descriptor_ = unittest::TestAllTypes::descriptor();
    TestUtil::SetAllFields(&all_fields_);
    all_fields_.SerializeToString(&all_fields_data_);
    ASSERT_TRUE(empty_message_.ParseFromString(all_fields_data_));
    unknown_fields_ = empty_message_.mutable_unknown_fields();
  }

  const UnknownField* GetField(const string& name) {
    const FieldDescriptor* field = descriptor_->FindFieldByName(name);
    if (field == NULL) return NULL;
    for (int i = 0; i < unknown_fields_->field_count(); i++) {
      if (unknown_fields_->field(i).number() == field->number()) {
        return &unknown_fields_->field(i);
      }
    }
    return NULL;
  }

  // Constructs a protocol buffer which contains fields with all the same
  // numbers as all_fields_data_ except that each field is some other wire
  // type.
  string GetBizarroData() {
    unittest::TestEmptyMessage bizarro_message;
    UnknownFieldSet* bizarro_unknown_fields =
      bizarro_message.mutable_unknown_fields();
    for (int i = 0; i < unknown_fields_->field_count(); i++) {
      const UnknownField& unknown_field = unknown_fields_->field(i);
      if (unknown_field.type() == UnknownField::TYPE_VARINT) {
        bizarro_unknown_fields->AddFixed32(unknown_field.number(), 1);
      } else {
        bizarro_unknown_fields->AddVarint(unknown_field.number(), 1);
      }
    }

    string data;
    EXPECT_TRUE(bizarro_message.SerializeToString(&data));
    return data;
  }

  const Descriptor* descriptor_;
  unittest::TestAllTypes all_fields_;
  string all_fields_data_;

  // An empty message that has been parsed from all_fields_data_.  So, it has
  // unknown fields of every type.
  unittest::TestEmptyMessage empty_message_;
  UnknownFieldSet* unknown_fields_;
};

namespace {

TEST_F(UnknownFieldSetTest, AllFieldsPresent) {
  // All fields of TestAllTypes should be present, in numeric order (because
  // that's the order we parsed them in).  Fields that are not valid field
  // numbers of TestAllTypes should NOT be present.

  int pos = 0;

  for (int i = 0; i < 1000; i++) {
    const FieldDescriptor* field = descriptor_->FindFieldByNumber(i);
    if (field != NULL) {
      ASSERT_LT(pos, unknown_fields_->field_count());
      // Do not check oneof field if it is not set.
      if (field->containing_oneof() == NULL) {
        EXPECT_EQ(i, unknown_fields_->field(pos++).number());
      } else if (i == unknown_fields_->field(pos).number()) {
        pos++;
      }
      if (field->is_repeated()) {
        // Should have a second instance.
        ASSERT_LT(pos, unknown_fields_->field_count());
        EXPECT_EQ(i, unknown_fields_->field(pos++).number());
      }
    }
  }
  EXPECT_EQ(unknown_fields_->field_count(), pos);
}

TEST_F(UnknownFieldSetTest, Varint) {
  const UnknownField* field = GetField("optional_int32");
  ASSERT_TRUE(field != NULL);

  ASSERT_EQ(UnknownField::TYPE_VARINT, field->type());
  EXPECT_EQ(all_fields_.optional_int32(), field->varint());
}

TEST_F(UnknownFieldSetTest, Fixed32) {
  const UnknownField* field = GetField("optional_fixed32");
  ASSERT_TRUE(field != NULL);

  ASSERT_EQ(UnknownField::TYPE_FIXED32, field->type());
  EXPECT_EQ(all_fields_.optional_fixed32(), field->fixed32());
}

TEST_F(UnknownFieldSetTest, Fixed64) {
  const UnknownField* field = GetField("optional_fixed64");
  ASSERT_TRUE(field != NULL);

  ASSERT_EQ(UnknownField::TYPE_FIXED64, field->type());
  EXPECT_EQ(all_fields_.optional_fixed64(), field->fixed64());
}

TEST_F(UnknownFieldSetTest, LengthDelimited) {
  const UnknownField* field = GetField("optional_string");
  ASSERT_TRUE(field != NULL);

  ASSERT_EQ(UnknownField::TYPE_LENGTH_DELIMITED, field->type());
  EXPECT_EQ(all_fields_.optional_string(), field->length_delimited());
}

TEST_F(UnknownFieldSetTest, Group) {
  const UnknownField* field = GetField("optionalgroup");
  ASSERT_TRUE(field != NULL);

  ASSERT_EQ(UnknownField::TYPE_GROUP, field->type());
  ASSERT_EQ(1, field->group().field_count());

  const UnknownField& nested_field = field->group().field(0);
  const FieldDescriptor* nested_field_descriptor =
    unittest::TestAllTypes::OptionalGroup::descriptor()->FindFieldByName("a");
  ASSERT_TRUE(nested_field_descriptor != NULL);

  EXPECT_EQ(nested_field_descriptor->number(), nested_field.number());
  ASSERT_EQ(UnknownField::TYPE_VARINT, nested_field.type());
  EXPECT_EQ(all_fields_.optionalgroup().a(), nested_field.varint());
}

TEST_F(UnknownFieldSetTest, SerializeFastAndSlowAreEquivalent) {
  int size = WireFormat::ComputeUnknownFieldsSize(
      empty_message_.unknown_fields());
  string slow_buffer;
  string fast_buffer;
  slow_buffer.resize(size);
  fast_buffer.resize(size);

  uint8* target = reinterpret_cast<uint8*>(string_as_array(&fast_buffer));
  uint8* result = WireFormat::SerializeUnknownFieldsToArray(
          empty_message_.unknown_fields(), target);
  EXPECT_EQ(size, result - target);

  {
    io::ArrayOutputStream raw_stream(string_as_array(&slow_buffer), size, 1);
    io::CodedOutputStream output_stream(&raw_stream);
    WireFormat::SerializeUnknownFields(empty_message_.unknown_fields(),
                                       &output_stream);
    ASSERT_FALSE(output_stream.HadError());
  }
  EXPECT_TRUE(fast_buffer == slow_buffer);
}

TEST_F(UnknownFieldSetTest, Serialize) {
  // Check that serializing the UnknownFieldSet produces the original data
  // again.

  string data;
  empty_message_.SerializeToString(&data);

  // Don't use EXPECT_EQ because we don't want to dump raw binary data to
  // stdout.
  EXPECT_TRUE(data == all_fields_data_);
}

TEST_F(UnknownFieldSetTest, ParseViaReflection) {
  // Make sure fields are properly parsed to the UnknownFieldSet when parsing
  // via reflection.

  unittest::TestEmptyMessage message;
  io::ArrayInputStream raw_input(all_fields_data_.data(),
                                 all_fields_data_.size());
  io::CodedInputStream input(&raw_input);
  ASSERT_TRUE(WireFormat::ParseAndMergePartial(&input, &message));

  EXPECT_EQ(message.DebugString(), empty_message_.DebugString());
}

TEST_F(UnknownFieldSetTest, SerializeViaReflection) {
  // Make sure fields are properly written from the UnknownFieldSet when
  // serializing via reflection.

  string data;

  {
    io::StringOutputStream raw_output(&data);
    io::CodedOutputStream output(&raw_output);
    int size = WireFormat::ByteSize(empty_message_);
    WireFormat::SerializeWithCachedSizes(empty_message_, size, &output);
    ASSERT_FALSE(output.HadError());
  }

  // Don't use EXPECT_EQ because we don't want to dump raw binary data to
  // stdout.
  EXPECT_TRUE(data == all_fields_data_);
}

TEST_F(UnknownFieldSetTest, CopyFrom) {
  unittest::TestEmptyMessage message;

  message.CopyFrom(empty_message_);

  EXPECT_EQ(empty_message_.DebugString(), message.DebugString());
}

TEST_F(UnknownFieldSetTest, Swap) {
  unittest::TestEmptyMessage other_message;
  ASSERT_TRUE(other_message.ParseFromString(GetBizarroData()));

  EXPECT_GT(empty_message_.unknown_fields().field_count(), 0);
  EXPECT_GT(other_message.unknown_fields().field_count(), 0);
  const string debug_string = empty_message_.DebugString();
  const string other_debug_string = other_message.DebugString();
  EXPECT_NE(debug_string, other_debug_string);

  empty_message_.Swap(&other_message);
  EXPECT_EQ(debug_string, other_message.DebugString());
  EXPECT_EQ(other_debug_string, empty_message_.DebugString());
}

TEST_F(UnknownFieldSetTest, SwapWithSelf) {
  const string debug_string = empty_message_.DebugString();
  EXPECT_GT(empty_message_.unknown_fields().field_count(), 0);

  empty_message_.Swap(&empty_message_);
  EXPECT_GT(empty_message_.unknown_fields().field_count(), 0);
  EXPECT_EQ(debug_string, empty_message_.DebugString());
}

TEST_F(UnknownFieldSetTest, MergeFrom) {
  unittest::TestEmptyMessage source, destination;

  destination.mutable_unknown_fields()->AddVarint(1, 1);
  destination.mutable_unknown_fields()->AddVarint(3, 2);
  source.mutable_unknown_fields()->AddVarint(2, 3);
  source.mutable_unknown_fields()->AddVarint(3, 4);

  destination.MergeFrom(source);

  EXPECT_EQ(
    // Note:  The ordering of fields here depends on the ordering of adds
    //   and merging, above.
    "1: 1\n"
    "3: 2\n"
    "2: 3\n"
    "3: 4\n",
    destination.DebugString());
}


TEST_F(UnknownFieldSetTest, Clear) {
  // Clear the set.
  empty_message_.Clear();
  EXPECT_EQ(0, unknown_fields_->field_count());
}

TEST_F(UnknownFieldSetTest, ClearAndFreeMemory) {
  EXPECT_GT(unknown_fields_->field_count(), 0);
  unknown_fields_->ClearAndFreeMemory();
  EXPECT_EQ(0, unknown_fields_->field_count());
  unknown_fields_->AddVarint(123456, 654321);
  EXPECT_EQ(1, unknown_fields_->field_count());
}

TEST_F(UnknownFieldSetTest, ParseKnownAndUnknown) {
  // Test mixing known and unknown fields when parsing.

  unittest::TestEmptyMessage source;
  source.mutable_unknown_fields()->AddVarint(123456, 654321);
  string data;
  ASSERT_TRUE(source.SerializeToString(&data));

  unittest::TestAllTypes destination;
  ASSERT_TRUE(destination.ParseFromString(all_fields_data_ + data));

  TestUtil::ExpectAllFieldsSet(destination);
  ASSERT_EQ(1, destination.unknown_fields().field_count());
  ASSERT_EQ(UnknownField::TYPE_VARINT,
            destination.unknown_fields().field(0).type());
  EXPECT_EQ(654321, destination.unknown_fields().field(0).varint());
}

TEST_F(UnknownFieldSetTest, WrongTypeTreatedAsUnknown) {
  // Test that fields of the wrong wire type are treated like unknown fields
  // when parsing.

  unittest::TestAllTypes all_types_message;
  unittest::TestEmptyMessage empty_message;
  string bizarro_data = GetBizarroData();
  ASSERT_TRUE(all_types_message.ParseFromString(bizarro_data));
  ASSERT_TRUE(empty_message.ParseFromString(bizarro_data));

  // All fields should have been interpreted as unknown, so the debug strings
  // should be the same.
  EXPECT_EQ(empty_message.DebugString(), all_types_message.DebugString());
}

TEST_F(UnknownFieldSetTest, WrongTypeTreatedAsUnknownViaReflection) {
  // Same as WrongTypeTreatedAsUnknown but via the reflection interface.

  unittest::TestAllTypes all_types_message;
  unittest::TestEmptyMessage empty_message;
  string bizarro_data = GetBizarroData();
  io::ArrayInputStream raw_input(bizarro_data.data(), bizarro_data.size());
  io::CodedInputStream input(&raw_input);
  ASSERT_TRUE(WireFormat::ParseAndMergePartial(&input, &all_types_message));
  ASSERT_TRUE(empty_message.ParseFromString(bizarro_data));

  EXPECT_EQ(empty_message.DebugString(), all_types_message.DebugString());
}

TEST_F(UnknownFieldSetTest, UnknownExtensions) {
  // Make sure fields are properly parsed to the UnknownFieldSet even when
  // they are declared as extension numbers.

  unittest::TestEmptyMessageWithExtensions message;
  ASSERT_TRUE(message.ParseFromString(all_fields_data_));

  EXPECT_EQ(message.DebugString(), empty_message_.DebugString());
}

TEST_F(UnknownFieldSetTest, UnknownExtensionsReflection) {
  // Same as UnknownExtensions except parsing via reflection.

  unittest::TestEmptyMessageWithExtensions message;
  io::ArrayInputStream raw_input(all_fields_data_.data(),
                                 all_fields_data_.size());
  io::CodedInputStream input(&raw_input);
  ASSERT_TRUE(WireFormat::ParseAndMergePartial(&input, &message));

  EXPECT_EQ(message.DebugString(), empty_message_.DebugString());
}

TEST_F(UnknownFieldSetTest, WrongExtensionTypeTreatedAsUnknown) {
  // Test that fields of the wrong wire type are treated like unknown fields
  // when parsing extensions.

  unittest::TestAllExtensions all_extensions_message;
  unittest::TestEmptyMessage empty_message;
  string bizarro_data = GetBizarroData();
  ASSERT_TRUE(all_extensions_message.ParseFromString(bizarro_data));
  ASSERT_TRUE(empty_message.ParseFromString(bizarro_data));

  // All fields should have been interpreted as unknown, so the debug strings
  // should be the same.
  EXPECT_EQ(empty_message.DebugString(), all_extensions_message.DebugString());
}

TEST_F(UnknownFieldSetTest, UnknownEnumValue) {
  using unittest::TestAllTypes;
  using unittest::TestAllExtensions;
  using unittest::TestEmptyMessage;

  const FieldDescriptor* singular_field =
    TestAllTypes::descriptor()->FindFieldByName("optional_nested_enum");
  const FieldDescriptor* repeated_field =
    TestAllTypes::descriptor()->FindFieldByName("repeated_nested_enum");
  ASSERT_TRUE(singular_field != NULL);
  ASSERT_TRUE(repeated_field != NULL);

  string data;

  {
    TestEmptyMessage empty_message;
    UnknownFieldSet* unknown_fields = empty_message.mutable_unknown_fields();
    unknown_fields->AddVarint(singular_field->number(), TestAllTypes::BAR);
    unknown_fields->AddVarint(singular_field->number(), 5);  // not valid
    unknown_fields->AddVarint(repeated_field->number(), TestAllTypes::FOO);
    unknown_fields->AddVarint(repeated_field->number(), 4);  // not valid
    unknown_fields->AddVarint(repeated_field->number(), TestAllTypes::BAZ);
    unknown_fields->AddVarint(repeated_field->number(), 6);  // not valid
    empty_message.SerializeToString(&data);
  }

  {
    TestAllTypes message;
    ASSERT_TRUE(message.ParseFromString(data));
    EXPECT_EQ(TestAllTypes::BAR, message.optional_nested_enum());
    ASSERT_EQ(2, message.repeated_nested_enum_size());
    EXPECT_EQ(TestAllTypes::FOO, message.repeated_nested_enum(0));
    EXPECT_EQ(TestAllTypes::BAZ, message.repeated_nested_enum(1));

    const UnknownFieldSet& unknown_fields = message.unknown_fields();
    ASSERT_EQ(3, unknown_fields.field_count());

    EXPECT_EQ(singular_field->number(), unknown_fields.field(0).number());
    ASSERT_EQ(UnknownField::TYPE_VARINT, unknown_fields.field(0).type());
    EXPECT_EQ(5, unknown_fields.field(0).varint());

    EXPECT_EQ(repeated_field->number(), unknown_fields.field(1).number());
    ASSERT_EQ(UnknownField::TYPE_VARINT, unknown_fields.field(1).type());
    EXPECT_EQ(4, unknown_fields.field(1).varint());

    EXPECT_EQ(repeated_field->number(), unknown_fields.field(2).number());
    ASSERT_EQ(UnknownField::TYPE_VARINT, unknown_fields.field(2).type());
    EXPECT_EQ(6, unknown_fields.field(2).varint());
  }

  {
    using unittest::optional_nested_enum_extension;
    using unittest::repeated_nested_enum_extension;

    TestAllExtensions message;
    ASSERT_TRUE(message.ParseFromString(data));
    EXPECT_EQ(TestAllTypes::BAR,
              message.GetExtension(optional_nested_enum_extension));
    ASSERT_EQ(2, message.ExtensionSize(repeated_nested_enum_extension));
    EXPECT_EQ(TestAllTypes::FOO,
              message.GetExtension(repeated_nested_enum_extension, 0));
    EXPECT_EQ(TestAllTypes::BAZ,
              message.GetExtension(repeated_nested_enum_extension, 1));

    const UnknownFieldSet& unknown_fields = message.unknown_fields();
    ASSERT_EQ(3, unknown_fields.field_count());

    EXPECT_EQ(singular_field->number(), unknown_fields.field(0).number());
    ASSERT_EQ(UnknownField::TYPE_VARINT, unknown_fields.field(0).type());
    EXPECT_EQ(5, unknown_fields.field(0).varint());

    EXPECT_EQ(repeated_field->number(), unknown_fields.field(1).number());
    ASSERT_EQ(UnknownField::TYPE_VARINT, unknown_fields.field(1).type());
    EXPECT_EQ(4, unknown_fields.field(1).varint());

    EXPECT_EQ(repeated_field->number(), unknown_fields.field(2).number());
    ASSERT_EQ(UnknownField::TYPE_VARINT, unknown_fields.field(2).type());
    EXPECT_EQ(6, unknown_fields.field(2).varint());
  }
}

TEST_F(UnknownFieldSetTest, SpaceUsedExcludingSelf) {
  UnknownFieldSet empty;
  empty.AddVarint(1, 0);
  EXPECT_EQ(sizeof(std::vector<UnknownField>) + sizeof(UnknownField),
            empty.SpaceUsedExcludingSelf());
}

TEST_F(UnknownFieldSetTest, SpaceUsed) {
  unittest::TestEmptyMessage empty_message;

  // Make sure an unknown field set has zero space used until a field is
  // actually added.
  int base_size = empty_message.SpaceUsed();
  UnknownFieldSet* unknown_fields = empty_message.mutable_unknown_fields();
  EXPECT_EQ(base_size, empty_message.SpaceUsed());

  // Make sure each thing we add to the set increases the SpaceUsed().
  unknown_fields->AddVarint(1, 0);
  EXPECT_LT(base_size, empty_message.SpaceUsed());
  base_size = empty_message.SpaceUsed();

  string* str = unknown_fields->AddLengthDelimited(1);
  EXPECT_LT(base_size, empty_message.SpaceUsed());
  base_size = empty_message.SpaceUsed();

  str->assign(sizeof(string) + 1, 'x');
  EXPECT_LT(base_size, empty_message.SpaceUsed());
  base_size = empty_message.SpaceUsed();

  UnknownFieldSet* group = unknown_fields->AddGroup(1);
  EXPECT_LT(base_size, empty_message.SpaceUsed());
  base_size = empty_message.SpaceUsed();

  group->AddVarint(1, 0);
  EXPECT_LT(base_size, empty_message.SpaceUsed());
}


TEST_F(UnknownFieldSetTest, Empty) {
  UnknownFieldSet unknown_fields;
  EXPECT_TRUE(unknown_fields.empty());
  unknown_fields.AddVarint(6, 123);
  EXPECT_FALSE(unknown_fields.empty());
  unknown_fields.Clear();
  EXPECT_TRUE(unknown_fields.empty());
}

TEST_F(UnknownFieldSetTest, DeleteSubrange) {
  // Exhaustively test the deletion of every possible subrange in arrays of all
  // sizes from 0 through 9.
  for (int size = 0; size < 10; ++size) {
    for (int num = 0; num <= size; ++num) {
      for (int start = 0; start < size - num; ++start) {
        // Create a set with "size" fields.
        UnknownFieldSet unknown;
        for (int i = 0; i < size; ++i) {
          unknown.AddFixed32(i, i);
        }
        // Delete the specified subrange.
        unknown.DeleteSubrange(start, num);
        // Make sure the resulting field values are still correct.
        EXPECT_EQ(size - num, unknown.field_count());
        for (int i = 0; i < unknown.field_count(); ++i) {
          if (i < start) {
            EXPECT_EQ(i, unknown.field(i).fixed32());
          } else {
            EXPECT_EQ(i + num, unknown.field(i).fixed32());
          }
        }
      }
    }
  }
}

void CheckDeleteByNumber(const std::vector<int>& field_numbers,
                         int deleted_number,
                         const std::vector<int>& expected_field_nubmers) {
  UnknownFieldSet unknown_fields;
  for (int i = 0; i < field_numbers.size(); ++i) {
    unknown_fields.AddFixed32(field_numbers[i], i);
  }
  unknown_fields.DeleteByNumber(deleted_number);
  ASSERT_EQ(expected_field_nubmers.size(), unknown_fields.field_count());
  for (int i = 0; i < expected_field_nubmers.size(); ++i) {
    EXPECT_EQ(expected_field_nubmers[i],
              unknown_fields.field(i).number());
  }
}

#define MAKE_VECTOR(x) std::vector<int>(x, x + GOOGLE_ARRAYSIZE(x))
TEST_F(UnknownFieldSetTest, DeleteByNumber) {
  CheckDeleteByNumber(std::vector<int>(), 1, std::vector<int>());
  static const int kTestFieldNumbers1[] = {1, 2, 3};
  static const int kFieldNumberToDelete1 = 1;
  static const int kExpectedFieldNumbers1[] = {2, 3};
  CheckDeleteByNumber(MAKE_VECTOR(kTestFieldNumbers1), kFieldNumberToDelete1,
                      MAKE_VECTOR(kExpectedFieldNumbers1));
  static const int kTestFieldNumbers2[] = {1, 2, 3};
  static const int kFieldNumberToDelete2 = 2;
  static const int kExpectedFieldNumbers2[] = {1, 3};
  CheckDeleteByNumber(MAKE_VECTOR(kTestFieldNumbers2), kFieldNumberToDelete2,
                      MAKE_VECTOR(kExpectedFieldNumbers2));
  static const int kTestFieldNumbers3[] = {1, 2, 3};
  static const int kFieldNumberToDelete3 = 3;
  static const int kExpectedFieldNumbers3[] = {1, 2};
  CheckDeleteByNumber(MAKE_VECTOR(kTestFieldNumbers3), kFieldNumberToDelete3,
                      MAKE_VECTOR(kExpectedFieldNumbers3));
  static const int kTestFieldNumbers4[] = {1, 2, 1, 4, 1};
  static const int kFieldNumberToDelete4 = 1;
  static const int kExpectedFieldNumbers4[] = {2, 4};
  CheckDeleteByNumber(MAKE_VECTOR(kTestFieldNumbers4), kFieldNumberToDelete4,
                      MAKE_VECTOR(kExpectedFieldNumbers4));
  static const int kTestFieldNumbers5[] = {1, 2, 3, 4, 5};
  static const int kFieldNumberToDelete5 = 6;
  static const int kExpectedFieldNumbers5[] = {1, 2, 3, 4, 5};
  CheckDeleteByNumber(MAKE_VECTOR(kTestFieldNumbers5), kFieldNumberToDelete5,
                      MAKE_VECTOR(kExpectedFieldNumbers5));
}
#undef MAKE_VECTOR
}  // namespace

}  // namespace protobuf
}  // namespace google
