Home | History | Annotate | Download | only in protobuf
      1 // Protocol Buffers - Google's data interchange format
      2 // Copyright 2013 Google Inc.  All rights reserved.
      3 // http://code.google.com/p/protobuf/
      4 //
      5 // Redistribution and use in source and binary forms, with or without
      6 // modification, are permitted provided that the following conditions are
      7 // met:
      8 //
      9 //     * Redistributions of source code must retain the above copyright
     10 // notice, this list of conditions and the following disclaimer.
     11 //     * Redistributions in binary form must reproduce the above
     12 // copyright notice, this list of conditions and the following disclaimer
     13 // in the documentation and/or other materials provided with the
     14 // distribution.
     15 //     * Neither the name of Google Inc. nor the names of its
     16 // contributors may be used to endorse or promote products derived from
     17 // this software without specific prior written permission.
     18 //
     19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     30 
     31 package com.google.protobuf;
     32 
     33 import com.google.protobuf.nano.BytesOffsetLengthTestNanoOuterClass.BytesOffsetLengthTestNano;
     34 import com.google.protobuf.nano.CodedInputByteBufferNano;
     35 import com.google.protobuf.nano.CodedOutputByteBufferNano;
     36 import com.google.protobuf.nano.EnumClassNanoMultiple;
     37 import com.google.protobuf.nano.EnumClassNanos;
     38 import com.google.protobuf.nano.EnumValidity;
     39 import com.google.protobuf.nano.EnumValidityAccessors;
     40 import com.google.protobuf.nano.FileScopeEnumMultiple;
     41 import com.google.protobuf.nano.FileScopeEnumRefNano;
     42 import com.google.protobuf.nano.InternalNano;
     43 import com.google.protobuf.nano.InvalidProtocolBufferNanoException;
     44 import com.google.protobuf.nano.MessageNano;
     45 import com.google.protobuf.nano.MessageScopeEnumRefNano;
     46 import com.google.protobuf.nano.MultipleImportingNonMultipleNano1;
     47 import com.google.protobuf.nano.MultipleImportingNonMultipleNano2;
     48 import com.google.protobuf.nano.MultipleNameClashNano;
     49 import com.google.protobuf.nano.NanoAccessorsOuterClass.TestNanoAccessors;
     50 import com.google.protobuf.nano.NanoHasOuterClass.TestAllTypesNanoHas;
     51 import com.google.protobuf.nano.NanoOuterClass;
     52 import com.google.protobuf.nano.NanoOuterClass.TestAllTypesNano;
     53 import com.google.protobuf.nano.NanoReferenceTypes;
     54 import com.google.protobuf.nano.NanoReferenceTypesCompat;
     55 import com.google.protobuf.nano.NanoRepeatedPackables;
     56 import com.google.protobuf.nano.PackedExtensions;
     57 import com.google.protobuf.nano.RepeatedExtensions;
     58 import com.google.protobuf.nano.SingularExtensions;
     59 import com.google.protobuf.nano.TestRepeatedMergeNano;
     60 import com.google.protobuf.nano.UnittestMultipleNano;
     61 import com.google.protobuf.nano.UnittestRecursiveNano.RecursiveMessageNano;
     62 import com.google.protobuf.nano.UnittestSimpleNano.SimpleMessageNano;
     63 import com.google.protobuf.nano.UnittestSingleNano.SingleMessageNano;
     64 import com.google.protobuf.nano.UnknownEnumValuesNanoOuterClass.StandardVersion;
     65 import com.google.protobuf.nano.UnknownEnumValuesNanoOuterClass.VersionWithoutVal3;
     66 import com.google.protobuf.nano.testext.Extensions;
     67 import com.google.protobuf.nano.testext.Extensions.AnotherMessage;
     68 import com.google.protobuf.nano.testext.Extensions.MessageWithGroup;
     69 import com.google.protobuf.nano.testimport.UnittestImportNano;
     70 
     71 import junit.framework.TestCase;
     72 
     73 import java.util.Arrays;
     74 import java.util.HashMap;
     75 
     76 /**
     77  * Test nano runtime.
     78  *
     79  * @author ulas (at) google.com Ulas Kirazci
     80  */
     81 public class NanoTest extends TestCase {
     82   @Override
     83   public void setUp() throws Exception {
     84   }
     85 
     86   public void testSimpleMessageNano() throws Exception {
     87     SimpleMessageNano msg = new SimpleMessageNano();
     88     assertEquals(123, msg.d);
     89     assertEquals(null, msg.nestedMsg);
     90     assertEquals(SimpleMessageNano.BAZ, msg.defaultNestedEnum);
     91 
     92     msg.d = 456;
     93     assertEquals(456, msg.d);
     94 
     95     SimpleMessageNano.NestedMessage nestedMsg = new SimpleMessageNano.NestedMessage();
     96     nestedMsg.bb = 2;
     97     assertEquals(2, nestedMsg.bb);
     98     msg.nestedMsg = nestedMsg;
     99     assertEquals(2, msg.nestedMsg.bb);
    100 
    101     msg.defaultNestedEnum = SimpleMessageNano.BAR;
    102     assertEquals(SimpleMessageNano.BAR, msg.defaultNestedEnum);
    103 
    104     byte [] result = MessageNano.toByteArray(msg);
    105     int msgSerializedSize = msg.getSerializedSize();
    106     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
    107     assertTrue(msgSerializedSize == 9);
    108     assertEquals(result.length, msgSerializedSize);
    109 
    110     SimpleMessageNano newMsg = SimpleMessageNano.parseFrom(result);
    111     assertEquals(456, newMsg.d);
    112     assertEquals(2, msg.nestedMsg.bb);
    113     assertEquals(SimpleMessageNano.BAR, msg.defaultNestedEnum);
    114 
    115     msg.nestedMsg = null;
    116     assertTrue(msgSerializedSize != msg.getSerializedSize());
    117 
    118     msg.clear();
    119     assertEquals(0, msg.getSerializedSize());
    120   }
    121 
    122   public void testRecursiveMessageNano() throws Exception {
    123     RecursiveMessageNano msg = new RecursiveMessageNano();
    124     assertTrue(msg.repeatedRecursiveMessageNano.length == 0);
    125 
    126     RecursiveMessageNano msg1 = new RecursiveMessageNano();
    127     msg1.id = 1;
    128     assertEquals(1, msg1.id);
    129     RecursiveMessageNano msg2 = new RecursiveMessageNano();
    130     msg2.id = 2;
    131     RecursiveMessageNano msg3 = new RecursiveMessageNano();
    132     msg3.id = 3;
    133 
    134     RecursiveMessageNano.NestedMessage nestedMsg = new RecursiveMessageNano.NestedMessage();
    135     nestedMsg.a = msg1;
    136     assertEquals(1, nestedMsg.a.id);
    137 
    138     msg.id = 0;
    139     msg.nestedMessage = nestedMsg;
    140     msg.optionalRecursiveMessageNano = msg2;
    141     msg.repeatedRecursiveMessageNano = new RecursiveMessageNano[] { msg3 };
    142 
    143     byte [] result = MessageNano.toByteArray(msg);
    144     int msgSerializedSize = msg.getSerializedSize();
    145     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
    146     assertTrue(msgSerializedSize == 16);
    147     assertEquals(result.length, msgSerializedSize);
    148 
    149     RecursiveMessageNano newMsg = RecursiveMessageNano.parseFrom(result);
    150     assertEquals(1, newMsg.repeatedRecursiveMessageNano.length);
    151 
    152     assertEquals(0, newMsg.id);
    153     assertEquals(1, newMsg.nestedMessage.a.id);
    154     assertEquals(2, newMsg.optionalRecursiveMessageNano.id);
    155     assertEquals(3, newMsg.repeatedRecursiveMessageNano[0].id);
    156   }
    157 
    158   public void testMessageNoFields() {
    159     SingleMessageNano msg = new SingleMessageNano();
    160     assertEquals(0, msg.getSerializedSize());
    161     assertEquals(0, MessageNano.toByteArray(msg).length);
    162   }
    163 
    164   public void testNanoRequiredInt32() throws Exception {
    165     TestAllTypesNano msg = new TestAllTypesNano();
    166     msg.id = 123;
    167     assertEquals(123, msg.id);
    168     msg.clear().id = 456;
    169     assertEquals(456, msg.id);
    170     msg.clear();
    171 
    172     msg.id = 123;
    173     byte [] result = MessageNano.toByteArray(msg);
    174     int msgSerializedSize = msg.getSerializedSize();
    175     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
    176     assertTrue(msgSerializedSize == 3);
    177     assertEquals(result.length, msgSerializedSize);
    178 
    179     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
    180     assertEquals(123, newMsg.id);
    181   }
    182 
    183   public void testNanoOptionalInt32() throws Exception {
    184     TestAllTypesNano msg = new TestAllTypesNano();
    185     msg.optionalInt32 = 123;
    186     assertEquals(123, msg.optionalInt32);
    187     msg.clear()
    188        .optionalInt32 = 456;
    189     assertEquals(456, msg.optionalInt32);
    190     msg.clear();
    191 
    192     msg.optionalInt32 = 123;
    193     byte [] result = MessageNano.toByteArray(msg);
    194     int msgSerializedSize = msg.getSerializedSize();
    195     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
    196     assertTrue(msgSerializedSize == 5);
    197     assertEquals(result.length, msgSerializedSize);
    198 
    199     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
    200     assertEquals(123, newMsg.optionalInt32);
    201   }
    202 
    203   public void testNanoOptionalInt64() throws Exception {
    204     TestAllTypesNano msg = new TestAllTypesNano();
    205     msg.optionalInt64 = 123;
    206     assertEquals(123, msg.optionalInt64);
    207     msg.clear()
    208        .optionalInt64 = 456;
    209     assertEquals(456, msg.optionalInt64);
    210     msg.clear();
    211     assertEquals(0, msg.optionalInt64);
    212 
    213     msg.optionalInt64 = 123;
    214     byte [] result = MessageNano.toByteArray(msg);
    215     int msgSerializedSize = msg.getSerializedSize();
    216     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
    217     assertTrue(msgSerializedSize == 5);
    218     assertEquals(result.length, msgSerializedSize);
    219 
    220     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
    221     assertEquals(123, newMsg.optionalInt64);
    222   }
    223 
    224   public void testNanoOptionalUint32() throws Exception {
    225     TestAllTypesNano msg = new TestAllTypesNano();
    226     msg.optionalUint32 = 123;
    227     assertEquals(123, msg.optionalUint32);
    228     msg.clear()
    229        .optionalUint32 = 456;
    230     assertEquals(456, msg.optionalUint32);
    231     msg.clear();
    232     assertEquals(0, msg.optionalUint32);
    233 
    234     msg.optionalUint32 = 123;
    235     byte [] result = MessageNano.toByteArray(msg);
    236     int msgSerializedSize = msg.getSerializedSize();
    237     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
    238     assertTrue(msgSerializedSize == 5);
    239     assertEquals(result.length, msgSerializedSize);
    240 
    241     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
    242     assertEquals(123, newMsg.optionalUint32);
    243   }
    244 
    245   public void testNanoOptionalUint64() throws Exception {
    246     TestAllTypesNano msg = new TestAllTypesNano();
    247     msg.optionalUint64 = 123;
    248     assertEquals(123, msg.optionalUint64);
    249     msg.clear()
    250        .optionalUint64 = 456;
    251     assertEquals(456, msg.optionalUint64);
    252     msg.clear();
    253     assertEquals(0, msg.optionalUint64);
    254 
    255     msg.optionalUint64 = 123;
    256     byte [] result = MessageNano.toByteArray(msg);
    257     int msgSerializedSize = msg.getSerializedSize();
    258     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
    259     assertTrue(msgSerializedSize == 5);
    260     assertEquals(result.length, msgSerializedSize);
    261 
    262     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
    263     assertEquals(123, newMsg.optionalUint64);
    264   }
    265 
    266   public void testNanoOptionalSint32() throws Exception {
    267     TestAllTypesNano msg = new TestAllTypesNano();
    268     msg.optionalSint32 = 123;
    269     assertEquals(123, msg.optionalSint32);
    270     msg.clear()
    271        .optionalSint32 = 456;
    272     assertEquals(456, msg.optionalSint32);
    273     msg.clear();
    274     assertEquals(0, msg.optionalSint32);
    275 
    276     msg.optionalSint32 = -123;
    277     byte [] result = MessageNano.toByteArray(msg);
    278     int msgSerializedSize = msg.getSerializedSize();
    279     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
    280     assertTrue(msgSerializedSize == 6);
    281     assertEquals(result.length, msgSerializedSize);
    282 
    283     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
    284     assertEquals(-123, newMsg.optionalSint32);
    285   }
    286 
    287   public void testNanoOptionalSint64() throws Exception {
    288     TestAllTypesNano msg = new TestAllTypesNano();
    289     msg.optionalSint64 = 123;
    290     assertEquals(123, msg.optionalSint64);
    291     msg.clear()
    292        .optionalSint64 = 456;
    293     assertEquals(456, msg.optionalSint64);
    294     msg.clear();
    295     assertEquals(0, msg.optionalSint64);
    296 
    297     msg.optionalSint64 = -123;
    298     byte [] result = MessageNano.toByteArray(msg);
    299     int msgSerializedSize = msg.getSerializedSize();
    300     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
    301     assertTrue(msgSerializedSize == 6);
    302     assertEquals(result.length, msgSerializedSize);
    303 
    304     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
    305     assertEquals(-123, newMsg.optionalSint64);
    306   }
    307 
    308   public void testNanoOptionalFixed32() throws Exception {
    309     TestAllTypesNano msg = new TestAllTypesNano();
    310     msg.optionalFixed32 = 123;
    311     assertEquals(123, msg.optionalFixed32);
    312     msg.clear()
    313        .optionalFixed32 = 456;
    314     assertEquals(456, msg.optionalFixed32);
    315     msg.clear();
    316     assertEquals(0, msg.optionalFixed32);
    317 
    318     msg.optionalFixed32 = 123;
    319     byte [] result = MessageNano.toByteArray(msg);
    320     int msgSerializedSize = msg.getSerializedSize();
    321     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
    322     assertTrue(msgSerializedSize == 8);
    323     assertEquals(result.length, msgSerializedSize);
    324 
    325     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
    326     assertEquals(123, newMsg.optionalFixed32);
    327   }
    328 
    329   public void testNanoOptionalFixed64() throws Exception {
    330     TestAllTypesNano msg = new TestAllTypesNano();
    331     msg.optionalFixed64 = 123;
    332     assertEquals(123, msg.optionalFixed64);
    333     msg.clear()
    334        .optionalFixed64 = 456;
    335     assertEquals(456, msg.optionalFixed64);
    336     msg.clear();
    337     assertEquals(0, msg.optionalFixed64);
    338 
    339     msg.optionalFixed64 = 123;
    340     byte [] result = MessageNano.toByteArray(msg);
    341     int msgSerializedSize = msg.getSerializedSize();
    342     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
    343     assertTrue(msgSerializedSize == 12);
    344     assertEquals(result.length, msgSerializedSize);
    345 
    346     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
    347     assertEquals(123, newMsg.optionalFixed64);
    348   }
    349 
    350   public void testNanoOptionalSfixed32() throws Exception {
    351     TestAllTypesNano msg = new TestAllTypesNano();
    352     msg.optionalSfixed32 = 123;
    353     assertEquals(123, msg.optionalSfixed32);
    354     msg.clear()
    355        .optionalSfixed32 = 456;
    356     assertEquals(456, msg.optionalSfixed32);
    357     msg.clear();
    358     assertEquals(0, msg.optionalSfixed32);
    359 
    360     msg.optionalSfixed32 = 123;
    361     byte [] result = MessageNano.toByteArray(msg);
    362     int msgSerializedSize = msg.getSerializedSize();
    363     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
    364     assertTrue(msgSerializedSize == 8);
    365     assertEquals(result.length, msgSerializedSize);
    366 
    367     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
    368     assertEquals(123, newMsg.optionalSfixed32);
    369   }
    370 
    371   public void testNanoOptionalSfixed64() throws Exception {
    372     TestAllTypesNano msg = new TestAllTypesNano();
    373     msg.optionalSfixed64 = 123;
    374     assertEquals(123, msg.optionalSfixed64);
    375     msg.clear()
    376        .optionalSfixed64 = 456;
    377     assertEquals(456, msg.optionalSfixed64);
    378     msg.clear();
    379     assertEquals(0, msg.optionalSfixed64);
    380 
    381     msg.optionalSfixed64 = -123;
    382     byte [] result = MessageNano.toByteArray(msg);
    383     int msgSerializedSize = msg.getSerializedSize();
    384     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
    385     assertTrue(msgSerializedSize == 12);
    386     assertEquals(result.length, msgSerializedSize);
    387 
    388     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
    389     assertEquals(-123, newMsg.optionalSfixed64);
    390   }
    391 
    392   public void testNanoOptionalFloat() throws Exception {
    393     TestAllTypesNano msg = new TestAllTypesNano();
    394     msg.optionalFloat = 123f;
    395     assertTrue(123.0f == msg.optionalFloat);
    396     msg.clear()
    397        .optionalFloat = 456.0f;
    398     assertTrue(456.0f == msg.optionalFloat);
    399     msg.clear();
    400     assertTrue(0.0f == msg.optionalFloat);
    401 
    402     msg.optionalFloat = -123.456f;
    403     byte [] result = MessageNano.toByteArray(msg);
    404     int msgSerializedSize = msg.getSerializedSize();
    405     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
    406     assertTrue(msgSerializedSize == 8);
    407     assertEquals(result.length, msgSerializedSize);
    408 
    409     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
    410     assertTrue(-123.456f == newMsg.optionalFloat);
    411   }
    412 
    413   public void testNanoOptionalDouble() throws Exception {
    414     TestAllTypesNano msg = new TestAllTypesNano();
    415     msg.optionalDouble = 123;
    416     assertTrue(123.0 == msg.optionalDouble);
    417     msg.clear()
    418        .optionalDouble = 456.0;
    419     assertTrue(456.0 == msg.optionalDouble);
    420     msg.clear();
    421     assertTrue(0.0 == msg.optionalDouble);
    422 
    423     msg.optionalDouble = -123.456;
    424     byte [] result = MessageNano.toByteArray(msg);
    425     int msgSerializedSize = msg.getSerializedSize();
    426     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
    427     assertTrue(msgSerializedSize == 12);
    428     assertEquals(result.length, msgSerializedSize);
    429 
    430     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
    431     assertTrue(-123.456 == newMsg.optionalDouble);
    432   }
    433 
    434   public void testNanoOptionalBool() throws Exception {
    435     TestAllTypesNano msg = new TestAllTypesNano();
    436     msg.optionalBool = true;
    437     assertTrue(msg.optionalBool);
    438     msg.clear()
    439        .optionalBool = true;
    440     assertTrue(msg.optionalBool);
    441     msg.clear();
    442     assertFalse(msg.optionalBool);
    443 
    444     msg.optionalBool = true;
    445     byte [] result = MessageNano.toByteArray(msg);
    446     int msgSerializedSize = msg.getSerializedSize();
    447     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
    448     assertTrue(msgSerializedSize == 5);
    449     assertEquals(result.length, msgSerializedSize);
    450 
    451     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
    452     assertTrue(newMsg.optionalBool);
    453   }
    454 
    455   public void testNanoOptionalString() throws Exception {
    456     TestAllTypesNano msg = new TestAllTypesNano();
    457     msg.optionalString = "hello";
    458     assertEquals("hello", msg.optionalString);
    459     msg.clear();
    460     assertTrue(msg.optionalString.isEmpty());
    461     msg.clear()
    462        .optionalString = "hello2";
    463     assertEquals("hello2", msg.optionalString);
    464     msg.clear();
    465     assertTrue(msg.optionalString.isEmpty());
    466 
    467     msg.optionalString = "bye";
    468     byte [] result = MessageNano.toByteArray(msg);
    469     int msgSerializedSize = msg.getSerializedSize();
    470     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
    471     assertTrue(msgSerializedSize == 8);
    472     assertEquals(result.length, msgSerializedSize);
    473 
    474     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
    475     assertTrue(newMsg.optionalString != null);
    476     assertEquals("bye", newMsg.optionalString);
    477   }
    478 
    479   public void testNanoOptionalBytes() throws Exception {
    480     TestAllTypesNano msg = new TestAllTypesNano();
    481     assertFalse(msg.optionalBytes.length > 0);
    482     msg.optionalBytes = InternalNano.copyFromUtf8("hello");
    483     assertTrue(msg.optionalBytes.length > 0);
    484     assertEquals("hello", new String(msg.optionalBytes, "UTF-8"));
    485     msg.clear();
    486     assertFalse(msg.optionalBytes.length > 0);
    487     msg.clear()
    488        .optionalBytes = InternalNano.copyFromUtf8("hello");
    489     assertTrue(msg.optionalBytes.length > 0);
    490     msg.clear();
    491     assertFalse(msg.optionalBytes.length > 0);
    492 
    493     msg.optionalBytes = InternalNano.copyFromUtf8("bye");
    494     byte [] result = MessageNano.toByteArray(msg);
    495     int msgSerializedSize = msg.getSerializedSize();
    496     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
    497     assertTrue(msgSerializedSize == 8);
    498     assertEquals(result.length, msgSerializedSize);
    499 
    500     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
    501     assertTrue(newMsg.optionalBytes.length > 0);
    502     assertEquals("bye", new String(newMsg.optionalBytes, "UTF-8"));
    503   }
    504 
    505   public void testNanoOptionalGroup() throws Exception {
    506     TestAllTypesNano msg = new TestAllTypesNano();
    507     TestAllTypesNano.OptionalGroup grp = new TestAllTypesNano.OptionalGroup();
    508     grp.a = 1;
    509     assertFalse(msg.optionalGroup != null);
    510     msg.optionalGroup = grp;
    511     assertTrue(msg.optionalGroup != null);
    512     assertEquals(1, msg.optionalGroup.a);
    513     msg.clear();
    514     assertFalse(msg.optionalGroup != null);
    515     msg.clear()
    516        .optionalGroup = new TestAllTypesNano.OptionalGroup();
    517     msg.optionalGroup.a = 2;
    518     assertTrue(msg.optionalGroup != null);
    519     msg.clear();
    520     assertFalse(msg.optionalGroup != null);
    521 
    522     msg.optionalGroup = grp;
    523     byte [] result = MessageNano.toByteArray(msg);
    524     int msgSerializedSize = msg.getSerializedSize();
    525     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
    526     assertTrue(msgSerializedSize == 10);
    527     assertEquals(result.length, msgSerializedSize);
    528 
    529     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
    530     assertTrue(newMsg.optionalGroup != null);
    531     assertEquals(1, newMsg.optionalGroup.a);
    532   }
    533 
    534   public void testNanoOptionalGroupWithUnknownFieldsEnabled() throws Exception {
    535     MessageWithGroup msg = new MessageWithGroup();
    536     MessageWithGroup.Group grp = new MessageWithGroup.Group();
    537     grp.a = 1;
    538     msg.group = grp;
    539     byte [] serialized = MessageNano.toByteArray(msg);
    540 
    541     MessageWithGroup parsed = MessageWithGroup.parseFrom(serialized);
    542     assertEquals(1, parsed.group.a);
    543 
    544     byte [] serialized2 = MessageNano.toByteArray(parsed);
    545     assertEquals(serialized.length, serialized2.length);
    546     MessageWithGroup parsed2 = MessageWithGroup.parseFrom(serialized2);
    547     assertEquals(1, parsed2.group.a);
    548   }
    549 
    550   public void testNanoOptionalNestedMessage() throws Exception {
    551     TestAllTypesNano msg = new TestAllTypesNano();
    552     TestAllTypesNano.NestedMessage nestedMsg = new TestAllTypesNano.NestedMessage();
    553     nestedMsg.bb = 1;
    554     assertFalse(msg.optionalNestedMessage != null);
    555     msg.optionalNestedMessage = nestedMsg;
    556     assertTrue(msg.optionalNestedMessage != null);
    557     assertEquals(1, msg.optionalNestedMessage.bb);
    558     msg.clear();
    559     assertFalse(msg.optionalNestedMessage != null);
    560     msg.clear()
    561        .optionalNestedMessage = new TestAllTypesNano.NestedMessage();
    562     msg.optionalNestedMessage.bb = 2;
    563     assertTrue(msg.optionalNestedMessage != null);
    564     msg.clear();
    565     assertFalse(msg.optionalNestedMessage != null);
    566 
    567     msg.optionalNestedMessage = nestedMsg;
    568     byte [] result = MessageNano.toByteArray(msg);
    569     int msgSerializedSize = msg.getSerializedSize();
    570     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
    571     assertTrue(msgSerializedSize == 8);
    572     assertEquals(result.length, msgSerializedSize);
    573 
    574     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
    575     assertTrue(newMsg.optionalNestedMessage != null);
    576     assertEquals(1, newMsg.optionalNestedMessage.bb);
    577   }
    578 
    579   public void testNanoOptionalForeignMessage() throws Exception {
    580     TestAllTypesNano msg = new TestAllTypesNano();
    581     NanoOuterClass.ForeignMessageNano nestedMsg = new NanoOuterClass.ForeignMessageNano();
    582     nestedMsg.c = 1;
    583     assertFalse(msg.optionalForeignMessage != null);
    584     msg.optionalForeignMessage = nestedMsg;
    585     assertTrue(msg.optionalForeignMessage != null);
    586     assertEquals(1, msg.optionalForeignMessage.c);
    587     msg.clear();
    588     assertFalse(msg.optionalForeignMessage != null);
    589     msg.clear()
    590        .optionalForeignMessage = new NanoOuterClass.ForeignMessageNano();
    591     msg.optionalForeignMessage.c = 2;
    592     assertTrue(msg.optionalForeignMessage != null);
    593     msg.clear();
    594     assertFalse(msg.optionalForeignMessage != null);
    595 
    596     msg.optionalForeignMessage = nestedMsg;
    597     byte [] result = MessageNano.toByteArray(msg);
    598     int msgSerializedSize = msg.getSerializedSize();
    599     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
    600     assertTrue(msgSerializedSize == 8);
    601     assertEquals(result.length, msgSerializedSize);
    602 
    603     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
    604     assertTrue(newMsg.optionalForeignMessage != null);
    605     assertEquals(1, newMsg.optionalForeignMessage.c);
    606   }
    607 
    608   public void testNanoOptionalImportMessage() throws Exception {
    609     TestAllTypesNano msg = new TestAllTypesNano();
    610     UnittestImportNano.ImportMessageNano nestedMsg = new UnittestImportNano.ImportMessageNano();
    611     nestedMsg.d = 1;
    612     assertFalse(msg.optionalImportMessage != null);
    613     msg.optionalImportMessage = nestedMsg;
    614     assertTrue(msg.optionalImportMessage != null);
    615     assertEquals(1, msg.optionalImportMessage.d);
    616     msg.clear();
    617     assertFalse(msg.optionalImportMessage != null);
    618     msg.clear()
    619        .optionalImportMessage = new UnittestImportNano.ImportMessageNano();
    620     msg.optionalImportMessage.d = 2;
    621     assertTrue(msg.optionalImportMessage != null);
    622     msg.clear();
    623     assertFalse(msg.optionalImportMessage != null);
    624 
    625     msg.optionalImportMessage = nestedMsg;
    626     byte [] result = MessageNano.toByteArray(msg);
    627     int msgSerializedSize = msg.getSerializedSize();
    628     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
    629     assertTrue(msgSerializedSize == 8);
    630     assertEquals(result.length, msgSerializedSize);
    631 
    632     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
    633     assertTrue(newMsg.optionalImportMessage != null);
    634     assertEquals(1, newMsg.optionalImportMessage.d);
    635   }
    636 
    637   public void testNanoOptionalNestedEnum() throws Exception {
    638     TestAllTypesNano msg = new TestAllTypesNano();
    639     msg.optionalNestedEnum = TestAllTypesNano.BAR;
    640     assertEquals(TestAllTypesNano.BAR, msg.optionalNestedEnum);
    641     msg.clear()
    642        .optionalNestedEnum = TestAllTypesNano.BAZ;
    643     assertEquals(TestAllTypesNano.BAZ, msg.optionalNestedEnum);
    644     msg.clear();
    645     assertEquals(TestAllTypesNano.FOO, msg.optionalNestedEnum);
    646 
    647     msg.optionalNestedEnum = TestAllTypesNano.BAR;
    648     byte [] result = MessageNano.toByteArray(msg);
    649     int msgSerializedSize = msg.getSerializedSize();
    650     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
    651     assertTrue(msgSerializedSize == 6);
    652     assertEquals(result.length, msgSerializedSize);
    653 
    654     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
    655     assertEquals(TestAllTypesNano.BAR, newMsg.optionalNestedEnum);
    656   }
    657 
    658   public void testNanoOptionalForeignEnum() throws Exception {
    659     TestAllTypesNano msg = new TestAllTypesNano();
    660     msg.optionalForeignEnum = NanoOuterClass.FOREIGN_NANO_BAR;
    661     assertEquals(NanoOuterClass.FOREIGN_NANO_BAR, msg.optionalForeignEnum);
    662     msg.clear()
    663        .optionalForeignEnum = NanoOuterClass.FOREIGN_NANO_BAZ;
    664     assertEquals(NanoOuterClass.FOREIGN_NANO_BAZ, msg.optionalForeignEnum);
    665     msg.clear();
    666     assertEquals(NanoOuterClass.FOREIGN_NANO_FOO, msg.optionalForeignEnum);
    667 
    668     msg.optionalForeignEnum = NanoOuterClass.FOREIGN_NANO_BAR;
    669     byte [] result = MessageNano.toByteArray(msg);
    670     int msgSerializedSize = msg.getSerializedSize();
    671     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
    672     assertTrue(msgSerializedSize == 6);
    673     assertEquals(result.length, msgSerializedSize);
    674 
    675     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
    676     assertEquals(NanoOuterClass.FOREIGN_NANO_BAR, newMsg.optionalForeignEnum);
    677   }
    678 
    679   public void testNanoOptionalImportEnum() throws Exception {
    680     TestAllTypesNano msg = new TestAllTypesNano();
    681     msg.optionalImportEnum = UnittestImportNano.IMPORT_NANO_BAR;
    682     assertEquals(UnittestImportNano.IMPORT_NANO_BAR, msg.optionalImportEnum);
    683     msg.clear()
    684        .optionalImportEnum = UnittestImportNano.IMPORT_NANO_BAZ;
    685     assertEquals(UnittestImportNano.IMPORT_NANO_BAZ, msg.optionalImportEnum);
    686     msg.clear();
    687     assertEquals(UnittestImportNano.IMPORT_NANO_FOO, msg.optionalImportEnum);
    688 
    689     msg.optionalImportEnum = UnittestImportNano.IMPORT_NANO_BAR;
    690     byte [] result = MessageNano.toByteArray(msg);
    691     int msgSerializedSize = msg.getSerializedSize();
    692     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
    693     assertTrue(msgSerializedSize == 6);
    694     assertEquals(result.length, msgSerializedSize);
    695 
    696     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
    697     assertEquals(UnittestImportNano.IMPORT_NANO_BAR, newMsg.optionalImportEnum);
    698   }
    699 
    700   public void testNanoOptionalStringPiece() throws Exception {
    701     TestAllTypesNano msg = new TestAllTypesNano();
    702     msg.optionalStringPiece = "hello";
    703     assertEquals("hello", msg.optionalStringPiece);
    704     msg.clear();
    705     assertTrue(msg.optionalStringPiece.isEmpty());
    706     msg.clear()
    707        .optionalStringPiece = "hello2";
    708     assertEquals("hello2", msg.optionalStringPiece);
    709     msg.clear();
    710     assertTrue(msg.optionalStringPiece.isEmpty());
    711 
    712     msg.optionalStringPiece = "bye";
    713     byte [] result = MessageNano.toByteArray(msg);
    714     int msgSerializedSize = msg.getSerializedSize();
    715     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
    716     assertTrue(msgSerializedSize == 9);
    717     assertEquals(result.length, msgSerializedSize);
    718 
    719     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
    720     assertTrue(newMsg.optionalStringPiece != null);
    721     assertEquals("bye", newMsg.optionalStringPiece);
    722   }
    723 
    724   public void testNanoOptionalCord() throws Exception {
    725     TestAllTypesNano msg = new TestAllTypesNano();
    726     msg.optionalCord = "hello";
    727     assertEquals("hello", msg.optionalCord);
    728     msg.clear();
    729     assertTrue(msg.optionalCord.isEmpty());
    730     msg.clear()
    731        .optionalCord = "hello2";
    732     assertEquals("hello2", msg.optionalCord);
    733     msg.clear();
    734     assertTrue(msg.optionalCord.isEmpty());
    735 
    736     msg.optionalCord = "bye";
    737     byte [] result = MessageNano.toByteArray(msg);
    738     int msgSerializedSize = msg.getSerializedSize();
    739     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
    740     assertTrue(msgSerializedSize == 9);
    741     assertEquals(result.length, msgSerializedSize);
    742 
    743     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
    744     assertTrue(newMsg.optionalCord != null);
    745     assertEquals("bye", newMsg.optionalCord);
    746   }
    747 
    748   public void testNanoRepeatedInt32() throws Exception {
    749     TestAllTypesNano msg = new TestAllTypesNano();
    750     assertEquals(0, msg.repeatedInt32.length);
    751     msg.repeatedInt32 = new int[] { 123, 789, 456 };
    752     assertEquals(789, msg.repeatedInt32[1]);
    753     assertEquals(456, msg.repeatedInt32[2]);
    754     msg.clear();
    755     assertEquals(0, msg.repeatedInt32.length);
    756     msg.clear()
    757        .repeatedInt32 = new int[] { 456 };
    758     assertEquals(1, msg.repeatedInt32.length);
    759     assertEquals(456, msg.repeatedInt32[0]);
    760     msg.clear();
    761     assertEquals(0, msg.repeatedInt32.length);
    762 
    763     // Test 1 entry
    764     msg.clear()
    765        .repeatedInt32 = new int[] { 123 };
    766     assertEquals(1, msg.repeatedInt32.length);
    767     byte [] result = MessageNano.toByteArray(msg);
    768     int msgSerializedSize = msg.getSerializedSize();
    769     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
    770     assertTrue(msgSerializedSize == 6);
    771     assertEquals(result.length, msgSerializedSize);
    772     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
    773     assertEquals(1, newMsg.repeatedInt32.length);
    774     assertEquals(123, newMsg.repeatedInt32[0]);
    775 
    776     // Test 2 entries
    777     msg.clear()
    778        .repeatedInt32 = new int[] { 123, 456 };
    779     assertEquals(2, msg.repeatedInt32.length);
    780     result = MessageNano.toByteArray(msg);
    781     msgSerializedSize = msg.getSerializedSize();
    782     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
    783     assertTrue(msgSerializedSize == 10);
    784     assertEquals(result.length, msgSerializedSize);
    785 
    786     newMsg = TestAllTypesNano.parseFrom(result);
    787     assertEquals(2, newMsg.repeatedInt32.length);
    788     assertEquals(123, newMsg.repeatedInt32[0]);
    789     assertEquals(456, newMsg.repeatedInt32[1]);
    790   }
    791 
    792   public void testNanoRepeatedInt64() throws Exception {
    793     TestAllTypesNano msg = new TestAllTypesNano();
    794     assertEquals(0, msg.repeatedInt64.length);
    795     msg.repeatedInt64 = new long[] { 123, 789, 456 };
    796     assertEquals(789, msg.repeatedInt64[1]);
    797     assertEquals(456, msg.repeatedInt64[2]);
    798     msg.clear();
    799     assertEquals(0, msg.repeatedInt64.length);
    800     msg.clear()
    801        .repeatedInt64 = new long[] { 456 };
    802     assertEquals(1, msg.repeatedInt64.length);
    803     assertEquals(456, msg.repeatedInt64[0]);
    804     msg.clear();
    805     assertEquals(0, msg.repeatedInt64.length);
    806 
    807     // Test 1 entry
    808     msg.clear()
    809        .repeatedInt64 = new long[] { 123 };
    810     assertEquals(1, msg.repeatedInt64.length);
    811     byte [] result = MessageNano.toByteArray(msg);
    812     int msgSerializedSize = msg.getSerializedSize();
    813     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
    814     assertTrue(msgSerializedSize == 6);
    815     assertEquals(result.length, msgSerializedSize);
    816     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
    817     assertEquals(1, newMsg.repeatedInt64.length);
    818     assertEquals(123, newMsg.repeatedInt64[0]);
    819 
    820     // Test 2 entries
    821     msg.clear()
    822        .repeatedInt64 = new long[] { 123, 456 };
    823     assertEquals(2, msg.repeatedInt64.length);
    824     result = MessageNano.toByteArray(msg);
    825     msgSerializedSize = msg.getSerializedSize();
    826     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
    827     assertTrue(msgSerializedSize == 10);
    828     assertEquals(result.length, msgSerializedSize);
    829 
    830     newMsg = TestAllTypesNano.parseFrom(result);
    831     assertEquals(2, newMsg.repeatedInt64.length);
    832     assertEquals(123, newMsg.repeatedInt64[0]);
    833     assertEquals(456, newMsg.repeatedInt64[1]);
    834   }
    835 
    836   public void testNanoRepeatedUint32() throws Exception {
    837     TestAllTypesNano msg = new TestAllTypesNano();
    838     assertEquals(0, msg.repeatedUint32.length);
    839     msg.repeatedUint32 = new int[] { 123, 789, 456 };
    840     assertEquals(789, msg.repeatedUint32[1]);
    841     assertEquals(456, msg.repeatedUint32[2]);
    842     msg.clear();
    843     assertEquals(0, msg.repeatedUint32.length);
    844     msg.clear()
    845        .repeatedUint32 = new int[] { 456 };
    846     assertEquals(1, msg.repeatedUint32.length);
    847     assertEquals(456, msg.repeatedUint32[0]);
    848     msg.clear();
    849     assertEquals(0, msg.repeatedUint32.length);
    850 
    851     // Test 1 entry
    852     msg.clear()
    853        .repeatedUint32 = new int[] { 123 };
    854     assertEquals(1, msg.repeatedUint32.length);
    855     byte [] result = MessageNano.toByteArray(msg);
    856     int msgSerializedSize = msg.getSerializedSize();
    857     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
    858     assertTrue(msgSerializedSize == 6);
    859     assertEquals(result.length, msgSerializedSize);
    860     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
    861     assertEquals(1, newMsg.repeatedUint32.length);
    862     assertEquals(123, newMsg.repeatedUint32[0]);
    863 
    864     // Test 2 entries
    865     msg.clear()
    866        .repeatedUint32 = new int[] { 123, 456 };
    867     assertEquals(2, msg.repeatedUint32.length);
    868     result = MessageNano.toByteArray(msg);
    869     msgSerializedSize = msg.getSerializedSize();
    870     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
    871     assertTrue(msgSerializedSize == 10);
    872     assertEquals(result.length, msgSerializedSize);
    873 
    874     newMsg = TestAllTypesNano.parseFrom(result);
    875     assertEquals(2, newMsg.repeatedUint32.length);
    876     assertEquals(123, newMsg.repeatedUint32[0]);
    877     assertEquals(456, newMsg.repeatedUint32[1]);
    878   }
    879 
    880   public void testNanoRepeatedUint64() throws Exception {
    881     TestAllTypesNano msg = new TestAllTypesNano();
    882     assertEquals(0, msg.repeatedUint64.length);
    883     msg.repeatedUint64 = new long[] { 123, 789, 456 };
    884     assertEquals(789, msg.repeatedUint64[1]);
    885     assertEquals(456, msg.repeatedUint64[2]);
    886     msg.clear();
    887     assertEquals(0, msg.repeatedUint64.length);
    888     msg.clear()
    889        .repeatedUint64 = new long[] { 456 };
    890     assertEquals(1, msg.repeatedUint64.length);
    891     assertEquals(456, msg.repeatedUint64[0]);
    892     msg.clear();
    893     assertEquals(0, msg.repeatedUint64.length);
    894 
    895     // Test 1 entry
    896     msg.clear()
    897        .repeatedUint64 = new long[] { 123 };
    898     assertEquals(1, msg.repeatedUint64.length);
    899     byte [] result = MessageNano.toByteArray(msg);
    900     int msgSerializedSize = msg.getSerializedSize();
    901     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
    902     assertTrue(msgSerializedSize == 6);
    903     assertEquals(result.length, msgSerializedSize);
    904     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
    905     assertEquals(1, newMsg.repeatedUint64.length);
    906     assertEquals(123, newMsg.repeatedUint64[0]);
    907 
    908     // Test 2 entries
    909     msg.clear()
    910        .repeatedUint64 = new long[] { 123, 456 };
    911     assertEquals(2, msg.repeatedUint64.length);
    912     result = MessageNano.toByteArray(msg);
    913     msgSerializedSize = msg.getSerializedSize();
    914     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
    915     assertTrue(msgSerializedSize == 10);
    916     assertEquals(result.length, msgSerializedSize);
    917 
    918     newMsg = TestAllTypesNano.parseFrom(result);
    919     assertEquals(2, newMsg.repeatedUint64.length);
    920     assertEquals(123, newMsg.repeatedUint64[0]);
    921     assertEquals(456, newMsg.repeatedUint64[1]);
    922   }
    923 
    924   public void testNanoRepeatedSint32() throws Exception {
    925     TestAllTypesNano msg = new TestAllTypesNano();
    926     assertEquals(0, msg.repeatedSint32.length);
    927     msg.repeatedSint32 = new int[] { 123, 789, 456 };
    928     assertEquals(789, msg.repeatedSint32[1]);
    929     assertEquals(456, msg.repeatedSint32[2]);
    930     msg.clear();
    931     assertEquals(0, msg.repeatedSint32.length);
    932     msg.clear()
    933        .repeatedSint32 = new int[] { 456 };
    934     assertEquals(1, msg.repeatedSint32.length);
    935     assertEquals(456, msg.repeatedSint32[0]);
    936     msg.clear();
    937     assertEquals(0, msg.repeatedSint32.length);
    938 
    939     // Test 1 entry
    940     msg.clear()
    941        .repeatedSint32 = new int[] { 123 };
    942     assertEquals(1, msg.repeatedSint32.length);
    943     byte [] result = MessageNano.toByteArray(msg);
    944     int msgSerializedSize = msg.getSerializedSize();
    945     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
    946     assertTrue(msgSerializedSize == 7);
    947     assertEquals(result.length, msgSerializedSize);
    948     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
    949     assertEquals(1, newMsg.repeatedSint32.length);
    950     assertEquals(123, newMsg.repeatedSint32[0]);
    951 
    952     // Test 2 entries
    953     msg.clear()
    954        .repeatedSint32 = new int[] { 123, 456 };
    955     assertEquals(2, msg.repeatedSint32.length);
    956     result = MessageNano.toByteArray(msg);
    957     msgSerializedSize = msg.getSerializedSize();
    958     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
    959     assertTrue(msgSerializedSize == 11);
    960     assertEquals(result.length, msgSerializedSize);
    961 
    962     newMsg = TestAllTypesNano.parseFrom(result);
    963     assertEquals(2, newMsg.repeatedSint32.length);
    964     assertEquals(123, newMsg.repeatedSint32[0]);
    965     assertEquals(456, newMsg.repeatedSint32[1]);
    966   }
    967 
    968   public void testNanoRepeatedSint64() throws Exception {
    969     TestAllTypesNano msg = new TestAllTypesNano();
    970     assertEquals(0, msg.repeatedSint64.length);
    971     msg.repeatedSint64 = new long[] { 123, 789, 456 };
    972     assertEquals(789, msg.repeatedSint64[1]);
    973     assertEquals(456, msg.repeatedSint64[2]);
    974     msg.clear();
    975     assertEquals(0, msg.repeatedSint64.length);
    976     msg.clear()
    977        .repeatedSint64 = new long[] { 456 };
    978     assertEquals(1, msg.repeatedSint64.length);
    979     assertEquals(456, msg.repeatedSint64[0]);
    980     msg.clear();
    981     assertEquals(0, msg.repeatedSint64.length);
    982 
    983     // Test 1 entry
    984     msg.clear()
    985        .repeatedSint64 = new long[] { 123 };
    986     assertEquals(1, msg.repeatedSint64.length);
    987     byte [] result = MessageNano.toByteArray(msg);
    988     int msgSerializedSize = msg.getSerializedSize();
    989     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
    990     assertTrue(msgSerializedSize == 7);
    991     assertEquals(result.length, msgSerializedSize);
    992     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
    993     assertEquals(1, newMsg.repeatedSint64.length);
    994     assertEquals(123, newMsg.repeatedSint64[0]);
    995 
    996     // Test 2 entries
    997     msg.clear()
    998        .repeatedSint64 = new long[] { 123, 456 };
    999     assertEquals(2, msg.repeatedSint64.length);
   1000     result = MessageNano.toByteArray(msg);
   1001     msgSerializedSize = msg.getSerializedSize();
   1002     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
   1003     assertTrue(msgSerializedSize == 11);
   1004     assertEquals(result.length, msgSerializedSize);
   1005 
   1006     newMsg = TestAllTypesNano.parseFrom(result);
   1007     assertEquals(2, newMsg.repeatedSint64.length);
   1008     assertEquals(123, newMsg.repeatedSint64[0]);
   1009     assertEquals(456, newMsg.repeatedSint64[1]);
   1010   }
   1011 
   1012   public void testNanoRepeatedFixed32() throws Exception {
   1013     TestAllTypesNano msg = new TestAllTypesNano();
   1014     assertEquals(0, msg.repeatedFixed32.length);
   1015     msg.repeatedFixed32 = new int[] { 123, 789, 456 };
   1016     assertEquals(789, msg.repeatedFixed32[1]);
   1017     assertEquals(456, msg.repeatedFixed32[2]);
   1018     msg.clear();
   1019     assertEquals(0, msg.repeatedFixed32.length);
   1020     msg.clear()
   1021        .repeatedFixed32 = new int[] { 456 };
   1022     assertEquals(1, msg.repeatedFixed32.length);
   1023     assertEquals(456, msg.repeatedFixed32[0]);
   1024     msg.clear();
   1025     assertEquals(0, msg.repeatedFixed32.length);
   1026 
   1027     // Test 1 entry
   1028     msg.clear()
   1029        .repeatedFixed32 = new int[] { 123 };
   1030     assertEquals(1, msg.repeatedFixed32.length);
   1031     byte [] result = MessageNano.toByteArray(msg);
   1032     int msgSerializedSize = msg.getSerializedSize();
   1033     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
   1034     assertTrue(msgSerializedSize == 9);
   1035     assertEquals(result.length, msgSerializedSize);
   1036     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
   1037     assertEquals(1, newMsg.repeatedFixed32.length);
   1038     assertEquals(123, newMsg.repeatedFixed32[0]);
   1039 
   1040     // Test 2 entries
   1041     msg.clear()
   1042        .repeatedFixed32 = new int[] { 123, 456 };
   1043     assertEquals(2, msg.repeatedFixed32.length);
   1044     result = MessageNano.toByteArray(msg);
   1045     msgSerializedSize = msg.getSerializedSize();
   1046     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
   1047     assertTrue(msgSerializedSize == 15);
   1048     assertEquals(result.length, msgSerializedSize);
   1049 
   1050     newMsg = TestAllTypesNano.parseFrom(result);
   1051     assertEquals(2, newMsg.repeatedFixed32.length);
   1052     assertEquals(123, newMsg.repeatedFixed32[0]);
   1053     assertEquals(456, newMsg.repeatedFixed32[1]);
   1054   }
   1055 
   1056   public void testNanoRepeatedFixed64() throws Exception {
   1057     TestAllTypesNano msg = new TestAllTypesNano();
   1058     assertEquals(0, msg.repeatedFixed64.length);
   1059     msg.repeatedFixed64 = new long[] { 123, 789, 456 };
   1060     assertEquals(789, msg.repeatedFixed64[1]);
   1061     assertEquals(456, msg.repeatedFixed64[2]);
   1062     msg.clear();
   1063     assertEquals(0, msg.repeatedFixed64.length);
   1064     msg.clear()
   1065        .repeatedFixed64 = new long[] { 456 };
   1066     assertEquals(1, msg.repeatedFixed64.length);
   1067     assertEquals(456, msg.repeatedFixed64[0]);
   1068     msg.clear();
   1069     assertEquals(0, msg.repeatedFixed64.length);
   1070 
   1071     // Test 1 entry
   1072     msg.clear()
   1073        .repeatedFixed64 = new long[] { 123 };
   1074     assertEquals(1, msg.repeatedFixed64.length);
   1075     byte [] result = MessageNano.toByteArray(msg);
   1076     int msgSerializedSize = msg.getSerializedSize();
   1077     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
   1078     assertTrue(msgSerializedSize == 13);
   1079     assertEquals(result.length, msgSerializedSize);
   1080     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
   1081     assertEquals(1, newMsg.repeatedFixed64.length);
   1082     assertEquals(123, newMsg.repeatedFixed64[0]);
   1083 
   1084     // Test 2 entries
   1085     msg.clear()
   1086        .repeatedFixed64 = new long[] { 123, 456 };
   1087     assertEquals(2, msg.repeatedFixed64.length);
   1088     result = MessageNano.toByteArray(msg);
   1089     msgSerializedSize = msg.getSerializedSize();
   1090     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
   1091     assertTrue(msgSerializedSize == 23);
   1092     assertEquals(result.length, msgSerializedSize);
   1093 
   1094     newMsg = TestAllTypesNano.parseFrom(result);
   1095     assertEquals(2, newMsg.repeatedFixed64.length);
   1096     assertEquals(123, newMsg.repeatedFixed64[0]);
   1097     assertEquals(456, newMsg.repeatedFixed64[1]);
   1098   }
   1099 
   1100   public void testNanoRepeatedSfixed32() throws Exception {
   1101     TestAllTypesNano msg = new TestAllTypesNano();
   1102     assertEquals(0, msg.repeatedSfixed32.length);
   1103     msg.repeatedSfixed32 = new int[] { 123, 789, 456 };
   1104     assertEquals(789, msg.repeatedSfixed32[1]);
   1105     assertEquals(456, msg.repeatedSfixed32[2]);
   1106     msg.clear();
   1107     assertEquals(0, msg.repeatedSfixed32.length);
   1108     msg.clear()
   1109        .repeatedSfixed32 = new int[] { 456 };
   1110     assertEquals(1, msg.repeatedSfixed32.length);
   1111     assertEquals(456, msg.repeatedSfixed32[0]);
   1112     msg.clear();
   1113     assertEquals(0, msg.repeatedSfixed32.length);
   1114 
   1115     // Test 1 entry
   1116     msg.clear()
   1117        .repeatedSfixed32 = new int[] { 123 };
   1118     assertEquals(1, msg.repeatedSfixed32.length);
   1119     byte [] result = MessageNano.toByteArray(msg);
   1120     int msgSerializedSize = msg.getSerializedSize();
   1121     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
   1122     assertTrue(msgSerializedSize == 9);
   1123     assertEquals(result.length, msgSerializedSize);
   1124     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
   1125     assertEquals(1, newMsg.repeatedSfixed32.length);
   1126     assertEquals(123, newMsg.repeatedSfixed32[0]);
   1127 
   1128     // Test 2 entries
   1129     msg.clear()
   1130        .repeatedSfixed32 = new int[] { 123, 456 };
   1131     assertEquals(2, msg.repeatedSfixed32.length);
   1132     result = MessageNano.toByteArray(msg);
   1133     msgSerializedSize = msg.getSerializedSize();
   1134     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
   1135     assertTrue(msgSerializedSize == 15);
   1136     assertEquals(result.length, msgSerializedSize);
   1137 
   1138     newMsg = TestAllTypesNano.parseFrom(result);
   1139     assertEquals(2, newMsg.repeatedSfixed32.length);
   1140     assertEquals(123, newMsg.repeatedSfixed32[0]);
   1141     assertEquals(456, newMsg.repeatedSfixed32[1]);
   1142   }
   1143 
   1144   public void testNanoRepeatedSfixed64() throws Exception {
   1145     TestAllTypesNano msg = new TestAllTypesNano();
   1146     assertEquals(0, msg.repeatedSfixed64.length);
   1147     msg.repeatedSfixed64 = new long[] { 123, 789, 456 };
   1148     assertEquals(789, msg.repeatedSfixed64[1]);
   1149     assertEquals(456, msg.repeatedSfixed64[2]);
   1150     msg.clear();
   1151     assertEquals(0, msg.repeatedSfixed64.length);
   1152     msg.clear()
   1153        .repeatedSfixed64 = new long[] { 456 };
   1154     assertEquals(1, msg.repeatedSfixed64.length);
   1155     assertEquals(456, msg.repeatedSfixed64[0]);
   1156     msg.clear();
   1157     assertEquals(0, msg.repeatedSfixed64.length);
   1158 
   1159     // Test 1 entry
   1160     msg.clear()
   1161        .repeatedSfixed64 = new long[] { 123 };
   1162     assertEquals(1, msg.repeatedSfixed64.length);
   1163     byte [] result = MessageNano.toByteArray(msg);
   1164     int msgSerializedSize = msg.getSerializedSize();
   1165     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
   1166     assertTrue(msgSerializedSize == 13);
   1167     assertEquals(result.length, msgSerializedSize);
   1168     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
   1169     assertEquals(1, newMsg.repeatedSfixed64.length);
   1170     assertEquals(123, newMsg.repeatedSfixed64[0]);
   1171 
   1172     // Test 2 entries
   1173     msg.clear()
   1174        .repeatedSfixed64 = new long[] { 123, 456 };
   1175     assertEquals(2, msg.repeatedSfixed64.length);
   1176     result = MessageNano.toByteArray(msg);
   1177     msgSerializedSize = msg.getSerializedSize();
   1178     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
   1179     assertTrue(msgSerializedSize == 23);
   1180     assertEquals(result.length, msgSerializedSize);
   1181 
   1182     newMsg = TestAllTypesNano.parseFrom(result);
   1183     assertEquals(2, newMsg.repeatedSfixed64.length);
   1184     assertEquals(123, newMsg.repeatedSfixed64[0]);
   1185     assertEquals(456, newMsg.repeatedSfixed64[1]);
   1186   }
   1187 
   1188   public void testNanoRepeatedFloat() throws Exception {
   1189     TestAllTypesNano msg = new TestAllTypesNano();
   1190     assertEquals(0, msg.repeatedFloat.length);
   1191     msg.repeatedFloat = new float[] { 123f, 789f, 456f };
   1192     assertEquals(789f, msg.repeatedFloat[1]);
   1193     assertEquals(456f, msg.repeatedFloat[2]);
   1194     msg.clear();
   1195     assertEquals(0, msg.repeatedFloat.length);
   1196     msg.clear()
   1197        .repeatedFloat = new float[] { 456f };
   1198     assertEquals(1, msg.repeatedFloat.length);
   1199     assertEquals(456f, msg.repeatedFloat[0]);
   1200     msg.clear();
   1201     assertEquals(0, msg.repeatedFloat.length);
   1202 
   1203     // Test 1 entry
   1204     msg.clear()
   1205        .repeatedFloat = new float[] { 123f };
   1206     assertEquals(1, msg.repeatedFloat.length);
   1207     byte [] result = MessageNano.toByteArray(msg);
   1208     int msgSerializedSize = msg.getSerializedSize();
   1209     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
   1210     assertTrue(msgSerializedSize == 9);
   1211     assertEquals(result.length, msgSerializedSize);
   1212     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
   1213     assertEquals(1, newMsg.repeatedFloat.length);
   1214     assertEquals(123f, newMsg.repeatedFloat[0]);
   1215 
   1216     // Test 2 entries
   1217     msg.clear()
   1218        .repeatedFloat = new float[] { 123f, 456f };
   1219     assertEquals(2, msg.repeatedFloat.length);
   1220     result = MessageNano.toByteArray(msg);
   1221     msgSerializedSize = msg.getSerializedSize();
   1222     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
   1223     assertTrue(msgSerializedSize == 15);
   1224     assertEquals(result.length, msgSerializedSize);
   1225 
   1226     newMsg = TestAllTypesNano.parseFrom(result);
   1227     assertEquals(2, newMsg.repeatedFloat.length);
   1228     assertEquals(123f, newMsg.repeatedFloat[0]);
   1229     assertEquals(456f, newMsg.repeatedFloat[1]);
   1230   }
   1231 
   1232   public void testNanoRepeatedDouble() throws Exception {
   1233     TestAllTypesNano msg = new TestAllTypesNano();
   1234     assertEquals(0, msg.repeatedDouble.length);
   1235     msg.repeatedDouble = new double[] { 123.0, 789.0, 456.0 };
   1236     assertEquals(789.0, msg.repeatedDouble[1]);
   1237     assertEquals(456.0, msg.repeatedDouble[2]);
   1238     msg.clear();
   1239     assertEquals(0, msg.repeatedDouble.length);
   1240     msg.clear()
   1241        .repeatedDouble = new double[] { 456.0 };
   1242     assertEquals(1, msg.repeatedDouble.length);
   1243     assertEquals(456.0, msg.repeatedDouble[0]);
   1244     msg.clear();
   1245     assertEquals(0, msg.repeatedDouble.length);
   1246 
   1247     // Test 1 entry
   1248     msg.clear()
   1249        .repeatedDouble = new double[] { 123.0 };
   1250     assertEquals(1, msg.repeatedDouble.length);
   1251     byte [] result = MessageNano.toByteArray(msg);
   1252     int msgSerializedSize = msg.getSerializedSize();
   1253     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
   1254     assertTrue(msgSerializedSize == 13);
   1255     assertEquals(result.length, msgSerializedSize);
   1256     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
   1257     assertEquals(1, newMsg.repeatedDouble.length);
   1258     assertEquals(123.0, newMsg.repeatedDouble[0]);
   1259 
   1260     // Test 2 entries
   1261     msg.clear()
   1262        .repeatedDouble = new double[] { 123.0, 456.0 };
   1263     assertEquals(2, msg.repeatedDouble.length);
   1264     result = MessageNano.toByteArray(msg);
   1265     msgSerializedSize = msg.getSerializedSize();
   1266     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
   1267     assertTrue(msgSerializedSize == 23);
   1268     assertEquals(result.length, msgSerializedSize);
   1269 
   1270     newMsg = TestAllTypesNano.parseFrom(result);
   1271     assertEquals(2, newMsg.repeatedDouble.length);
   1272     assertEquals(123.0, newMsg.repeatedDouble[0]);
   1273     assertEquals(456.0, newMsg.repeatedDouble[1]);
   1274   }
   1275 
   1276   public void testNanoRepeatedBool() throws Exception {
   1277     TestAllTypesNano msg = new TestAllTypesNano();
   1278     assertEquals(0, msg.repeatedBool.length);
   1279     msg.repeatedBool = new boolean[] { false, true, false };
   1280     assertTrue(msg.repeatedBool[1]);
   1281     assertFalse(msg.repeatedBool[2]);
   1282     msg.clear();
   1283     assertEquals(0, msg.repeatedBool.length);
   1284     msg.clear()
   1285        .repeatedBool = new boolean[] { true };
   1286     assertEquals(1, msg.repeatedBool.length);
   1287     assertTrue(msg.repeatedBool[0]);
   1288     msg.clear();
   1289     assertEquals(0, msg.repeatedBool.length);
   1290 
   1291     // Test 1 entry
   1292     msg.clear()
   1293        .repeatedBool = new boolean[] { false };
   1294     assertEquals(1, msg.repeatedBool.length);
   1295     byte [] result = MessageNano.toByteArray(msg);
   1296     int msgSerializedSize = msg.getSerializedSize();
   1297     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
   1298     assertTrue(msgSerializedSize == 6);
   1299     assertEquals(result.length, msgSerializedSize);
   1300     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
   1301     assertEquals(1, newMsg.repeatedBool.length);
   1302     assertFalse(newMsg.repeatedBool[0]);
   1303 
   1304     // Test 2 entries
   1305     msg.clear()
   1306        .repeatedBool = new boolean[] { true, false };
   1307     assertEquals(2, msg.repeatedBool.length);
   1308     result = MessageNano.toByteArray(msg);
   1309     msgSerializedSize = msg.getSerializedSize();
   1310     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
   1311     assertTrue(msgSerializedSize == 9);
   1312     assertEquals(result.length, msgSerializedSize);
   1313 
   1314     newMsg = TestAllTypesNano.parseFrom(result);
   1315     assertEquals(2, newMsg.repeatedBool.length);
   1316     assertTrue(newMsg.repeatedBool[0]);
   1317     assertFalse(newMsg.repeatedBool[1]);
   1318   }
   1319 
   1320   public void testNanoRepeatedString() throws Exception {
   1321     TestAllTypesNano msg = new TestAllTypesNano();
   1322     assertEquals(0, msg.repeatedString.length);
   1323     msg.repeatedString = new String[] { "hello", "bye", "boo" };
   1324     assertEquals("bye", msg.repeatedString[1]);
   1325     assertEquals("boo", msg.repeatedString[2]);
   1326     msg.clear();
   1327     assertEquals(0, msg.repeatedString.length);
   1328     msg.clear()
   1329        .repeatedString = new String[] { "boo" };
   1330     assertEquals(1, msg.repeatedString.length);
   1331     assertEquals("boo", msg.repeatedString[0]);
   1332     msg.clear();
   1333     assertEquals(0, msg.repeatedString.length);
   1334 
   1335     // Test 1 entry
   1336     msg.clear()
   1337        .repeatedString = new String[] { "" };
   1338     assertEquals(1, msg.repeatedString.length);
   1339     byte [] result = MessageNano.toByteArray(msg);
   1340     int msgSerializedSize = msg.getSerializedSize();
   1341     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
   1342     assertTrue(msgSerializedSize == 6);
   1343     assertEquals(result.length, msgSerializedSize);
   1344     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
   1345     assertEquals(1, newMsg.repeatedString.length);
   1346     assertTrue(newMsg.repeatedString[0].isEmpty());
   1347 
   1348     // Test 2 entries
   1349     msg.clear()
   1350        .repeatedString = new String[] { "hello", "world" };
   1351     assertEquals(2, msg.repeatedString.length);
   1352     result = MessageNano.toByteArray(msg);
   1353     msgSerializedSize = msg.getSerializedSize();
   1354     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
   1355     assertTrue(msgSerializedSize == 19);
   1356     assertEquals(result.length, msgSerializedSize);
   1357 
   1358     newMsg = TestAllTypesNano.parseFrom(result);
   1359     assertEquals(2, newMsg.repeatedString.length);
   1360     assertEquals("hello", newMsg.repeatedString[0]);
   1361     assertEquals("world", newMsg.repeatedString[1]);
   1362   }
   1363 
   1364   public void testNanoRepeatedBytes() throws Exception {
   1365     TestAllTypesNano msg = new TestAllTypesNano();
   1366     assertEquals(0, msg.repeatedBytes.length);
   1367     msg.repeatedBytes = new byte[][] {
   1368         InternalNano.copyFromUtf8("hello"),
   1369         InternalNano.copyFromUtf8("bye"),
   1370         InternalNano.copyFromUtf8("boo")
   1371     };
   1372     assertEquals("bye", new String(msg.repeatedBytes[1], "UTF-8"));
   1373     assertEquals("boo", new String(msg.repeatedBytes[2], "UTF-8"));
   1374     msg.clear();
   1375     assertEquals(0, msg.repeatedBytes.length);
   1376     msg.clear()
   1377        .repeatedBytes = new byte[][] { InternalNano.copyFromUtf8("boo") };
   1378     assertEquals(1, msg.repeatedBytes.length);
   1379     assertEquals("boo", new String(msg.repeatedBytes[0], "UTF-8"));
   1380     msg.clear();
   1381     assertEquals(0, msg.repeatedBytes.length);
   1382 
   1383     // Test 1 entry
   1384     msg.clear()
   1385        .repeatedBytes = new byte[][] { InternalNano.copyFromUtf8("") };
   1386     assertEquals(1, msg.repeatedBytes.length);
   1387     byte [] result = MessageNano.toByteArray(msg);
   1388     int msgSerializedSize = msg.getSerializedSize();
   1389     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
   1390     assertTrue(msgSerializedSize == 6);
   1391     assertEquals(result.length, msgSerializedSize);
   1392     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
   1393     assertEquals(1, newMsg.repeatedBytes.length);
   1394     assertTrue(newMsg.repeatedBytes[0].length == 0);
   1395 
   1396     // Test 2 entries
   1397     msg.clear()
   1398        .repeatedBytes = new byte[][] {
   1399       InternalNano.copyFromUtf8("hello"),
   1400       InternalNano.copyFromUtf8("world")
   1401     };
   1402     assertEquals(2, msg.repeatedBytes.length);
   1403     result = MessageNano.toByteArray(msg);
   1404     msgSerializedSize = msg.getSerializedSize();
   1405     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
   1406     assertTrue(msgSerializedSize == 19);
   1407     assertEquals(result.length, msgSerializedSize);
   1408 
   1409     newMsg = TestAllTypesNano.parseFrom(result);
   1410     assertEquals(2, newMsg.repeatedBytes.length);
   1411     assertEquals("hello", new String(newMsg.repeatedBytes[0], "UTF-8"));
   1412     assertEquals("world", new String(newMsg.repeatedBytes[1], "UTF-8"));
   1413   }
   1414 
   1415   public void testNanoRepeatedGroup() throws Exception {
   1416     TestAllTypesNano msg = new TestAllTypesNano();
   1417     TestAllTypesNano.RepeatedGroup group0 =
   1418       new TestAllTypesNano.RepeatedGroup();
   1419     group0.a = 0;
   1420     TestAllTypesNano.RepeatedGroup group1 =
   1421       new TestAllTypesNano.RepeatedGroup();
   1422     group1.a = 1;
   1423     TestAllTypesNano.RepeatedGroup group2 =
   1424       new TestAllTypesNano.RepeatedGroup();
   1425     group2.a = 2;
   1426 
   1427     msg.repeatedGroup = new TestAllTypesNano.RepeatedGroup[] { group0, group1, group2 };
   1428     assertEquals(3, msg.repeatedGroup.length);
   1429     assertEquals(0, msg.repeatedGroup[0].a);
   1430     assertEquals(1, msg.repeatedGroup[1].a);
   1431     assertEquals(2, msg.repeatedGroup[2].a);
   1432     msg.clear();
   1433     assertEquals(0, msg.repeatedGroup.length);
   1434     msg.clear()
   1435        .repeatedGroup = new TestAllTypesNano.RepeatedGroup[] { group1 };
   1436     assertEquals(1, msg.repeatedGroup.length);
   1437     assertEquals(1, msg.repeatedGroup[0].a);
   1438     msg.clear();
   1439     assertEquals(0, msg.repeatedGroup.length);
   1440 
   1441     // Test 1 entry
   1442     msg.clear()
   1443        .repeatedGroup = new TestAllTypesNano.RepeatedGroup[] { group0 };
   1444     assertEquals(1, msg.repeatedGroup.length);
   1445     byte [] result = MessageNano.toByteArray(msg);
   1446     int msgSerializedSize = msg.getSerializedSize();
   1447     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
   1448     assertTrue(msgSerializedSize == 7);
   1449     assertEquals(result.length, msgSerializedSize);
   1450     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
   1451     assertEquals(1, newMsg.repeatedGroup.length);
   1452     assertEquals(0, newMsg.repeatedGroup[0].a);
   1453 
   1454     // Test 2 entries
   1455     msg.clear()
   1456        .repeatedGroup = new TestAllTypesNano.RepeatedGroup[] { group0, group1 };
   1457     assertEquals(2, msg.repeatedGroup.length);
   1458     result = MessageNano.toByteArray(msg);
   1459     msgSerializedSize = msg.getSerializedSize();
   1460     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
   1461     assertTrue(msgSerializedSize == 14);
   1462     assertEquals(result.length, msgSerializedSize);
   1463 
   1464     newMsg = TestAllTypesNano.parseFrom(result);
   1465     assertEquals(2, newMsg.repeatedGroup.length);
   1466     assertEquals(0, newMsg.repeatedGroup[0].a);
   1467     assertEquals(1, newMsg.repeatedGroup[1].a);
   1468   }
   1469 
   1470   public void testNanoRepeatedNestedMessage() throws Exception {
   1471     TestAllTypesNano msg = new TestAllTypesNano();
   1472     TestAllTypesNano.NestedMessage nestedMsg0 =
   1473       new TestAllTypesNano.NestedMessage();
   1474     nestedMsg0.bb = 0;
   1475     TestAllTypesNano.NestedMessage nestedMsg1 =
   1476       new TestAllTypesNano.NestedMessage();
   1477     nestedMsg1.bb = 1;
   1478     TestAllTypesNano.NestedMessage nestedMsg2 =
   1479       new TestAllTypesNano.NestedMessage();
   1480     nestedMsg2.bb = 2;
   1481 
   1482     msg.repeatedNestedMessage =
   1483         new TestAllTypesNano.NestedMessage[] { nestedMsg0, nestedMsg1, nestedMsg2 };
   1484     assertEquals(3, msg.repeatedNestedMessage.length);
   1485     assertEquals(0, msg.repeatedNestedMessage[0].bb);
   1486     assertEquals(1, msg.repeatedNestedMessage[1].bb);
   1487     assertEquals(2, msg.repeatedNestedMessage[2].bb);
   1488     msg.clear();
   1489     assertEquals(0, msg.repeatedNestedMessage.length);
   1490     msg.clear()
   1491        .repeatedNestedMessage = new TestAllTypesNano.NestedMessage[] { nestedMsg1 };
   1492     assertEquals(1, msg.repeatedNestedMessage.length);
   1493     assertEquals(1, msg.repeatedNestedMessage[0].bb);
   1494     msg.clear();
   1495     assertEquals(0, msg.repeatedNestedMessage.length);
   1496 
   1497     // Test 1 entry
   1498     msg.clear()
   1499        .repeatedNestedMessage = new TestAllTypesNano.NestedMessage[] { nestedMsg0 };
   1500     assertEquals(1, msg.repeatedNestedMessage.length);
   1501     byte [] result = MessageNano.toByteArray(msg);
   1502     int msgSerializedSize = msg.getSerializedSize();
   1503     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
   1504     assertTrue(msgSerializedSize == 6);
   1505     assertEquals(result.length, msgSerializedSize);
   1506     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
   1507     assertEquals(1, newMsg.repeatedNestedMessage.length);
   1508     assertEquals(0, newMsg.repeatedNestedMessage[0].bb);
   1509 
   1510     // Test 2 entries
   1511     msg.clear()
   1512        .repeatedNestedMessage = new TestAllTypesNano.NestedMessage[] { nestedMsg0, nestedMsg1 };
   1513     assertEquals(2, msg.repeatedNestedMessage.length);
   1514     result = MessageNano.toByteArray(msg);
   1515     msgSerializedSize = msg.getSerializedSize();
   1516     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
   1517     assertTrue(msgSerializedSize == 11);
   1518     assertEquals(result.length, msgSerializedSize);
   1519 
   1520     newMsg = TestAllTypesNano.parseFrom(result);
   1521     assertEquals(2, newMsg.repeatedNestedMessage.length);
   1522     assertEquals(0, newMsg.repeatedNestedMessage[0].bb);
   1523     assertEquals(1, newMsg.repeatedNestedMessage[1].bb);
   1524   }
   1525 
   1526   public void testNanoRepeatedForeignMessage() throws Exception {
   1527     TestAllTypesNano msg = new TestAllTypesNano();
   1528     NanoOuterClass.ForeignMessageNano foreignMsg0 =
   1529       new NanoOuterClass.ForeignMessageNano();
   1530     foreignMsg0.c = 0;
   1531     NanoOuterClass.ForeignMessageNano foreignMsg1 =
   1532       new NanoOuterClass.ForeignMessageNano();
   1533     foreignMsg1.c = 1;
   1534     NanoOuterClass.ForeignMessageNano foreignMsg2 =
   1535       new NanoOuterClass.ForeignMessageNano();
   1536     foreignMsg2.c = 2;
   1537 
   1538     msg.repeatedForeignMessage =
   1539         new NanoOuterClass.ForeignMessageNano[] { foreignMsg0, foreignMsg1, foreignMsg2 };
   1540     assertEquals(3, msg.repeatedForeignMessage.length);
   1541     assertEquals(0, msg.repeatedForeignMessage[0].c);
   1542     assertEquals(1, msg.repeatedForeignMessage[1].c);
   1543     assertEquals(2, msg.repeatedForeignMessage[2].c);
   1544     msg.clear();
   1545     assertEquals(0, msg.repeatedForeignMessage.length);
   1546     msg.clear()
   1547        .repeatedForeignMessage = new NanoOuterClass.ForeignMessageNano[] { foreignMsg1 };
   1548     assertEquals(1, msg.repeatedForeignMessage.length);
   1549     assertEquals(1, msg.repeatedForeignMessage[0].c);
   1550     msg.clear();
   1551     assertEquals(0, msg.repeatedForeignMessage.length);
   1552 
   1553     // Test 1 entry
   1554     msg.clear()
   1555        .repeatedForeignMessage = new NanoOuterClass.ForeignMessageNano[] { foreignMsg0 };
   1556     assertEquals(1, msg.repeatedForeignMessage.length);
   1557     byte [] result = MessageNano.toByteArray(msg);
   1558     int msgSerializedSize = msg.getSerializedSize();
   1559     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
   1560     assertTrue(msgSerializedSize == 6);
   1561     assertEquals(result.length, msgSerializedSize);
   1562     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
   1563     assertEquals(1, newMsg.repeatedForeignMessage.length);
   1564     assertEquals(0, newMsg.repeatedForeignMessage[0].c);
   1565 
   1566     // Test 2 entries
   1567     msg.clear()
   1568        .repeatedForeignMessage = new NanoOuterClass.ForeignMessageNano[] { foreignMsg0, foreignMsg1 };
   1569     assertEquals(2, msg.repeatedForeignMessage.length);
   1570     result = MessageNano.toByteArray(msg);
   1571     msgSerializedSize = msg.getSerializedSize();
   1572     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
   1573     assertTrue(msgSerializedSize == 11);
   1574     assertEquals(result.length, msgSerializedSize);
   1575 
   1576     newMsg = TestAllTypesNano.parseFrom(result);
   1577     assertEquals(2, newMsg.repeatedForeignMessage.length);
   1578     assertEquals(0, newMsg.repeatedForeignMessage[0].c);
   1579     assertEquals(1, newMsg.repeatedForeignMessage[1].c);
   1580   }
   1581 
   1582   public void testNanoRepeatedImportMessage() throws Exception {
   1583     TestAllTypesNano msg = new TestAllTypesNano();
   1584     UnittestImportNano.ImportMessageNano foreignMsg0 =
   1585       new UnittestImportNano.ImportMessageNano();
   1586     foreignMsg0.d = 0;
   1587     UnittestImportNano.ImportMessageNano foreignMsg1 =
   1588       new UnittestImportNano.ImportMessageNano();
   1589     foreignMsg1.d = 1;
   1590     UnittestImportNano.ImportMessageNano foreignMsg2 =
   1591       new UnittestImportNano.ImportMessageNano();
   1592     foreignMsg2.d = 2;
   1593 
   1594     msg.repeatedImportMessage =
   1595         new UnittestImportNano.ImportMessageNano[] { foreignMsg0, foreignMsg1, foreignMsg2 };
   1596     assertEquals(3, msg.repeatedImportMessage.length);
   1597     assertEquals(0, msg.repeatedImportMessage[0].d);
   1598     assertEquals(1, msg.repeatedImportMessage[1].d);
   1599     assertEquals(2, msg.repeatedImportMessage[2].d);
   1600     msg.clear();
   1601     assertEquals(0, msg.repeatedImportMessage.length);
   1602     msg.clear()
   1603        .repeatedImportMessage = new UnittestImportNano.ImportMessageNano[] { foreignMsg1 };
   1604     assertEquals(1, msg.repeatedImportMessage.length);
   1605     assertEquals(1, msg.repeatedImportMessage[0].d);
   1606     msg.clear();
   1607     assertEquals(0, msg.repeatedImportMessage.length);
   1608 
   1609     // Test 1 entry
   1610     msg.clear()
   1611        .repeatedImportMessage = new UnittestImportNano.ImportMessageNano[] { foreignMsg0 };
   1612     assertEquals(1, msg.repeatedImportMessage.length);
   1613     byte [] result = MessageNano.toByteArray(msg);
   1614     int msgSerializedSize = msg.getSerializedSize();
   1615     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
   1616     assertTrue(msgSerializedSize == 6);
   1617     assertEquals(result.length, msgSerializedSize);
   1618     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
   1619     assertEquals(1, newMsg.repeatedImportMessage.length);
   1620     assertEquals(0, newMsg.repeatedImportMessage[0].d);
   1621 
   1622     // Test 2 entries
   1623     msg.clear()
   1624        .repeatedImportMessage = new UnittestImportNano.ImportMessageNano[] { foreignMsg0, foreignMsg1 };
   1625     assertEquals(2, msg.repeatedImportMessage.length);
   1626     result = MessageNano.toByteArray(msg);
   1627     msgSerializedSize = msg.getSerializedSize();
   1628     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
   1629     assertTrue(msgSerializedSize == 11);
   1630     assertEquals(result.length, msgSerializedSize);
   1631 
   1632     newMsg = TestAllTypesNano.parseFrom(result);
   1633     assertEquals(2, newMsg.repeatedImportMessage.length);
   1634     assertEquals(0, newMsg.repeatedImportMessage[0].d);
   1635     assertEquals(1, newMsg.repeatedImportMessage[1].d);
   1636   }
   1637 
   1638   public void testNanoRepeatedNestedEnum() throws Exception {
   1639     TestAllTypesNano msg = new TestAllTypesNano();
   1640     msg.repeatedNestedEnum = new int[] {
   1641         TestAllTypesNano.FOO,
   1642         TestAllTypesNano.BAR,
   1643         TestAllTypesNano.BAZ
   1644     };
   1645     assertEquals(3, msg.repeatedNestedEnum.length);
   1646     assertEquals(TestAllTypesNano.FOO, msg.repeatedNestedEnum[0]);
   1647     assertEquals(TestAllTypesNano.BAR, msg.repeatedNestedEnum[1]);
   1648     assertEquals(TestAllTypesNano.BAZ, msg.repeatedNestedEnum[2]);
   1649     msg.clear();
   1650     assertEquals(0, msg.repeatedNestedEnum.length);
   1651     msg.clear()
   1652        .repeatedNestedEnum = new int[] { TestAllTypesNano.BAR };
   1653     assertEquals(1, msg.repeatedNestedEnum.length);
   1654     assertEquals(TestAllTypesNano.BAR, msg.repeatedNestedEnum[0]);
   1655     msg.clear();
   1656     assertEquals(0, msg.repeatedNestedEnum.length);
   1657 
   1658     // Test 1 entry
   1659     msg.clear()
   1660        .repeatedNestedEnum = new int[] { TestAllTypesNano.FOO };
   1661     byte [] result = MessageNano.toByteArray(msg);
   1662     int msgSerializedSize = msg.getSerializedSize();
   1663     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
   1664     assertTrue(msgSerializedSize == 6);
   1665     assertEquals(result.length, msgSerializedSize);
   1666     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
   1667     assertEquals(1, newMsg.repeatedNestedEnum.length);
   1668     assertEquals(TestAllTypesNano.FOO, msg.repeatedNestedEnum[0]);
   1669 
   1670     // Test 2 entries
   1671     msg.clear()
   1672        .repeatedNestedEnum = new int[] { TestAllTypesNano.FOO, TestAllTypesNano.BAR };
   1673     assertEquals(2, msg.repeatedNestedEnum.length);
   1674     result = MessageNano.toByteArray(msg);
   1675     msgSerializedSize = msg.getSerializedSize();
   1676     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
   1677     assertTrue(msgSerializedSize == 9);
   1678     assertEquals(result.length, msgSerializedSize);
   1679 
   1680     newMsg = TestAllTypesNano.parseFrom(result);
   1681     assertEquals(2, newMsg.repeatedNestedEnum.length);
   1682     assertEquals(TestAllTypesNano.FOO, msg.repeatedNestedEnum[0]);
   1683     assertEquals(TestAllTypesNano.BAR, msg.repeatedNestedEnum[1]);
   1684   }
   1685 
   1686   public void testNanoRepeatedForeignEnum() throws Exception {
   1687     TestAllTypesNano msg = new TestAllTypesNano();
   1688     msg.repeatedForeignEnum = new int[] {
   1689         NanoOuterClass.FOREIGN_NANO_FOO,
   1690         NanoOuterClass.FOREIGN_NANO_BAR,
   1691         NanoOuterClass.FOREIGN_NANO_BAZ
   1692     };
   1693     assertEquals(3, msg.repeatedForeignEnum.length);
   1694     assertEquals(NanoOuterClass.FOREIGN_NANO_FOO, msg.repeatedForeignEnum[0]);
   1695     assertEquals(NanoOuterClass.FOREIGN_NANO_BAR, msg.repeatedForeignEnum[1]);
   1696     assertEquals(NanoOuterClass.FOREIGN_NANO_BAZ, msg.repeatedForeignEnum[2]);
   1697     msg.clear();
   1698     assertEquals(0, msg.repeatedForeignEnum.length);
   1699     msg.clear()
   1700        .repeatedForeignEnum = new int[] { NanoOuterClass.FOREIGN_NANO_BAR };
   1701     assertEquals(1, msg.repeatedForeignEnum.length);
   1702     assertEquals(NanoOuterClass.FOREIGN_NANO_BAR, msg.repeatedForeignEnum[0]);
   1703     msg.clear();
   1704     assertEquals(0, msg.repeatedForeignEnum.length);
   1705 
   1706     // Test 1 entry
   1707     msg.clear()
   1708        .repeatedForeignEnum = new int[] { NanoOuterClass.FOREIGN_NANO_FOO };
   1709     byte [] result = MessageNano.toByteArray(msg);
   1710     int msgSerializedSize = msg.getSerializedSize();
   1711     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
   1712     assertTrue(msgSerializedSize == 6);
   1713     assertEquals(result.length, msgSerializedSize);
   1714     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
   1715     assertEquals(1, newMsg.repeatedForeignEnum.length);
   1716     assertEquals(NanoOuterClass.FOREIGN_NANO_FOO, msg.repeatedForeignEnum[0]);
   1717 
   1718     // Test 2 entries
   1719     msg.clear()
   1720        .repeatedForeignEnum = new int[] {
   1721       NanoOuterClass.FOREIGN_NANO_FOO,
   1722       NanoOuterClass.FOREIGN_NANO_BAR
   1723     };
   1724     assertEquals(2, msg.repeatedForeignEnum.length);
   1725     result = MessageNano.toByteArray(msg);
   1726     msgSerializedSize = msg.getSerializedSize();
   1727     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
   1728     assertTrue(msgSerializedSize == 9);
   1729     assertEquals(result.length, msgSerializedSize);
   1730 
   1731     newMsg = TestAllTypesNano.parseFrom(result);
   1732     assertEquals(2, newMsg.repeatedForeignEnum.length);
   1733     assertEquals(NanoOuterClass.FOREIGN_NANO_FOO, msg.repeatedForeignEnum[0]);
   1734     assertEquals(NanoOuterClass.FOREIGN_NANO_BAR, msg.repeatedForeignEnum[1]);
   1735   }
   1736 
   1737   public void testNanoRepeatedImportEnum() throws Exception {
   1738     TestAllTypesNano msg = new TestAllTypesNano();
   1739     msg.repeatedImportEnum = new int[] {
   1740         UnittestImportNano.IMPORT_NANO_FOO,
   1741         UnittestImportNano.IMPORT_NANO_BAR,
   1742         UnittestImportNano.IMPORT_NANO_BAZ
   1743     };
   1744     assertEquals(3, msg.repeatedImportEnum.length);
   1745     assertEquals(UnittestImportNano.IMPORT_NANO_FOO, msg.repeatedImportEnum[0]);
   1746     assertEquals(UnittestImportNano.IMPORT_NANO_BAR, msg.repeatedImportEnum[1]);
   1747     assertEquals(UnittestImportNano.IMPORT_NANO_BAZ, msg.repeatedImportEnum[2]);
   1748     msg.clear();
   1749     assertEquals(0, msg.repeatedImportEnum.length);
   1750     msg.clear()
   1751        .repeatedImportEnum = new int[] { UnittestImportNano.IMPORT_NANO_BAR };
   1752     assertEquals(1, msg.repeatedImportEnum.length);
   1753     assertEquals(UnittestImportNano.IMPORT_NANO_BAR, msg.repeatedImportEnum[0]);
   1754     msg.clear();
   1755     assertEquals(0, msg.repeatedImportEnum.length);
   1756 
   1757     // Test 1 entry
   1758     msg.clear()
   1759        .repeatedImportEnum = new int[] { UnittestImportNano.IMPORT_NANO_FOO };
   1760     byte [] result = MessageNano.toByteArray(msg);
   1761     int msgSerializedSize = msg.getSerializedSize();
   1762     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
   1763     assertTrue(msgSerializedSize == 6);
   1764     assertEquals(result.length, msgSerializedSize);
   1765     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
   1766     assertEquals(1, newMsg.repeatedImportEnum.length);
   1767     assertEquals(UnittestImportNano.IMPORT_NANO_FOO, msg.repeatedImportEnum[0]);
   1768 
   1769     // Test 2 entries
   1770     msg.clear()
   1771        .repeatedImportEnum = new int[] {
   1772       UnittestImportNano.IMPORT_NANO_FOO,
   1773       UnittestImportNano.IMPORT_NANO_BAR
   1774     };
   1775     assertEquals(2, msg.repeatedImportEnum.length);
   1776     result = MessageNano.toByteArray(msg);
   1777     msgSerializedSize = msg.getSerializedSize();
   1778     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
   1779     assertTrue(msgSerializedSize == 9);
   1780     assertEquals(result.length, msgSerializedSize);
   1781 
   1782     newMsg = TestAllTypesNano.parseFrom(result);
   1783     assertEquals(2, newMsg.repeatedImportEnum.length);
   1784     assertEquals(UnittestImportNano.IMPORT_NANO_FOO, msg.repeatedImportEnum[0]);
   1785     assertEquals(UnittestImportNano.IMPORT_NANO_BAR, msg.repeatedImportEnum[1]);
   1786   }
   1787 
   1788   public void testNanoRepeatedStringPiece() throws Exception {
   1789     TestAllTypesNano msg = new TestAllTypesNano();
   1790     assertEquals(0, msg.repeatedStringPiece.length);
   1791     msg.repeatedStringPiece = new String[] { "hello", "bye", "boo" };
   1792     assertEquals("bye", msg.repeatedStringPiece[1]);
   1793     assertEquals("boo", msg.repeatedStringPiece[2]);
   1794     msg.clear();
   1795     assertEquals(0, msg.repeatedStringPiece.length);
   1796     msg.clear()
   1797        .repeatedStringPiece = new String[] { "boo" };
   1798     assertEquals(1, msg.repeatedStringPiece.length);
   1799     assertEquals("boo", msg.repeatedStringPiece[0]);
   1800     msg.clear();
   1801     assertEquals(0, msg.repeatedStringPiece.length);
   1802 
   1803     // Test 1 entry
   1804     msg.clear()
   1805        .repeatedStringPiece = new String[] { "" };
   1806     assertEquals(1, msg.repeatedStringPiece.length);
   1807     byte [] result = MessageNano.toByteArray(msg);
   1808     int msgSerializedSize = msg.getSerializedSize();
   1809     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
   1810     assertTrue(msgSerializedSize == 6);
   1811     assertEquals(result.length, msgSerializedSize);
   1812     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
   1813     assertEquals(1, newMsg.repeatedStringPiece.length);
   1814     assertTrue(newMsg.repeatedStringPiece[0].isEmpty());
   1815 
   1816     // Test 2 entries
   1817     msg.clear()
   1818        .repeatedStringPiece = new String[] { "hello", "world" };
   1819     assertEquals(2, msg.repeatedStringPiece.length);
   1820     result = MessageNano.toByteArray(msg);
   1821     msgSerializedSize = msg.getSerializedSize();
   1822     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
   1823     assertTrue(msgSerializedSize == 19);
   1824     assertEquals(result.length, msgSerializedSize);
   1825 
   1826     newMsg = TestAllTypesNano.parseFrom(result);
   1827     assertEquals(2, newMsg.repeatedStringPiece.length);
   1828     assertEquals("hello", newMsg.repeatedStringPiece[0]);
   1829     assertEquals("world", newMsg.repeatedStringPiece[1]);
   1830   }
   1831 
   1832   public void testNanoRepeatedCord() throws Exception {
   1833     TestAllTypesNano msg = new TestAllTypesNano();
   1834     assertEquals(0, msg.repeatedCord.length);
   1835     msg.repeatedCord = new String[] { "hello", "bye", "boo" };
   1836     assertEquals("bye", msg.repeatedCord[1]);
   1837     assertEquals("boo", msg.repeatedCord[2]);
   1838     msg.clear();
   1839     assertEquals(0, msg.repeatedCord.length);
   1840     msg.clear()
   1841        .repeatedCord = new String[] { "boo" };
   1842     assertEquals(1, msg.repeatedCord.length);
   1843     assertEquals("boo", msg.repeatedCord[0]);
   1844     msg.clear();
   1845     assertEquals(0, msg.repeatedCord.length);
   1846 
   1847     // Test 1 entry
   1848     msg.clear()
   1849        .repeatedCord = new String[] { "" };
   1850     assertEquals(1, msg.repeatedCord.length);
   1851     byte [] result = MessageNano.toByteArray(msg);
   1852     int msgSerializedSize = msg.getSerializedSize();
   1853     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
   1854     assertTrue(msgSerializedSize == 6);
   1855     assertEquals(result.length, msgSerializedSize);
   1856     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
   1857     assertEquals(1, newMsg.repeatedCord.length);
   1858     assertTrue(newMsg.repeatedCord[0].isEmpty());
   1859 
   1860     // Test 2 entries
   1861     msg.clear()
   1862        .repeatedCord = new String[] { "hello", "world" };
   1863     assertEquals(2, msg.repeatedCord.length);
   1864     result = MessageNano.toByteArray(msg);
   1865     msgSerializedSize = msg.getSerializedSize();
   1866     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
   1867     assertTrue(msgSerializedSize == 19);
   1868     assertEquals(result.length, msgSerializedSize);
   1869 
   1870     newMsg = TestAllTypesNano.parseFrom(result);
   1871     assertEquals(2, newMsg.repeatedCord.length);
   1872     assertEquals("hello", newMsg.repeatedCord[0]);
   1873     assertEquals("world", newMsg.repeatedCord[1]);
   1874   }
   1875 
   1876   public void testNanoRepeatedPackedInt32() throws Exception {
   1877     TestAllTypesNano msg = new TestAllTypesNano();
   1878     assertEquals(0, msg.repeatedPackedInt32.length);
   1879     msg.repeatedPackedInt32 = new int[] { 123, 789, 456 };
   1880     assertEquals(789, msg.repeatedPackedInt32[1]);
   1881     assertEquals(456, msg.repeatedPackedInt32[2]);
   1882     msg.clear();
   1883     assertEquals(0, msg.repeatedPackedInt32.length);
   1884     msg.clear()
   1885        .repeatedPackedInt32 = new int[] { 456 };
   1886     assertEquals(1, msg.repeatedPackedInt32.length);
   1887     assertEquals(456, msg.repeatedPackedInt32[0]);
   1888     msg.clear();
   1889     assertEquals(0, msg.repeatedPackedInt32.length);
   1890 
   1891     // Test 1 entry
   1892     msg.clear()
   1893        .repeatedPackedInt32 = new int[] { 123 };
   1894     assertEquals(1, msg.repeatedPackedInt32.length);
   1895     byte [] result = MessageNano.toByteArray(msg);
   1896     int msgSerializedSize = msg.getSerializedSize();
   1897     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
   1898     assertTrue(msgSerializedSize == 7);
   1899     assertEquals(result.length, msgSerializedSize);
   1900     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
   1901     assertEquals(1, newMsg.repeatedPackedInt32.length);
   1902     assertEquals(123, newMsg.repeatedPackedInt32[0]);
   1903 
   1904     // Test 2 entries
   1905     msg.clear()
   1906        .repeatedPackedInt32 = new int[] { 123, 456 };
   1907     assertEquals(2, msg.repeatedPackedInt32.length);
   1908     result = MessageNano.toByteArray(msg);
   1909     msgSerializedSize = msg.getSerializedSize();
   1910     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
   1911     assertTrue(msgSerializedSize == 9);
   1912     assertEquals(result.length, msgSerializedSize);
   1913 
   1914     newMsg = TestAllTypesNano.parseFrom(result);
   1915     assertEquals(2, newMsg.repeatedPackedInt32.length);
   1916     assertEquals(123, newMsg.repeatedPackedInt32[0]);
   1917     assertEquals(456, newMsg.repeatedPackedInt32[1]);
   1918   }
   1919 
   1920   public void testNanoRepeatedPackedSfixed64() throws Exception {
   1921     TestAllTypesNano msg = new TestAllTypesNano();
   1922     assertEquals(0, msg.repeatedPackedSfixed64.length);
   1923     msg.repeatedPackedSfixed64 = new long[] { 123, 789, 456 };
   1924     assertEquals(789, msg.repeatedPackedSfixed64[1]);
   1925     assertEquals(456, msg.repeatedPackedSfixed64[2]);
   1926     msg.clear();
   1927     assertEquals(0, msg.repeatedPackedSfixed64.length);
   1928     msg.clear()
   1929        .repeatedPackedSfixed64 = new long[] { 456 };
   1930     assertEquals(1, msg.repeatedPackedSfixed64.length);
   1931     assertEquals(456, msg.repeatedPackedSfixed64[0]);
   1932     msg.clear();
   1933     assertEquals(0, msg.repeatedPackedSfixed64.length);
   1934 
   1935     // Test 1 entry
   1936     msg.clear()
   1937        .repeatedPackedSfixed64 = new long[] { 123 };
   1938     assertEquals(1, msg.repeatedPackedSfixed64.length);
   1939     byte [] result = MessageNano.toByteArray(msg);
   1940     int msgSerializedSize = msg.getSerializedSize();
   1941     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
   1942     assertTrue(msgSerializedSize == 14);
   1943     assertEquals(result.length, msgSerializedSize);
   1944     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
   1945     assertEquals(1, newMsg.repeatedPackedSfixed64.length);
   1946     assertEquals(123, newMsg.repeatedPackedSfixed64[0]);
   1947 
   1948     // Test 2 entries
   1949     msg.clear()
   1950        .repeatedPackedSfixed64 = new long[] { 123, 456 };
   1951     assertEquals(2, msg.repeatedPackedSfixed64.length);
   1952     result = MessageNano.toByteArray(msg);
   1953     msgSerializedSize = msg.getSerializedSize();
   1954     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
   1955     assertTrue(msgSerializedSize == 22);
   1956     assertEquals(result.length, msgSerializedSize);
   1957 
   1958     newMsg = TestAllTypesNano.parseFrom(result);
   1959     assertEquals(2, newMsg.repeatedPackedSfixed64.length);
   1960     assertEquals(123, newMsg.repeatedPackedSfixed64[0]);
   1961     assertEquals(456, newMsg.repeatedPackedSfixed64[1]);
   1962   }
   1963 
   1964   public void testNanoRepeatedPackedNestedEnum() throws Exception {
   1965     TestAllTypesNano msg = new TestAllTypesNano();
   1966     msg.repeatedPackedNestedEnum = new int[] {
   1967         TestAllTypesNano.FOO,
   1968         TestAllTypesNano.BAR,
   1969         TestAllTypesNano.BAZ
   1970     };
   1971     assertEquals(3, msg.repeatedPackedNestedEnum.length);
   1972     assertEquals(TestAllTypesNano.FOO, msg.repeatedPackedNestedEnum[0]);
   1973     assertEquals(TestAllTypesNano.BAR, msg.repeatedPackedNestedEnum[1]);
   1974     assertEquals(TestAllTypesNano.BAZ, msg.repeatedPackedNestedEnum[2]);
   1975     msg.clear();
   1976     assertEquals(0, msg.repeatedPackedNestedEnum.length);
   1977     msg.clear()
   1978        .repeatedPackedNestedEnum = new int[] { TestAllTypesNano.BAR };
   1979     assertEquals(1, msg.repeatedPackedNestedEnum.length);
   1980     assertEquals(TestAllTypesNano.BAR, msg.repeatedPackedNestedEnum[0]);
   1981     msg.clear();
   1982     assertEquals(0, msg.repeatedPackedNestedEnum.length);
   1983 
   1984     // Test 1 entry
   1985     msg.clear()
   1986        .repeatedPackedNestedEnum = new int[] { TestAllTypesNano.FOO };
   1987     byte [] result = MessageNano.toByteArray(msg);
   1988     int msgSerializedSize = msg.getSerializedSize();
   1989     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
   1990     assertTrue(msgSerializedSize == 7);
   1991     assertEquals(result.length, msgSerializedSize);
   1992     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
   1993     assertEquals(1, newMsg.repeatedPackedNestedEnum.length);
   1994     assertEquals(TestAllTypesNano.FOO, msg.repeatedPackedNestedEnum[0]);
   1995 
   1996     // Test 2 entries
   1997     msg.clear()
   1998        .repeatedPackedNestedEnum = new int[] { TestAllTypesNano.FOO, TestAllTypesNano.BAR };
   1999     assertEquals(2, msg.repeatedPackedNestedEnum.length);
   2000     result = MessageNano.toByteArray(msg);
   2001     msgSerializedSize = msg.getSerializedSize();
   2002     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
   2003     assertTrue(msgSerializedSize == 8);
   2004     assertEquals(result.length, msgSerializedSize);
   2005 
   2006     newMsg = TestAllTypesNano.parseFrom(result);
   2007     assertEquals(2, newMsg.repeatedPackedNestedEnum.length);
   2008     assertEquals(TestAllTypesNano.FOO, msg.repeatedPackedNestedEnum[0]);
   2009     assertEquals(TestAllTypesNano.BAR, msg.repeatedPackedNestedEnum[1]);
   2010   }
   2011 
   2012   public void testNanoRepeatedPackedSerializedSize() throws Exception {
   2013     TestAllTypesNano msg = new TestAllTypesNano();
   2014     msg.repeatedPackedInt32 = new int[] { 123, 789, 456 };
   2015     int msgSerializedSize = msg.getSerializedSize();
   2016     byte [] result = MessageNano.toByteArray(msg);
   2017     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
   2018     assertTrue(msgSerializedSize == 11);
   2019     assertEquals(result.length, msgSerializedSize);
   2020     TestAllTypesNano msg2 = new TestAllTypesNano();
   2021     msg2.repeatedPackedInt32 = new int[] { 123, 789, 456 };
   2022     byte [] result2 = new byte[msgSerializedSize];
   2023     MessageNano.toByteArray(msg2, result2, 0, msgSerializedSize);
   2024 
   2025     // Check equal size and content.
   2026     assertEquals(msgSerializedSize, msg2.getSerializedSize());
   2027     assertTrue(Arrays.equals(result, result2));
   2028   }
   2029 
   2030   public void testNanoRepeatedInt32ReMerge() throws Exception {
   2031     TestAllTypesNano msg = new TestAllTypesNano();
   2032     msg.repeatedInt32 = new int[] { 234 };
   2033     byte [] result1 = MessageNano.toByteArray(msg);
   2034 
   2035     msg.clear().optionalInt32 = 789;
   2036     byte [] result2 = MessageNano.toByteArray(msg);
   2037 
   2038     msg.clear().repeatedInt32 = new int[] { 123, 456 };
   2039     byte [] result3 = MessageNano.toByteArray(msg);
   2040 
   2041     // Concatenate the three serializations and read as one message.
   2042     byte [] result = new byte[result1.length + result2.length + result3.length];
   2043     System.arraycopy(result1, 0, result, 0, result1.length);
   2044     System.arraycopy(result2, 0, result, result1.length, result2.length);
   2045     System.arraycopy(result3, 0, result, result1.length + result2.length, result3.length);
   2046 
   2047     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
   2048     assertEquals(789, newMsg.optionalInt32);
   2049     assertEquals(3, newMsg.repeatedInt32.length);
   2050     assertEquals(234, newMsg.repeatedInt32[0]);
   2051     assertEquals(123, newMsg.repeatedInt32[1]);
   2052     assertEquals(456, newMsg.repeatedInt32[2]);
   2053   }
   2054 
   2055   public void testNanoRepeatedNestedEnumReMerge() throws Exception {
   2056     TestAllTypesNano msg = new TestAllTypesNano();
   2057     msg.repeatedNestedEnum = new int[] { TestAllTypesNano.FOO };
   2058     byte [] result1 = MessageNano.toByteArray(msg);
   2059 
   2060     msg.clear().optionalInt32 = 789;
   2061     byte [] result2 = MessageNano.toByteArray(msg);
   2062 
   2063     msg.clear().repeatedNestedEnum = new int[] { TestAllTypesNano.BAR, TestAllTypesNano.FOO };
   2064     byte [] result3 = MessageNano.toByteArray(msg);
   2065 
   2066     // Concatenate the three serializations and read as one message.
   2067     byte [] result = new byte[result1.length + result2.length + result3.length];
   2068     System.arraycopy(result1, 0, result, 0, result1.length);
   2069     System.arraycopy(result2, 0, result, result1.length, result2.length);
   2070     System.arraycopy(result3, 0, result, result1.length + result2.length, result3.length);
   2071 
   2072     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
   2073     assertEquals(789, newMsg.optionalInt32);
   2074     assertEquals(3, newMsg.repeatedNestedEnum.length);
   2075     assertEquals(TestAllTypesNano.FOO, newMsg.repeatedNestedEnum[0]);
   2076     assertEquals(TestAllTypesNano.BAR, newMsg.repeatedNestedEnum[1]);
   2077     assertEquals(TestAllTypesNano.FOO, newMsg.repeatedNestedEnum[2]);
   2078   }
   2079 
   2080   public void testNanoRepeatedNestedMessageReMerge() throws Exception {
   2081     TestAllTypesNano msg = new TestAllTypesNano();
   2082     TestAllTypesNano.NestedMessage nestedMsg0 =
   2083       new TestAllTypesNano.NestedMessage();
   2084     nestedMsg0.bb = 0;
   2085     TestAllTypesNano.NestedMessage nestedMsg1 =
   2086       new TestAllTypesNano.NestedMessage();
   2087     nestedMsg1.bb = 1;
   2088     TestAllTypesNano.NestedMessage nestedMsg2 =
   2089       new TestAllTypesNano.NestedMessage();
   2090     nestedMsg2.bb = 2;
   2091 
   2092     msg.repeatedNestedMessage = new TestAllTypesNano.NestedMessage[] { nestedMsg0 };
   2093     byte [] result1 = MessageNano.toByteArray(msg);
   2094 
   2095     msg.clear().optionalInt32 = 789;
   2096     byte [] result2 = MessageNano.toByteArray(msg);
   2097 
   2098     msg.clear().repeatedNestedMessage =
   2099         new TestAllTypesNano.NestedMessage[] { nestedMsg1, nestedMsg2 };
   2100     byte [] result3 = MessageNano.toByteArray(msg);
   2101 
   2102     // Concatenate the three serializations and read as one message.
   2103     byte [] result = new byte[result1.length + result2.length + result3.length];
   2104     System.arraycopy(result1, 0, result, 0, result1.length);
   2105     System.arraycopy(result2, 0, result, result1.length, result2.length);
   2106     System.arraycopy(result3, 0, result, result1.length + result2.length, result3.length);
   2107 
   2108     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
   2109     assertEquals(789, newMsg.optionalInt32);
   2110     assertEquals(3, newMsg.repeatedNestedMessage.length);
   2111     assertEquals(nestedMsg0.bb, newMsg.repeatedNestedMessage[0].bb);
   2112     assertEquals(nestedMsg1.bb, newMsg.repeatedNestedMessage[1].bb);
   2113     assertEquals(nestedMsg2.bb, newMsg.repeatedNestedMessage[2].bb);
   2114   }
   2115 
   2116   /**
   2117    * Tests that invalid enum values from the wire are not accepted.
   2118    */
   2119   public void testNanoEnumValidity() throws Exception {
   2120     final int invalid = 120;
   2121     final int alsoInvalid = 121;
   2122 
   2123     EnumValidity.M m = new EnumValidity.M();
   2124     // Sanity check & baseline of the assertions for the first case below.
   2125     assertEquals(EnumValidity.E.default_, m.optionalE);
   2126     assertEquals(EnumValidity.E.BAZ, m.defaultE);
   2127 
   2128     m.optionalE = invalid;
   2129     m.defaultE = invalid;
   2130     // E contains all valid values
   2131     m.repeatedE = new int[] {EnumValidity.E.FOO, EnumValidity.E.BAR};
   2132     m.packedE = new int[] {EnumValidity.E.FOO, EnumValidity.E.BAZ};
   2133     // E2 contains some invalid values
   2134     m.repeatedE2 = new int[] {invalid, EnumValidity.E.BAR, alsoInvalid};
   2135     m.packedE2 = new int[] {EnumValidity.E.FOO, invalid, alsoInvalid};
   2136     // E3 contains all invalid values
   2137     m.repeatedE3 = new int[] {invalid, invalid};
   2138     m.packedE3 = new int[] {alsoInvalid, alsoInvalid};
   2139     byte[] serialized = MessageNano.toByteArray(m);
   2140     // Sanity check that we do have all data in the byte array.
   2141     assertEquals(31, serialized.length);
   2142 
   2143     // Test 1: tests that invalid values aren't included in the deserialized message.
   2144     EnumValidity.M deserialized = MessageNano.mergeFrom(new EnumValidity.M(), serialized);
   2145     assertEquals(EnumValidity.E.default_, deserialized.optionalE);
   2146     assertEquals(EnumValidity.E.BAZ, deserialized.defaultE);
   2147     assertTrue(Arrays.equals(
   2148         new int[] {EnumValidity.E.FOO, EnumValidity.E.BAR}, deserialized.repeatedE));
   2149     assertTrue(Arrays.equals(
   2150         new int[] {EnumValidity.E.FOO, EnumValidity.E.BAZ}, deserialized.packedE));
   2151     assertTrue(Arrays.equals(
   2152         new int[] {EnumValidity.E.BAR}, deserialized.repeatedE2));
   2153     assertTrue(Arrays.equals(
   2154         new int[] {EnumValidity.E.FOO}, deserialized.packedE2));
   2155     assertEquals(0, deserialized.repeatedE3.length);
   2156     assertEquals(0, deserialized.packedE3.length);
   2157 
   2158     // Test 2: tests that invalid values do not override previous values in the field, including
   2159     // arrays, including pre-existing invalid values.
   2160     deserialized.optionalE = EnumValidity.E.BAR;
   2161     deserialized.defaultE = alsoInvalid;
   2162     deserialized.repeatedE = new int[] {EnumValidity.E.BAZ};
   2163     deserialized.packedE = new int[] {EnumValidity.E.BAZ, alsoInvalid};
   2164     deserialized.repeatedE2 = new int[] {invalid, alsoInvalid};
   2165     deserialized.packedE2 = null;
   2166     deserialized.repeatedE3 = null;
   2167     deserialized.packedE3 = new int[0];
   2168     MessageNano.mergeFrom(deserialized, serialized);
   2169     assertEquals(EnumValidity.E.BAR, deserialized.optionalE);
   2170     assertEquals(alsoInvalid, deserialized.defaultE);
   2171     assertTrue(Arrays.equals(
   2172         new int[] {EnumValidity.E.BAZ, /* + */ EnumValidity.E.FOO, EnumValidity.E.BAR},
   2173         deserialized.repeatedE));
   2174     assertTrue(Arrays.equals(
   2175         new int[] {EnumValidity.E.BAZ, alsoInvalid, /* + */ EnumValidity.E.FOO, EnumValidity.E.BAZ},
   2176         deserialized.packedE));
   2177     assertTrue(Arrays.equals(
   2178         new int[] {invalid, alsoInvalid, /* + */ EnumValidity.E.BAR},
   2179         deserialized.repeatedE2));
   2180     assertTrue(Arrays.equals(
   2181         new int[] {/* <null> + */ EnumValidity.E.FOO},
   2182         deserialized.packedE2));
   2183     assertNull(deserialized.repeatedE3); // null + all invalid == null
   2184     assertEquals(0, deserialized.packedE3.length); // empty + all invalid == empty
   2185 
   2186     // Test 3: reading by alternative forms
   2187     EnumValidity.Alt alt = MessageNano.mergeFrom(new EnumValidity.Alt(), serialized);
   2188     assertEquals(EnumValidity.E.BAR, // last valid value in m.repeatedE2
   2189         alt.repeatedE2AsOptional);
   2190     assertTrue(Arrays.equals(new int[] {EnumValidity.E.FOO}, alt.packedE2AsNonPacked));
   2191     assertEquals(0, alt.nonPackedE3AsPacked.length);
   2192   }
   2193 
   2194   /**
   2195    * Tests the same as {@link #testNanoEnumValidity()} with accessor style. Repeated fields are
   2196    * not re-tested here because they are not affected by the accessor style.
   2197    */
   2198   public void testNanoEnumValidityAccessors() throws Exception {
   2199     final int invalid = 120;
   2200     final int alsoInvalid = 121;
   2201 
   2202     EnumValidityAccessors.M m = new EnumValidityAccessors.M();
   2203     // Sanity check & baseline of the assertions for the first case below.
   2204     assertEquals(EnumValidityAccessors.default_, m.getOptionalE());
   2205     assertEquals(EnumValidityAccessors.BAZ, m.getDefaultE());
   2206 
   2207     m.setOptionalE(invalid);
   2208     m.setDefaultE(invalid);
   2209     // Set repeatedE2 for Alt.repeatedE2AsOptional
   2210     m.repeatedE2 = new int[] {invalid, EnumValidityAccessors.BAR, alsoInvalid};
   2211     byte[] serialized = MessageNano.toByteArray(m);
   2212     // Sanity check that we do have all data in the byte array.
   2213     assertEquals(10, serialized.length);
   2214 
   2215     // Test 1: tests that invalid values aren't included in the deserialized message.
   2216     EnumValidityAccessors.M deserialized =
   2217         MessageNano.mergeFrom(new EnumValidityAccessors.M(), serialized);
   2218     assertEquals(EnumValidityAccessors.default_, deserialized.getOptionalE());
   2219     assertEquals(EnumValidityAccessors.BAZ, deserialized.getDefaultE());
   2220 
   2221     // Test 2: tests that invalid values do not override previous values in the field, including
   2222     // pre-existing invalid values.
   2223     deserialized.setOptionalE(EnumValidityAccessors.BAR);
   2224     deserialized.setDefaultE(alsoInvalid);
   2225     MessageNano.mergeFrom(deserialized, serialized);
   2226     assertEquals(EnumValidityAccessors.BAR, deserialized.getOptionalE());
   2227     assertEquals(alsoInvalid, deserialized.getDefaultE());
   2228 
   2229     // Test 3: reading by alternative forms
   2230     EnumValidityAccessors.Alt alt =
   2231         MessageNano.mergeFrom(new EnumValidityAccessors.Alt(), serialized);
   2232     assertEquals(EnumValidityAccessors.BAR, // last valid value in m.repeatedE2
   2233         alt.getRepeatedE2AsOptional());
   2234   }
   2235 
   2236   /**
   2237    * Tests that code generation correctly wraps a single message into its outer
   2238    * class. The class {@code SingleMessageNano} is imported from the outer
   2239    * class {@code UnittestSingleNano}, whose name is implicit. Any error would
   2240    * cause this method to fail compilation.
   2241    */
   2242   public void testNanoSingle() throws Exception {
   2243     SingleMessageNano msg = new SingleMessageNano();
   2244     assertNotNull(msg);
   2245   }
   2246 
   2247   /**
   2248    * Tests that code generation correctly skips generating the outer class if
   2249    * unnecessary, letting a file-scope entity have the same name. The class
   2250    * {@code MultipleNameClashNano} shares the same name with the file's outer
   2251    * class defined explicitly, but the file contains no other entities and has
   2252    * java_multiple_files set. Any error would cause this method to fail
   2253    * compilation.
   2254    */
   2255   public void testNanoMultipleNameClash() throws Exception {
   2256     MultipleNameClashNano msg = new MultipleNameClashNano();
   2257     msg.field = 0;
   2258   }
   2259 
   2260   /**
   2261    * Tests that code generation correctly handles enums in different scopes in
   2262    * a source file with the option java_multiple_files set to true. Any error
   2263    * would cause this method to fail compilation.
   2264    */
   2265   public void testNanoMultipleEnumScoping() throws Exception {
   2266     FileScopeEnumRefNano msg1 = new FileScopeEnumRefNano();
   2267     msg1.enumField = UnittestMultipleNano.ONE;
   2268     MessageScopeEnumRefNano msg2 = new MessageScopeEnumRefNano();
   2269     msg2.enumField = MessageScopeEnumRefNano.TWO;
   2270   }
   2271 
   2272   /**
   2273    * Tests that code generation with mixed values of the java_multiple_files
   2274    * options between the main source file and the imported source files would
   2275    * generate correct references. Any error would cause this method to fail
   2276    * compilation.
   2277    */
   2278   public void testNanoMultipleImportingNonMultiple() throws Exception {
   2279     UnittestImportNano.ImportMessageNano importMsg = new UnittestImportNano.ImportMessageNano();
   2280     MultipleImportingNonMultipleNano1 nano1 = new MultipleImportingNonMultipleNano1();
   2281     nano1.field = importMsg;
   2282     MultipleImportingNonMultipleNano2 nano2 = new MultipleImportingNonMultipleNano2();
   2283     nano2.nano1 = nano1;
   2284   }
   2285 
   2286   public void testNanoDefaults() throws Exception {
   2287     TestAllTypesNano msg = new TestAllTypesNano();
   2288     for (int i = 0; i < 2; i++) {
   2289       assertEquals(41, msg.defaultInt32);
   2290       assertEquals(42, msg.defaultInt64);
   2291       assertEquals(43, msg.defaultUint32);
   2292       assertEquals(44, msg.defaultUint64);
   2293       assertEquals(-45, msg.defaultSint32);
   2294       assertEquals(46, msg.defaultSint64);
   2295       assertEquals(47, msg.defaultFixed32);
   2296       assertEquals(48, msg.defaultFixed64);
   2297       assertEquals(49, msg.defaultSfixed32);
   2298       assertEquals(-50, msg.defaultSfixed64);
   2299       assertTrue(51.5f == msg.defaultFloat);
   2300       assertTrue(52.0e3 == msg.defaultDouble);
   2301       assertEquals(true, msg.defaultBool);
   2302       assertEquals("hello", msg.defaultString);
   2303       assertEquals("world", new String(msg.defaultBytes, "UTF-8"));
   2304       assertEquals("dnya", msg.defaultStringNonascii);
   2305       assertEquals("dnyab", new String(msg.defaultBytesNonascii, "UTF-8"));
   2306       assertEquals(TestAllTypesNano.BAR, msg.defaultNestedEnum);
   2307       assertEquals(NanoOuterClass.FOREIGN_NANO_BAR, msg.defaultForeignEnum);
   2308       assertEquals(UnittestImportNano.IMPORT_NANO_BAR, msg.defaultImportEnum);
   2309       assertEquals(Float.POSITIVE_INFINITY, msg.defaultFloatInf);
   2310       assertEquals(Float.NEGATIVE_INFINITY, msg.defaultFloatNegInf);
   2311       assertEquals(Float.NaN, msg.defaultFloatNan);
   2312       assertEquals(Double.POSITIVE_INFINITY, msg.defaultDoubleInf);
   2313       assertEquals(Double.NEGATIVE_INFINITY, msg.defaultDoubleNegInf);
   2314       assertEquals(Double.NaN, msg.defaultDoubleNan);
   2315 
   2316       // Default values are not output, except for required fields.
   2317       byte [] result = MessageNano.toByteArray(msg);
   2318       int msgSerializedSize = msg.getSerializedSize();
   2319       //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
   2320       assertTrue(msgSerializedSize == 3);
   2321       assertEquals(result.length, msgSerializedSize);
   2322       msg.clear();
   2323     }
   2324   }
   2325 
   2326   public void testDifferentStringLengthsNano() throws Exception {
   2327     // Test string serialization roundtrip using strings of the following lengths,
   2328     // with ASCII and Unicode characters requiring different UTF-8 byte counts per
   2329     // char, hence causing the length delimiter varint to sometimes require more
   2330     // bytes for the Unicode strings than the ASCII string of the same length.
   2331     int[] lengths = new int[] {
   2332             0,
   2333             1,
   2334             (1 << 4) - 1,  // 1 byte for ASCII and Unicode
   2335             (1 << 7) - 1,  // 1 byte for ASCII, 2 bytes for Unicode
   2336             (1 << 11) - 1, // 2 bytes for ASCII and Unicode
   2337             (1 << 14) - 1, // 2 bytes for ASCII, 3 bytes for Unicode
   2338             (1 << 17) - 1, // 3 bytes for ASCII and Unicode
   2339     };
   2340     for (int i : lengths) {
   2341       testEncodingOfString('q', i);      // 1 byte per char
   2342       testEncodingOfString('\u07FF', i); // 2 bytes per char
   2343       testEncodingOfString('\u0981', i); // 3 bytes per char
   2344     }
   2345   }
   2346 
   2347   /** Regression test for https://github.com/google/protobuf/issues/292 */
   2348   public void testCorrectExceptionThrowWhenEncodingStringsWithoutEnoughSpace() throws Exception {
   2349     String testCase = "Foooooooo";
   2350     assertEquals(CodedOutputByteBufferNano.computeRawVarint32Size(testCase.length()),
   2351             CodedOutputByteBufferNano.computeRawVarint32Size(testCase.length() * 3));
   2352     assertEquals(11, CodedOutputByteBufferNano.computeStringSize(1, testCase));
   2353     // Tag is one byte, varint describing string length is 1 byte, string length is 9 bytes.
   2354     // An array of size 1 will cause a failure when trying to write the varint.
   2355     for (int i = 0; i < 11; i++) {
   2356       CodedOutputByteBufferNano bufferNano = CodedOutputByteBufferNano.newInstance(new byte[i]);
   2357       try {
   2358         bufferNano.writeString(1, testCase);
   2359         fail("Should have thrown an out of space exception");
   2360       } catch (CodedOutputByteBufferNano.OutOfSpaceException expected) {}
   2361     }
   2362   }
   2363 
   2364   private void testEncodingOfString(char c, int length) throws InvalidProtocolBufferNanoException {
   2365     TestAllTypesNano testAllTypesNano = new TestAllTypesNano();
   2366     final String fullString = fullString(c, length);
   2367     testAllTypesNano.optionalString = fullString;
   2368     final TestAllTypesNano resultNano = new TestAllTypesNano();
   2369     MessageNano.mergeFrom(resultNano, MessageNano.toByteArray(testAllTypesNano));
   2370     assertEquals(fullString, resultNano.optionalString);
   2371   }
   2372 
   2373   private String fullString(char c, int length) {
   2374     char[] result = new char[length];
   2375     Arrays.fill(result, c);
   2376     return new String(result);
   2377   }
   2378 
   2379   public void testNanoWithHasParseFrom() throws Exception {
   2380     TestAllTypesNanoHas msg = null;
   2381     // Test false on creation, after clear and upon empty parse.
   2382     for (int i = 0; i < 3; i++) {
   2383       if (i == 0) {
   2384         msg = new TestAllTypesNanoHas();
   2385       } else if (i == 1) {
   2386         msg.clear();
   2387       } else if (i == 2) {
   2388         msg = TestAllTypesNanoHas.parseFrom(new byte[0]);
   2389       }
   2390       assertFalse(msg.hasOptionalInt32);
   2391       assertFalse(msg.hasOptionalString);
   2392       assertFalse(msg.hasOptionalBytes);
   2393       assertFalse(msg.hasOptionalNestedEnum);
   2394       assertFalse(msg.hasDefaultInt32);
   2395       assertFalse(msg.hasDefaultString);
   2396       assertFalse(msg.hasDefaultBytes);
   2397       assertFalse(msg.hasDefaultFloatNan);
   2398       assertFalse(msg.hasDefaultNestedEnum);
   2399       assertFalse(msg.hasId);
   2400       assertFalse(msg.hasRequiredEnum);
   2401       msg.optionalInt32 = 123;
   2402       msg.optionalNestedMessage = new TestAllTypesNanoHas.NestedMessage();
   2403       msg.optionalNestedMessage.bb = 2;
   2404       msg.optionalNestedEnum = TestAllTypesNano.BAZ;
   2405     }
   2406 
   2407     byte [] result = MessageNano.toByteArray(msg);
   2408     int msgSerializedSize = msg.getSerializedSize();
   2409     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
   2410     assertTrue(msgSerializedSize == 10);
   2411     assertEquals(result.length, msgSerializedSize);
   2412 
   2413     // Has fields true upon parse.
   2414     TestAllTypesNanoHas newMsg = TestAllTypesNanoHas.parseFrom(result);
   2415     assertEquals(123, newMsg.optionalInt32);
   2416     assertTrue(newMsg.hasOptionalInt32);
   2417     assertEquals(2, newMsg.optionalNestedMessage.bb);
   2418     assertTrue(newMsg.optionalNestedMessage.hasBb);
   2419     assertEquals(TestAllTypesNanoHas.BAZ, newMsg.optionalNestedEnum);
   2420     assertTrue(newMsg.hasOptionalNestedEnum);
   2421   }
   2422 
   2423   public void testNanoWithHasSerialize() throws Exception {
   2424     TestAllTypesNanoHas msg = new TestAllTypesNanoHas();
   2425     msg.hasOptionalInt32 = true;
   2426     msg.hasOptionalString = true;
   2427     msg.hasOptionalBytes = true;
   2428     msg.optionalNestedMessage = new TestAllTypesNanoHas.NestedMessage();
   2429     msg.optionalNestedMessage.hasBb = true;
   2430     msg.hasOptionalNestedEnum = true;
   2431     msg.hasDefaultInt32 = true;
   2432     msg.hasDefaultString = true;
   2433     msg.hasDefaultBytes = true;
   2434     msg.hasDefaultFloatNan = true;
   2435     msg.hasDefaultNestedEnum = true;
   2436     msg.hasId = true;
   2437     msg.hasRequiredEnum = true;
   2438 
   2439     byte [] result = MessageNano.toByteArray(msg);
   2440     int msgSerializedSize = msg.getSerializedSize();
   2441     assertEquals(result.length, msgSerializedSize);
   2442 
   2443     // Now deserialize and find that all fields are set and equal to their defaults.
   2444     TestAllTypesNanoHas newMsg = TestAllTypesNanoHas.parseFrom(result);
   2445     assertTrue(newMsg.hasOptionalInt32);
   2446     assertTrue(newMsg.hasOptionalString);
   2447     assertTrue(newMsg.hasOptionalBytes);
   2448     assertTrue(newMsg.optionalNestedMessage.hasBb);
   2449     assertTrue(newMsg.hasOptionalNestedEnum);
   2450     assertTrue(newMsg.hasDefaultInt32);
   2451     assertTrue(newMsg.hasDefaultString);
   2452     assertTrue(newMsg.hasDefaultBytes);
   2453     assertTrue(newMsg.hasDefaultFloatNan);
   2454     assertTrue(newMsg.hasDefaultNestedEnum);
   2455     assertTrue(newMsg.hasId);
   2456     assertTrue(newMsg.hasRequiredEnum);
   2457     assertEquals(0, newMsg.optionalInt32);
   2458     assertEquals(0, newMsg.optionalString.length());
   2459     assertEquals(0, newMsg.optionalBytes.length);
   2460     assertEquals(0, newMsg.optionalNestedMessage.bb);
   2461     assertEquals(TestAllTypesNanoHas.FOO, newMsg.optionalNestedEnum);
   2462     assertEquals(41, newMsg.defaultInt32);
   2463     assertEquals("hello", newMsg.defaultString);
   2464     assertEquals("world", new String(newMsg.defaultBytes, "UTF-8"));
   2465     assertEquals(TestAllTypesNanoHas.BAR, newMsg.defaultNestedEnum);
   2466     assertEquals(Float.NaN, newMsg.defaultFloatNan);
   2467     assertEquals(0, newMsg.id);
   2468     assertEquals(TestAllTypesNanoHas.FOO, newMsg.requiredEnum);
   2469   }
   2470 
   2471   public void testNanoWithAccessorsBasic() throws Exception {
   2472     TestNanoAccessors msg = new TestNanoAccessors();
   2473 
   2474     // Makes sure required, repeated, and message fields are still public
   2475     msg.id = 3;
   2476     msg.repeatedBytes = new byte[2][3];
   2477     msg.optionalNestedMessage = null;
   2478 
   2479     // Test accessors
   2480     assertEquals(0, msg.getOptionalInt32());
   2481     assertFalse(msg.hasOptionalInt32());
   2482     msg.setOptionalInt32(135);
   2483     assertEquals(135, msg.getOptionalInt32());
   2484     assertTrue(msg.hasOptionalInt32());
   2485     msg.clearOptionalInt32();
   2486     assertFalse(msg.hasOptionalInt32());
   2487     msg.setOptionalInt32(0); // default value
   2488     assertTrue(msg.hasOptionalInt32());
   2489 
   2490     // Test NPE
   2491     try {
   2492       msg.setOptionalBytes(null);
   2493       fail();
   2494     } catch (NullPointerException expected) {}
   2495     try {
   2496       msg.setOptionalString(null);
   2497       fail();
   2498     } catch (NullPointerException expected) {}
   2499 
   2500     // Test has bit on bytes field with defaults and clear() re-clones the default array
   2501     assertFalse(msg.hasDefaultBytes());
   2502     byte[] defaultBytes = msg.getDefaultBytes();
   2503     msg.setDefaultBytes(defaultBytes);
   2504     assertTrue(msg.hasDefaultBytes());
   2505     msg.clearDefaultBytes();
   2506     assertFalse(msg.hasDefaultBytes());
   2507     defaultBytes[0]++; // modify original array
   2508     assertFalse(Arrays.equals(defaultBytes, msg.getDefaultBytes()));
   2509 
   2510     // Test has bits that require additional bit fields
   2511     assertFalse(msg.hasBitFieldCheck());
   2512     msg.setBitFieldCheck(0);
   2513     assertTrue(msg.hasBitFieldCheck());
   2514     assertFalse(msg.hasBeforeBitFieldCheck()); // checks bit field does not leak
   2515     assertFalse(msg.hasAfterBitFieldCheck());
   2516 
   2517     // Test clear() clears has bits
   2518     msg.setOptionalString("hi");
   2519     msg.setDefaultString("there");
   2520     msg.clear();
   2521     assertFalse(msg.hasOptionalString());
   2522     assertFalse(msg.hasDefaultString());
   2523     assertFalse(msg.hasBitFieldCheck());
   2524 
   2525     // Test set() and clear() returns itself (compiles = success)
   2526     msg.clear()
   2527         .setOptionalInt32(3)
   2528         .clearDefaultBytes()
   2529         .setOptionalString("4");
   2530   }
   2531 
   2532   public void testNanoWithAccessorsParseFrom() throws Exception {
   2533     TestNanoAccessors msg = null;
   2534     // Test false on creation, after clear and upon empty parse.
   2535     for (int i = 0; i < 3; i++) {
   2536       if (i == 0) {
   2537         msg = new TestNanoAccessors();
   2538       } else if (i == 1) {
   2539         msg.clear();
   2540       } else if (i == 2) {
   2541         msg = TestNanoAccessors.parseFrom(new byte[0]);
   2542       }
   2543       assertFalse(msg.hasOptionalInt32());
   2544       assertFalse(msg.hasOptionalString());
   2545       assertFalse(msg.hasOptionalBytes());
   2546       assertFalse(msg.hasOptionalNestedEnum());
   2547       assertFalse(msg.hasDefaultInt32());
   2548       assertFalse(msg.hasDefaultString());
   2549       assertFalse(msg.hasDefaultBytes());
   2550       assertFalse(msg.hasDefaultFloatNan());
   2551       assertFalse(msg.hasDefaultNestedEnum());
   2552       msg.optionalNestedMessage = new TestNanoAccessors.NestedMessage();
   2553       msg.optionalNestedMessage.setBb(2);
   2554       msg.setOptionalNestedEnum(TestNanoAccessors.BAZ);
   2555       msg.setDefaultInt32(msg.getDefaultInt32());
   2556     }
   2557 
   2558     byte [] result = MessageNano.toByteArray(msg);
   2559     int msgSerializedSize = msg.getSerializedSize();
   2560     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
   2561     assertTrue(msgSerializedSize == 14);
   2562     assertEquals(result.length, msgSerializedSize);
   2563 
   2564     // Has fields true upon parse.
   2565     TestNanoAccessors newMsg = TestNanoAccessors.parseFrom(result);
   2566     assertEquals(2, newMsg.optionalNestedMessage.getBb());
   2567     assertTrue(newMsg.optionalNestedMessage.hasBb());
   2568     assertEquals(TestNanoAccessors.BAZ, newMsg.getOptionalNestedEnum());
   2569     assertTrue(newMsg.hasOptionalNestedEnum());
   2570 
   2571     // Has field true on fields with explicit default values from wire.
   2572     assertTrue(newMsg.hasDefaultInt32());
   2573     assertEquals(41, newMsg.getDefaultInt32());
   2574   }
   2575 
   2576   public void testNanoWithAccessorsPublicFieldTypes() throws Exception {
   2577     TestNanoAccessors msg = new TestNanoAccessors();
   2578     assertNull(msg.optionalNestedMessage);
   2579     assertEquals(0, msg.id);
   2580     assertEquals(0, msg.repeatedNestedEnum.length);
   2581 
   2582     TestNanoAccessors newMsg = TestNanoAccessors.parseFrom(MessageNano.toByteArray(msg));
   2583     assertNull(newMsg.optionalNestedMessage);
   2584     assertEquals(0, newMsg.id);
   2585     assertEquals(0, newMsg.repeatedNestedEnum.length);
   2586 
   2587     TestNanoAccessors.NestedMessage nestedMessage = new TestNanoAccessors.NestedMessage();
   2588     nestedMessage.setBb(5);
   2589     newMsg.optionalNestedMessage = nestedMessage;
   2590     newMsg.id = -1;
   2591     newMsg.repeatedNestedEnum = new int[] { TestAllTypesNano.FOO };
   2592 
   2593     TestNanoAccessors newMsg2 = TestNanoAccessors.parseFrom(MessageNano.toByteArray(newMsg));
   2594     assertEquals(nestedMessage.getBb(), newMsg2.optionalNestedMessage.getBb());
   2595     assertEquals(-1, newMsg2.id);
   2596     assertEquals(TestAllTypesNano.FOO, newMsg2.repeatedNestedEnum[0]);
   2597 
   2598     newMsg2.optionalNestedMessage = null;
   2599     newMsg2.id = 0;
   2600     newMsg2.repeatedNestedEnum = null;
   2601 
   2602     TestNanoAccessors newMsg3 = TestNanoAccessors.parseFrom(MessageNano.toByteArray(newMsg2));
   2603     assertNull(newMsg3.optionalNestedMessage);
   2604     assertEquals(0, newMsg3.id);
   2605     assertEquals(0, newMsg3.repeatedNestedEnum.length);
   2606   }
   2607 
   2608   public void testNanoWithAccessorsSerialize() throws Exception {
   2609     TestNanoAccessors msg = new TestNanoAccessors();
   2610     msg.setOptionalInt32(msg.getOptionalInt32());
   2611     msg.setOptionalString(msg.getOptionalString());
   2612     msg.setOptionalBytes(msg.getOptionalBytes());
   2613     TestNanoAccessors.NestedMessage nestedMessage = new TestNanoAccessors.NestedMessage();
   2614     nestedMessage.setBb(nestedMessage.getBb());
   2615     msg.optionalNestedMessage = nestedMessage;
   2616     msg.setOptionalNestedEnum(msg.getOptionalNestedEnum());
   2617     msg.setDefaultInt32(msg.getDefaultInt32());
   2618     msg.setDefaultString(msg.getDefaultString());
   2619     msg.setDefaultBytes(msg.getDefaultBytes());
   2620     msg.setDefaultFloatNan(msg.getDefaultFloatNan());
   2621     msg.setDefaultNestedEnum(msg.getDefaultNestedEnum());
   2622 
   2623     byte [] result = MessageNano.toByteArray(msg);
   2624     int msgSerializedSize = msg.getSerializedSize();
   2625     assertEquals(result.length, msgSerializedSize);
   2626 
   2627     // Now deserialize and find that all fields are set and equal to their defaults.
   2628     TestNanoAccessors newMsg = TestNanoAccessors.parseFrom(result);
   2629     assertTrue(newMsg.hasOptionalInt32());
   2630     assertTrue(newMsg.hasOptionalString());
   2631     assertTrue(newMsg.hasOptionalBytes());
   2632     assertTrue(newMsg.optionalNestedMessage.hasBb());
   2633     assertTrue(newMsg.hasOptionalNestedEnum());
   2634     assertTrue(newMsg.hasDefaultInt32());
   2635     assertTrue(newMsg.hasDefaultString());
   2636     assertTrue(newMsg.hasDefaultBytes());
   2637     assertTrue(newMsg.hasDefaultFloatNan());
   2638     assertTrue(newMsg.hasDefaultNestedEnum());
   2639     assertEquals(0, newMsg.getOptionalInt32());
   2640     assertEquals(0, newMsg.getOptionalString().length());
   2641     assertEquals(0, newMsg.getOptionalBytes().length);
   2642     assertEquals(0, newMsg.optionalNestedMessage.getBb());
   2643     assertEquals(TestNanoAccessors.FOO, newMsg.getOptionalNestedEnum());
   2644     assertEquals(41, newMsg.getDefaultInt32());
   2645     assertEquals("hello", newMsg.getDefaultString());
   2646     assertEquals("world", new String(newMsg.getDefaultBytes(), "UTF-8"));
   2647     assertEquals(TestNanoAccessors.BAR, newMsg.getDefaultNestedEnum());
   2648     assertEquals(Float.NaN, newMsg.getDefaultFloatNan());
   2649     assertEquals(0, newMsg.id);
   2650   }
   2651 
   2652   public void testNanoJavaEnumStyle() throws Exception {
   2653     EnumClassNanos.EnumClassNano msg = new EnumClassNanos.EnumClassNano();
   2654     assertEquals(EnumClassNanos.FileScopeEnum.ONE, msg.one);
   2655     assertEquals(EnumClassNanos.EnumClassNano.MessageScopeEnum.TWO, msg.two);
   2656 
   2657     EnumClassNanoMultiple msg2 = new EnumClassNanoMultiple();
   2658     assertEquals(FileScopeEnumMultiple.THREE, msg2.three);
   2659     assertEquals(EnumClassNanoMultiple.MessageScopeEnumMultiple.FOUR, msg2.four);
   2660   }
   2661 
   2662   /**
   2663    * Tests that fields with a default value of NaN are not serialized when
   2664    * set to NaN. This is a special case as NaN != NaN, so normal equality
   2665    * checks don't work.
   2666    */
   2667   public void testNanoNotANumberDefaults() throws Exception {
   2668     TestAllTypesNano msg = new TestAllTypesNano();
   2669     msg.defaultDoubleNan = 0;
   2670     msg.defaultFloatNan = 0;
   2671     byte[] result = MessageNano.toByteArray(msg);
   2672     int msgSerializedSize = msg.getSerializedSize();
   2673     assertTrue(result.length == msgSerializedSize);
   2674     assertTrue(msgSerializedSize > 3);
   2675 
   2676     msg.defaultDoubleNan = Double.NaN;
   2677     msg.defaultFloatNan = Float.NaN;
   2678     result = MessageNano.toByteArray(msg);
   2679     msgSerializedSize = msg.getSerializedSize();
   2680     assertEquals(3, result.length);
   2681     assertEquals(3, msgSerializedSize);
   2682   }
   2683 
   2684   /**
   2685    * Test that a bug in skipRawBytes() has been fixed:  if the skip skips
   2686    * exactly up to a limit, this should not break things.
   2687    */
   2688   public void testSkipRawBytesBug() throws Exception {
   2689     byte[] rawBytes = new byte[] { 1, 2 };
   2690     CodedInputByteBufferNano input = CodedInputByteBufferNano.newInstance(rawBytes);
   2691 
   2692     int limit = input.pushLimit(1);
   2693     input.skipRawBytes(1);
   2694     input.popLimit(limit);
   2695     assertEquals(2, input.readRawByte());
   2696   }
   2697 
   2698   /**
   2699    * Test that a bug in skipRawBytes() has been fixed:  if the skip skips
   2700    * past the end of a buffer with a limit that has been set past the end of
   2701    * that buffer, this should not break things.
   2702    */
   2703   public void testSkipRawBytesPastEndOfBufferWithLimit() throws Exception {
   2704     byte[] rawBytes = new byte[] { 1, 2, 3, 4, 5 };
   2705     CodedInputByteBufferNano input = CodedInputByteBufferNano.newInstance(rawBytes);
   2706 
   2707     int limit = input.pushLimit(4);
   2708     // In order to expose the bug we need to read at least one byte to prime the
   2709     // buffer inside the CodedInputStream.
   2710     assertEquals(1, input.readRawByte());
   2711     // Skip to the end of the limit.
   2712     input.skipRawBytes(3);
   2713     assertTrue(input.isAtEnd());
   2714     input.popLimit(limit);
   2715     assertEquals(5, input.readRawByte());
   2716   }
   2717 
   2718   // Test a smattering of various proto types for printing
   2719   public void testMessageNanoPrinter() {
   2720     TestAllTypesNano msg = new TestAllTypesNano();
   2721     msg.optionalInt32 = 14;
   2722     msg.optionalFloat = 42.3f;
   2723     msg.optionalString = "String \"with' both quotes";
   2724     msg.optionalBytes = new byte[] {'"', '\0', 1, 8};
   2725     msg.optionalGroup = new TestAllTypesNano.OptionalGroup();
   2726     msg.optionalGroup.a = 15;
   2727     msg.repeatedInt64 = new long[2];
   2728     msg.repeatedInt64[0] = 1L;
   2729     msg.repeatedInt64[1] = -1L;
   2730     msg.repeatedBytes = new byte[2][];
   2731     msg.repeatedBytes[1] = new byte[] {'h', 'e', 'l', 'l', 'o'};
   2732     msg.repeatedGroup = new TestAllTypesNano.RepeatedGroup[2];
   2733     msg.repeatedGroup[0] = new TestAllTypesNano.RepeatedGroup();
   2734     msg.repeatedGroup[0].a = -27;
   2735     msg.repeatedGroup[1] = new TestAllTypesNano.RepeatedGroup();
   2736     msg.repeatedGroup[1].a = -72;
   2737     msg.optionalNestedMessage = new TestAllTypesNano.NestedMessage();
   2738     msg.optionalNestedMessage.bb = 7;
   2739     msg.repeatedNestedMessage = new TestAllTypesNano.NestedMessage[2];
   2740     msg.repeatedNestedMessage[0] = new TestAllTypesNano.NestedMessage();
   2741     msg.repeatedNestedMessage[0].bb = 77;
   2742     msg.repeatedNestedMessage[1] = new TestAllTypesNano.NestedMessage();
   2743     msg.repeatedNestedMessage[1].bb = 88;
   2744     msg.optionalNestedEnum = TestAllTypesNano.BAZ;
   2745     msg.repeatedNestedEnum = new int[2];
   2746     msg.repeatedNestedEnum[0] = TestAllTypesNano.BAR;
   2747     msg.repeatedNestedEnum[1] = TestAllTypesNano.FOO;
   2748     msg.repeatedStringPiece = new String[] {null, "world"};
   2749 
   2750     String protoPrint = msg.toString();
   2751     assertTrue(protoPrint.contains("optional_int32: 14"));
   2752     assertTrue(protoPrint.contains("optional_float: 42.3"));
   2753     assertTrue(protoPrint.contains("optional_double: 0.0"));
   2754     assertTrue(protoPrint.contains("optional_string: \"String \\u0022with\\u0027 both quotes\""));
   2755     assertTrue(protoPrint.contains("optional_bytes: \"\\\"\\000\\001\\010\""));
   2756     assertTrue(protoPrint.contains("optional_group <\n  a: 15\n>"));
   2757 
   2758     assertTrue(protoPrint.contains("repeated_int64: 1\nrepeated_int64: -1"));
   2759     assertFalse(protoPrint.contains("repeated_bytes: \"\"")); // null should be dropped
   2760     assertTrue(protoPrint.contains("repeated_bytes: \"hello\""));
   2761     assertTrue(protoPrint.contains("repeated_group <\n  a: -27\n>\n"
   2762             + "repeated_group <\n  a: -72\n>"));
   2763     assertTrue(protoPrint.contains("optional_nested_message <\n  bb: 7\n>"));
   2764     assertTrue(protoPrint.contains("repeated_nested_message <\n  bb: 77\n>\n"
   2765             + "repeated_nested_message <\n  bb: 88\n>"));
   2766     assertTrue(protoPrint.contains("optional_nested_enum: 3"));
   2767     assertTrue(protoPrint.contains("repeated_nested_enum: 2\nrepeated_nested_enum: 1"));
   2768     assertTrue(protoPrint.contains("default_int32: 41"));
   2769     assertTrue(protoPrint.contains("default_string: \"hello\""));
   2770     assertFalse(protoPrint.contains("repeated_string_piece: \"\""));  // null should be dropped
   2771     assertTrue(protoPrint.contains("repeated_string_piece: \"world\""));
   2772   }
   2773 
   2774   public void testMessageNanoPrinterAccessors() throws Exception {
   2775     TestNanoAccessors msg = new TestNanoAccessors();
   2776     msg.setOptionalInt32(13);
   2777     msg.setOptionalString("foo");
   2778     msg.setOptionalBytes(new byte[] {'"', '\0', 1, 8});
   2779     msg.optionalNestedMessage = new TestNanoAccessors.NestedMessage();
   2780     msg.optionalNestedMessage.setBb(7);
   2781     msg.setOptionalNestedEnum(TestNanoAccessors.BAZ);
   2782     msg.repeatedInt32 = new int[] { 1, -1 };
   2783     msg.repeatedString = new String[] { "Hello", "world" };
   2784     msg.repeatedBytes = new byte[2][];
   2785     msg.repeatedBytes[1] = new byte[] {'h', 'e', 'l', 'l', 'o'};
   2786     msg.repeatedNestedMessage = new TestNanoAccessors.NestedMessage[2];
   2787     msg.repeatedNestedMessage[0] = new TestNanoAccessors.NestedMessage();
   2788     msg.repeatedNestedMessage[0].setBb(5);
   2789     msg.repeatedNestedMessage[1] = new TestNanoAccessors.NestedMessage();
   2790     msg.repeatedNestedMessage[1].setBb(6);
   2791     msg.repeatedNestedEnum = new int[] { TestNanoAccessors.FOO, TestNanoAccessors.BAR };
   2792     msg.id = 33;
   2793 
   2794     String protoPrint = msg.toString();
   2795     assertTrue(protoPrint.contains("optional_int32: 13"));
   2796     assertTrue(protoPrint.contains("optional_string: \"foo\""));
   2797     assertTrue(protoPrint.contains("optional_bytes: \"\\\"\\000\\001\\010\""));
   2798     assertTrue(protoPrint.contains("optional_nested_message <\n  bb: 7\n>"));
   2799     assertTrue(protoPrint.contains("optional_nested_enum: 3"));
   2800     assertTrue(protoPrint.contains("repeated_int32: 1\nrepeated_int32: -1"));
   2801     assertTrue(protoPrint.contains("repeated_string: \"Hello\"\nrepeated_string: \"world\""));
   2802     assertFalse(protoPrint.contains("repeated_bytes: \"\"")); // null should be dropped
   2803     assertTrue(protoPrint.contains("repeated_bytes: \"hello\""));
   2804     assertTrue(protoPrint.contains("repeated_nested_message <\n  bb: 5\n>\n"
   2805             + "repeated_nested_message <\n  bb: 6\n>"));
   2806     assertTrue(protoPrint.contains("repeated_nested_enum: 1\nrepeated_nested_enum: 2"));
   2807     assertTrue(protoPrint.contains("id: 33"));
   2808   }
   2809 
   2810   public void testExtensions() throws Exception {
   2811     Extensions.ExtendableMessage message = new Extensions.ExtendableMessage();
   2812     message.field = 5;
   2813     int[] int32s = {1, 2};
   2814     int[] uint32s = {3, 4};
   2815     int[] sint32s = {-5, -6};
   2816     long[] int64s = {7, 8};
   2817     long[] uint64s = {9, 10};
   2818     long[] sint64s = {-11, -12};
   2819     int[] fixed32s = {13, 14};
   2820     int[] sfixed32s = {-15, -16};
   2821     long[] fixed64s = {17, 18};
   2822     long[] sfixed64s = {-19, -20};
   2823     boolean[] bools = {true, false};
   2824     float[] floats = {2.1f, 2.2f};
   2825     double[] doubles = {2.3, 2.4};
   2826     int[] enums = {Extensions.SECOND_VALUE, Extensions.FIRST_VALUE};
   2827     String[] strings = {"vijfentwintig", "twenty-six"};
   2828     byte[][] bytess = {{2, 7}, {2, 8}};
   2829     AnotherMessage another1 = new AnotherMessage();
   2830     another1.string = "er shi jiu";
   2831     another1.value = false;
   2832     AnotherMessage another2 = new AnotherMessage();
   2833     another2.string = "trente";
   2834     another2.value = true;
   2835     AnotherMessage[] messages = {another1, another2};
   2836     RepeatedExtensions.RepeatedGroup group1 = new RepeatedExtensions.RepeatedGroup();
   2837     group1.a = 31;
   2838     RepeatedExtensions.RepeatedGroup group2 = new RepeatedExtensions.RepeatedGroup();
   2839     group2.a = 32;
   2840     RepeatedExtensions.RepeatedGroup[] groups = {group1, group2};
   2841     assertFalse(message.hasExtension(RepeatedExtensions.repeatedInt32));
   2842     message.setExtension(RepeatedExtensions.repeatedInt32, int32s);
   2843     assertTrue(message.hasExtension(RepeatedExtensions.repeatedInt32));
   2844     assertFalse(message.hasExtension(RepeatedExtensions.repeatedUint32));
   2845     message.setExtension(RepeatedExtensions.repeatedUint32, uint32s);
   2846     assertTrue(message.hasExtension(RepeatedExtensions.repeatedUint32));
   2847     message.setExtension(RepeatedExtensions.repeatedSint32, sint32s);
   2848     assertFalse(message.hasExtension(RepeatedExtensions.repeatedInt64));
   2849     message.setExtension(RepeatedExtensions.repeatedInt64, int64s);
   2850     assertTrue(message.hasExtension(RepeatedExtensions.repeatedInt64));
   2851     assertFalse(message.hasExtension(RepeatedExtensions.repeatedUint64));
   2852     message.setExtension(RepeatedExtensions.repeatedUint64, uint64s);
   2853     assertTrue(message.hasExtension(RepeatedExtensions.repeatedUint64));
   2854     assertFalse(message.hasExtension(RepeatedExtensions.repeatedSint64));
   2855     message.setExtension(RepeatedExtensions.repeatedSint64, sint64s);
   2856     assertTrue(message.hasExtension(RepeatedExtensions.repeatedSint64));
   2857     assertFalse(message.hasExtension(RepeatedExtensions.repeatedFixed32));
   2858     message.setExtension(RepeatedExtensions.repeatedFixed32, fixed32s);
   2859     assertTrue(message.hasExtension(RepeatedExtensions.repeatedFixed32));
   2860     assertFalse(message.hasExtension(RepeatedExtensions.repeatedSfixed32));
   2861     message.setExtension(RepeatedExtensions.repeatedSfixed32, sfixed32s);
   2862     assertTrue(message.hasExtension(RepeatedExtensions.repeatedSfixed32));
   2863     assertFalse(message.hasExtension(RepeatedExtensions.repeatedFixed64));
   2864     message.setExtension(RepeatedExtensions.repeatedFixed64, fixed64s);
   2865     assertTrue(message.hasExtension(RepeatedExtensions.repeatedFixed64));
   2866     assertFalse(message.hasExtension(RepeatedExtensions.repeatedSfixed64));
   2867     message.setExtension(RepeatedExtensions.repeatedSfixed64, sfixed64s);
   2868     assertTrue(message.hasExtension(RepeatedExtensions.repeatedSfixed64));
   2869     assertFalse(message.hasExtension(RepeatedExtensions.repeatedBool));
   2870     message.setExtension(RepeatedExtensions.repeatedBool, bools);
   2871     assertTrue(message.hasExtension(RepeatedExtensions.repeatedBool));
   2872     assertFalse(message.hasExtension(RepeatedExtensions.repeatedFloat));
   2873     message.setExtension(RepeatedExtensions.repeatedFloat, floats);
   2874     assertTrue(message.hasExtension(RepeatedExtensions.repeatedFloat));
   2875     assertFalse(message.hasExtension(RepeatedExtensions.repeatedDouble));
   2876     message.setExtension(RepeatedExtensions.repeatedDouble, doubles);
   2877     assertTrue(message.hasExtension(RepeatedExtensions.repeatedDouble));
   2878     assertFalse(message.hasExtension(RepeatedExtensions.repeatedEnum));
   2879     message.setExtension(RepeatedExtensions.repeatedEnum, enums);
   2880     assertTrue(message.hasExtension(RepeatedExtensions.repeatedEnum));
   2881     assertFalse(message.hasExtension(RepeatedExtensions.repeatedString));
   2882     message.setExtension(RepeatedExtensions.repeatedString, strings);
   2883     assertTrue(message.hasExtension(RepeatedExtensions.repeatedString));
   2884     assertFalse(message.hasExtension(RepeatedExtensions.repeatedBytes));
   2885     message.setExtension(RepeatedExtensions.repeatedBytes, bytess);
   2886     assertTrue(message.hasExtension(RepeatedExtensions.repeatedBytes));
   2887     assertFalse(message.hasExtension(RepeatedExtensions.repeatedMessage));
   2888     message.setExtension(RepeatedExtensions.repeatedMessage, messages);
   2889     assertTrue(message.hasExtension(RepeatedExtensions.repeatedMessage));
   2890     assertFalse(message.hasExtension(RepeatedExtensions.repeatedGroup));
   2891     message.setExtension(RepeatedExtensions.repeatedGroup, groups);
   2892     assertTrue(message.hasExtension(RepeatedExtensions.repeatedGroup));
   2893 
   2894     byte[] data = MessageNano.toByteArray(message);
   2895     message = Extensions.ExtendableMessage.parseFrom(data);
   2896     assertEquals(5, message.field);
   2897 
   2898     // Test reading back using SingularExtensions: the retrieved value should equal the last
   2899     // in each array.
   2900     assertEquals(int32s[1], (int) message.getExtension(SingularExtensions.someInt32));
   2901     assertEquals(uint32s[1], (int) message.getExtension(SingularExtensions.someUint32));
   2902     assertEquals(sint32s[1], (int) message.getExtension(SingularExtensions.someSint32));
   2903     assertEquals(int64s[1], (long) message.getExtension(SingularExtensions.someInt64));
   2904     assertEquals(uint64s[1], (long) message.getExtension(SingularExtensions.someUint64));
   2905     assertEquals(sint64s[1], (long) message.getExtension(SingularExtensions.someSint64));
   2906     assertEquals(fixed32s[1], (int) message.getExtension(SingularExtensions.someFixed32));
   2907     assertEquals(sfixed32s[1], (int) message.getExtension(SingularExtensions.someSfixed32));
   2908     assertEquals(fixed64s[1], (long) message.getExtension(SingularExtensions.someFixed64));
   2909     assertEquals(sfixed64s[1], (long) message.getExtension(SingularExtensions.someSfixed64));
   2910     assertEquals(bools[1], (boolean) message.getExtension(SingularExtensions.someBool));
   2911     assertEquals(floats[1], (float) message.getExtension(SingularExtensions.someFloat));
   2912     assertEquals(doubles[1], (double) message.getExtension(SingularExtensions.someDouble));
   2913     assertEquals(enums[1], (int) message.getExtension(SingularExtensions.someEnum));
   2914     assertEquals(strings[1], message.getExtension(SingularExtensions.someString));
   2915     assertTrue(Arrays.equals(bytess[1], message.getExtension(SingularExtensions.someBytes)));
   2916     AnotherMessage deserializedMessage = message.getExtension(SingularExtensions.someMessage);
   2917     assertEquals(another2.string, deserializedMessage.string);
   2918     assertEquals(another2.value, deserializedMessage.value);
   2919     assertEquals(group2.a, message.getExtension(SingularExtensions.someGroup).a);
   2920 
   2921     // Test reading back using RepeatedExtensions: the arrays should be equal.
   2922     message = Extensions.ExtendableMessage.parseFrom(data);
   2923     assertEquals(5, message.field);
   2924     assertTrue(Arrays.equals(int32s, message.getExtension(RepeatedExtensions.repeatedInt32)));
   2925     assertTrue(Arrays.equals(uint32s, message.getExtension(RepeatedExtensions.repeatedUint32)));
   2926     assertTrue(Arrays.equals(sint32s, message.getExtension(RepeatedExtensions.repeatedSint32)));
   2927     assertTrue(Arrays.equals(int64s, message.getExtension(RepeatedExtensions.repeatedInt64)));
   2928     assertTrue(Arrays.equals(uint64s, message.getExtension(RepeatedExtensions.repeatedUint64)));
   2929     assertTrue(Arrays.equals(sint64s, message.getExtension(RepeatedExtensions.repeatedSint64)));
   2930     assertTrue(Arrays.equals(fixed32s, message.getExtension(RepeatedExtensions.repeatedFixed32)));
   2931     assertTrue(Arrays.equals(sfixed32s, message.getExtension(RepeatedExtensions.repeatedSfixed32)));
   2932     assertTrue(Arrays.equals(fixed64s, message.getExtension(RepeatedExtensions.repeatedFixed64)));
   2933     assertTrue(Arrays.equals(sfixed64s, message.getExtension(RepeatedExtensions.repeatedSfixed64)));
   2934     assertTrue(Arrays.equals(bools, message.getExtension(RepeatedExtensions.repeatedBool)));
   2935     assertTrue(Arrays.equals(floats, message.getExtension(RepeatedExtensions.repeatedFloat)));
   2936     assertTrue(Arrays.equals(doubles, message.getExtension(RepeatedExtensions.repeatedDouble)));
   2937     assertTrue(Arrays.equals(enums, message.getExtension(RepeatedExtensions.repeatedEnum)));
   2938     assertTrue(Arrays.equals(strings, message.getExtension(RepeatedExtensions.repeatedString)));
   2939     byte[][] deserializedRepeatedBytes = message.getExtension(RepeatedExtensions.repeatedBytes);
   2940     assertEquals(2, deserializedRepeatedBytes.length);
   2941     assertTrue(Arrays.equals(bytess[0], deserializedRepeatedBytes[0]));
   2942     assertTrue(Arrays.equals(bytess[1], deserializedRepeatedBytes[1]));
   2943     AnotherMessage[] deserializedRepeatedMessage =
   2944         message.getExtension(RepeatedExtensions.repeatedMessage);
   2945     assertEquals(2, deserializedRepeatedMessage.length);
   2946     assertEquals(another1.string, deserializedRepeatedMessage[0].string);
   2947     assertEquals(another1.value, deserializedRepeatedMessage[0].value);
   2948     assertEquals(another2.string, deserializedRepeatedMessage[1].string);
   2949     assertEquals(another2.value, deserializedRepeatedMessage[1].value);
   2950     RepeatedExtensions.RepeatedGroup[] deserializedRepeatedGroup =
   2951         message.getExtension(RepeatedExtensions.repeatedGroup);
   2952     assertEquals(2, deserializedRepeatedGroup.length);
   2953     assertEquals(group1.a, deserializedRepeatedGroup[0].a);
   2954     assertEquals(group2.a, deserializedRepeatedGroup[1].a);
   2955 
   2956     message = Extensions.ExtendableMessage.parseFrom(data);
   2957     assertEquals(5, message.field);
   2958     // Test hasExtension using PackedExtensions.
   2959     assertTrue(message.hasExtension(PackedExtensions.packedInt32));
   2960     assertTrue(message.hasExtension(PackedExtensions.packedUint32));
   2961     assertTrue(message.hasExtension(PackedExtensions.packedSint32));
   2962     assertTrue(message.hasExtension(PackedExtensions.packedInt64));
   2963     assertTrue(message.hasExtension(PackedExtensions.packedUint64));
   2964     assertTrue(message.hasExtension(PackedExtensions.packedSint64));
   2965     assertTrue(message.hasExtension(PackedExtensions.packedFixed32));
   2966     assertTrue(message.hasExtension(PackedExtensions.packedSfixed32));
   2967     assertTrue(message.hasExtension(PackedExtensions.packedFixed64));
   2968     assertTrue(message.hasExtension(PackedExtensions.packedSfixed64));
   2969     assertTrue(message.hasExtension(PackedExtensions.packedBool));
   2970     assertTrue(message.hasExtension(PackedExtensions.packedFloat));
   2971     assertTrue(message.hasExtension(PackedExtensions.packedDouble));
   2972     assertTrue(message.hasExtension(PackedExtensions.packedEnum));
   2973 
   2974     // Test reading back using PackedExtensions: the arrays should be equal, even the fields
   2975     // are non-packed.
   2976     assertTrue(Arrays.equals(int32s, message.getExtension(PackedExtensions.packedInt32)));
   2977     assertTrue(Arrays.equals(uint32s, message.getExtension(PackedExtensions.packedUint32)));
   2978     assertTrue(Arrays.equals(sint32s, message.getExtension(PackedExtensions.packedSint32)));
   2979     assertTrue(Arrays.equals(int64s, message.getExtension(PackedExtensions.packedInt64)));
   2980     assertTrue(Arrays.equals(uint64s, message.getExtension(PackedExtensions.packedUint64)));
   2981     assertTrue(Arrays.equals(sint64s, message.getExtension(PackedExtensions.packedSint64)));
   2982     assertTrue(Arrays.equals(fixed32s, message.getExtension(PackedExtensions.packedFixed32)));
   2983     assertTrue(Arrays.equals(sfixed32s, message.getExtension(PackedExtensions.packedSfixed32)));
   2984     assertTrue(Arrays.equals(fixed64s, message.getExtension(PackedExtensions.packedFixed64)));
   2985     assertTrue(Arrays.equals(sfixed64s, message.getExtension(PackedExtensions.packedSfixed64)));
   2986     assertTrue(Arrays.equals(bools, message.getExtension(PackedExtensions.packedBool)));
   2987     assertTrue(Arrays.equals(floats, message.getExtension(PackedExtensions.packedFloat)));
   2988     assertTrue(Arrays.equals(doubles, message.getExtension(PackedExtensions.packedDouble)));
   2989     assertTrue(Arrays.equals(enums, message.getExtension(PackedExtensions.packedEnum)));
   2990 
   2991     // Now set the packable extension values using PackedExtensions so they're serialized packed.
   2992     message.setExtension(PackedExtensions.packedInt32, int32s);
   2993     message.setExtension(PackedExtensions.packedUint32, uint32s);
   2994     message.setExtension(PackedExtensions.packedSint32, sint32s);
   2995     message.setExtension(PackedExtensions.packedInt64, int64s);
   2996     message.setExtension(PackedExtensions.packedUint64, uint64s);
   2997     message.setExtension(PackedExtensions.packedSint64, sint64s);
   2998     message.setExtension(PackedExtensions.packedFixed32, fixed32s);
   2999     message.setExtension(PackedExtensions.packedSfixed32, sfixed32s);
   3000     message.setExtension(PackedExtensions.packedFixed64, fixed64s);
   3001     message.setExtension(PackedExtensions.packedSfixed64, sfixed64s);
   3002     message.setExtension(PackedExtensions.packedBool, bools);
   3003     message.setExtension(PackedExtensions.packedFloat, floats);
   3004     message.setExtension(PackedExtensions.packedDouble, doubles);
   3005     message.setExtension(PackedExtensions.packedEnum, enums);
   3006 
   3007     // And read back using non-packed RepeatedExtensions.
   3008     byte[] data2 = MessageNano.toByteArray(message);
   3009     message = MessageNano.mergeFrom(new Extensions.ExtendableMessage(), data2);
   3010     assertTrue(Arrays.equals(int32s, message.getExtension(RepeatedExtensions.repeatedInt32)));
   3011     assertTrue(Arrays.equals(uint32s, message.getExtension(RepeatedExtensions.repeatedUint32)));
   3012     assertTrue(Arrays.equals(sint32s, message.getExtension(RepeatedExtensions.repeatedSint32)));
   3013     assertTrue(Arrays.equals(int64s, message.getExtension(RepeatedExtensions.repeatedInt64)));
   3014     assertTrue(Arrays.equals(uint64s, message.getExtension(RepeatedExtensions.repeatedUint64)));
   3015     assertTrue(Arrays.equals(sint64s, message.getExtension(RepeatedExtensions.repeatedSint64)));
   3016     assertTrue(Arrays.equals(fixed32s, message.getExtension(RepeatedExtensions.repeatedFixed32)));
   3017     assertTrue(Arrays.equals(sfixed32s, message.getExtension(RepeatedExtensions.repeatedSfixed32)));
   3018     assertTrue(Arrays.equals(fixed64s, message.getExtension(RepeatedExtensions.repeatedFixed64)));
   3019     assertTrue(Arrays.equals(sfixed64s, message.getExtension(RepeatedExtensions.repeatedSfixed64)));
   3020     assertTrue(Arrays.equals(bools, message.getExtension(RepeatedExtensions.repeatedBool)));
   3021     assertTrue(Arrays.equals(floats, message.getExtension(RepeatedExtensions.repeatedFloat)));
   3022     assertTrue(Arrays.equals(doubles, message.getExtension(RepeatedExtensions.repeatedDouble)));
   3023     assertTrue(Arrays.equals(enums, message.getExtension(RepeatedExtensions.repeatedEnum)));
   3024 
   3025     // Clone the message and ensure it's still equal.
   3026     Extensions.ExtendableMessage clone = message.clone();
   3027     assertEquals(clone, message);
   3028   }
   3029 
   3030   public void testNullExtensions() throws Exception {
   3031     // Check that clearing the extension on an empty message is a no-op.
   3032     Extensions.ExtendableMessage message = new Extensions.ExtendableMessage();
   3033     assertFalse(message.hasExtension(SingularExtensions.someMessage));
   3034     message.setExtension(SingularExtensions.someMessage, null);
   3035     assertFalse(message.hasExtension(SingularExtensions.someMessage));
   3036     assertEquals(0, MessageNano.toByteArray(message).length);
   3037 
   3038     // Check that the message is empty after setting and clearing an extension.
   3039     AnotherMessage another = new AnotherMessage();
   3040     assertFalse(message.hasExtension(SingularExtensions.someMessage));
   3041     message.setExtension(SingularExtensions.someMessage, another);
   3042     assertTrue(message.hasExtension(SingularExtensions.someMessage));
   3043     assertTrue(MessageNano.toByteArray(message).length > 0);
   3044     message.setExtension(SingularExtensions.someMessage, null);
   3045     assertFalse(message.hasExtension(SingularExtensions.someMessage));
   3046     assertEquals(0, MessageNano.toByteArray(message).length);
   3047   }
   3048 
   3049   public void testExtensionsMutation() {
   3050     Extensions.ExtendableMessage extendableMessage = new Extensions.ExtendableMessage();
   3051     extendableMessage.setExtension(SingularExtensions.someMessage,
   3052         new Extensions.AnotherMessage());
   3053 
   3054     extendableMessage.getExtension(SingularExtensions.someMessage).string = "not empty";
   3055 
   3056     assertEquals("not empty",
   3057         extendableMessage.getExtension(SingularExtensions.someMessage).string);
   3058   }
   3059 
   3060   public void testExtensionsMutation_Equals() throws InvalidProtocolBufferNanoException {
   3061     Extensions.ExtendableMessage extendableMessage = new Extensions.ExtendableMessage();
   3062     extendableMessage.field = 5;
   3063     int int32 = 42;
   3064     int[] uint32s = {3, 4};
   3065     int[] sint32s = {-5, -6};
   3066     long[] int64s = {7, 8};
   3067     long[] uint64s = {9, 10};
   3068     long[] sint64s = {-11, -12};
   3069     int[] fixed32s = {13, 14};
   3070     int[] sfixed32s = {-15, -16};
   3071     long[] fixed64s = {17, 18};
   3072     long[] sfixed64s = {-19, -20};
   3073     boolean[] bools = {true, false};
   3074     float[] floats = {2.1f, 2.2f};
   3075     double[] doubles = {2.3, 2.4};
   3076     int[] enums = {Extensions.SECOND_VALUE, Extensions.FIRST_VALUE};
   3077     String[] strings = {"vijfentwintig", "twenty-six"};
   3078     byte[][] bytess = {{2, 7}, {2, 8}};
   3079     AnotherMessage another1 = new AnotherMessage();
   3080     another1.string = "er shi jiu";
   3081     another1.value = false;
   3082     AnotherMessage another2 = new AnotherMessage();
   3083     another2.string = "trente";
   3084     another2.value = true;
   3085     AnotherMessage[] messages = {another1, another2};
   3086     RepeatedExtensions.RepeatedGroup group1 = new RepeatedExtensions.RepeatedGroup();
   3087     group1.a = 31;
   3088     RepeatedExtensions.RepeatedGroup group2 = new RepeatedExtensions.RepeatedGroup();
   3089     group2.a = 32;
   3090     RepeatedExtensions.RepeatedGroup[] groups = {group1, group2};
   3091     extendableMessage.setExtension(SingularExtensions.someInt32, int32);
   3092     extendableMessage.setExtension(RepeatedExtensions.repeatedUint32, uint32s);
   3093     extendableMessage.setExtension(RepeatedExtensions.repeatedSint32, sint32s);
   3094     extendableMessage.setExtension(RepeatedExtensions.repeatedInt64, int64s);
   3095     extendableMessage.setExtension(RepeatedExtensions.repeatedUint64, uint64s);
   3096     extendableMessage.setExtension(RepeatedExtensions.repeatedSint64, sint64s);
   3097     extendableMessage.setExtension(RepeatedExtensions.repeatedFixed32, fixed32s);
   3098     extendableMessage.setExtension(RepeatedExtensions.repeatedSfixed32, sfixed32s);
   3099     extendableMessage.setExtension(RepeatedExtensions.repeatedFixed64, fixed64s);
   3100     extendableMessage.setExtension(RepeatedExtensions.repeatedSfixed64, sfixed64s);
   3101     extendableMessage.setExtension(RepeatedExtensions.repeatedBool, bools);
   3102     extendableMessage.setExtension(RepeatedExtensions.repeatedFloat, floats);
   3103     extendableMessage.setExtension(RepeatedExtensions.repeatedDouble, doubles);
   3104     extendableMessage.setExtension(RepeatedExtensions.repeatedEnum, enums);
   3105     extendableMessage.setExtension(RepeatedExtensions.repeatedString, strings);
   3106     extendableMessage.setExtension(RepeatedExtensions.repeatedBytes, bytess);
   3107     extendableMessage.setExtension(RepeatedExtensions.repeatedMessage, messages);
   3108     extendableMessage.setExtension(RepeatedExtensions.repeatedGroup, groups);
   3109 
   3110     byte[] data = MessageNano.toByteArray(extendableMessage);
   3111 
   3112     extendableMessage = Extensions.ExtendableMessage.parseFrom(data);
   3113     Extensions.ExtendableMessage messageCopy = Extensions.ExtendableMessage.parseFrom(data);
   3114 
   3115     // Without deserialising.
   3116     assertEquals(extendableMessage, messageCopy);
   3117     assertEquals(extendableMessage.hashCode(), messageCopy.hashCode());
   3118 
   3119     // Only one deserialized.
   3120     extendableMessage.getExtension(SingularExtensions.someInt32);
   3121     extendableMessage.getExtension(RepeatedExtensions.repeatedUint32);
   3122     extendableMessage.getExtension(RepeatedExtensions.repeatedSint32);
   3123     extendableMessage.getExtension(RepeatedExtensions.repeatedInt64);
   3124     extendableMessage.getExtension(RepeatedExtensions.repeatedUint64);
   3125     extendableMessage.getExtension(RepeatedExtensions.repeatedSint64);
   3126     extendableMessage.getExtension(RepeatedExtensions.repeatedFixed32);
   3127     extendableMessage.getExtension(RepeatedExtensions.repeatedSfixed32);
   3128     extendableMessage.getExtension(RepeatedExtensions.repeatedFixed64);
   3129     extendableMessage.getExtension(RepeatedExtensions.repeatedSfixed64);
   3130     extendableMessage.getExtension(RepeatedExtensions.repeatedBool);
   3131     extendableMessage.getExtension(RepeatedExtensions.repeatedFloat);
   3132     extendableMessage.getExtension(RepeatedExtensions.repeatedDouble);
   3133     extendableMessage.getExtension(RepeatedExtensions.repeatedEnum);
   3134     extendableMessage.getExtension(RepeatedExtensions.repeatedString);
   3135     extendableMessage.getExtension(RepeatedExtensions.repeatedBytes);
   3136     extendableMessage.getExtension(RepeatedExtensions.repeatedMessage);
   3137     extendableMessage.getExtension(RepeatedExtensions.repeatedGroup);
   3138     assertEquals(extendableMessage, messageCopy);
   3139     assertEquals(extendableMessage.hashCode(), messageCopy.hashCode());
   3140 
   3141     // Both deserialized.
   3142     messageCopy.getExtension(SingularExtensions.someInt32);
   3143     messageCopy.getExtension(RepeatedExtensions.repeatedUint32);
   3144     messageCopy.getExtension(RepeatedExtensions.repeatedSint32);
   3145     messageCopy.getExtension(RepeatedExtensions.repeatedInt64);
   3146     messageCopy.getExtension(RepeatedExtensions.repeatedUint64);
   3147     messageCopy.getExtension(RepeatedExtensions.repeatedSint64);
   3148     messageCopy.getExtension(RepeatedExtensions.repeatedFixed32);
   3149     messageCopy.getExtension(RepeatedExtensions.repeatedSfixed32);
   3150     messageCopy.getExtension(RepeatedExtensions.repeatedFixed64);
   3151     messageCopy.getExtension(RepeatedExtensions.repeatedSfixed64);
   3152     messageCopy.getExtension(RepeatedExtensions.repeatedBool);
   3153     messageCopy.getExtension(RepeatedExtensions.repeatedFloat);
   3154     messageCopy.getExtension(RepeatedExtensions.repeatedDouble);
   3155     messageCopy.getExtension(RepeatedExtensions.repeatedEnum);
   3156     messageCopy.getExtension(RepeatedExtensions.repeatedString);
   3157     messageCopy.getExtension(RepeatedExtensions.repeatedBytes);
   3158     messageCopy.getExtension(RepeatedExtensions.repeatedMessage);
   3159     messageCopy.getExtension(RepeatedExtensions.repeatedGroup);
   3160     assertEquals(extendableMessage, messageCopy);
   3161     assertEquals(extendableMessage.hashCode(), messageCopy.hashCode());
   3162 
   3163     // Change one, make sure they are still different.
   3164     messageCopy.getExtension(RepeatedExtensions.repeatedMessage)[0].string = "not empty";
   3165     assertFalse(extendableMessage.equals(messageCopy));
   3166 
   3167     // Even if the extension hasn't been deserialized.
   3168     extendableMessage = Extensions.ExtendableMessage.parseFrom(data);
   3169     assertFalse(extendableMessage.equals(messageCopy));
   3170   }
   3171 
   3172   public void testExtensionsCaching() {
   3173     Extensions.ExtendableMessage extendableMessage = new Extensions.ExtendableMessage();
   3174     extendableMessage.setExtension(SingularExtensions.someMessage,
   3175         new Extensions.AnotherMessage());
   3176     assertSame("Consecutive calls to getExtensions should return the same object",
   3177         extendableMessage.getExtension(SingularExtensions.someMessage),
   3178         extendableMessage.getExtension(SingularExtensions.someMessage));
   3179   }
   3180 
   3181   public void testUnknownFields() throws Exception {
   3182     // Check that we roundtrip (serialize and deserialize) unrecognized fields.
   3183     AnotherMessage message = new AnotherMessage();
   3184     message.string = "Hello World";
   3185     message.value = false;
   3186 
   3187     byte[] bytes = MessageNano.toByteArray(message);
   3188     int extraFieldSize = CodedOutputStream.computeStringSize(1001, "This is an unknown field");
   3189     byte[] newBytes = new byte[bytes.length + extraFieldSize];
   3190     System.arraycopy(bytes, 0, newBytes, 0, bytes.length);
   3191     CodedOutputStream.newInstance(newBytes, bytes.length, extraFieldSize).writeString(1001,
   3192         "This is an unknown field");
   3193 
   3194     // Deserialize with an unknown field.
   3195     AnotherMessage deserialized = AnotherMessage.parseFrom(newBytes);
   3196     byte[] serialized = MessageNano.toByteArray(deserialized);
   3197 
   3198     assertEquals(newBytes.length, serialized.length);
   3199 
   3200     // Clear, and make sure it clears everything.
   3201     deserialized.clear();
   3202     assertEquals(0, MessageNano.toByteArray(deserialized).length);
   3203   }
   3204 
   3205   public void testMergeFrom() throws Exception {
   3206     SimpleMessageNano message = new SimpleMessageNano();
   3207     message.d = 123;
   3208     byte[] bytes = MessageNano.toByteArray(message);
   3209 
   3210     SimpleMessageNano newMessage = MessageNano.mergeFrom(new SimpleMessageNano(), bytes);
   3211     assertEquals(message.d, newMessage.d);
   3212   }
   3213 
   3214   public void testJavaKeyword() throws Exception {
   3215     TestAllTypesNano msg = new TestAllTypesNano();
   3216     msg.synchronized_ = 123;
   3217     assertEquals(123, msg.synchronized_);
   3218   }
   3219 
   3220   public void testReferenceTypesForPrimitives() throws Exception {
   3221     NanoReferenceTypes.TestAllTypesNano message = new NanoReferenceTypes.TestAllTypesNano();
   3222 
   3223     // Base check - when nothing is set, we serialize nothing.
   3224     assertHasWireData(message, false);
   3225 
   3226     message.defaultBool = true;
   3227     assertHasWireData(message, true);
   3228 
   3229     message.defaultBool = false;
   3230     assertHasWireData(message, true);
   3231 
   3232     message.defaultBool = null;
   3233     assertHasWireData(message, false);
   3234 
   3235     message.defaultInt32 = 5;
   3236     assertHasWireData(message, true);
   3237 
   3238     message.defaultInt32 = null;
   3239     assertHasWireData(message, false);
   3240 
   3241     message.defaultInt64 = 123456L;
   3242     assertHasWireData(message, true);
   3243 
   3244     message.defaultInt64 = null;
   3245     assertHasWireData(message, false);
   3246 
   3247     message.defaultFloat = 1f;
   3248     assertHasWireData(message, true);
   3249 
   3250     message.defaultFloat = null;
   3251     assertHasWireData(message, false);
   3252 
   3253     message.defaultDouble = 2.1;
   3254     assertHasWireData(message, true);
   3255 
   3256     message.defaultDouble = null;
   3257     assertHasWireData(message, false);
   3258 
   3259     message.defaultString = "hello";
   3260     assertHasWireData(message, true);
   3261 
   3262     message.defaultString = null;
   3263     assertHasWireData(message, false);
   3264 
   3265     message.defaultBytes = new byte[] { 1, 2, 3 };
   3266     assertHasWireData(message, true);
   3267 
   3268     message.defaultBytes = null;
   3269     assertHasWireData(message, false);
   3270   }
   3271 
   3272   public void testHashCodeEquals() throws Exception {
   3273     // Complete equality:
   3274     TestAllTypesNano a = createMessageForHashCodeEqualsTest();
   3275     TestAllTypesNano aEquivalent = createMessageForHashCodeEqualsTest();
   3276 
   3277     assertTrue(MessageNano.messageNanoEquals(a, aEquivalent));
   3278     assertFalse(MessageNano.messageNanoEquals(a, new TestAllTypesNano()));
   3279 
   3280     // Null and empty array for repeated fields equality:
   3281     TestAllTypesNano b = createMessageForHashCodeEqualsTest();
   3282     b.repeatedBool = null;
   3283     b.repeatedFloat = new float[0];
   3284     TestAllTypesNano bEquivalent = createMessageForHashCodeEqualsTest();
   3285     bEquivalent.repeatedBool = new boolean[0];
   3286     bEquivalent.repeatedFloat = null;
   3287 
   3288     // Ref-element-type repeated fields use non-null subsequence equality:
   3289     TestAllTypesNano c = createMessageForHashCodeEqualsTest();
   3290     c.repeatedString = null;
   3291     c.repeatedStringPiece = new String[] {null, "one", null, "two"};
   3292     c.repeatedBytes = new byte[][] {{3, 4}, null};
   3293     TestAllTypesNano cEquivalent = createMessageForHashCodeEqualsTest();
   3294     cEquivalent.repeatedString = new String[3];
   3295     cEquivalent.repeatedStringPiece = new String[] {"one", "two", null};
   3296     cEquivalent.repeatedBytes = new byte[][] {{3, 4}};
   3297 
   3298     // Complete equality for messages with has fields:
   3299     TestAllTypesNanoHas d = createMessageWithHasForHashCodeEqualsTest();
   3300     TestAllTypesNanoHas dEquivalent = createMessageWithHasForHashCodeEqualsTest();
   3301 
   3302     // If has-fields exist, fields with the same default values but
   3303     // different has-field values are different.
   3304     TestAllTypesNanoHas e = createMessageWithHasForHashCodeEqualsTest();
   3305     e.optionalInt32++; // make different from d
   3306     e.hasDefaultString = false;
   3307     TestAllTypesNanoHas eDifferent = createMessageWithHasForHashCodeEqualsTest();
   3308     eDifferent.optionalInt32 = e.optionalInt32;
   3309     eDifferent.hasDefaultString = true;
   3310 
   3311     // Complete equality for messages with accessors:
   3312     TestNanoAccessors f = createMessageWithAccessorsForHashCodeEqualsTest();
   3313     TestNanoAccessors fEquivalent = createMessageWithAccessorsForHashCodeEqualsTest();
   3314 
   3315     // If using accessors, explicitly setting a field to its default value
   3316     // should make the message different.
   3317     TestNanoAccessors g = createMessageWithAccessorsForHashCodeEqualsTest();
   3318     g.setOptionalInt32(g.getOptionalInt32() + 1); // make different from f
   3319     g.clearDefaultString();
   3320     TestNanoAccessors gDifferent = createMessageWithAccessorsForHashCodeEqualsTest();
   3321     gDifferent.setOptionalInt32(g.getOptionalInt32());
   3322     gDifferent.setDefaultString(g.getDefaultString());
   3323 
   3324     // Complete equality for reference typed messages:
   3325     NanoReferenceTypes.TestAllTypesNano h = createRefTypedMessageForHashCodeEqualsTest();
   3326     NanoReferenceTypes.TestAllTypesNano hEquivalent = createRefTypedMessageForHashCodeEqualsTest();
   3327 
   3328     // Inequality of null and default value for reference typed messages:
   3329     NanoReferenceTypes.TestAllTypesNano i = createRefTypedMessageForHashCodeEqualsTest();
   3330     i.optionalInt32 = 1; // make different from h
   3331     i.optionalFloat = null;
   3332     NanoReferenceTypes.TestAllTypesNano iDifferent = createRefTypedMessageForHashCodeEqualsTest();
   3333     iDifferent.optionalInt32 = i.optionalInt32;
   3334     iDifferent.optionalFloat = 0.0f;
   3335 
   3336     HashMap<MessageNano, String> hashMap = new HashMap<MessageNano, String>();
   3337     hashMap.put(a, "a");
   3338     hashMap.put(b, "b");
   3339     hashMap.put(c, "c");
   3340     hashMap.put(d, "d");
   3341     hashMap.put(e, "e");
   3342     hashMap.put(f, "f");
   3343     hashMap.put(g, "g");
   3344     hashMap.put(h, "h");
   3345     hashMap.put(i, "i");
   3346 
   3347     assertEquals(9, hashMap.size()); // a-i should be different from each other.
   3348 
   3349     assertEquals("a", hashMap.get(a));
   3350     assertEquals("a", hashMap.get(aEquivalent));
   3351 
   3352     assertEquals("b", hashMap.get(b));
   3353     assertEquals("b", hashMap.get(bEquivalent));
   3354 
   3355     assertEquals("c", hashMap.get(c));
   3356     assertEquals("c", hashMap.get(cEquivalent));
   3357 
   3358     assertEquals("d", hashMap.get(d));
   3359     assertEquals("d", hashMap.get(dEquivalent));
   3360 
   3361     assertEquals("e", hashMap.get(e));
   3362     assertNull(hashMap.get(eDifferent));
   3363 
   3364     assertEquals("f", hashMap.get(f));
   3365     assertEquals("f", hashMap.get(fEquivalent));
   3366 
   3367     assertEquals("g", hashMap.get(g));
   3368     assertNull(hashMap.get(gDifferent));
   3369 
   3370     assertEquals("h", hashMap.get(h));
   3371     assertEquals("h", hashMap.get(hEquivalent));
   3372 
   3373     assertEquals("i", hashMap.get(i));
   3374     assertNull(hashMap.get(iDifferent));
   3375   }
   3376 
   3377   private TestAllTypesNano createMessageForHashCodeEqualsTest() {
   3378     TestAllTypesNano message = new TestAllTypesNano();
   3379     message.optionalInt32 = 5;
   3380     message.optionalInt64 = 777;
   3381     message.optionalFloat = 1.0f;
   3382     message.optionalDouble = 2.0;
   3383     message.optionalBool = true;
   3384     message.optionalString = "Hello";
   3385     message.optionalBytes = new byte[] { 1, 2, 3 };
   3386     message.optionalNestedMessage = new TestAllTypesNano.NestedMessage();
   3387     message.optionalNestedMessage.bb = 27;
   3388     message.optionalNestedEnum = TestAllTypesNano.BAR;
   3389     message.repeatedInt32 = new int[] { 5, 6, 7, 8 };
   3390     message.repeatedInt64 = new long[] { 27L, 28L, 29L };
   3391     message.repeatedFloat = new float[] { 5.0f, 6.0f };
   3392     message.repeatedDouble = new double[] { 99.1, 22.5 };
   3393     message.repeatedBool = new boolean[] { true, false, true };
   3394     message.repeatedString = new String[] { "One", "Two" };
   3395     message.repeatedBytes = new byte[][] { { 2, 7 }, { 2, 7 } };
   3396     message.repeatedNestedMessage = new TestAllTypesNano.NestedMessage[] {
   3397       message.optionalNestedMessage,
   3398       message.optionalNestedMessage
   3399     };
   3400     message.repeatedNestedEnum = new int[] {
   3401       TestAllTypesNano.BAR,
   3402       TestAllTypesNano.BAZ
   3403     };
   3404     return message;
   3405   }
   3406 
   3407   private TestAllTypesNanoHas createMessageWithHasForHashCodeEqualsTest() {
   3408     TestAllTypesNanoHas message = new TestAllTypesNanoHas();
   3409     message.optionalInt32 = 5;
   3410     message.optionalString = "Hello";
   3411     message.optionalBytes = new byte[] { 1, 2, 3 };
   3412     message.optionalNestedMessage = new TestAllTypesNanoHas.NestedMessage();
   3413     message.optionalNestedMessage.bb = 27;
   3414     message.optionalNestedEnum = TestAllTypesNano.BAR;
   3415     message.repeatedInt32 = new int[] { 5, 6, 7, 8 };
   3416     message.repeatedString = new String[] { "One", "Two" };
   3417     message.repeatedBytes = new byte[][] { { 2, 7 }, { 2, 7 } };
   3418     message.repeatedNestedMessage = new TestAllTypesNanoHas.NestedMessage[] {
   3419       message.optionalNestedMessage,
   3420       message.optionalNestedMessage
   3421     };
   3422     message.repeatedNestedEnum = new int[] {
   3423       TestAllTypesNano.BAR,
   3424       TestAllTypesNano.BAZ
   3425     };
   3426     return message;
   3427   }
   3428 
   3429   private TestNanoAccessors createMessageWithAccessorsForHashCodeEqualsTest() {
   3430     TestNanoAccessors message = new TestNanoAccessors()
   3431         .setOptionalInt32(5)
   3432         .setOptionalString("Hello")
   3433         .setOptionalBytes(new byte[] {1, 2, 3})
   3434         .setOptionalNestedEnum(TestNanoAccessors.BAR);
   3435     message.optionalNestedMessage = new TestNanoAccessors.NestedMessage().setBb(27);
   3436     message.repeatedInt32 = new int[] { 5, 6, 7, 8 };
   3437     message.repeatedString = new String[] { "One", "Two" };
   3438     message.repeatedBytes = new byte[][] { { 2, 7 }, { 2, 7 } };
   3439     message.repeatedNestedMessage = new TestNanoAccessors.NestedMessage[] {
   3440       message.optionalNestedMessage,
   3441       message.optionalNestedMessage
   3442     };
   3443     message.repeatedNestedEnum = new int[] {
   3444       TestAllTypesNano.BAR,
   3445       TestAllTypesNano.BAZ
   3446     };
   3447     return message;
   3448   }
   3449 
   3450   private NanoReferenceTypes.TestAllTypesNano createRefTypedMessageForHashCodeEqualsTest() {
   3451     NanoReferenceTypes.TestAllTypesNano message = new NanoReferenceTypes.TestAllTypesNano();
   3452     message.optionalInt32 = 5;
   3453     message.optionalInt64 = 777L;
   3454     message.optionalFloat = 1.0f;
   3455     message.optionalDouble = 2.0;
   3456     message.optionalBool = true;
   3457     message.optionalString = "Hello";
   3458     message.optionalBytes = new byte[] { 1, 2, 3 };
   3459     message.optionalNestedMessage =
   3460         new NanoReferenceTypes.TestAllTypesNano.NestedMessage();
   3461     message.optionalNestedMessage.foo = 27;
   3462     message.optionalNestedEnum = NanoReferenceTypes.TestAllTypesNano.BAR;
   3463     message.repeatedInt32 = new int[] { 5, 6, 7, 8 };
   3464     message.repeatedInt64 = new long[] { 27L, 28L, 29L };
   3465     message.repeatedFloat = new float[] { 5.0f, 6.0f };
   3466     message.repeatedDouble = new double[] { 99.1, 22.5 };
   3467     message.repeatedBool = new boolean[] { true, false, true };
   3468     message.repeatedString = new String[] { "One", "Two" };
   3469     message.repeatedBytes = new byte[][] { { 2, 7 }, { 2, 7 } };
   3470     message.repeatedNestedMessage =
   3471         new NanoReferenceTypes.TestAllTypesNano.NestedMessage[] {
   3472           message.optionalNestedMessage,
   3473           message.optionalNestedMessage
   3474         };
   3475     message.repeatedNestedEnum = new int[] {
   3476       NanoReferenceTypes.TestAllTypesNano.BAR,
   3477       NanoReferenceTypes.TestAllTypesNano.BAZ
   3478     };
   3479     return message;
   3480   }
   3481 
   3482   public void testEqualsWithSpecialFloatingPointValues() throws Exception {
   3483     // Checks that the nano implementation complies with Object.equals() when treating
   3484     // floating point numbers, i.e. NaN == NaN and +0.0 != -0.0.
   3485     // This test assumes that the generated equals() implementations are symmetric, so
   3486     // there will only be one direction for each equality check.
   3487 
   3488     TestAllTypesNano m1 = new TestAllTypesNano();
   3489     m1.optionalFloat = Float.NaN;
   3490     m1.optionalDouble = Double.NaN;
   3491     TestAllTypesNano m2 = new TestAllTypesNano();
   3492     m2.optionalFloat = Float.NaN;
   3493     m2.optionalDouble = Double.NaN;
   3494     assertTrue(m1.equals(m2));
   3495     assertTrue(m1.equals(
   3496         MessageNano.mergeFrom(new TestAllTypesNano(), MessageNano.toByteArray(m1))));
   3497 
   3498     m1.optionalFloat = +0f;
   3499     m2.optionalFloat = -0f;
   3500     assertFalse(m1.equals(m2));
   3501 
   3502     m1.optionalFloat = -0f;
   3503     m1.optionalDouble = +0d;
   3504     m2.optionalDouble = -0d;
   3505     assertFalse(m1.equals(m2));
   3506 
   3507     m1.optionalDouble = -0d;
   3508     assertTrue(m1.equals(m2));
   3509     assertFalse(m1.equals(new TestAllTypesNano())); // -0 does not equals() the default +0
   3510     assertTrue(m1.equals(
   3511         MessageNano.mergeFrom(new TestAllTypesNano(), MessageNano.toByteArray(m1))));
   3512 
   3513     // -------
   3514 
   3515     TestAllTypesNanoHas m3 = new TestAllTypesNanoHas();
   3516     m3.optionalFloat = Float.NaN;
   3517     m3.hasOptionalFloat = true;
   3518     m3.optionalDouble = Double.NaN;
   3519     m3.hasOptionalDouble = true;
   3520     TestAllTypesNanoHas m4 = new TestAllTypesNanoHas();
   3521     m4.optionalFloat = Float.NaN;
   3522     m4.hasOptionalFloat = true;
   3523     m4.optionalDouble = Double.NaN;
   3524     m4.hasOptionalDouble = true;
   3525     assertTrue(m3.equals(m4));
   3526     assertTrue(m3.equals(
   3527         MessageNano.mergeFrom(new TestAllTypesNanoHas(), MessageNano.toByteArray(m3))));
   3528 
   3529     m3.optionalFloat = +0f;
   3530     m4.optionalFloat = -0f;
   3531     assertFalse(m3.equals(m4));
   3532 
   3533     m3.optionalFloat = -0f;
   3534     m3.optionalDouble = +0d;
   3535     m4.optionalDouble = -0d;
   3536     assertFalse(m3.equals(m4));
   3537 
   3538     m3.optionalDouble = -0d;
   3539     m3.hasOptionalFloat = false;  // -0 does not equals() the default +0,
   3540     m3.hasOptionalDouble = false; // so these incorrect 'has' flags should be disregarded.
   3541     assertTrue(m3.equals(m4));    // note: m4 has the 'has' flags set.
   3542     assertFalse(m3.equals(new TestAllTypesNanoHas())); // note: the new message has +0 defaults
   3543     assertTrue(m3.equals(
   3544         MessageNano.mergeFrom(new TestAllTypesNanoHas(), MessageNano.toByteArray(m3))));
   3545                                   // note: the deserialized message has the 'has' flags set.
   3546 
   3547     // -------
   3548 
   3549     TestNanoAccessors m5 = new TestNanoAccessors();
   3550     m5.setOptionalFloat(Float.NaN);
   3551     m5.setOptionalDouble(Double.NaN);
   3552     TestNanoAccessors m6 = new TestNanoAccessors();
   3553     m6.setOptionalFloat(Float.NaN);
   3554     m6.setOptionalDouble(Double.NaN);
   3555     assertTrue(m5.equals(m6));
   3556     assertTrue(m5.equals(
   3557         MessageNano.mergeFrom(new TestNanoAccessors(), MessageNano.toByteArray(m6))));
   3558 
   3559     m5.setOptionalFloat(+0f);
   3560     m6.setOptionalFloat(-0f);
   3561     assertFalse(m5.equals(m6));
   3562 
   3563     m5.setOptionalFloat(-0f);
   3564     m5.setOptionalDouble(+0d);
   3565     m6.setOptionalDouble(-0d);
   3566     assertFalse(m5.equals(m6));
   3567 
   3568     m5.setOptionalDouble(-0d);
   3569     assertTrue(m5.equals(m6));
   3570     assertFalse(m5.equals(new TestNanoAccessors()));
   3571     assertTrue(m5.equals(
   3572         MessageNano.mergeFrom(new TestNanoAccessors(), MessageNano.toByteArray(m6))));
   3573 
   3574     // -------
   3575 
   3576     NanoReferenceTypes.TestAllTypesNano m7 = new NanoReferenceTypes.TestAllTypesNano();
   3577     m7.optionalFloat = Float.NaN;
   3578     m7.optionalDouble = Double.NaN;
   3579     NanoReferenceTypes.TestAllTypesNano m8 = new NanoReferenceTypes.TestAllTypesNano();
   3580     m8.optionalFloat = Float.NaN;
   3581     m8.optionalDouble = Double.NaN;
   3582     assertTrue(m7.equals(m8));
   3583     assertTrue(m7.equals(MessageNano.mergeFrom(
   3584         new NanoReferenceTypes.TestAllTypesNano(), MessageNano.toByteArray(m7))));
   3585 
   3586     m7.optionalFloat = +0f;
   3587     m8.optionalFloat = -0f;
   3588     assertFalse(m7.equals(m8));
   3589 
   3590     m7.optionalFloat = -0f;
   3591     m7.optionalDouble = +0d;
   3592     m8.optionalDouble = -0d;
   3593     assertFalse(m7.equals(m8));
   3594 
   3595     m7.optionalDouble = -0d;
   3596     assertTrue(m7.equals(m8));
   3597     assertFalse(m7.equals(new NanoReferenceTypes.TestAllTypesNano()));
   3598     assertTrue(m7.equals(MessageNano.mergeFrom(
   3599         new NanoReferenceTypes.TestAllTypesNano(), MessageNano.toByteArray(m7))));
   3600   }
   3601 
   3602   public void testNullRepeatedFields() throws Exception {
   3603     // Check that serialization after explicitly setting a repeated field
   3604     // to null doesn't NPE.
   3605     TestAllTypesNano message = new TestAllTypesNano();
   3606     message.repeatedInt32 = null;
   3607     MessageNano.toByteArray(message);  // should not NPE
   3608     message.toString(); // should not NPE
   3609 
   3610     message.repeatedNestedEnum = null;
   3611     MessageNano.toByteArray(message);  // should not NPE
   3612     message.toString(); // should not NPE
   3613 
   3614     message.repeatedBytes = null;
   3615     MessageNano.toByteArray(message); // should not NPE
   3616     message.toString(); // should not NPE
   3617 
   3618     message.repeatedNestedMessage = null;
   3619     MessageNano.toByteArray(message); // should not NPE
   3620     message.toString(); // should not NPE
   3621 
   3622     message.repeatedPackedInt32 = null;
   3623     MessageNano.toByteArray(message); // should not NPE
   3624     message.toString(); // should not NPE
   3625 
   3626     message.repeatedPackedNestedEnum = null;
   3627     MessageNano.toByteArray(message); // should not NPE
   3628     message.toString(); // should not NPE
   3629 
   3630     // Create a second message to merge into message.
   3631     TestAllTypesNano secondMessage = new TestAllTypesNano();
   3632     secondMessage.repeatedInt32 = new int[] {1, 2, 3};
   3633     secondMessage.repeatedNestedEnum = new int[] {
   3634       TestAllTypesNano.FOO, TestAllTypesNano.BAR
   3635     };
   3636     secondMessage.repeatedBytes = new byte[][] {{1, 2}, {3, 4}};
   3637     TestAllTypesNano.NestedMessage nested =
   3638         new TestAllTypesNano.NestedMessage();
   3639     nested.bb = 55;
   3640     secondMessage.repeatedNestedMessage =
   3641         new TestAllTypesNano.NestedMessage[] {nested};
   3642     secondMessage.repeatedPackedInt32 = new int[] {1, 2, 3};
   3643     secondMessage.repeatedPackedNestedEnum = new int[] {
   3644         TestAllTypesNano.FOO, TestAllTypesNano.BAR
   3645       };
   3646 
   3647     // Should not NPE
   3648     message.mergeFrom(CodedInputByteBufferNano.newInstance(
   3649         MessageNano.toByteArray(secondMessage)));
   3650     assertEquals(3, message.repeatedInt32.length);
   3651     assertEquals(3, message.repeatedInt32[2]);
   3652     assertEquals(2, message.repeatedNestedEnum.length);
   3653     assertEquals(TestAllTypesNano.FOO, message.repeatedNestedEnum[0]);
   3654     assertEquals(2, message.repeatedBytes.length);
   3655     assertEquals(4, message.repeatedBytes[1][1]);
   3656     assertEquals(1, message.repeatedNestedMessage.length);
   3657     assertEquals(55, message.repeatedNestedMessage[0].bb);
   3658     assertEquals(3, message.repeatedPackedInt32.length);
   3659     assertEquals(2, message.repeatedPackedInt32[1]);
   3660     assertEquals(2, message.repeatedPackedNestedEnum.length);
   3661     assertEquals(TestAllTypesNano.BAR, message.repeatedPackedNestedEnum[1]);
   3662   }
   3663 
   3664   public void testNullRepeatedFieldElements() throws Exception {
   3665     // Check that serialization with null array elements doesn't NPE.
   3666     String string1 = "1";
   3667     String string2 = "2";
   3668     byte[] bytes1 = {3, 4};
   3669     byte[] bytes2 = {5, 6};
   3670     TestAllTypesNano.NestedMessage msg1 = new TestAllTypesNano.NestedMessage();
   3671     msg1.bb = 7;
   3672     TestAllTypesNano.NestedMessage msg2 = new TestAllTypesNano.NestedMessage();
   3673     msg2.bb = 8;
   3674 
   3675     TestAllTypesNano message = new TestAllTypesNano();
   3676     message.repeatedString = new String[] {null, string1, string2};
   3677     message.repeatedBytes = new byte[][] {bytes1, null, bytes2};
   3678     message.repeatedNestedMessage = new TestAllTypesNano.NestedMessage[] {msg1, msg2, null};
   3679     message.repeatedGroup = new TestAllTypesNano.RepeatedGroup[] {null, null, null};
   3680 
   3681     byte[] serialized = MessageNano.toByteArray(message); // should not NPE
   3682     TestAllTypesNano deserialized = MessageNano.mergeFrom(new TestAllTypesNano(), serialized);
   3683     assertEquals(2, deserialized.repeatedString.length);
   3684     assertEquals(string1, deserialized.repeatedString[0]);
   3685     assertEquals(string2, deserialized.repeatedString[1]);
   3686     assertEquals(2, deserialized.repeatedBytes.length);
   3687     assertTrue(Arrays.equals(bytes1, deserialized.repeatedBytes[0]));
   3688     assertTrue(Arrays.equals(bytes2, deserialized.repeatedBytes[1]));
   3689     assertEquals(2, deserialized.repeatedNestedMessage.length);
   3690     assertEquals(msg1.bb, deserialized.repeatedNestedMessage[0].bb);
   3691     assertEquals(msg2.bb, deserialized.repeatedNestedMessage[1].bb);
   3692     assertEquals(0, deserialized.repeatedGroup.length);
   3693   }
   3694 
   3695   public void testRepeatedMerge() throws Exception {
   3696     // Check that merging repeated fields cause the arrays to expand with
   3697     // new data.
   3698     TestAllTypesNano first = new TestAllTypesNano();
   3699     first.repeatedInt32 = new int[] {1, 2, 3};
   3700     TestAllTypesNano second = new TestAllTypesNano();
   3701     second.repeatedInt32 = new int[] {4, 5};
   3702     MessageNano.mergeFrom(first, MessageNano.toByteArray(second));
   3703     assertEquals(5, first.repeatedInt32.length);
   3704     assertEquals(1, first.repeatedInt32[0]);
   3705     assertEquals(4, first.repeatedInt32[3]);
   3706 
   3707     first = new TestAllTypesNano();
   3708     first.repeatedNestedEnum = new int[] {TestAllTypesNano.BAR};
   3709     second = new TestAllTypesNano();
   3710     second.repeatedNestedEnum = new int[] {TestAllTypesNano.FOO};
   3711     MessageNano.mergeFrom(first, MessageNano.toByteArray(second));
   3712     assertEquals(2, first.repeatedNestedEnum.length);
   3713     assertEquals(TestAllTypesNano.BAR, first.repeatedNestedEnum[0]);
   3714     assertEquals(TestAllTypesNano.FOO, first.repeatedNestedEnum[1]);
   3715 
   3716     first = new TestAllTypesNano();
   3717     first.repeatedNestedMessage = new TestAllTypesNano.NestedMessage[] {
   3718       new TestAllTypesNano.NestedMessage()
   3719     };
   3720     first.repeatedNestedMessage[0].bb = 3;
   3721     second = new TestAllTypesNano();
   3722     second.repeatedNestedMessage = new TestAllTypesNano.NestedMessage[] {
   3723       new TestAllTypesNano.NestedMessage()
   3724     };
   3725     second.repeatedNestedMessage[0].bb = 5;
   3726     MessageNano.mergeFrom(first, MessageNano.toByteArray(second));
   3727     assertEquals(2, first.repeatedNestedMessage.length);
   3728     assertEquals(3, first.repeatedNestedMessage[0].bb);
   3729     assertEquals(5, first.repeatedNestedMessage[1].bb);
   3730 
   3731     first = new TestAllTypesNano();
   3732     first.repeatedPackedSfixed64 = new long[] {-1, -2, -3};
   3733     second = new TestAllTypesNano();
   3734     second.repeatedPackedSfixed64 = new long[] {-4, -5};
   3735     MessageNano.mergeFrom(first, MessageNano.toByteArray(second));
   3736     assertEquals(5, first.repeatedPackedSfixed64.length);
   3737     assertEquals(-1, first.repeatedPackedSfixed64[0]);
   3738     assertEquals(-4, first.repeatedPackedSfixed64[3]);
   3739 
   3740     first = new TestAllTypesNano();
   3741     first.repeatedPackedNestedEnum = new int[] {TestAllTypesNano.BAR};
   3742     second = new TestAllTypesNano();
   3743     second.repeatedPackedNestedEnum = new int[] {TestAllTypesNano.FOO};
   3744     MessageNano.mergeFrom(first, MessageNano.toByteArray(second));
   3745     assertEquals(2, first.repeatedPackedNestedEnum.length);
   3746     assertEquals(TestAllTypesNano.BAR, first.repeatedPackedNestedEnum[0]);
   3747     assertEquals(TestAllTypesNano.FOO, first.repeatedPackedNestedEnum[1]);
   3748 
   3749     // Now test repeated merging in a nested scope
   3750     TestRepeatedMergeNano firstContainer = new TestRepeatedMergeNano();
   3751     firstContainer.contained = new TestAllTypesNano();
   3752     firstContainer.contained.repeatedInt32 = new int[] {10, 20};
   3753     TestRepeatedMergeNano secondContainer = new TestRepeatedMergeNano();
   3754     secondContainer.contained = new TestAllTypesNano();
   3755     secondContainer.contained.repeatedInt32 = new int[] {30};
   3756     MessageNano.mergeFrom(firstContainer, MessageNano.toByteArray(secondContainer));
   3757     assertEquals(3, firstContainer.contained.repeatedInt32.length);
   3758     assertEquals(20, firstContainer.contained.repeatedInt32[1]);
   3759     assertEquals(30, firstContainer.contained.repeatedInt32[2]);
   3760   }
   3761 
   3762   public void testRepeatedPackables() throws Exception {
   3763     // Check that repeated fields with packable types can accept both packed and unpacked
   3764     // serialized forms.
   3765     NanoRepeatedPackables.NonPacked nonPacked = new NanoRepeatedPackables.NonPacked();
   3766     // Exaggerates the first values of varint-typed arrays. This is to test that the parsing code
   3767     // of packed fields handles non-packed data correctly. If the code incorrectly thinks it is
   3768     // reading from a packed tag, it will read the first value as the byte length of the field,
   3769     // and the large number will cause the input to go out of bounds, thus capturing the error.
   3770     nonPacked.int32S = new int[] {1000, 2, 3};
   3771     nonPacked.int64S = new long[] {4000, 5, 6};
   3772     nonPacked.uint32S = new int[] {7000, 8, 9};
   3773     nonPacked.uint64S = new long[] {10000, 11, 12};
   3774     nonPacked.sint32S = new int[] {13000, 14, 15};
   3775     nonPacked.sint64S = new long[] {16000, 17, 18};
   3776     nonPacked.fixed32S = new int[] {19, 20, 21};
   3777     nonPacked.fixed64S = new long[] {22, 23, 24};
   3778     nonPacked.sfixed32S = new int[] {25, 26, 27};
   3779     nonPacked.sfixed64S = new long[] {28, 29, 30};
   3780     nonPacked.floats = new float[] {31, 32, 33};
   3781     nonPacked.doubles = new double[] {34, 35, 36};
   3782     nonPacked.bools = new boolean[] {false, true};
   3783     nonPacked.enums = new int[] {
   3784       NanoRepeatedPackables.Enum.OPTION_ONE,
   3785       NanoRepeatedPackables.Enum.OPTION_TWO,
   3786     };
   3787     nonPacked.noise = 13579;
   3788 
   3789     byte[] nonPackedSerialized = MessageNano.toByteArray(nonPacked);
   3790 
   3791     NanoRepeatedPackables.Packed packed =
   3792         MessageNano.mergeFrom(new NanoRepeatedPackables.Packed(), nonPackedSerialized);
   3793     assertRepeatedPackablesEqual(nonPacked, packed);
   3794 
   3795     byte[] packedSerialized = MessageNano.toByteArray(packed);
   3796     // Just a cautious check that the two serialized forms are different,
   3797     // to make sure the remaining of this test is useful:
   3798     assertFalse(Arrays.equals(nonPackedSerialized, packedSerialized));
   3799 
   3800     nonPacked = MessageNano.mergeFrom(new NanoRepeatedPackables.NonPacked(), packedSerialized);
   3801     assertRepeatedPackablesEqual(nonPacked, packed);
   3802 
   3803     // Test mixed serialized form.
   3804     byte[] mixedSerialized = new byte[nonPackedSerialized.length + packedSerialized.length];
   3805     System.arraycopy(nonPackedSerialized, 0, mixedSerialized, 0, nonPackedSerialized.length);
   3806     System.arraycopy(packedSerialized, 0,
   3807         mixedSerialized, nonPackedSerialized.length, packedSerialized.length);
   3808 
   3809     nonPacked = MessageNano.mergeFrom(new NanoRepeatedPackables.NonPacked(), mixedSerialized);
   3810     packed = MessageNano.mergeFrom(new NanoRepeatedPackables.Packed(), mixedSerialized);
   3811     assertRepeatedPackablesEqual(nonPacked, packed);
   3812     assertTrue(Arrays.equals(new int[] {1000, 2, 3, 1000, 2, 3}, nonPacked.int32S));
   3813     assertTrue(Arrays.equals(new int[] {13000, 14, 15, 13000, 14, 15}, nonPacked.sint32S));
   3814     assertTrue(Arrays.equals(new int[] {25, 26, 27, 25, 26, 27}, nonPacked.sfixed32S));
   3815     assertTrue(Arrays.equals(new boolean[] {false, true, false, true}, nonPacked.bools));
   3816   }
   3817 
   3818   public void testRepeatedFieldInitializedInReftypesCompatMode() {
   3819     NanoReferenceTypesCompat.TestAllTypesNano proto = new NanoReferenceTypesCompat.TestAllTypesNano();
   3820     assertNotNull(proto.repeatedString);
   3821   }
   3822 
   3823   private void assertRepeatedPackablesEqual(
   3824       NanoRepeatedPackables.NonPacked nonPacked, NanoRepeatedPackables.Packed packed) {
   3825     // Not using MessageNano.equals() -- that belongs to a separate test.
   3826     assertTrue(Arrays.equals(nonPacked.int32S, packed.int32S));
   3827     assertTrue(Arrays.equals(nonPacked.int64S, packed.int64S));
   3828     assertTrue(Arrays.equals(nonPacked.uint32S, packed.uint32S));
   3829     assertTrue(Arrays.equals(nonPacked.uint64S, packed.uint64S));
   3830     assertTrue(Arrays.equals(nonPacked.sint32S, packed.sint32S));
   3831     assertTrue(Arrays.equals(nonPacked.sint64S, packed.sint64S));
   3832     assertTrue(Arrays.equals(nonPacked.fixed32S, packed.fixed32S));
   3833     assertTrue(Arrays.equals(nonPacked.fixed64S, packed.fixed64S));
   3834     assertTrue(Arrays.equals(nonPacked.sfixed32S, packed.sfixed32S));
   3835     assertTrue(Arrays.equals(nonPacked.sfixed64S, packed.sfixed64S));
   3836     assertTrue(Arrays.equals(nonPacked.floats, packed.floats));
   3837     assertTrue(Arrays.equals(nonPacked.doubles, packed.doubles));
   3838     assertTrue(Arrays.equals(nonPacked.bools, packed.bools));
   3839     assertTrue(Arrays.equals(nonPacked.enums, packed.enums));
   3840   }
   3841 
   3842   public void testClone() throws Exception {
   3843     // A simple message.
   3844     AnotherMessage anotherMessage = new AnotherMessage();
   3845     anotherMessage.string = "Hello";
   3846     anotherMessage.value = true;
   3847     anotherMessage.integers = new int[] { 1, 2, 3 };
   3848 
   3849     AnotherMessage clone = anotherMessage.clone();
   3850     assertEquals(clone, anotherMessage);
   3851 
   3852     // Verify it was a deep clone - changes to the clone shouldn't affect the
   3853     // original.
   3854     clone.integers[1] = 100;
   3855     assertFalse(clone.equals(anotherMessage));
   3856   }
   3857 
   3858   public void testBytesOffsetLength() throws Exception {
   3859     BytesOffsetLengthTestNano msg = new BytesOffsetLengthTestNano();
   3860     msg.fooBuffer = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
   3861     msg.fooOffset = 2;
   3862     msg.fooLength = 3;
   3863     msg.barBuffer = msg.fooBuffer;
   3864     msg.barOffset = 7;
   3865     msg.barLength = 1;
   3866 
   3867     byte[] bytes = MessageNano.toByteArray(msg);
   3868     // Two tags + two lengths + the arrays
   3869     assertEquals("Unexpected size of encoded proto", 8, bytes.length);
   3870 
   3871     msg = BytesOffsetLengthTestNano.parseFrom(bytes);
   3872     byte[] foo = new byte[msg.fooLength];
   3873     System.arraycopy(msg.fooBuffer, msg.fooOffset, foo, 0, msg.fooLength);
   3874     assertTrue("foo was not deserialized correctly", Arrays.equals(new byte[] { 2, 3, 4 }, foo));
   3875     byte[] bar = new byte[msg.barLength];
   3876     System.arraycopy(msg.barBuffer, msg.barOffset, bar, 0, msg.barLength);
   3877     assertTrue("bar was not deserialized correctly", Arrays.equals(new byte[] { 7 }, bar));
   3878   }
   3879 
   3880   public void testUnknownOptionalEnumValue() throws Exception {
   3881     StandardVersion standardMsg = new StandardVersion();
   3882     standardMsg.optionalField = StandardVersion.VAL_3;
   3883     byte[] standardMsgBytes = MessageNano.toByteArray(standardMsg);
   3884 
   3885     // When parsing and reading, the unknown value appears as UNKNOWN.
   3886     VersionWithoutVal3 withoutVal3Msg = new VersionWithoutVal3();
   3887     MessageNano.mergeFrom(withoutVal3Msg, standardMsgBytes);
   3888     assertEquals(VersionWithoutVal3.UNKNOWN, withoutVal3Msg.optionalField);
   3889 
   3890     // When serializing and reparsing as the standard version, the old, unknown value wins out (even
   3891     // if a new one is set).
   3892     withoutVal3Msg.optionalField = VersionWithoutVal3.VAL_2;
   3893     byte[] withoutVal3MsgBytes = MessageNano.toByteArray(withoutVal3Msg);
   3894     StandardVersion standardMsgFromWithoutVal3Msg = new StandardVersion();
   3895     MessageNano.mergeFrom(standardMsgFromWithoutVal3Msg, withoutVal3MsgBytes);
   3896     assertEquals(StandardVersion.VAL_3, standardMsgFromWithoutVal3Msg.optionalField);
   3897   }
   3898 
   3899   public void testUnknownRepeatedEnumValue() throws Exception {
   3900     StandardVersion standardMsg = new StandardVersion();
   3901     standardMsg.repeatedField = new int[] { StandardVersion.VAL_3, StandardVersion.VAL_2 };
   3902     byte[] standardMsgBytes = MessageNano.toByteArray(standardMsg);
   3903 
   3904     // When parsing and reading, the unknown value is stripped out.
   3905     VersionWithoutVal3 withoutVal3Msg = new VersionWithoutVal3();
   3906     MessageNano.mergeFrom(withoutVal3Msg, standardMsgBytes);
   3907     assertTrue(Arrays.equals(new int[] { VersionWithoutVal3.VAL_2 }, withoutVal3Msg.repeatedField));
   3908 
   3909     // When serializing and reparsing as the standard version, the old, unknown value reappears, but
   3910     // at the end of all entries (including any newly added ones).
   3911     withoutVal3Msg.repeatedField = new int[] { VersionWithoutVal3.VAL_2, VersionWithoutVal3.VAL_1 };
   3912     byte[] withoutVal3MsgBytes = MessageNano.toByteArray(withoutVal3Msg);
   3913     StandardVersion standardMsgFromWithoutVal3Msg = new StandardVersion();
   3914     MessageNano.mergeFrom(standardMsgFromWithoutVal3Msg, withoutVal3MsgBytes);
   3915     assertTrue(Arrays.equals(
   3916             new int[] { StandardVersion.VAL_2, StandardVersion.VAL_1, StandardVersion.VAL_3 },
   3917             standardMsgFromWithoutVal3Msg.repeatedField));
   3918   }
   3919 
   3920   public void testUnknownRepeatedPackedEnumValue() throws Exception {
   3921     StandardVersion standardMsg = new StandardVersion();
   3922     standardMsg.packedField = new int[] { StandardVersion.VAL_3, StandardVersion.VAL_2 };
   3923     byte[] standardMsgBytes = MessageNano.toByteArray(standardMsg);
   3924 
   3925     // When parsing and reading, the unknown value is stripped out.
   3926     VersionWithoutVal3 withoutVal3Msg = new VersionWithoutVal3();
   3927     MessageNano.mergeFrom(withoutVal3Msg, standardMsgBytes);
   3928     assertTrue(Arrays.equals(new int[] { VersionWithoutVal3.VAL_2 }, withoutVal3Msg.packedField));
   3929 
   3930     // When serializing and reparsing as the standard version, the old, unknown value reappears, but
   3931     // at the end of all entries (including any newly added ones).
   3932     withoutVal3Msg.packedField = new int[] { VersionWithoutVal3.VAL_2, VersionWithoutVal3.VAL_1 };
   3933     byte[] withoutVal3MsgBytes = MessageNano.toByteArray(withoutVal3Msg);
   3934     StandardVersion standardMsgFromWithoutVal3Msg = new StandardVersion();
   3935     MessageNano.mergeFrom(standardMsgFromWithoutVal3Msg, withoutVal3MsgBytes);
   3936     assertTrue(Arrays.equals(
   3937             new int[] { StandardVersion.VAL_2, StandardVersion.VAL_1, StandardVersion.VAL_3 },
   3938             standardMsgFromWithoutVal3Msg.packedField));
   3939   }
   3940 
   3941   private void assertHasWireData(MessageNano message, boolean expected) {
   3942     byte[] bytes = MessageNano.toByteArray(message);
   3943     int wireLength = bytes.length;
   3944     if (expected) {
   3945       assertFalse(wireLength == 0);
   3946     } else {
   3947       if (wireLength != 0) {
   3948         fail("Expected no wire data for message \n" + message
   3949             + "\nBut got:\n"
   3950             + hexDump(bytes));
   3951       }
   3952     }
   3953   }
   3954 
   3955   private static String hexDump(byte[] bytes) {
   3956     StringBuilder sb = new StringBuilder();
   3957     for (byte b : bytes) {
   3958       sb.append(String.format("%02x ", b));
   3959     }
   3960     return sb.toString();
   3961   }
   3962 }
   3963