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

package com.google.protobuf;

import protobuf_unittest.UnittestProto;
import protobuf_unittest.UnittestProto.ForeignEnum;
import protobuf_unittest.UnittestProto.TestAllExtensions;
import protobuf_unittest.UnittestProto.TestAllTypes;
import protobuf_unittest.UnittestProto.TestEmptyMessage;
import protobuf_unittest.UnittestProto.TestEmptyMessageWithExtensions;
import protobuf_unittest.UnittestProto.TestPackedExtensions;
import protobuf_unittest.UnittestProto.TestPackedTypes;
import java.util.Arrays;
import java.util.Map;
import junit.framework.TestCase;

/**
 * Tests related to unknown field handling.
 *
 * @author kenton@google.com (Kenton Varda)
 */
public class UnknownFieldSetTest extends TestCase {
  @Override
  public void setUp() throws Exception {
    descriptor = TestAllTypes.getDescriptor();
    allFields = TestUtil.getAllSet();
    allFieldsData = allFields.toByteString();
    emptyMessage = TestEmptyMessage.parseFrom(allFieldsData);
    unknownFields = emptyMessage.getUnknownFields();
  }

  UnknownFieldSet.Field getField(String name) {
    Descriptors.FieldDescriptor field = descriptor.findFieldByName(name);
    assertNotNull(field);
    return unknownFields.getField(field.getNumber());
  }

  // Constructs a protocol buffer which contains fields with all the same
  // numbers as allFieldsData except that each field is some other wire
  // type.
  ByteString getBizarroData() throws Exception {
    UnknownFieldSet.Builder bizarroFields = UnknownFieldSet.newBuilder();

    UnknownFieldSet.Field varintField =
      UnknownFieldSet.Field.newBuilder().addVarint(1).build();
    UnknownFieldSet.Field fixed32Field =
      UnknownFieldSet.Field.newBuilder().addFixed32(1).build();

    for (Map.Entry<Integer, UnknownFieldSet.Field> entry :
         unknownFields.asMap().entrySet()) {
      if (entry.getValue().getVarintList().isEmpty()) {
        // Original field is not a varint, so use a varint.
        bizarroFields.addField(entry.getKey(), varintField);
      } else {
        // Original field *is* a varint, so use something else.
        bizarroFields.addField(entry.getKey(), fixed32Field);
      }
    }

    return bizarroFields.build().toByteString();
  }

  Descriptors.Descriptor descriptor;
  TestAllTypes allFields;
  ByteString allFieldsData;

  // An empty message that has been parsed from allFieldsData.  So, it has
  // unknown fields of every type.
  TestEmptyMessage emptyMessage;
  UnknownFieldSet unknownFields;

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

  public void testVarint() throws Exception {
    UnknownFieldSet.Field field = getField("optional_int32");
    assertEquals(1, field.getVarintList().size());
    assertEquals(allFields.getOptionalInt32(),
                 (long) field.getVarintList().get(0));
  }

  public void testFixed32() throws Exception {
    UnknownFieldSet.Field field = getField("optional_fixed32");
    assertEquals(1, field.getFixed32List().size());
    assertEquals(allFields.getOptionalFixed32(),
                 (int) field.getFixed32List().get(0));
  }

  public void testFixed64() throws Exception {
    UnknownFieldSet.Field field = getField("optional_fixed64");
    assertEquals(1, field.getFixed64List().size());
    assertEquals(allFields.getOptionalFixed64(),
                 (long) field.getFixed64List().get(0));
  }

  public void testLengthDelimited() throws Exception {
    UnknownFieldSet.Field field = getField("optional_bytes");
    assertEquals(1, field.getLengthDelimitedList().size());
    assertEquals(allFields.getOptionalBytes(),
                 field.getLengthDelimitedList().get(0));
  }

  public void testGroup() throws Exception {
    Descriptors.FieldDescriptor nestedFieldDescriptor =
      TestAllTypes.OptionalGroup.getDescriptor().findFieldByName("a");
    assertNotNull(nestedFieldDescriptor);

    UnknownFieldSet.Field field = getField("optionalgroup");
    assertEquals(1, field.getGroupList().size());

    UnknownFieldSet group = field.getGroupList().get(0);
    assertEquals(1, group.asMap().size());
    assertTrue(group.hasField(nestedFieldDescriptor.getNumber()));

    UnknownFieldSet.Field nestedField =
      group.getField(nestedFieldDescriptor.getNumber());
    assertEquals(1, nestedField.getVarintList().size());
    assertEquals(allFields.getOptionalGroup().getA(),
                 (long) nestedField.getVarintList().get(0));
  }

  public void testSerialize() throws Exception {
    // Check that serializing the UnknownFieldSet produces the original data
    // again.
    ByteString data = emptyMessage.toByteString();
    assertEquals(allFieldsData, data);
  }

  public void testCopyFrom() throws Exception {
    TestEmptyMessage message =
      TestEmptyMessage.newBuilder().mergeFrom(emptyMessage).build();

    assertEquals(emptyMessage.toString(), message.toString());
  }

  public void testMergeFrom() throws Exception {
    TestEmptyMessage source =
      TestEmptyMessage.newBuilder()
        .setUnknownFields(
          UnknownFieldSet.newBuilder()
            .addField(2,
              UnknownFieldSet.Field.newBuilder()
                .addVarint(2).build())
            .addField(3,
              UnknownFieldSet.Field.newBuilder()
                .addVarint(4).build())
            .build())
        .build();
    TestEmptyMessage destination =
      TestEmptyMessage.newBuilder()
        .setUnknownFields(
          UnknownFieldSet.newBuilder()
            .addField(1,
              UnknownFieldSet.Field.newBuilder()
                .addVarint(1).build())
            .addField(3,
              UnknownFieldSet.Field.newBuilder()
                .addVarint(3).build())
            .build())
        .mergeFrom(source)
        .build();

    assertEquals(
      "1: 1\n" +
      "2: 2\n" +
      "3: 3\n" +
      "3: 4\n",
      destination.toString());
  }

  public void testClear() throws Exception {
    UnknownFieldSet fields =
      UnknownFieldSet.newBuilder().mergeFrom(unknownFields).clear().build();
    assertTrue(fields.asMap().isEmpty());
  }

  public void testClearMessage() throws Exception {
    TestEmptyMessage message =
      TestEmptyMessage.newBuilder().mergeFrom(emptyMessage).clear().build();
    assertEquals(0, message.getSerializedSize());
  }
  
  public void testClearField() throws Exception {
    int fieldNumber = unknownFields.asMap().keySet().iterator().next();
    UnknownFieldSet fields =
        UnknownFieldSet.newBuilder().mergeFrom(unknownFields).clearField(fieldNumber).build();
    assertFalse(fields.hasField(fieldNumber));
  }

  public void testParseKnownAndUnknown() throws Exception {
    // Test mixing known and unknown fields when parsing.

    UnknownFieldSet fields =
      UnknownFieldSet.newBuilder(unknownFields)
        .addField(123456,
          UnknownFieldSet.Field.newBuilder().addVarint(654321).build())
        .build();

    ByteString data = fields.toByteString();
    TestAllTypes destination = TestAllTypes.parseFrom(data);

    TestUtil.assertAllFieldsSet(destination);
    assertEquals(1, destination.getUnknownFields().asMap().size());

    UnknownFieldSet.Field field =
      destination.getUnknownFields().getField(123456);
    assertEquals(1, field.getVarintList().size());
    assertEquals(654321, (long) field.getVarintList().get(0));
  }

  public void testWrongTypeTreatedAsUnknown() throws Exception {
    // Test that fields of the wrong wire type are treated like unknown fields
    // when parsing.

    ByteString bizarroData = getBizarroData();
    TestAllTypes allTypesMessage = TestAllTypes.parseFrom(bizarroData);
    TestEmptyMessage emptyMessage = TestEmptyMessage.parseFrom(bizarroData);

    // All fields should have been interpreted as unknown, so the debug strings
    // should be the same.
    assertEquals(emptyMessage.toString(), allTypesMessage.toString());
  }

  public void testUnknownExtensions() throws Exception {
    // Make sure fields are properly parsed to the UnknownFieldSet even when
    // they are declared as extension numbers.

    TestEmptyMessageWithExtensions message =
      TestEmptyMessageWithExtensions.parseFrom(allFieldsData);

    assertEquals(unknownFields.asMap().size(),
                 message.getUnknownFields().asMap().size());
    assertEquals(allFieldsData, message.toByteString());
  }

  public void testWrongExtensionTypeTreatedAsUnknown() throws Exception {
    // Test that fields of the wrong wire type are treated like unknown fields
    // when parsing extensions.

    ByteString bizarroData = getBizarroData();
    TestAllExtensions allExtensionsMessage =
      TestAllExtensions.parseFrom(bizarroData);
    TestEmptyMessage emptyMessage = TestEmptyMessage.parseFrom(bizarroData);

    // All fields should have been interpreted as unknown, so the debug strings
    // should be the same.
    assertEquals(emptyMessage.toString(),
                 allExtensionsMessage.toString());
  }

  public void testParseUnknownEnumValue() throws Exception {
    Descriptors.FieldDescriptor singularField =
      TestAllTypes.getDescriptor().findFieldByName("optional_nested_enum");
    Descriptors.FieldDescriptor repeatedField =
      TestAllTypes.getDescriptor().findFieldByName("repeated_nested_enum");
    assertNotNull(singularField);
    assertNotNull(repeatedField);

    ByteString data =
      UnknownFieldSet.newBuilder()
        .addField(singularField.getNumber(),
          UnknownFieldSet.Field.newBuilder()
            .addVarint(TestAllTypes.NestedEnum.BAR.getNumber())
            .addVarint(5)   // not valid
            .build())
        .addField(repeatedField.getNumber(),
          UnknownFieldSet.Field.newBuilder()
            .addVarint(TestAllTypes.NestedEnum.FOO.getNumber())
            .addVarint(4)   // not valid
            .addVarint(TestAllTypes.NestedEnum.BAZ.getNumber())
            .addVarint(6)   // not valid
            .build())
        .build()
        .toByteString();

    {
      TestAllTypes message = TestAllTypes.parseFrom(data);
      assertEquals(TestAllTypes.NestedEnum.BAR,
                   message.getOptionalNestedEnum());
      assertEquals(
        Arrays.asList(TestAllTypes.NestedEnum.FOO, TestAllTypes.NestedEnum.BAZ),
        message.getRepeatedNestedEnumList());
      assertEquals(Arrays.asList(5L),
                   message.getUnknownFields()
                          .getField(singularField.getNumber())
                          .getVarintList());
      assertEquals(Arrays.asList(4L, 6L),
                   message.getUnknownFields()
                          .getField(repeatedField.getNumber())
                          .getVarintList());
    }

    {
      TestAllExtensions message =
        TestAllExtensions.parseFrom(data, TestUtil.getExtensionRegistry());
      assertEquals(TestAllTypes.NestedEnum.BAR,
        message.getExtension(UnittestProto.optionalNestedEnumExtension));
      assertEquals(
        Arrays.asList(TestAllTypes.NestedEnum.FOO, TestAllTypes.NestedEnum.BAZ),
        message.getExtension(UnittestProto.repeatedNestedEnumExtension));
      assertEquals(Arrays.asList(5L),
                   message.getUnknownFields()
                          .getField(singularField.getNumber())
                          .getVarintList());
      assertEquals(Arrays.asList(4L, 6L),
                   message.getUnknownFields()
                          .getField(repeatedField.getNumber())
                          .getVarintList());
    }
  }

  public void testLargeVarint() throws Exception {
    ByteString data =
      UnknownFieldSet.newBuilder()
        .addField(1,
          UnknownFieldSet.Field.newBuilder()
            .addVarint(0x7FFFFFFFFFFFFFFFL)
            .build())
        .build()
        .toByteString();
    UnknownFieldSet parsed = UnknownFieldSet.parseFrom(data);
    UnknownFieldSet.Field field = parsed.getField(1);
    assertEquals(1, field.getVarintList().size());
    assertEquals(0x7FFFFFFFFFFFFFFFL, (long)field.getVarintList().get(0));
  }

  public void testEqualsAndHashCode() {
    UnknownFieldSet.Field fixed32Field =
        UnknownFieldSet.Field.newBuilder()
            .addFixed32(1)
            .build();
    UnknownFieldSet.Field fixed64Field =
        UnknownFieldSet.Field.newBuilder()
            .addFixed64(1)
            .build();
    UnknownFieldSet.Field varIntField =
        UnknownFieldSet.Field.newBuilder()
            .addVarint(1)
            .build();
    UnknownFieldSet.Field lengthDelimitedField =
        UnknownFieldSet.Field.newBuilder()
            .addLengthDelimited(ByteString.EMPTY)
            .build();
    UnknownFieldSet.Field groupField =
        UnknownFieldSet.Field.newBuilder()
            .addGroup(unknownFields)
            .build();

    UnknownFieldSet a =
        UnknownFieldSet.newBuilder()
            .addField(1, fixed32Field)
            .build();
    UnknownFieldSet b =
        UnknownFieldSet.newBuilder()
            .addField(1, fixed64Field)
            .build();
    UnknownFieldSet c =
        UnknownFieldSet.newBuilder()
            .addField(1, varIntField)
            .build();
    UnknownFieldSet d =
        UnknownFieldSet.newBuilder()
            .addField(1, lengthDelimitedField)
            .build();
    UnknownFieldSet e =
        UnknownFieldSet.newBuilder()
            .addField(1, groupField)
            .build();

    checkEqualsIsConsistent(a);
    checkEqualsIsConsistent(b);
    checkEqualsIsConsistent(c);
    checkEqualsIsConsistent(d);
    checkEqualsIsConsistent(e);

    checkNotEqual(a, b);
    checkNotEqual(a, c);
    checkNotEqual(a, d);
    checkNotEqual(a, e);
    checkNotEqual(b, c);
    checkNotEqual(b, d);
    checkNotEqual(b, e);
    checkNotEqual(c, d);
    checkNotEqual(c, e);
    checkNotEqual(d, e);
  }

  /**
   * Asserts that the given field sets are not equal and have different
   * hash codes.
   *
   * @warning It's valid for non-equal objects to have the same hash code, so
   *   this test is stricter than it needs to be. However, this should happen
   *   relatively rarely.
   */
  private void checkNotEqual(UnknownFieldSet s1, UnknownFieldSet s2) {
    String equalsError = String.format("%s should not be equal to %s", s1, s2);
    assertFalse(equalsError, s1.equals(s2));
    assertFalse(equalsError, s2.equals(s1));

    assertFalse(
        String.format("%s should have a different hash code from %s", s1, s2),
        s1.hashCode() == s2.hashCode());
  }

  /**
   * Asserts that the given field sets are equal and have identical hash codes.
   */
  private void checkEqualsIsConsistent(UnknownFieldSet set) {
    // Object should be equal to itself.
    assertEquals(set, set);

    // Object should be equal to a copy of itself.
    UnknownFieldSet copy = UnknownFieldSet.newBuilder(set).build();
    assertEquals(set, copy);
    assertEquals(copy, set);
    assertEquals(set.hashCode(), copy.hashCode());
  }

  // =================================================================
}
