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