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