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