// 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 static com.google.protobuf.TestUtil.TEST_REQUIRED_INITIALIZED;
import static com.google.protobuf.TestUtil.TEST_REQUIRED_UNINITIALIZED;

import com.google.protobuf.Descriptors.FieldDescriptor;
import protobuf_unittest.UnittestOptimizeFor.TestOptimizedForSize;
import protobuf_unittest.UnittestProto;
import protobuf_unittest.UnittestProto.ForeignMessage;
import protobuf_unittest.UnittestProto.TestAllExtensions;
import protobuf_unittest.UnittestProto.TestAllTypes;
import protobuf_unittest.UnittestProto.TestPackedTypes;
import protobuf_unittest.UnittestProto.TestRequired;
import protobuf_unittest.UnittestProto.TestRequiredForeign;
import protobuf_unittest.UnittestProto.TestUnpackedTypes;
import java.util.Map;
import junit.framework.TestCase;

/**
 * Unit test for {@link AbstractMessage}.
 *
 * @author kenton@google.com Kenton Varda
 */
public class AbstractMessageTest extends TestCase {
  /**
   * Extends AbstractMessage and wraps some other message object.  The methods
   * of the Message interface which aren't explicitly implemented by
   * AbstractMessage are forwarded to the wrapped object.  This allows us to
   * test that AbstractMessage's implementations work even if the wrapped
   * object does not use them.
   */
  private static class AbstractMessageWrapper extends AbstractMessage {
    private final Message wrappedMessage;

    public AbstractMessageWrapper(Message wrappedMessage) {
      this.wrappedMessage = wrappedMessage;
    }

    @Override
    public Descriptors.Descriptor getDescriptorForType() {
      return wrappedMessage.getDescriptorForType();
    }
    @Override
    public AbstractMessageWrapper getDefaultInstanceForType() {
      return new AbstractMessageWrapper(
        wrappedMessage.getDefaultInstanceForType());
    }
    @Override
    public Map<Descriptors.FieldDescriptor, Object> getAllFields() {
      return wrappedMessage.getAllFields();
    }
    @Override
    public boolean hasField(Descriptors.FieldDescriptor field) {
      return wrappedMessage.hasField(field);
    }
    @Override
    public Object getField(Descriptors.FieldDescriptor field) {
      return wrappedMessage.getField(field);
    }
    @Override
    public int getRepeatedFieldCount(Descriptors.FieldDescriptor field) {
      return wrappedMessage.getRepeatedFieldCount(field);
    }
    @Override
    public Object getRepeatedField(Descriptors.FieldDescriptor field, int index) {
      return wrappedMessage.getRepeatedField(field, index);
    }
    @Override
    public UnknownFieldSet getUnknownFields() {
      return wrappedMessage.getUnknownFields();
    }
    @Override
    public Builder newBuilderForType() {
      return new Builder(wrappedMessage.newBuilderForType());
    }
    @Override
    public Builder toBuilder() {
      return new Builder(wrappedMessage.toBuilder());
    }

    static class Builder extends AbstractMessage.Builder<Builder> {
      private final Message.Builder wrappedBuilder;

      public Builder(Message.Builder wrappedBuilder) {
        this.wrappedBuilder = wrappedBuilder;
      }

      @Override
      public AbstractMessageWrapper build() {
        return new AbstractMessageWrapper(wrappedBuilder.build());
      }
      @Override
      public AbstractMessageWrapper buildPartial() {
        return new AbstractMessageWrapper(wrappedBuilder.buildPartial());
      }
      @Override
      public Builder clone() {
        return new Builder(wrappedBuilder.clone());
      }
      @Override
      public boolean isInitialized() {
        return clone().buildPartial().isInitialized();
      }
      @Override
      public Descriptors.Descriptor getDescriptorForType() {
        return wrappedBuilder.getDescriptorForType();
      }
      @Override
      public AbstractMessageWrapper getDefaultInstanceForType() {
        return new AbstractMessageWrapper(
          wrappedBuilder.getDefaultInstanceForType());
      }
      @Override
      public Map<Descriptors.FieldDescriptor, Object> getAllFields() {
        return wrappedBuilder.getAllFields();
      }
      @Override
      public Builder newBuilderForField(Descriptors.FieldDescriptor field) {
        return new Builder(wrappedBuilder.newBuilderForField(field));
      }
      @Override
      public boolean hasField(Descriptors.FieldDescriptor field) {
        return wrappedBuilder.hasField(field);
      }
      @Override
      public Object getField(Descriptors.FieldDescriptor field) {
        return wrappedBuilder.getField(field);
      }
      @Override
      public Builder setField(Descriptors.FieldDescriptor field, Object value) {
        wrappedBuilder.setField(field, value);
        return this;
      }
      @Override
      public Builder clearField(Descriptors.FieldDescriptor field) {
        wrappedBuilder.clearField(field);
        return this;
      }
      @Override
      public int getRepeatedFieldCount(Descriptors.FieldDescriptor field) {
        return wrappedBuilder.getRepeatedFieldCount(field);
      }
      @Override
      public Object getRepeatedField(Descriptors.FieldDescriptor field, int index) {
        return wrappedBuilder.getRepeatedField(field, index);
      }
      @Override
      public Builder setRepeatedField(Descriptors.FieldDescriptor field, int index, Object value) {
        wrappedBuilder.setRepeatedField(field, index, value);
        return this;
      }
      @Override
      public Builder addRepeatedField(Descriptors.FieldDescriptor field, Object value) {
        wrappedBuilder.addRepeatedField(field, value);
        return this;
      }
      @Override
      public UnknownFieldSet getUnknownFields() {
        return wrappedBuilder.getUnknownFields();
      }
      @Override
      public Builder setUnknownFields(UnknownFieldSet unknownFields) {
        wrappedBuilder.setUnknownFields(unknownFields);
        return this;
      }
      @Override
      public Message.Builder getFieldBuilder(FieldDescriptor field) {
        return wrappedBuilder.getFieldBuilder(field);
      }
    }
    @Override
    public Parser<? extends Message> getParserForType() {
      return wrappedMessage.getParserForType();
    }
  }

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

  TestUtil.ReflectionTester reflectionTester =
    new TestUtil.ReflectionTester(TestAllTypes.getDescriptor(), null);

  TestUtil.ReflectionTester extensionsReflectionTester =
    new TestUtil.ReflectionTester(TestAllExtensions.getDescriptor(),
                                  TestUtil.getExtensionRegistry());

  public void testClear() throws Exception {
    AbstractMessageWrapper message =
      new AbstractMessageWrapper.Builder(
          TestAllTypes.newBuilder(TestUtil.getAllSet()))
        .clear().build();
    TestUtil.assertClear((TestAllTypes) message.wrappedMessage);
  }

  public void testCopy() throws Exception {
    AbstractMessageWrapper message =
      new AbstractMessageWrapper.Builder(TestAllTypes.newBuilder())
        .mergeFrom(TestUtil.getAllSet()).build();
    TestUtil.assertAllFieldsSet((TestAllTypes) message.wrappedMessage);
  }

  public void testSerializedSize() throws Exception {
    TestAllTypes message = TestUtil.getAllSet();
    Message abstractMessage = new AbstractMessageWrapper(TestUtil.getAllSet());

    assertEquals(message.getSerializedSize(),
                 abstractMessage.getSerializedSize());
  }

  public void testSerialization() throws Exception {
    Message abstractMessage = new AbstractMessageWrapper(TestUtil.getAllSet());

    TestUtil.assertAllFieldsSet(
      TestAllTypes.parseFrom(abstractMessage.toByteString()));

    assertEquals(TestUtil.getAllSet().toByteString(),
                 abstractMessage.toByteString());
  }

  public void testParsing() throws Exception {
    AbstractMessageWrapper.Builder builder =
      new AbstractMessageWrapper.Builder(TestAllTypes.newBuilder());
    AbstractMessageWrapper message =
      builder.mergeFrom(TestUtil.getAllSet().toByteString()).build();
    TestUtil.assertAllFieldsSet((TestAllTypes) message.wrappedMessage);
  }

  public void testParsingUninitialized() throws Exception {
    TestRequiredForeign.Builder builder = TestRequiredForeign.newBuilder();
    builder.getOptionalMessageBuilder().setDummy2(10);
    ByteString bytes = builder.buildPartial().toByteString();
    Message.Builder abstractMessageBuilder =
        new AbstractMessageWrapper.Builder(TestRequiredForeign.newBuilder());
    // mergeFrom() should not throw initialization error.
    abstractMessageBuilder.mergeFrom(bytes).buildPartial();
    try {
      abstractMessageBuilder.mergeFrom(bytes).build();
      fail();
    } catch (UninitializedMessageException ex) {
      // pass
    }

    // test DynamicMessage directly.
    Message.Builder dynamicMessageBuilder = DynamicMessage.newBuilder(
        TestRequiredForeign.getDescriptor());
    // mergeFrom() should not throw initialization error.
    dynamicMessageBuilder.mergeFrom(bytes).buildPartial();
    try {
      dynamicMessageBuilder.mergeFrom(bytes).build();
      fail();
    } catch (UninitializedMessageException ex) {
      // pass
    }
  }

  public void testPackedSerialization() throws Exception {
    Message abstractMessage =
        new AbstractMessageWrapper(TestUtil.getPackedSet());

    TestUtil.assertPackedFieldsSet(
      TestPackedTypes.parseFrom(abstractMessage.toByteString()));

    assertEquals(TestUtil.getPackedSet().toByteString(),
                 abstractMessage.toByteString());
  }

  public void testPackedParsing() throws Exception {
    AbstractMessageWrapper.Builder builder =
      new AbstractMessageWrapper.Builder(TestPackedTypes.newBuilder());
    AbstractMessageWrapper message =
      builder.mergeFrom(TestUtil.getPackedSet().toByteString()).build();
    TestUtil.assertPackedFieldsSet((TestPackedTypes) message.wrappedMessage);
  }

  public void testUnpackedSerialization() throws Exception {
    Message abstractMessage =
      new AbstractMessageWrapper(TestUtil.getUnpackedSet());

    TestUtil.assertUnpackedFieldsSet(
      TestUnpackedTypes.parseFrom(abstractMessage.toByteString()));

    assertEquals(TestUtil.getUnpackedSet().toByteString(),
                 abstractMessage.toByteString());
  }

  public void testParsePackedToUnpacked() throws Exception {
    AbstractMessageWrapper.Builder builder =
      new AbstractMessageWrapper.Builder(TestUnpackedTypes.newBuilder());
    AbstractMessageWrapper message =
      builder.mergeFrom(TestUtil.getPackedSet().toByteString()).build();
    TestUtil.assertUnpackedFieldsSet(
      (TestUnpackedTypes) message.wrappedMessage);
  }

  public void testParseUnpackedToPacked() throws Exception {
    AbstractMessageWrapper.Builder builder =
      new AbstractMessageWrapper.Builder(TestPackedTypes.newBuilder());
    AbstractMessageWrapper message =
      builder.mergeFrom(TestUtil.getUnpackedSet().toByteString()).build();
    TestUtil.assertPackedFieldsSet((TestPackedTypes) message.wrappedMessage);
  }

  public void testUnpackedParsing() throws Exception {
    AbstractMessageWrapper.Builder builder =
      new AbstractMessageWrapper.Builder(TestUnpackedTypes.newBuilder());
    AbstractMessageWrapper message =
      builder.mergeFrom(TestUtil.getUnpackedSet().toByteString()).build();
    TestUtil.assertUnpackedFieldsSet(
      (TestUnpackedTypes) message.wrappedMessage);
  }

  public void testOptimizedForSize() throws Exception {
    // We're mostly only checking that this class was compiled successfully.
    TestOptimizedForSize message =
      TestOptimizedForSize.newBuilder().setI(1).build();
    message = TestOptimizedForSize.parseFrom(message.toByteString());
    assertEquals(2, message.getSerializedSize());
  }

  // -----------------------------------------------------------------
  // Tests for isInitialized().

  public void testIsInitialized() throws Exception {
    TestRequired.Builder builder = TestRequired.newBuilder();
    AbstractMessageWrapper.Builder abstractBuilder =
      new AbstractMessageWrapper.Builder(builder);

    assertFalse(abstractBuilder.isInitialized());
    assertEquals("a, b, c", abstractBuilder.getInitializationErrorString());
    builder.setA(1);
    assertFalse(abstractBuilder.isInitialized());
    assertEquals("b, c", abstractBuilder.getInitializationErrorString());
    builder.setB(1);
    assertFalse(abstractBuilder.isInitialized());
    assertEquals("c", abstractBuilder.getInitializationErrorString());
    builder.setC(1);
    assertTrue(abstractBuilder.isInitialized());
    assertEquals("", abstractBuilder.getInitializationErrorString());
  }

  public void testForeignIsInitialized() throws Exception {
    TestRequiredForeign.Builder builder = TestRequiredForeign.newBuilder();
    AbstractMessageWrapper.Builder abstractBuilder =
      new AbstractMessageWrapper.Builder(builder);

    assertTrue(abstractBuilder.isInitialized());
    assertEquals("", abstractBuilder.getInitializationErrorString());

    builder.setOptionalMessage(TEST_REQUIRED_UNINITIALIZED);
    assertFalse(abstractBuilder.isInitialized());
    assertEquals(
        "optional_message.b, optional_message.c",
        abstractBuilder.getInitializationErrorString());

    builder.setOptionalMessage(TEST_REQUIRED_INITIALIZED);
    assertTrue(abstractBuilder.isInitialized());
    assertEquals("", abstractBuilder.getInitializationErrorString());

    builder.addRepeatedMessage(TEST_REQUIRED_UNINITIALIZED);
    assertFalse(abstractBuilder.isInitialized());
    assertEquals(
        "repeated_message[0].b, repeated_message[0].c",
        abstractBuilder.getInitializationErrorString());

    builder.setRepeatedMessage(0, TEST_REQUIRED_INITIALIZED);
    assertTrue(abstractBuilder.isInitialized());
    assertEquals("", abstractBuilder.getInitializationErrorString());
  }

  // -----------------------------------------------------------------
  // Tests for mergeFrom

  static final TestAllTypes MERGE_SOURCE =
    TestAllTypes.newBuilder()
      .setOptionalInt32(1)
      .setOptionalString("foo")
      .setOptionalForeignMessage(ForeignMessage.getDefaultInstance())
      .addRepeatedString("bar")
      .build();

  static final TestAllTypes MERGE_DEST =
    TestAllTypes.newBuilder()
      .setOptionalInt64(2)
      .setOptionalString("baz")
      .setOptionalForeignMessage(ForeignMessage.newBuilder().setC(3).build())
      .addRepeatedString("qux")
      .build();

  static final String MERGE_RESULT_TEXT =
      "optional_int32: 1\n" +
      "optional_int64: 2\n" +
      "optional_string: \"foo\"\n" +
      "optional_foreign_message {\n" +
      "  c: 3\n" +
      "}\n" +
      "repeated_string: \"qux\"\n" +
      "repeated_string: \"bar\"\n";

  public void testMergeFrom() throws Exception {
    AbstractMessageWrapper result =
      new AbstractMessageWrapper.Builder(
        TestAllTypes.newBuilder(MERGE_DEST))
      .mergeFrom(MERGE_SOURCE).build();

    assertEquals(MERGE_RESULT_TEXT, result.toString());
  }

  // -----------------------------------------------------------------
  // Tests for equals and hashCode

  public void testEqualsAndHashCode() throws Exception {
    TestAllTypes a = TestUtil.getAllSet();
    TestAllTypes b = TestAllTypes.newBuilder().build();
    TestAllTypes c = TestAllTypes.newBuilder(b).addRepeatedString("x").build();
    TestAllTypes d = TestAllTypes.newBuilder(c).addRepeatedString("y").build();
    TestAllExtensions e = TestUtil.getAllExtensionsSet();
    TestAllExtensions f = TestAllExtensions.newBuilder(e)
        .addExtension(UnittestProto.repeatedInt32Extension, 999).build();

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

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

    checkNotEqual(b, c);
    checkNotEqual(b, d);
    checkNotEqual(b, e);
    checkNotEqual(b, f);

    checkNotEqual(c, d);
    checkNotEqual(c, e);
    checkNotEqual(c, f);

    checkNotEqual(d, e);
    checkNotEqual(d, f);

    checkNotEqual(e, f);

    // Deserializing into the TestEmptyMessage such that every field
    // is an {@link UnknownFieldSet.Field}.
    UnittestProto.TestEmptyMessage eUnknownFields =
        UnittestProto.TestEmptyMessage.parseFrom(e.toByteArray());
    UnittestProto.TestEmptyMessage fUnknownFields =
        UnittestProto.TestEmptyMessage.parseFrom(f.toByteArray());
    checkNotEqual(eUnknownFields, fUnknownFields);
    checkEqualsIsConsistent(eUnknownFields);
    checkEqualsIsConsistent(fUnknownFields);

    // Subsequent reconstitutions should be identical
    UnittestProto.TestEmptyMessage eUnknownFields2 =
        UnittestProto.TestEmptyMessage.parseFrom(e.toByteArray());
    checkEqualsIsConsistent(eUnknownFields, eUnknownFields2);
  }

  /**
   * Asserts that the given proto has symmetric equals and hashCode methods.
   */
  private void checkEqualsIsConsistent(Message message) {
    // Object should be equal to itself.
    assertEquals(message, message);

    // Object should be equal to a dynamic copy of itself.
    DynamicMessage dynamic = DynamicMessage.newBuilder(message).build();
    checkEqualsIsConsistent(message, dynamic);
  }

  /**
   * Asserts that the given protos are equal and have the same hash code.
   */
  private void checkEqualsIsConsistent(Message message1, Message message2) {
    assertEquals(message1, message2);
    assertEquals(message2, message1);
    assertEquals(message2.hashCode(), message1.hashCode());
  }

  /**
   * Asserts that the given protos 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(Message m1, Message m2) {
    String equalsError = String.format("%s should not be equal to %s", m1, m2);
    assertFalse(equalsError, m1.equals(m2));
    assertFalse(equalsError, m2.equals(m1));

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

  public void testCheckByteStringIsUtf8OnUtf8() {
    ByteString byteString = ByteString.copyFromUtf8("some text");
    AbstractMessageLite.checkByteStringIsUtf8(byteString);
    // No exception thrown.
  }

  public void testCheckByteStringIsUtf8OnNonUtf8() {
    ByteString byteString =
        ByteString.copyFrom(new byte[]{(byte) 0x80}); // A lone continuation byte.
    try {
      AbstractMessageLite.checkByteStringIsUtf8(byteString);
      fail("Expected AbstractMessageLite.checkByteStringIsUtf8 to throw IllegalArgumentException");
    } catch (IllegalArgumentException exception) {
      assertEquals("Byte string is not UTF-8.", exception.getMessage());
    }
  }

}
