// 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.valueOf(unknown4321),
        TestAllTypes.NestedEnum.UNRECOGNIZED);
    assertEquals(
        TestAllTypes.NestedEnum.valueOf(unknown5432),
        TestAllTypes.NestedEnum.UNRECOGNIZED);
    assertEquals(
        TestAllTypes.NestedEnum.valueOf(unknown6543),
        TestAllTypes.NestedEnum.UNRECOGNIZED);
    
    // 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.
    }
  }
}
