// 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.FieldDescriptor;
import com.google.protobuf.test.UnittestImport;
import protobuf_unittest.EnumWithNoOuter;
import protobuf_unittest.MessageWithNoOuter;
import protobuf_unittest.MultipleFilesTestProto;
import protobuf_unittest.NestedExtension.MyNestedExtension;
import protobuf_unittest.NonNestedExtension;
import protobuf_unittest.NonNestedExtension.MessageToBeExtended;
import protobuf_unittest.NonNestedExtension.MyNonNestedExtension;
import protobuf_unittest.OuterClassNameTest2OuterClass;
import protobuf_unittest.OuterClassNameTest3OuterClass;
import protobuf_unittest.OuterClassNameTestOuterClass;
import protobuf_unittest.ServiceWithNoOuter;
import protobuf_unittest.UnittestOptimizeFor.TestOptimizedForSize;
import protobuf_unittest.UnittestOptimizeFor.TestOptionalOptimizedForSize;
import protobuf_unittest.UnittestOptimizeFor.TestRequiredOptimizedForSize;
import protobuf_unittest.UnittestProto;
import protobuf_unittest.UnittestProto.ForeignEnum;
import protobuf_unittest.UnittestProto.ForeignMessage;
import protobuf_unittest.UnittestProto.ForeignMessageOrBuilder;
import protobuf_unittest.UnittestProto.NestedTestAllTypes;
import protobuf_unittest.UnittestProto.TestAllExtensions;
import protobuf_unittest.UnittestProto.TestAllTypes;
import protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage;
import protobuf_unittest.UnittestProto.TestAllTypesOrBuilder;
import protobuf_unittest.UnittestProto.TestExtremeDefaultValues;
import protobuf_unittest.UnittestProto.TestOneof2;
import protobuf_unittest.UnittestProto.TestPackedTypes;
import protobuf_unittest.UnittestProto.TestUnpackedTypes;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import junit.framework.TestCase;

/**
 * Unit test for generated messages and generated code.  See also
 * {@link MessageTest}, which tests some generated message functionality.
 *
 * @author kenton@google.com Kenton Varda
 */
public class GeneratedMessageTest extends TestCase {
  TestUtil.ReflectionTester reflectionTester =
    new TestUtil.ReflectionTester(TestAllTypes.getDescriptor(), null);

  public void testDefaultInstance() throws Exception {
    assertSame(TestAllTypes.getDefaultInstance(),
               TestAllTypes.getDefaultInstance().getDefaultInstanceForType());
    assertSame(TestAllTypes.getDefaultInstance(),
               TestAllTypes.newBuilder().getDefaultInstanceForType());
  }

  public void testMessageOrBuilder() throws Exception {
    TestAllTypes.Builder builder = TestAllTypes.newBuilder();
    TestUtil.setAllFields(builder);
    TestAllTypes message = builder.build();
    TestUtil.assertAllFieldsSet(message);
  }

  public void testUsingBuilderMultipleTimes() throws Exception {
    TestAllTypes.Builder builder = TestAllTypes.newBuilder();
    // primitive field scalar and repeated
    builder.setOptionalSfixed64(100);
    builder.addRepeatedInt32(100);
    // enum field scalar and repeated
    builder.setOptionalImportEnum(UnittestImport.ImportEnum.IMPORT_BAR);
    builder.addRepeatedImportEnum(UnittestImport.ImportEnum.IMPORT_BAR);
    // proto field scalar and repeated
    builder.setOptionalForeignMessage(ForeignMessage.newBuilder().setC(1));
    builder.addRepeatedForeignMessage(ForeignMessage.newBuilder().setC(1));

    TestAllTypes value1 = builder.build();

    assertEquals(100, value1.getOptionalSfixed64());
    assertEquals(100, value1.getRepeatedInt32(0));
    assertEquals(UnittestImport.ImportEnum.IMPORT_BAR,
        value1.getOptionalImportEnum());
    assertEquals(UnittestImport.ImportEnum.IMPORT_BAR,
        value1.getRepeatedImportEnum(0));
    assertEquals(1, value1.getOptionalForeignMessage().getC());
    assertEquals(1, value1.getRepeatedForeignMessage(0).getC());

    // Make sure that builder didn't update previously created values
    builder.setOptionalSfixed64(200);
    builder.setRepeatedInt32(0, 200);
    builder.setOptionalImportEnum(UnittestImport.ImportEnum.IMPORT_FOO);
    builder.setRepeatedImportEnum(0, UnittestImport.ImportEnum.IMPORT_FOO);
    builder.setOptionalForeignMessage(ForeignMessage.newBuilder().setC(2));
    builder.setRepeatedForeignMessage(0, ForeignMessage.newBuilder().setC(2));

    TestAllTypes value2 = builder.build();

    // Make sure value1 didn't change.
    assertEquals(100, value1.getOptionalSfixed64());
    assertEquals(100, value1.getRepeatedInt32(0));
    assertEquals(UnittestImport.ImportEnum.IMPORT_BAR,
        value1.getOptionalImportEnum());
    assertEquals(UnittestImport.ImportEnum.IMPORT_BAR,
        value1.getRepeatedImportEnum(0));
    assertEquals(1, value1.getOptionalForeignMessage().getC());
    assertEquals(1, value1.getRepeatedForeignMessage(0).getC());

    // Make sure value2 is correct
    assertEquals(200, value2.getOptionalSfixed64());
    assertEquals(200, value2.getRepeatedInt32(0));
    assertEquals(UnittestImport.ImportEnum.IMPORT_FOO,
        value2.getOptionalImportEnum());
    assertEquals(UnittestImport.ImportEnum.IMPORT_FOO,
        value2.getRepeatedImportEnum(0));
    assertEquals(2, value2.getOptionalForeignMessage().getC());
    assertEquals(2, value2.getRepeatedForeignMessage(0).getC());
  }

  public void testProtosShareRepeatedArraysIfDidntChange() throws Exception {
    TestAllTypes.Builder builder = TestAllTypes.newBuilder();
    builder.addRepeatedInt32(100);
    builder.addRepeatedForeignMessage(ForeignMessage.getDefaultInstance());

    TestAllTypes value1 = builder.build();
    TestAllTypes value2 = value1.toBuilder().build();

    assertSame(value1.getRepeatedInt32List(), value2.getRepeatedInt32List());
    assertSame(value1.getRepeatedForeignMessageList(),
        value2.getRepeatedForeignMessageList());
  }

  public void testRepeatedArraysAreImmutable() throws Exception {
    TestAllTypes.Builder builder = TestAllTypes.newBuilder();
    builder.addRepeatedInt32(100);
    builder.addRepeatedImportEnum(UnittestImport.ImportEnum.IMPORT_BAR);
    builder.addRepeatedForeignMessage(ForeignMessage.getDefaultInstance());
    assertIsUnmodifiable(builder.getRepeatedInt32List());
    assertIsUnmodifiable(builder.getRepeatedImportEnumList());
    assertIsUnmodifiable(builder.getRepeatedForeignMessageList());
    assertIsUnmodifiable(builder.getRepeatedFloatList());


    TestAllTypes value = builder.build();
    assertIsUnmodifiable(value.getRepeatedInt32List());
    assertIsUnmodifiable(value.getRepeatedImportEnumList());
    assertIsUnmodifiable(value.getRepeatedForeignMessageList());
    assertIsUnmodifiable(value.getRepeatedFloatList());
  }

  public void testParsedMessagesAreImmutable() throws Exception {
    TestAllTypes value = TestAllTypes.parser().parseFrom(TestUtil.getAllSet().toByteString());
    assertIsUnmodifiable(value.getRepeatedInt32List());
    assertIsUnmodifiable(value.getRepeatedInt64List());
    assertIsUnmodifiable(value.getRepeatedUint32List());
    assertIsUnmodifiable(value.getRepeatedUint64List());
    assertIsUnmodifiable(value.getRepeatedSint32List());
    assertIsUnmodifiable(value.getRepeatedSint64List());
    assertIsUnmodifiable(value.getRepeatedFixed32List());
    assertIsUnmodifiable(value.getRepeatedFixed64List());
    assertIsUnmodifiable(value.getRepeatedSfixed32List());
    assertIsUnmodifiable(value.getRepeatedSfixed64List());
    assertIsUnmodifiable(value.getRepeatedFloatList());
    assertIsUnmodifiable(value.getRepeatedDoubleList());
    assertIsUnmodifiable(value.getRepeatedBoolList());
    assertIsUnmodifiable(value.getRepeatedStringList());
    assertIsUnmodifiable(value.getRepeatedBytesList());
    assertIsUnmodifiable(value.getRepeatedGroupList());
    assertIsUnmodifiable(value.getRepeatedNestedMessageList());
    assertIsUnmodifiable(value.getRepeatedForeignMessageList());
    assertIsUnmodifiable(value.getRepeatedImportMessageList());
    assertIsUnmodifiable(value.getRepeatedNestedEnumList());
    assertIsUnmodifiable(value.getRepeatedForeignEnumList());
    assertIsUnmodifiable(value.getRepeatedImportEnumList());
  }

  private void assertIsUnmodifiable(List<?> list) {
    if (list == Collections.emptyList()) {
      // OKAY -- Need to check this b/c EmptyList allows you to call clear.
    } else {
      try {
        list.clear();
        fail("List wasn't immutable");
      } catch (UnsupportedOperationException e) {
        // good
      }
    }
  }

  public void testSettersRejectNull() throws Exception {
    TestAllTypes.Builder builder = TestAllTypes.newBuilder();
    try {
      builder.setOptionalString(null);
      fail("Exception was not thrown");
    } catch (NullPointerException e) {
      // We expect this exception.
    }
    try {
      builder.setOptionalBytes(null);
      fail("Exception was not thrown");
    } catch (NullPointerException e) {
      // We expect this exception.
    }
    try {
      builder.setOptionalNestedMessage((TestAllTypes.NestedMessage) null);
      fail("Exception was not thrown");
    } catch (NullPointerException e) {
      // We expect this exception.
    }
    try {
      builder.setOptionalNestedMessage(
          (TestAllTypes.NestedMessage.Builder) null);
      fail("Exception was not thrown");
    } catch (NullPointerException e) {
      // We expect this exception.
    }
    try {
      builder.setOptionalNestedEnum(null);
      fail("Exception was not thrown");
    } catch (NullPointerException e) {
      // We expect this exception.
    }
    try {
      builder.addRepeatedString(null);
      fail("Exception was not thrown");
    } catch (NullPointerException e) {
      // We expect this exception.
    }
    try {
      builder.addRepeatedBytes(null);
      fail("Exception was not thrown");
    } catch (NullPointerException e) {
      // We expect this exception.
    }
    try {
      builder.addRepeatedNestedMessage((TestAllTypes.NestedMessage) null);
      fail("Exception was not thrown");
    } catch (NullPointerException e) {
      // We expect this exception.
    }
    try {
      builder.addRepeatedNestedMessage(
          (TestAllTypes.NestedMessage.Builder) null);
      fail("Exception was not thrown");
    } catch (NullPointerException e) {
      // We expect this exception.
    }
    try {
      builder.addRepeatedNestedEnum(null);
      fail("Exception was not thrown");
    } catch (NullPointerException e) {
      // We expect this exception.
    }
  }

  public void testRepeatedSetters() throws Exception {
    TestAllTypes.Builder builder = TestAllTypes.newBuilder();
    TestUtil.setAllFields(builder);
    TestUtil.modifyRepeatedFields(builder);
    TestAllTypes message = builder.build();
    TestUtil.assertRepeatedFieldsModified(message);
  }

  public void testRepeatedSettersRejectNull() throws Exception {
    TestAllTypes.Builder builder = TestAllTypes.newBuilder();

    builder.addRepeatedString("one");
    builder.addRepeatedString("two");
    try {
      builder.setRepeatedString(1, null);
      fail("Exception was not thrown");
    } catch (NullPointerException e) {
      // We expect this exception.
    }

    builder.addRepeatedBytes(TestUtil.toBytes("one"));
    builder.addRepeatedBytes(TestUtil.toBytes("two"));
    try {
      builder.setRepeatedBytes(1, null);
      fail("Exception was not thrown");
    } catch (NullPointerException e) {
      // We expect this exception.
    }

    builder.addRepeatedNestedMessage(
      TestAllTypes.NestedMessage.newBuilder().setBb(218).build());
    builder.addRepeatedNestedMessage(
      TestAllTypes.NestedMessage.newBuilder().setBb(456).build());
    try {
      builder.setRepeatedNestedMessage(1, (TestAllTypes.NestedMessage) null);
      fail("Exception was not thrown");
    } catch (NullPointerException e) {
      // We expect this exception.
    }
    try {
      builder.setRepeatedNestedMessage(
          1, (TestAllTypes.NestedMessage.Builder) null);
      fail("Exception was not thrown");
    } catch (NullPointerException e) {
      // We expect this exception.
    }

    builder.addRepeatedNestedEnum(TestAllTypes.NestedEnum.FOO);
    builder.addRepeatedNestedEnum(TestAllTypes.NestedEnum.BAR);
    try {
      builder.setRepeatedNestedEnum(1, null);
      fail("Exception was not thrown");
    } catch (NullPointerException e) {
      // We expect this exception.
    }
  }

  public void testRepeatedAppend() throws Exception {
    TestAllTypes.Builder builder = TestAllTypes.newBuilder();

    builder.addAllRepeatedInt32(Arrays.asList(1, 2, 3, 4));
    builder.addAllRepeatedForeignEnum(Arrays.asList(ForeignEnum.FOREIGN_BAZ));

    ForeignMessage foreignMessage =
        ForeignMessage.newBuilder().setC(12).build();
    builder.addAllRepeatedForeignMessage(Arrays.asList(foreignMessage));

    TestAllTypes message = builder.build();
    assertEquals(message.getRepeatedInt32List(), Arrays.asList(1, 2, 3, 4));
    assertEquals(message.getRepeatedForeignEnumList(),
        Arrays.asList(ForeignEnum.FOREIGN_BAZ));
    assertEquals(1, message.getRepeatedForeignMessageCount());
    assertEquals(12, message.getRepeatedForeignMessage(0).getC());
  }

  public void testRepeatedAppendRejectsNull() throws Exception {
    TestAllTypes.Builder builder = TestAllTypes.newBuilder();

    ForeignMessage foreignMessage =
        ForeignMessage.newBuilder().setC(12).build();
    try {
      builder.addAllRepeatedForeignMessage(
          Arrays.asList(foreignMessage, (ForeignMessage) null));
      fail("Exception was not thrown");
    } catch (NullPointerException e) {
      // We expect this exception.
    }

    try {
      builder.addAllRepeatedForeignEnum(
          Arrays.asList(ForeignEnum.FOREIGN_BAZ, null));
      fail("Exception was not thrown");
    } catch (NullPointerException e) {
      // We expect this exception.
    }

    try {
      builder.addAllRepeatedString(Arrays.asList("one", null));
      fail("Exception was not thrown");
    } catch (NullPointerException e) {
      // We expect this exception.
    }

    try {
      builder.addAllRepeatedBytes(Arrays.asList(TestUtil.toBytes("one"), null));
      fail("Exception was not thrown");
    } catch (NullPointerException e) {
      // We expect this exception.
    }
  }
  
  public void testRepeatedAppendIterateOnlyOnce() throws Exception {
    // Create a Iterable that can only be iterated once.
    Iterable<String> stringIterable = new Iterable<String>() {
      private boolean called = false;
      @Override
      public Iterator<String> iterator() {
        if (called) {
          throw new IllegalStateException();
        }
        called = true;
        return Arrays.asList("one", "two", "three").iterator();
      }
    };
    TestAllTypes.Builder builder = TestAllTypes.newBuilder();
    builder.addAllRepeatedString(stringIterable);
    assertEquals(3, builder.getRepeatedStringCount());
    assertEquals("one", builder.getRepeatedString(0));
    assertEquals("two", builder.getRepeatedString(1));
    assertEquals("three", builder.getRepeatedString(2));

    try {
      builder.addAllRepeatedString(stringIterable);
      fail("Exception was not thrown");
    } catch (IllegalStateException e) {
      // We expect this exception.
    }
  }

  public void testMergeFromOtherRejectsNull() throws Exception {
    try {
      TestAllTypes.Builder builder = TestAllTypes.newBuilder();
      builder.mergeFrom((TestAllTypes) null);
      fail("Exception was not thrown");
    } catch (NullPointerException e) {
      // We expect this exception.
    }
  }

  public void testSettingForeignMessageUsingBuilder() throws Exception {
    TestAllTypes message = TestAllTypes.newBuilder()
        // Pass builder for foreign message instance.
        .setOptionalForeignMessage(ForeignMessage.newBuilder().setC(123))
        .build();
    TestAllTypes expectedMessage = TestAllTypes.newBuilder()
        // Create expected version passing foreign message instance explicitly.
        .setOptionalForeignMessage(
            ForeignMessage.newBuilder().setC(123).build())
        .build();
    // TODO(ngd): Upgrade to using real #equals method once implemented
    assertEquals(expectedMessage.toString(), message.toString());
  }

  public void testSettingRepeatedForeignMessageUsingBuilder() throws Exception {
    TestAllTypes message = TestAllTypes.newBuilder()
        // Pass builder for foreign message instance.
        .addRepeatedForeignMessage(ForeignMessage.newBuilder().setC(456))
        .build();
    TestAllTypes expectedMessage = TestAllTypes.newBuilder()
        // Create expected version passing foreign message instance explicitly.
        .addRepeatedForeignMessage(
            ForeignMessage.newBuilder().setC(456).build())
        .build();
    assertEquals(expectedMessage.toString(), message.toString());
  }

  public void testDefaults() throws Exception {
    TestUtil.assertClear(TestAllTypes.getDefaultInstance());
    TestUtil.assertClear(TestAllTypes.newBuilder().build());

    TestExtremeDefaultValues message =
        TestExtremeDefaultValues.getDefaultInstance();
    assertEquals("\u1234", message.getUtf8String());
    assertEquals(Double.POSITIVE_INFINITY, message.getInfDouble());
    assertEquals(Double.NEGATIVE_INFINITY, message.getNegInfDouble());
    assertTrue(Double.isNaN(message.getNanDouble()));
    assertEquals(Float.POSITIVE_INFINITY, message.getInfFloat());
    assertEquals(Float.NEGATIVE_INFINITY, message.getNegInfFloat());
    assertTrue(Float.isNaN(message.getNanFloat()));
    assertEquals("? ? ?? ?? ??? ??/ ??-", message.getCppTrigraph());
  }

  public void testClear() throws Exception {
    TestAllTypes.Builder builder = TestAllTypes.newBuilder();
    TestUtil.assertClear(builder);
    TestUtil.setAllFields(builder);
    builder.clear();
    TestUtil.assertClear(builder);
  }

  public void testReflectionGetters() throws Exception {
    TestAllTypes.Builder builder = TestAllTypes.newBuilder();
    TestUtil.setAllFields(builder);
    reflectionTester.assertAllFieldsSetViaReflection(builder);

    TestAllTypes message = builder.build();
    reflectionTester.assertAllFieldsSetViaReflection(message);
  }

  public void testReflectionSetters() throws Exception {
    TestAllTypes.Builder builder = TestAllTypes.newBuilder();
    reflectionTester.setAllFieldsViaReflection(builder);
    TestUtil.assertAllFieldsSet(builder);

    TestAllTypes message = builder.build();
    TestUtil.assertAllFieldsSet(message);
  }

  public void testReflectionSettersRejectNull() throws Exception {
    TestAllTypes.Builder builder = TestAllTypes.newBuilder();
    reflectionTester.assertReflectionSettersRejectNull(builder);
  }

  public void testReflectionRepeatedSetters() throws Exception {
    TestAllTypes.Builder builder = TestAllTypes.newBuilder();
    reflectionTester.setAllFieldsViaReflection(builder);
    reflectionTester.modifyRepeatedFieldsViaReflection(builder);
    TestUtil.assertRepeatedFieldsModified(builder);

    TestAllTypes message = builder.build();
    TestUtil.assertRepeatedFieldsModified(message);
  }

  public void testReflectionRepeatedSettersRejectNull() throws Exception {
    TestAllTypes.Builder builder = TestAllTypes.newBuilder();
    reflectionTester.assertReflectionRepeatedSettersRejectNull(builder);
  }

  public void testReflectionDefaults() throws Exception {
    reflectionTester.assertClearViaReflection(
      TestAllTypes.getDefaultInstance());
    reflectionTester.assertClearViaReflection(
      TestAllTypes.newBuilder().build());
  }

  public void testReflectionGetOneof() throws Exception {
    TestAllTypes.Builder builder = TestAllTypes.newBuilder();
    reflectionTester.setAllFieldsViaReflection(builder);
    Descriptors.OneofDescriptor oneof =
        TestAllTypes.getDescriptor().getOneofs().get(0);
    Descriptors.FieldDescriptor field =
        TestAllTypes.getDescriptor().findFieldByName("oneof_bytes");
    assertSame(field, builder.getOneofFieldDescriptor(oneof));

    TestAllTypes message = builder.build();
    assertSame(field, message.getOneofFieldDescriptor(oneof));
  }

  public void testReflectionClearOneof() throws Exception {
    TestAllTypes.Builder builder = TestAllTypes.newBuilder();
    reflectionTester.setAllFieldsViaReflection(builder);
    Descriptors.OneofDescriptor oneof =
        TestAllTypes.getDescriptor().getOneofs().get(0);
    Descriptors.FieldDescriptor field =
        TestAllTypes.getDescriptor().findFieldByName("oneof_bytes");

    assertTrue(builder.hasOneof(oneof));
    assertTrue(builder.hasField(field));
    builder.clearOneof(oneof);
    assertFalse(builder.hasOneof(oneof));
    assertFalse(builder.hasField(field));
  }

  public void testEnumInterface() throws Exception {
    assertTrue(TestAllTypes.getDefaultInstance().getDefaultNestedEnum()
        instanceof ProtocolMessageEnum);
  }

  public void testEnumMap() throws Exception {
    Internal.EnumLiteMap<ForeignEnum> map = ForeignEnum.internalGetValueMap();

    for (ForeignEnum value : ForeignEnum.values()) {
      assertEquals(value, map.findValueByNumber(value.getNumber()));
    }

    assertTrue(map.findValueByNumber(12345) == null);
  }

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

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

  // =================================================================
  // Extensions.

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

  public void testExtensionMessageOrBuilder() throws Exception {
    TestAllExtensions.Builder builder = TestAllExtensions.newBuilder();
    TestUtil.setAllExtensions(builder);
    TestAllExtensions message = builder.build();
    TestUtil.assertAllExtensionsSet(message);
  }

  public void testExtensionRepeatedSetters() throws Exception {
    TestAllExtensions.Builder builder = TestAllExtensions.newBuilder();
    TestUtil.setAllExtensions(builder);
    TestUtil.modifyRepeatedExtensions(builder);
    TestAllExtensions message = builder.build();
    TestUtil.assertRepeatedExtensionsModified(message);
  }

  public void testExtensionDefaults() throws Exception {
    TestUtil.assertExtensionsClear(TestAllExtensions.getDefaultInstance());
    TestUtil.assertExtensionsClear(TestAllExtensions.newBuilder().build());
  }

  public void testUnsetRepeatedExtensionGetField() {
    TestAllExtensions message = TestAllExtensions.getDefaultInstance();
    Object value;

    value = message.getField(UnittestProto.repeatedStringExtension.getDescriptor());
    assertTrue(value instanceof List);
    assertTrue(((List<?>) value).isEmpty());
    assertIsUnmodifiable((List<?>) value);

    value = message.getField(UnittestProto.repeatedNestedMessageExtension.getDescriptor());
    assertTrue(value instanceof List);
    assertTrue(((List<?>) value).isEmpty());
    assertIsUnmodifiable((List<?>) value);
  }

  public void testExtensionReflectionGetters() throws Exception {
    TestAllExtensions.Builder builder = TestAllExtensions.newBuilder();
    TestUtil.setAllExtensions(builder);
    extensionsReflectionTester.assertAllFieldsSetViaReflection(builder);

    TestAllExtensions message = builder.build();
    extensionsReflectionTester.assertAllFieldsSetViaReflection(message);
  }

  public void testExtensionReflectionSetters() throws Exception {
    TestAllExtensions.Builder builder = TestAllExtensions.newBuilder();
    extensionsReflectionTester.setAllFieldsViaReflection(builder);
    TestUtil.assertAllExtensionsSet(builder);

    TestAllExtensions message = builder.build();
    TestUtil.assertAllExtensionsSet(message);
  }

  public void testExtensionReflectionSettersRejectNull() throws Exception {
    TestAllExtensions.Builder builder = TestAllExtensions.newBuilder();
    extensionsReflectionTester.assertReflectionSettersRejectNull(builder);
  }

  public void testExtensionReflectionRepeatedSetters() throws Exception {
    TestAllExtensions.Builder builder = TestAllExtensions.newBuilder();
    extensionsReflectionTester.setAllFieldsViaReflection(builder);
    extensionsReflectionTester.modifyRepeatedFieldsViaReflection(builder);
    TestUtil.assertRepeatedExtensionsModified(builder);

    TestAllExtensions message = builder.build();
    TestUtil.assertRepeatedExtensionsModified(message);
  }

  public void testExtensionReflectionRepeatedSettersRejectNull()
      throws Exception {
    TestAllExtensions.Builder builder = TestAllExtensions.newBuilder();
    extensionsReflectionTester.assertReflectionRepeatedSettersRejectNull(
        builder);
  }

  public void testExtensionReflectionDefaults() throws Exception {
    extensionsReflectionTester.assertClearViaReflection(
      TestAllExtensions.getDefaultInstance());
    extensionsReflectionTester.assertClearViaReflection(
      TestAllExtensions.newBuilder().build());
  }

  public void testClearExtension() throws Exception {
    // clearExtension() is not actually used in TestUtil, so try it manually.
    assertFalse(
      TestAllExtensions.newBuilder()
        .setExtension(UnittestProto.optionalInt32Extension, 1)
        .clearExtension(UnittestProto.optionalInt32Extension)
        .hasExtension(UnittestProto.optionalInt32Extension));
    assertEquals(0,
      TestAllExtensions.newBuilder()
        .addExtension(UnittestProto.repeatedInt32Extension, 1)
        .clearExtension(UnittestProto.repeatedInt32Extension)
        .getExtensionCount(UnittestProto.repeatedInt32Extension));
  }

  public void testExtensionCopy() throws Exception {
    TestAllExtensions original = TestUtil.getAllExtensionsSet();
    TestAllExtensions copy = TestAllExtensions.newBuilder(original).build();
    TestUtil.assertAllExtensionsSet(copy);
  }

  public void testExtensionMergeFrom() throws Exception {
    TestAllExtensions original =
      TestAllExtensions.newBuilder()
        .setExtension(UnittestProto.optionalInt32Extension, 1).build();
    TestAllExtensions merged =
        TestAllExtensions.newBuilder().mergeFrom(original).build();
    assertTrue(merged.hasExtension(UnittestProto.optionalInt32Extension));
    assertEquals(
        1, (int) merged.getExtension(UnittestProto.optionalInt32Extension));
  }

  // =================================================================
  // multiple_files_test

  // Test that custom options of an file level enum are properly initialized.
  // This test needs to be put before any other access to MultipleFilesTestProto
  // or messages defined in multiple_files_test.proto because the class loading
  // order affects initialization process of custom options.
  public void testEnumValueOptionsInMultipleFilesMode() throws Exception {
    assertEquals(12345, EnumWithNoOuter.FOO.getValueDescriptor().getOptions()
        .getExtension(MultipleFilesTestProto.enumValueOption).intValue());
  }

  public void testMultipleFilesOption() throws Exception {
    // We mostly just want to check that things compile.
    MessageWithNoOuter message =
      MessageWithNoOuter.newBuilder()
        .setNested(MessageWithNoOuter.NestedMessage.newBuilder().setI(1))
        .addForeign(TestAllTypes.newBuilder().setOptionalInt32(1))
        .setNestedEnum(MessageWithNoOuter.NestedEnum.BAZ)
        .setForeignEnum(EnumWithNoOuter.BAR)
        .build();
    assertEquals(message, MessageWithNoOuter.parseFrom(message.toByteString()));

    assertEquals(MultipleFilesTestProto.getDescriptor(),
                 MessageWithNoOuter.getDescriptor().getFile());

    Descriptors.FieldDescriptor field =
      MessageWithNoOuter.getDescriptor().findFieldByName("foreign_enum");
    assertEquals(EnumWithNoOuter.BAR.getValueDescriptor(),
                 message.getField(field));

    assertEquals(MultipleFilesTestProto.getDescriptor(),
                 ServiceWithNoOuter.getDescriptor().getFile());

    assertFalse(
      TestAllExtensions.getDefaultInstance().hasExtension(
        MultipleFilesTestProto.extensionWithOuter));
  }

  public void testOptionalFieldWithRequiredSubfieldsOptimizedForSize()
    throws Exception {
    TestOptionalOptimizedForSize message =
        TestOptionalOptimizedForSize.getDefaultInstance();
    assertTrue(message.isInitialized());

    message = TestOptionalOptimizedForSize.newBuilder().setO(
        TestRequiredOptimizedForSize.newBuilder().buildPartial()
        ).buildPartial();
    assertFalse(message.isInitialized());

    message = TestOptionalOptimizedForSize.newBuilder().setO(
        TestRequiredOptimizedForSize.newBuilder().setX(5).buildPartial()
        ).buildPartial();
    assertTrue(message.isInitialized());
  }

  public void testUninitializedExtensionInOptimizedForSize()
      throws Exception {
    TestOptimizedForSize.Builder builder = TestOptimizedForSize.newBuilder();
    builder.setExtension(TestOptimizedForSize.testExtension2,
        TestRequiredOptimizedForSize.newBuilder().buildPartial());
    assertFalse(builder.isInitialized());
    assertFalse(builder.buildPartial().isInitialized());

    builder = TestOptimizedForSize.newBuilder();
    builder.setExtension(TestOptimizedForSize.testExtension2,
        TestRequiredOptimizedForSize.newBuilder().setX(10).buildPartial());
    assertTrue(builder.isInitialized());
    assertTrue(builder.buildPartial().isInitialized());
  }

  public void testToBuilder() throws Exception {
    TestAllTypes.Builder builder = TestAllTypes.newBuilder();
    TestUtil.setAllFields(builder);
    TestAllTypes message = builder.build();
    TestUtil.assertAllFieldsSet(message);
    TestUtil.assertAllFieldsSet(message.toBuilder().build());
  }

  public void testFieldConstantValues() throws Exception {
    assertEquals(TestAllTypes.NestedMessage.BB_FIELD_NUMBER, 1);
    assertEquals(TestAllTypes.OPTIONAL_INT32_FIELD_NUMBER, 1);
    assertEquals(TestAllTypes.OPTIONALGROUP_FIELD_NUMBER, 16);
    assertEquals(TestAllTypes.OPTIONAL_NESTED_MESSAGE_FIELD_NUMBER, 18);
    assertEquals(TestAllTypes.OPTIONAL_NESTED_ENUM_FIELD_NUMBER, 21);
    assertEquals(TestAllTypes.REPEATED_INT32_FIELD_NUMBER, 31);
    assertEquals(TestAllTypes.REPEATEDGROUP_FIELD_NUMBER, 46);
    assertEquals(TestAllTypes.REPEATED_NESTED_MESSAGE_FIELD_NUMBER, 48);
    assertEquals(TestAllTypes.REPEATED_NESTED_ENUM_FIELD_NUMBER, 51);
  }

  public void testExtensionConstantValues() throws Exception {
    assertEquals(UnittestProto.TestRequired.SINGLE_FIELD_NUMBER, 1000);
    assertEquals(UnittestProto.TestRequired.MULTI_FIELD_NUMBER, 1001);
    assertEquals(UnittestProto.OPTIONAL_INT32_EXTENSION_FIELD_NUMBER, 1);
    assertEquals(UnittestProto.OPTIONALGROUP_EXTENSION_FIELD_NUMBER, 16);
    assertEquals(
      UnittestProto.OPTIONAL_NESTED_MESSAGE_EXTENSION_FIELD_NUMBER, 18);
    assertEquals(UnittestProto.OPTIONAL_NESTED_ENUM_EXTENSION_FIELD_NUMBER, 21);
    assertEquals(UnittestProto.REPEATED_INT32_EXTENSION_FIELD_NUMBER, 31);
    assertEquals(UnittestProto.REPEATEDGROUP_EXTENSION_FIELD_NUMBER, 46);
    assertEquals(
      UnittestProto.REPEATED_NESTED_MESSAGE_EXTENSION_FIELD_NUMBER, 48);
    assertEquals(UnittestProto.REPEATED_NESTED_ENUM_EXTENSION_FIELD_NUMBER, 51);
  }

  public void testRecursiveMessageDefaultInstance() throws Exception {
    UnittestProto.TestRecursiveMessage message =
        UnittestProto.TestRecursiveMessage.getDefaultInstance();
    assertTrue(message != null);
    assertNotNull(message.getA());
    assertTrue(message.getA() == message);
  }

  public void testSerialize() throws Exception {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    TestAllTypes.Builder builder = TestAllTypes.newBuilder();
    TestUtil.setAllFields(builder);
    TestAllTypes expected = builder.build();
    ObjectOutputStream out = new ObjectOutputStream(baos);
    try {
      out.writeObject(expected);
    } finally {
      out.close();
    }
    ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
    ObjectInputStream in = new ObjectInputStream(bais);
    TestAllTypes actual = (TestAllTypes) in.readObject();
    assertEquals(expected, actual);
  }

  public void testSerializePartial() throws Exception {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    TestAllTypes.Builder builder = TestAllTypes.newBuilder();
    TestAllTypes expected = builder.buildPartial();
    ObjectOutputStream out = new ObjectOutputStream(baos);
    try {
      out.writeObject(expected);
    } finally {
      out.close();
    }
    ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
    ObjectInputStream in = new ObjectInputStream(bais);
    TestAllTypes actual = (TestAllTypes) in.readObject();
    assertEquals(expected, actual);
  }

  public void testEnumValues() {
    assertEquals(TestAllTypes.NestedEnum.BAR_VALUE, TestAllTypes.NestedEnum.BAR.getNumber());
    assertEquals(TestAllTypes.NestedEnum.BAZ_VALUE, TestAllTypes.NestedEnum.BAZ.getNumber());
    assertEquals(TestAllTypes.NestedEnum.FOO_VALUE, TestAllTypes.NestedEnum.FOO.getNumber());
  }

  public void testNonNestedExtensionInitialization() {
    assertTrue(NonNestedExtension.nonNestedExtension
               .getMessageDefaultInstance() instanceof MyNonNestedExtension);
    assertEquals("nonNestedExtension",
                 NonNestedExtension.nonNestedExtension.getDescriptor().getName());
  }

  public void testNestedExtensionInitialization() {
    assertTrue(MyNestedExtension.recursiveExtension.getMessageDefaultInstance()
               instanceof MessageToBeExtended);
    assertEquals("recursiveExtension",
                 MyNestedExtension.recursiveExtension.getDescriptor().getName());
  }

  public void testInvalidations() throws Exception {
    GeneratedMessage.enableAlwaysUseFieldBuildersForTesting();
    TestAllTypes.NestedMessage nestedMessage1 =
        TestAllTypes.NestedMessage.newBuilder().build();
    TestAllTypes.NestedMessage nestedMessage2 =
        TestAllTypes.NestedMessage.newBuilder().build();

    // Set all three flavors (enum, primitive, message and singular/repeated)
    // and verify no invalidations fired
    TestUtil.MockBuilderParent mockParent = new TestUtil.MockBuilderParent();

    TestAllTypes.Builder builder = (TestAllTypes.Builder)
        ((AbstractMessage) TestAllTypes.getDefaultInstance()).
            newBuilderForType(mockParent);
    builder.setOptionalInt32(1);
    builder.setOptionalNestedEnum(TestAllTypes.NestedEnum.BAR);
    builder.setOptionalNestedMessage(nestedMessage1);
    builder.addRepeatedInt32(1);
    builder.addRepeatedNestedEnum(TestAllTypes.NestedEnum.BAR);
    builder.addRepeatedNestedMessage(nestedMessage1);
    assertEquals(0, mockParent.getInvalidationCount());

    // Now tell it we want changes and make sure it's only fired once
    // And do this for each flavor

    // primitive single
    builder.buildPartial();
    builder.setOptionalInt32(2);
    builder.setOptionalInt32(3);
    assertEquals(1, mockParent.getInvalidationCount());

    // enum single
    builder.buildPartial();
    builder.setOptionalNestedEnum(TestAllTypes.NestedEnum.BAZ);
    builder.setOptionalNestedEnum(TestAllTypes.NestedEnum.BAR);
    assertEquals(2, mockParent.getInvalidationCount());

    // message single
    builder.buildPartial();
    builder.setOptionalNestedMessage(nestedMessage2);
    builder.setOptionalNestedMessage(nestedMessage1);
    assertEquals(3, mockParent.getInvalidationCount());

    // primitive repeated
    builder.buildPartial();
    builder.addRepeatedInt32(2);
    builder.addRepeatedInt32(3);
    assertEquals(4, mockParent.getInvalidationCount());

    // enum repeated
    builder.buildPartial();
    builder.addRepeatedNestedEnum(TestAllTypes.NestedEnum.BAZ);
    builder.addRepeatedNestedEnum(TestAllTypes.NestedEnum.BAZ);
    assertEquals(5, mockParent.getInvalidationCount());

    // message repeated
    builder.buildPartial();
    builder.addRepeatedNestedMessage(nestedMessage2);
    builder.addRepeatedNestedMessage(nestedMessage1);
    assertEquals(6, mockParent.getInvalidationCount());

  }

  public void testInvalidations_Extensions() throws Exception {
    TestUtil.MockBuilderParent mockParent = new TestUtil.MockBuilderParent();

    TestAllExtensions.Builder builder = (TestAllExtensions.Builder)
        ((AbstractMessage) TestAllExtensions.getDefaultInstance()).
            newBuilderForType(mockParent);

    builder.addExtension(UnittestProto.repeatedInt32Extension, 1);
    builder.setExtension(UnittestProto.repeatedInt32Extension, 0, 2);
    builder.clearExtension(UnittestProto.repeatedInt32Extension);
    assertEquals(0, mockParent.getInvalidationCount());

    // Now tell it we want changes and make sure it's only fired once
    builder.buildPartial();
    builder.addExtension(UnittestProto.repeatedInt32Extension, 2);
    builder.addExtension(UnittestProto.repeatedInt32Extension, 3);
    assertEquals(1, mockParent.getInvalidationCount());

    builder.buildPartial();
    builder.setExtension(UnittestProto.repeatedInt32Extension, 0, 4);
    builder.setExtension(UnittestProto.repeatedInt32Extension, 1, 5);
    assertEquals(2, mockParent.getInvalidationCount());

    builder.buildPartial();
    builder.clearExtension(UnittestProto.repeatedInt32Extension);
    builder.clearExtension(UnittestProto.repeatedInt32Extension);
    assertEquals(3, mockParent.getInvalidationCount());
  }

  public void testBaseMessageOrBuilder() {
    // Mostly just makes sure the base interface exists and has some methods.
    TestAllTypes.Builder builder = TestAllTypes.newBuilder();
    TestAllTypes message = builder.buildPartial();
    TestAllTypesOrBuilder builderAsInterface = (TestAllTypesOrBuilder) builder;
    TestAllTypesOrBuilder messageAsInterface = (TestAllTypesOrBuilder) message;

    assertEquals(
        messageAsInterface.getDefaultBool(),
        messageAsInterface.getDefaultBool());
    assertEquals(
        messageAsInterface.getOptionalDouble(),
        messageAsInterface.getOptionalDouble());
  }

  public void testMessageOrBuilderGetters() {
    TestAllTypes.Builder builder = TestAllTypes.newBuilder();

    // single fields
    assertSame(ForeignMessage.getDefaultInstance(),
        builder.getOptionalForeignMessageOrBuilder());
    ForeignMessage.Builder subBuilder =
        builder.getOptionalForeignMessageBuilder();
    assertSame(subBuilder, builder.getOptionalForeignMessageOrBuilder());

    // repeated fields
    ForeignMessage m0 = ForeignMessage.newBuilder().buildPartial();
    ForeignMessage m1 = ForeignMessage.newBuilder().buildPartial();
    ForeignMessage m2 = ForeignMessage.newBuilder().buildPartial();
    builder.addRepeatedForeignMessage(m0);
    builder.addRepeatedForeignMessage(m1);
    builder.addRepeatedForeignMessage(m2);
    assertSame(m0, builder.getRepeatedForeignMessageOrBuilder(0));
    assertSame(m1, builder.getRepeatedForeignMessageOrBuilder(1));
    assertSame(m2, builder.getRepeatedForeignMessageOrBuilder(2));
    ForeignMessage.Builder b0 = builder.getRepeatedForeignMessageBuilder(0);
    ForeignMessage.Builder b1 = builder.getRepeatedForeignMessageBuilder(1);
    assertSame(b0, builder.getRepeatedForeignMessageOrBuilder(0));
    assertSame(b1, builder.getRepeatedForeignMessageOrBuilder(1));
    assertSame(m2, builder.getRepeatedForeignMessageOrBuilder(2));

    List<? extends ForeignMessageOrBuilder> messageOrBuilderList =
        builder.getRepeatedForeignMessageOrBuilderList();
    assertSame(b0, messageOrBuilderList.get(0));
    assertSame(b1, messageOrBuilderList.get(1));
    assertSame(m2, messageOrBuilderList.get(2));
  }

  public void testGetFieldBuilder() {
    Descriptor descriptor = TestAllTypes.getDescriptor();

    FieldDescriptor fieldDescriptor =
        descriptor.findFieldByName("optional_nested_message");
    FieldDescriptor foreignFieldDescriptor =
        descriptor.findFieldByName("optional_foreign_message");
    FieldDescriptor importFieldDescriptor =
        descriptor.findFieldByName("optional_import_message");

    // Mutate the message with new field builder
    // Mutate nested message
    TestAllTypes.Builder builder1 = TestAllTypes.newBuilder();
    Message.Builder fieldBuilder1 = builder1.newBuilderForField(fieldDescriptor)
        .mergeFrom((Message) builder1.getField(fieldDescriptor));
    FieldDescriptor subFieldDescriptor1 =
        fieldBuilder1.getDescriptorForType().findFieldByName("bb");
    fieldBuilder1.setField(subFieldDescriptor1, 1);
    builder1.setField(fieldDescriptor, fieldBuilder1.build());

    // Mutate foreign message
    Message.Builder foreignFieldBuilder1 = builder1.newBuilderForField(
        foreignFieldDescriptor)
        .mergeFrom((Message) builder1.getField(foreignFieldDescriptor));
    FieldDescriptor subForeignFieldDescriptor1 =
        foreignFieldBuilder1.getDescriptorForType().findFieldByName("c");
    foreignFieldBuilder1.setField(subForeignFieldDescriptor1, 2);
    builder1.setField(foreignFieldDescriptor, foreignFieldBuilder1.build());

    // Mutate import message
    Message.Builder importFieldBuilder1 = builder1.newBuilderForField(
        importFieldDescriptor)
        .mergeFrom((Message) builder1.getField(importFieldDescriptor));
    FieldDescriptor subImportFieldDescriptor1 =
        importFieldBuilder1.getDescriptorForType().findFieldByName("d");
    importFieldBuilder1.setField(subImportFieldDescriptor1, 3);
    builder1.setField(importFieldDescriptor, importFieldBuilder1.build());

    Message newMessage1 = builder1.build();

    // Mutate the message with existing field builder
    // Mutate nested message
    TestAllTypes.Builder builder2 = TestAllTypes.newBuilder();
    Message.Builder fieldBuilder2 = builder2.getFieldBuilder(fieldDescriptor);
    FieldDescriptor subFieldDescriptor2 =
        fieldBuilder2.getDescriptorForType().findFieldByName("bb");
    fieldBuilder2.setField(subFieldDescriptor2, 1);
    builder2.setField(fieldDescriptor, fieldBuilder2.build());

    // Mutate foreign message
    Message.Builder foreignFieldBuilder2 = builder2.newBuilderForField(
        foreignFieldDescriptor)
        .mergeFrom((Message) builder2.getField(foreignFieldDescriptor));
    FieldDescriptor subForeignFieldDescriptor2 =
        foreignFieldBuilder2.getDescriptorForType().findFieldByName("c");
    foreignFieldBuilder2.setField(subForeignFieldDescriptor2, 2);
    builder2.setField(foreignFieldDescriptor, foreignFieldBuilder2.build());

    // Mutate import message
    Message.Builder importFieldBuilder2 = builder2.newBuilderForField(
        importFieldDescriptor)
        .mergeFrom((Message) builder2.getField(importFieldDescriptor));
    FieldDescriptor subImportFieldDescriptor2 =
        importFieldBuilder2.getDescriptorForType().findFieldByName("d");
    importFieldBuilder2.setField(subImportFieldDescriptor2, 3);
    builder2.setField(importFieldDescriptor, importFieldBuilder2.build());

    Message newMessage2 = builder2.build();

    // These two messages should be equal.
    assertEquals(newMessage1, newMessage2);
  }

  public void testGetFieldBuilderWithInitializedValue() {
    Descriptor descriptor = TestAllTypes.getDescriptor();
    FieldDescriptor fieldDescriptor =
        descriptor.findFieldByName("optional_nested_message");

    // Before setting field, builder is initialized by default value. 
    TestAllTypes.Builder builder = TestAllTypes.newBuilder();
    NestedMessage.Builder fieldBuilder =
        (NestedMessage.Builder) builder.getFieldBuilder(fieldDescriptor);
    assertEquals(0, fieldBuilder.getBb());

    // Setting field value with new field builder instance.
    builder = TestAllTypes.newBuilder();
    NestedMessage.Builder newFieldBuilder =
        builder.getOptionalNestedMessageBuilder();
    newFieldBuilder.setBb(2);
    // Then get the field builder instance by getFieldBuilder().
    fieldBuilder =
        (NestedMessage.Builder) builder.getFieldBuilder(fieldDescriptor);
    // It should contain new value.
    assertEquals(2, fieldBuilder.getBb());
    // These two builder should be equal.
    assertSame(fieldBuilder, newFieldBuilder);
  }

  public void testGetFieldBuilderNotSupportedException() {
    Descriptor descriptor = TestAllTypes.getDescriptor();
    TestAllTypes.Builder builder = TestAllTypes.newBuilder();
    try {
      builder.getFieldBuilder(descriptor.findFieldByName("optional_int32"));
      fail("Exception was not thrown");
    } catch (UnsupportedOperationException e) {
      // We expect this exception.
    }
    try {
      builder.getFieldBuilder(
          descriptor.findFieldByName("optional_nested_enum"));
      fail("Exception was not thrown");
    } catch (UnsupportedOperationException e) {
      // We expect this exception.
    }
    try {
      builder.getFieldBuilder(descriptor.findFieldByName("repeated_int32"));
      fail("Exception was not thrown");
    } catch (UnsupportedOperationException e) {
      // We expect this exception.
    }
    try {
      builder.getFieldBuilder(
          descriptor.findFieldByName("repeated_nested_enum"));
      fail("Exception was not thrown");
    } catch (UnsupportedOperationException e) {
      // We expect this exception.
    }
    try {
      builder.getFieldBuilder(
          descriptor.findFieldByName("repeated_nested_message"));
      fail("Exception was not thrown");
    } catch (UnsupportedOperationException e) {
      // We expect this exception.
    }
  }

  // Test that when the default outer class name conflicts with another type
  // defined in the proto the compiler will append a suffix to avoid the
  // conflict.
  public void testConflictingOuterClassName() {
    // We just need to make sure we can refer to the outer class with the
    // expected name. There is nothing else to test.
    OuterClassNameTestOuterClass.OuterClassNameTest message =
        OuterClassNameTestOuterClass.OuterClassNameTest.newBuilder().build();
    assertTrue(message.getDescriptorForType() ==
        OuterClassNameTestOuterClass.OuterClassNameTest.getDescriptor());

    OuterClassNameTest2OuterClass.TestMessage2.NestedMessage.OuterClassNameTest2
        message2 = OuterClassNameTest2OuterClass.TestMessage2.NestedMessage
            .OuterClassNameTest2.newBuilder().build();
    assertEquals(0, message2.getSerializedSize());

    OuterClassNameTest3OuterClass.TestMessage3.NestedMessage.OuterClassNameTest3
        enumValue = OuterClassNameTest3OuterClass.TestMessage3.NestedMessage
            .OuterClassNameTest3.DUMMY_VALUE;
    assertEquals(1, enumValue.getNumber());
  }

  // =================================================================
  // oneof generated code test
  public void testOneofEnumCase() throws Exception {
    TestOneof2 message = TestOneof2.newBuilder()
        .setFooInt(123).setFooString("foo").setFooCord("bar").build();
    TestUtil.assertAtMostOneFieldSetOneof(message);
  }

  public void testClearOneof() throws Exception {
    TestOneof2.Builder builder = TestOneof2.newBuilder().setFooInt(123);
    assertEquals(TestOneof2.FooCase.FOO_INT, builder.getFooCase());
    builder.clearFoo();
    assertEquals(TestOneof2.FooCase.FOO_NOT_SET, builder.getFooCase());
  }

  public void testSetOneofClearsOthers() throws Exception {
    TestOneof2.Builder builder = TestOneof2.newBuilder();
    TestOneof2 message =
        builder.setFooInt(123).setFooString("foo").buildPartial();
    assertTrue(message.hasFooString());
    TestUtil.assertAtMostOneFieldSetOneof(message);

    message = builder.setFooCord("bar").buildPartial();
    assertTrue(message.hasFooCord());
    TestUtil.assertAtMostOneFieldSetOneof(message);

    message = builder.setFooStringPiece("baz").buildPartial();
    assertTrue(message.hasFooStringPiece());
    TestUtil.assertAtMostOneFieldSetOneof(message);

    message = builder.setFooBytes(TestUtil.toBytes("qux")).buildPartial();
    assertTrue(message.hasFooBytes());
    TestUtil.assertAtMostOneFieldSetOneof(message);

    message = builder.setFooEnum(TestOneof2.NestedEnum.FOO).buildPartial();
    assertTrue(message.hasFooEnum());
    TestUtil.assertAtMostOneFieldSetOneof(message);

    message = builder.setFooMessage(
        TestOneof2.NestedMessage.newBuilder().setQuxInt(234).build()).buildPartial();
    assertTrue(message.hasFooMessage());
    TestUtil.assertAtMostOneFieldSetOneof(message);

    message = builder.setFooInt(123).buildPartial();
    assertTrue(message.hasFooInt());
    TestUtil.assertAtMostOneFieldSetOneof(message);
  }

  public void testOneofTypes() throws Exception {
    // Primitive
    {
      TestOneof2.Builder builder = TestOneof2.newBuilder();
      assertEquals(builder.getFooInt(), 0);
      assertFalse(builder.hasFooInt());
      assertTrue(builder.setFooInt(123).hasFooInt());
      assertEquals(builder.getFooInt(), 123);
      TestOneof2 message = builder.buildPartial();
      assertTrue(message.hasFooInt());
      assertEquals(message.getFooInt(), 123);

      assertFalse(builder.clearFooInt().hasFooInt());
      TestOneof2 message2 = builder.build();
      assertFalse(message2.hasFooInt());
      assertEquals(0, message2.getFooInt());
    }

    // Enum
    {
      TestOneof2.Builder builder = TestOneof2.newBuilder();
      assertEquals(TestOneof2.NestedEnum.FOO, builder.getFooEnum());
      assertTrue(builder.setFooEnum(TestOneof2.NestedEnum.BAR).hasFooEnum());
      assertEquals(TestOneof2.NestedEnum.BAR, builder.getFooEnum());
      TestOneof2 message = builder.buildPartial();
      assertTrue(message.hasFooEnum());
      assertEquals(TestOneof2.NestedEnum.BAR, message.getFooEnum());

      assertFalse(builder.clearFooEnum().hasFooEnum());
      TestOneof2 message2 = builder.build();
      assertFalse(message2.hasFooEnum());
      assertEquals(TestOneof2.NestedEnum.FOO, message2.getFooEnum());
    }

    // String
    {
      TestOneof2.Builder builder = TestOneof2.newBuilder();
      assertEquals("", builder.getFooString());
      builder.setFooString("foo");
      assertTrue(builder.hasFooString());
      assertEquals("foo", builder.getFooString());
      TestOneof2 message = builder.buildPartial();
      assertTrue(message.hasFooString());
      assertEquals("foo", message.getFooString());
      assertEquals(message.getFooStringBytes(), TestUtil.toBytes("foo"));

      assertFalse(builder.clearFooString().hasFooString());
      TestOneof2 message2 = builder.buildPartial();
      assertFalse(message2.hasFooString());
      assertEquals("", message2.getFooString());
      assertEquals(message2.getFooStringBytes(), TestUtil.toBytes(""));

      // Get method should not change the oneof value.
      builder.setFooInt(123);
      assertEquals("", builder.getFooString());
      assertEquals(builder.getFooStringBytes(), TestUtil.toBytes(""));
      assertEquals(123, builder.getFooInt());

      message = builder.build();
      assertEquals("", message.getFooString());
      assertEquals(message.getFooStringBytes(), TestUtil.toBytes(""));
      assertEquals(123, message.getFooInt());
    }

    // Cord
    {
      TestOneof2.Builder builder = TestOneof2.newBuilder();
      assertEquals("", builder.getFooCord());
      builder.setFooCord("foo");
      assertTrue(builder.hasFooCord());
      assertEquals("foo", builder.getFooCord());
      TestOneof2 message = builder.buildPartial();
      assertTrue(message.hasFooCord());
      assertEquals("foo", message.getFooCord());
      assertEquals(message.getFooCordBytes(), TestUtil.toBytes("foo"));

      assertFalse(builder.clearFooCord().hasFooCord());
      TestOneof2 message2 = builder.build();
      assertFalse(message2.hasFooCord());
      assertEquals("", message2.getFooCord());
      assertEquals(message2.getFooCordBytes(), TestUtil.toBytes(""));
    }

    // StringPiece
    {
      TestOneof2.Builder builder = TestOneof2.newBuilder();
      assertEquals("", builder.getFooStringPiece());
      builder.setFooStringPiece("foo");
      assertTrue(builder.hasFooStringPiece());
      assertEquals("foo", builder.getFooStringPiece());
      TestOneof2 message = builder.buildPartial();
      assertTrue(message.hasFooStringPiece());
      assertEquals("foo", message.getFooStringPiece());
      assertEquals(message.getFooStringPieceBytes(), TestUtil.toBytes("foo"));

      assertFalse(builder.clearFooStringPiece().hasFooStringPiece());
      TestOneof2 message2 = builder.build();
      assertFalse(message2.hasFooStringPiece());
      assertEquals("", message2.getFooStringPiece());
      assertEquals(message2.getFooStringPieceBytes(), TestUtil.toBytes(""));
    }

    // Message
    {
      // set
      TestOneof2.Builder builder = TestOneof2.newBuilder();
      assertEquals(0, builder.getFooMessage().getQuxInt());
      builder.setFooMessage(
          TestOneof2.NestedMessage.newBuilder().setQuxInt(234).build());
      assertTrue(builder.hasFooMessage());
      assertEquals(234, builder.getFooMessage().getQuxInt());
      TestOneof2 message = builder.buildPartial();
      assertTrue(message.hasFooMessage());
      assertEquals(234, message.getFooMessage().getQuxInt());

      // clear
      assertFalse(builder.clearFooMessage().hasFooString());
      message = builder.build();
      assertFalse(message.hasFooMessage());
      assertEquals(0, message.getFooMessage().getQuxInt());

      // nested builder
      builder = TestOneof2.newBuilder();
      assertSame(builder.getFooMessageOrBuilder(),
          TestOneof2.NestedMessage.getDefaultInstance());
      assertFalse(builder.hasFooMessage());
      builder.getFooMessageBuilder().setQuxInt(123);
      assertTrue(builder.hasFooMessage());
      assertEquals(123, builder.getFooMessage().getQuxInt());
      message = builder.build();
      assertTrue(message.hasFooMessage());
      assertEquals(123, message.getFooMessage().getQuxInt());
    }

    // LazyMessage is tested in LazyMessageLiteTest.java
  }

  public void testOneofMerge() throws Exception {
    // Primitive Type
    {
      TestOneof2.Builder builder = TestOneof2.newBuilder();
      TestOneof2 message = builder.setFooInt(123).build();
      TestOneof2 message2 = TestOneof2.newBuilder().mergeFrom(message).build();
      assertTrue(message2.hasFooInt());
      assertEquals(123, message2.getFooInt());
    }

    // String
    {
      TestOneof2.Builder builder = TestOneof2.newBuilder();
      TestOneof2 message = builder.setFooString("foo").build();
      TestOneof2 message2 = TestOneof2.newBuilder().mergeFrom(message).build();
      assertTrue(message2.hasFooString());
      assertEquals("foo", message2.getFooString());
    }

    // Enum
    {
      TestOneof2.Builder builder = TestOneof2.newBuilder();
      TestOneof2 message = builder.setFooEnum(TestOneof2.NestedEnum.BAR).build();
      TestOneof2 message2 = TestOneof2.newBuilder().mergeFrom(message).build();
      assertTrue(message2.hasFooEnum());
      assertEquals(TestOneof2.NestedEnum.BAR, message2.getFooEnum());
    }

    // Message
    {
      TestOneof2.Builder builder = TestOneof2.newBuilder();
      TestOneof2 message = builder.setFooMessage(
          TestOneof2.NestedMessage.newBuilder().setQuxInt(234).build()).build();
      TestOneof2 message2 = TestOneof2.newBuilder().mergeFrom(message).build();
      assertTrue(message2.hasFooMessage());
      assertEquals(234, message2.getFooMessage().getQuxInt());
    }
  }

  public void testOneofSerialization() throws Exception {
    // Primitive Type
    {
      TestOneof2.Builder builder = TestOneof2.newBuilder();
      TestOneof2 message = builder.setFooInt(123).build();
      ByteString serialized = message.toByteString();
      TestOneof2 message2 = TestOneof2.parseFrom(serialized);
      assertTrue(message2.hasFooInt());
      assertEquals(123, message2.getFooInt());
    }

    // String
    {
      TestOneof2.Builder builder = TestOneof2.newBuilder();
      TestOneof2 message = builder.setFooString("foo").build();
      ByteString serialized = message.toByteString();
      TestOneof2 message2 = TestOneof2.parseFrom(serialized);
      assertTrue(message2.hasFooString());
      assertEquals("foo", message2.getFooString());
    }

    // Enum
    {
      TestOneof2.Builder builder = TestOneof2.newBuilder();
      TestOneof2 message = builder.setFooEnum(TestOneof2.NestedEnum.BAR).build();
      ByteString serialized = message.toByteString();
      TestOneof2 message2 = TestOneof2.parseFrom(serialized);
      assertTrue(message2.hasFooEnum());
      assertEquals(TestOneof2.NestedEnum.BAR, message2.getFooEnum());
    }

    // Message
    {
      TestOneof2.Builder builder = TestOneof2.newBuilder();
      TestOneof2 message = builder.setFooMessage(
          TestOneof2.NestedMessage.newBuilder().setQuxInt(234).build()).build();
      ByteString serialized = message.toByteString();
      TestOneof2 message2 = TestOneof2.parseFrom(serialized);
      assertTrue(message2.hasFooMessage());
      assertEquals(234, message2.getFooMessage().getQuxInt());
    }
  }

  public void testOneofNestedBuilderOnChangePropagation() {
    NestedTestAllTypes.Builder parentBuilder = NestedTestAllTypes.newBuilder();
    TestAllTypes.Builder builder = parentBuilder.getPayloadBuilder();
    builder.getOneofNestedMessageBuilder();
    assertTrue(builder.hasOneofNestedMessage());
    assertTrue(parentBuilder.hasPayload());
    NestedTestAllTypes message = parentBuilder.build();
    assertTrue(message.hasPayload());
    assertTrue(message.getPayload().hasOneofNestedMessage());
  }

  public void testGetRepeatedFieldBuilder() {
    Descriptor descriptor = TestAllTypes.getDescriptor();

    FieldDescriptor fieldDescriptor =
        descriptor.findFieldByName("repeated_nested_message");
    FieldDescriptor foreignFieldDescriptor =
        descriptor.findFieldByName("repeated_foreign_message");
    FieldDescriptor importFieldDescriptor =
        descriptor.findFieldByName("repeated_import_message");

    // Mutate the message with new field builder
    // Mutate nested message
    TestAllTypes.Builder builder1 = TestAllTypes.newBuilder();
    Message.Builder fieldBuilder1 = builder1.newBuilderForField(
        fieldDescriptor);
    FieldDescriptor subFieldDescriptor1 =
        fieldBuilder1.getDescriptorForType().findFieldByName("bb");
    fieldBuilder1.setField(subFieldDescriptor1, 1);
    builder1.addRepeatedField(fieldDescriptor, fieldBuilder1.build());

    // Mutate foreign message
    Message.Builder foreignFieldBuilder1 = builder1.newBuilderForField(
        foreignFieldDescriptor);
    FieldDescriptor subForeignFieldDescriptor1 =
        foreignFieldBuilder1.getDescriptorForType().findFieldByName("c");
    foreignFieldBuilder1.setField(subForeignFieldDescriptor1, 2);
    builder1.addRepeatedField(foreignFieldDescriptor,
        foreignFieldBuilder1.build());

    // Mutate import message
    Message.Builder importFieldBuilder1 = builder1.newBuilderForField(
        importFieldDescriptor);
    FieldDescriptor subImportFieldDescriptor1 =
        importFieldBuilder1.getDescriptorForType().findFieldByName("d");
    importFieldBuilder1.setField(subImportFieldDescriptor1, 3);
    builder1.addRepeatedField(importFieldDescriptor,
        importFieldBuilder1.build());

    Message newMessage1 = builder1.build();

    // Mutate the message with existing field builder
    // Mutate nested message
    TestAllTypes.Builder builder2 = TestAllTypes.newBuilder();
    builder2.addRepeatedNestedMessageBuilder();
    Message.Builder fieldBuilder2 = builder2.getRepeatedFieldBuilder(
        fieldDescriptor, 0);
    FieldDescriptor subFieldDescriptor2 =
        fieldBuilder2.getDescriptorForType().findFieldByName("bb");
    fieldBuilder2.setField(subFieldDescriptor2, 1);

    // Mutate foreign message
    Message.Builder foreignFieldBuilder2 = builder2.newBuilderForField(
        foreignFieldDescriptor);
    FieldDescriptor subForeignFieldDescriptor2 =
        foreignFieldBuilder2.getDescriptorForType().findFieldByName("c");
    foreignFieldBuilder2.setField(subForeignFieldDescriptor2, 2);
    builder2.addRepeatedField(foreignFieldDescriptor,
        foreignFieldBuilder2.build());

    // Mutate import message
    Message.Builder importFieldBuilder2 = builder2.newBuilderForField(
        importFieldDescriptor);
    FieldDescriptor subImportFieldDescriptor2 =
        importFieldBuilder2.getDescriptorForType().findFieldByName("d");
    importFieldBuilder2.setField(subImportFieldDescriptor2, 3);
    builder2.addRepeatedField(importFieldDescriptor,
        importFieldBuilder2.build());

    Message newMessage2 = builder2.build();

    // These two messages should be equal.
    assertEquals(newMessage1, newMessage2);
  }

  public void testGetRepeatedFieldBuilderWithInitializedValue() {
    Descriptor descriptor = TestAllTypes.getDescriptor();
    FieldDescriptor fieldDescriptor =
        descriptor.findFieldByName("repeated_nested_message");

    // Before setting field, builder is initialized by default value. 
    TestAllTypes.Builder builder = TestAllTypes.newBuilder();
    builder.addRepeatedNestedMessageBuilder();
    NestedMessage.Builder fieldBuilder =
        (NestedMessage.Builder) builder.getRepeatedFieldBuilder(fieldDescriptor, 0);
    assertEquals(0, fieldBuilder.getBb());

    // Setting field value with new field builder instance.
    builder = TestAllTypes.newBuilder();
    NestedMessage.Builder newFieldBuilder =
        builder.addRepeatedNestedMessageBuilder();
    newFieldBuilder.setBb(2);
    // Then get the field builder instance by getRepeatedFieldBuilder().
    fieldBuilder =
        (NestedMessage.Builder) builder.getRepeatedFieldBuilder(fieldDescriptor, 0);
    // It should contain new value.
    assertEquals(2, fieldBuilder.getBb());
    // These two builder should be equal.
    assertSame(fieldBuilder, newFieldBuilder);
  }

  public void testGetRepeatedFieldBuilderNotSupportedException() {
    Descriptor descriptor = TestAllTypes.getDescriptor();
    TestAllTypes.Builder builder = TestAllTypes.newBuilder();
    try {
      builder.getRepeatedFieldBuilder(descriptor.findFieldByName("repeated_int32"), 0);
      fail("Exception was not thrown");
    } catch (UnsupportedOperationException e) {
      // We expect this exception.
    }
    try {
      builder.getRepeatedFieldBuilder(
          descriptor.findFieldByName("repeated_nested_enum"), 0);
      fail("Exception was not thrown");
    } catch (UnsupportedOperationException e) {
      // We expect this exception.
    }
    try {
      builder.getRepeatedFieldBuilder(descriptor.findFieldByName("optional_int32"), 0);
      fail("Exception was not thrown");
    } catch (UnsupportedOperationException e) {
      // We expect this exception.
    }
    try {
      builder.getRepeatedFieldBuilder(
          descriptor.findFieldByName("optional_nested_enum"), 0);
      fail("Exception was not thrown");
    } catch (UnsupportedOperationException e) {
      // We expect this exception.
    }
    try {
      builder.getRepeatedFieldBuilder(
          descriptor.findFieldByName("optional_nested_message"), 0);
      fail("Exception was not thrown");
    } catch (UnsupportedOperationException e) {
      // We expect this exception.
    }
  }
}
