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