// 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 com.google.protobuf.Descriptors.Descriptor;
import com.google.protobuf.Descriptors.EnumDescriptor;
import com.google.protobuf.Descriptors.EnumValueDescriptor;
import com.google.protobuf.Descriptors.FieldDescriptor;
import com.google.protobuf.FieldPresenceTestProto.TestAllTypes;
import com.google.protobuf.TextFormat.ParseException;
import junit.framework.TestCase;

/**
 * Unit tests for protos that keep unknown enum values rather than discard
 * them as unknown fields.
 */
public class UnknownEnumValueTest extends TestCase {
  public void testUnknownEnumValues() throws Exception {
    TestAllTypes.Builder builder = TestAllTypes.newBuilder();
    builder.setOptionalNestedEnumValue(4321);
    builder.addRepeatedNestedEnumValue(5432);
    builder.addPackedNestedEnumValue(6543);
    TestAllTypes message = builder.build();
    assertEquals(4321, message.getOptionalNestedEnumValue());
    assertEquals(5432, message.getRepeatedNestedEnumValue(0));
    assertEquals(5432, message.getRepeatedNestedEnumValueList().get(0).intValue());
    assertEquals(6543, message.getPackedNestedEnumValue(0));
    // Returns UNRECOGNIZED if an enum type is requested.
    assertEquals(TestAllTypes.NestedEnum.UNRECOGNIZED, message.getOptionalNestedEnum());
    assertEquals(TestAllTypes.NestedEnum.UNRECOGNIZED, message.getRepeatedNestedEnum(0));
    assertEquals(TestAllTypes.NestedEnum.UNRECOGNIZED, message.getRepeatedNestedEnumList().get(0));
    assertEquals(TestAllTypes.NestedEnum.UNRECOGNIZED, message.getPackedNestedEnum(0));
    
    // Test serialization and parsing.
    ByteString data = message.toByteString();
    message = TestAllTypes.parseFrom(data);
    assertEquals(4321, message.getOptionalNestedEnumValue());
    assertEquals(5432, message.getRepeatedNestedEnumValue(0));
    assertEquals(5432, message.getRepeatedNestedEnumValueList().get(0).intValue());
    assertEquals(6543, message.getPackedNestedEnumValue(0));
    // Returns UNRECOGNIZED if an enum type is requested.
    assertEquals(TestAllTypes.NestedEnum.UNRECOGNIZED, message.getOptionalNestedEnum());
    assertEquals(TestAllTypes.NestedEnum.UNRECOGNIZED, message.getRepeatedNestedEnum(0));
    assertEquals(TestAllTypes.NestedEnum.UNRECOGNIZED, message.getRepeatedNestedEnumList().get(0));
    assertEquals(TestAllTypes.NestedEnum.UNRECOGNIZED, message.getPackedNestedEnum(0));
    
    // Test toBuilder().
    builder = message.toBuilder();
    assertEquals(4321, builder.getOptionalNestedEnumValue());
    assertEquals(5432, builder.getRepeatedNestedEnumValue(0));
    assertEquals(5432, builder.getRepeatedNestedEnumValueList().get(0).intValue());
    assertEquals(6543, builder.getPackedNestedEnumValue(0));    
    // Returns UNRECOGNIZED if an enum type is requested.
    assertEquals(TestAllTypes.NestedEnum.UNRECOGNIZED, builder.getOptionalNestedEnum());
    assertEquals(TestAllTypes.NestedEnum.UNRECOGNIZED, builder.getRepeatedNestedEnum(0));
    assertEquals(TestAllTypes.NestedEnum.UNRECOGNIZED, builder.getRepeatedNestedEnumList().get(0));
    assertEquals(TestAllTypes.NestedEnum.UNRECOGNIZED, builder.getPackedNestedEnum(0));
    
    // Test mergeFrom().
    builder = TestAllTypes.newBuilder().mergeFrom(message);
    assertEquals(4321, builder.getOptionalNestedEnumValue());
    assertEquals(5432, builder.getRepeatedNestedEnumValue(0));
    assertEquals(5432, builder.getRepeatedNestedEnumValueList().get(0).intValue());
    assertEquals(6543, builder.getPackedNestedEnumValue(0));
    // Returns UNRECOGNIZED if an enum type is requested.
    assertEquals(TestAllTypes.NestedEnum.UNRECOGNIZED, builder.getOptionalNestedEnum());
    assertEquals(TestAllTypes.NestedEnum.UNRECOGNIZED, builder.getRepeatedNestedEnum(0));
    assertEquals(TestAllTypes.NestedEnum.UNRECOGNIZED, builder.getRepeatedNestedEnumList().get(0));
    assertEquals(TestAllTypes.NestedEnum.UNRECOGNIZED, builder.getPackedNestedEnum(0));
    
    // Test equals() and hashCode()
    TestAllTypes sameMessage = builder.build();
    assertEquals(message, sameMessage);
    assertEquals(message.hashCode(), sameMessage.hashCode());

    // Getting the numeric value of UNRECOGNIZED will throw an exception.
    try {
      TestAllTypes.NestedEnum.UNRECOGNIZED.getNumber();
      fail("Exception is expected.");
    } catch (IllegalArgumentException e) {
      // Expected.
    }

    // Setting an enum field to an UNRECOGNIZED value will throw an exception.
    try {
      builder.setOptionalNestedEnum(builder.getOptionalNestedEnum());
      fail("Exception is expected.");
    } catch (IllegalArgumentException e) {
      // Expected.
    }
    try {
      builder.addRepeatedNestedEnum(builder.getOptionalNestedEnum());
      fail("Exception is expected.");
    } catch (IllegalArgumentException e) {
      // Expected.
    }
  }
  
  public void testUnknownEnumValueInReflectionApi() throws Exception {
    Descriptor descriptor = TestAllTypes.getDescriptor();
    FieldDescriptor optionalNestedEnumField = descriptor.findFieldByName("optional_nested_enum");
    FieldDescriptor repeatedNestedEnumField = descriptor.findFieldByName("repeated_nested_enum");
    FieldDescriptor packedNestedEnumField = descriptor.findFieldByName("packed_nested_enum");
    EnumDescriptor enumType = TestAllTypes.NestedEnum.getDescriptor();

    TestAllTypes.Builder builder = TestAllTypes.newBuilder();
    builder.setField(optionalNestedEnumField,
        enumType.findValueByNumberCreatingIfUnknown(4321));
    builder.addRepeatedField(repeatedNestedEnumField,
        enumType.findValueByNumberCreatingIfUnknown(5432));
    builder.addRepeatedField(packedNestedEnumField,
        enumType.findValueByNumberCreatingIfUnknown(6543));
    TestAllTypes message = builder.build();
    
    // Getters will return unknown enum values as EnumValueDescriptor.
    EnumValueDescriptor unknown4321 =
        (EnumValueDescriptor) message.getField(optionalNestedEnumField);
    EnumValueDescriptor unknown5432 =
        (EnumValueDescriptor) message.getRepeatedField(repeatedNestedEnumField, 0);
    EnumValueDescriptor unknown6543 =
        (EnumValueDescriptor) message.getRepeatedField(packedNestedEnumField, 0);
    assertEquals(4321, unknown4321.getNumber());
    assertEquals(5432, unknown5432.getNumber());
    assertEquals(6543, unknown6543.getNumber());

    // Unknown EnumValueDescriptor will map to UNRECOGNIZED.
    assertEquals(
        TestAllTypes.NestedEnum.UNRECOGNIZED, TestAllTypes.NestedEnum.valueOf(unknown4321));
    assertEquals(
        TestAllTypes.NestedEnum.UNRECOGNIZED, TestAllTypes.NestedEnum.valueOf(unknown5432));
    assertEquals(
        TestAllTypes.NestedEnum.UNRECOGNIZED, TestAllTypes.NestedEnum.valueOf(unknown6543));

    // Setters also accept unknown EnumValueDescriptor.
    builder.setField(optionalNestedEnumField, unknown6543);
    builder.setRepeatedField(repeatedNestedEnumField, 0, unknown4321);
    builder.setRepeatedField(packedNestedEnumField, 0, unknown5432);
    message = builder.build();
    // Like other descriptors, unknown EnumValueDescriptor can be compared by
    // object identity.
    assertTrue(unknown6543 == message.getField(optionalNestedEnumField));
    assertTrue(unknown4321 == message.getRepeatedField(repeatedNestedEnumField, 0));
    assertTrue(unknown5432 == message.getRepeatedField(packedNestedEnumField, 0));
  }
  
  public void testUnknownEnumValueWithDynamicMessage() throws Exception {
    Descriptor descriptor = TestAllTypes.getDescriptor();
    FieldDescriptor optionalNestedEnumField = descriptor.findFieldByName("optional_nested_enum");
    FieldDescriptor repeatedNestedEnumField = descriptor.findFieldByName("repeated_nested_enum");
    FieldDescriptor packedNestedEnumField = descriptor.findFieldByName("packed_nested_enum");
    EnumDescriptor enumType = TestAllTypes.NestedEnum.getDescriptor();
    
    Message dynamicMessageDefaultInstance = DynamicMessage.getDefaultInstance(descriptor);

    Message.Builder builder = dynamicMessageDefaultInstance.newBuilderForType();
    builder.setField(optionalNestedEnumField,
        enumType.findValueByNumberCreatingIfUnknown(4321));
    builder.addRepeatedField(repeatedNestedEnumField,
        enumType.findValueByNumberCreatingIfUnknown(5432));
    builder.addRepeatedField(packedNestedEnumField,
        enumType.findValueByNumberCreatingIfUnknown(6543));
    Message message = builder.build();
    assertEquals(4321,
        ((EnumValueDescriptor) message.getField(optionalNestedEnumField)).getNumber());
    assertEquals(5432,
        ((EnumValueDescriptor) message.getRepeatedField(repeatedNestedEnumField, 0)).getNumber());
    assertEquals(6543,
        ((EnumValueDescriptor) message.getRepeatedField(packedNestedEnumField, 0)).getNumber());
    
    // Test reflection based serialization/parsing implementation.
    ByteString data = message.toByteString();
    message = dynamicMessageDefaultInstance
        .newBuilderForType()
        .mergeFrom(data)
        .build();
    assertEquals(4321,
        ((EnumValueDescriptor) message.getField(optionalNestedEnumField)).getNumber());
    assertEquals(5432,
        ((EnumValueDescriptor) message.getRepeatedField(repeatedNestedEnumField, 0)).getNumber());
    assertEquals(6543,
        ((EnumValueDescriptor) message.getRepeatedField(packedNestedEnumField, 0)).getNumber());
    
    // Test reflection based equals()/hashCode().
    builder = dynamicMessageDefaultInstance.newBuilderForType();
    builder.setField(optionalNestedEnumField,
        enumType.findValueByNumberCreatingIfUnknown(4321));
    builder.addRepeatedField(repeatedNestedEnumField,
        enumType.findValueByNumberCreatingIfUnknown(5432));
    builder.addRepeatedField(packedNestedEnumField,
        enumType.findValueByNumberCreatingIfUnknown(6543));
    Message sameMessage = builder.build();
    assertEquals(message, sameMessage);
    assertEquals(message.hashCode(), sameMessage.hashCode());
    builder.setField(optionalNestedEnumField,
        enumType.findValueByNumberCreatingIfUnknown(0));
    Message differentMessage = builder.build();
    assertFalse(message.equals(differentMessage));
  }
  
  public void testUnknownEnumValuesInTextFormat() {
    TestAllTypes.Builder builder = TestAllTypes.newBuilder();
    builder.setOptionalNestedEnumValue(4321);
    builder.addRepeatedNestedEnumValue(5432);
    builder.addPackedNestedEnumValue(6543);
    TestAllTypes message = builder.build();
    
    // We can print a message with unknown enum values.
    String textData = TextFormat.printToString(message);
    assertEquals(
        "optional_nested_enum: UNKNOWN_ENUM_VALUE_NestedEnum_4321\n"
        + "repeated_nested_enum: UNKNOWN_ENUM_VALUE_NestedEnum_5432\n"
        + "packed_nested_enum: UNKNOWN_ENUM_VALUE_NestedEnum_6543\n", textData);
    
    // Parsing unknown enum values will fail just like parsing other kinds of
    // unknown fields.
    try {
      TextFormat.merge(textData, builder);
      fail();
    } catch (ParseException e) {
      // expected.
    }
  }
}
