• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc.  All rights reserved.
3 //
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file or at
6 // https://developers.google.com/open-source/licenses/bsd
7 
8 package com.google.protobuf;
9 
10 import static com.google.common.truth.Truth.assertThat;
11 import static com.google.common.truth.Truth.assertWithMessage;
12 import static org.junit.Assert.assertThrows;
13 
14 import com.google.protobuf.Descriptors.Descriptor;
15 import com.google.protobuf.Descriptors.FieldDescriptor;
16 import com.google.protobuf.test.UnittestImport;
17 import protobuf_unittest.EnumWithNoOuter;
18 import protobuf_unittest.MessageWithNoOuter;
19 import protobuf_unittest.MultipleFilesTestProto;
20 import protobuf_unittest.NestedExtension.MyNestedExtension;
21 import protobuf_unittest.NonNestedExtension;
22 import protobuf_unittest.NonNestedExtension.MessageToBeExtended;
23 import protobuf_unittest.NonNestedExtension.MyNonNestedExtension;
24 import protobuf_unittest.OuterClassNameTest2OuterClass;
25 import protobuf_unittest.OuterClassNameTest3OuterClass;
26 import protobuf_unittest.OuterClassNameTestOuterClass;
27 import protobuf_unittest.ServiceWithNoOuter;
28 import protobuf_unittest.UnittestOptimizeFor.TestOptimizedForSize;
29 import protobuf_unittest.UnittestOptimizeFor.TestOptionalOptimizedForSize;
30 import protobuf_unittest.UnittestOptimizeFor.TestRequiredOptimizedForSize;
31 import protobuf_unittest.UnittestProto;
32 import protobuf_unittest.UnittestProto.ForeignEnum;
33 import protobuf_unittest.UnittestProto.ForeignMessage;
34 import protobuf_unittest.UnittestProto.ForeignMessageOrBuilder;
35 import protobuf_unittest.UnittestProto.NestedTestAllTypes;
36 import protobuf_unittest.UnittestProto.TestAllExtensions;
37 import protobuf_unittest.UnittestProto.TestAllTypes;
38 import protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage;
39 import protobuf_unittest.UnittestProto.TestAllTypesOrBuilder;
40 import protobuf_unittest.UnittestProto.TestExtremeDefaultValues;
41 import protobuf_unittest.UnittestProto.TestOneof2;
42 import protobuf_unittest.UnittestProto.TestPackedTypes;
43 import protobuf_unittest.UnittestProto.TestUnpackedTypes;
44 import java.io.ByteArrayInputStream;
45 import java.io.ByteArrayOutputStream;
46 import java.io.IOException;
47 import java.io.InputStream;
48 import java.io.ObjectInputStream;
49 import java.io.ObjectOutputStream;
50 import java.util.Arrays;
51 import java.util.Collections;
52 import java.util.Iterator;
53 import java.util.List;
54 import java.util.Map;
55 import org.junit.After;
56 import org.junit.Test;
57 import org.junit.runner.RunWith;
58 import org.junit.runners.JUnit4;
59 
60 /**
61  * Unit test for generated messages and generated code. See also {@link MessageTest}, which tests
62  * some generated message functionality.
63  */
64 @SuppressWarnings({"ProtoBuilderReturnValueIgnored", "ReturnValueIgnored"})
65 @RunWith(JUnit4.class)
66 public class GeneratedMessageTest {
67 
68   private static final TestOneof2 EXPECTED_MERGED_MESSAGE =
69       TestOneof2.newBuilder()
70           .setFooMessage(TestOneof2.NestedMessage.newBuilder().addCorgeInt(1).addCorgeInt(2))
71           .build();
72 
73   private static final TestOneof2 MESSAGE_TO_MERGE_FROM =
74       TestOneof2.newBuilder()
75           .setFooMessage(TestOneof2.NestedMessage.newBuilder().addCorgeInt(2))
76           .build();
77 
78   private static final FieldDescriptor NESTED_MESSAGE_BB_FIELD =
79       UnittestProto.TestAllTypes.NestedMessage.getDescriptor().findFieldByName("bb");
80 
81   TestUtil.ReflectionTester reflectionTester =
82       new TestUtil.ReflectionTester(TestAllTypes.getDescriptor(), null);
83 
84   @After
tearDown()85   public void tearDown() {
86     GeneratedMessage.setAlwaysUseFieldBuildersForTesting(false);
87   }
88 
89   @Test
testGetFieldBuilderForExtensionField()90   public void testGetFieldBuilderForExtensionField() {
91     TestAllExtensions.Builder builder = TestAllExtensions.newBuilder();
92     Message.Builder fieldBuilder =
93         builder.getFieldBuilder(UnittestProto.optionalNestedMessageExtension.getDescriptor());
94     int expected = 7432;
95     FieldDescriptor field =
96         NestedMessage.getDescriptor().findFieldByNumber(NestedMessage.BB_FIELD_NUMBER);
97     fieldBuilder.setField(field, expected);
98     assertThat(builder.build().getExtension(UnittestProto.optionalNestedMessageExtension).getBb())
99         .isEqualTo(expected);
100 
101     // fieldBuilder still updates the builder after builder build() has been called.
102     expected += 100;
103     fieldBuilder.setField(field, expected);
104     assertThat(builder.build().getExtension(UnittestProto.optionalNestedMessageExtension).getBb())
105         .isEqualTo(expected);
106   }
107 
108   @Test
testGetFieldBuilderWithExistingMessage()109   public void testGetFieldBuilderWithExistingMessage() {
110     TestAllExtensions.Builder builder = TestAllExtensions.newBuilder();
111     builder.setExtension(
112         UnittestProto.optionalNestedMessageExtension,
113         NestedMessage.newBuilder().setBb(123).build());
114     Message.Builder fieldBuilder =
115         builder.getFieldBuilder(UnittestProto.optionalNestedMessageExtension.getDescriptor());
116     int expected = 7432;
117     FieldDescriptor field =
118         NestedMessage.getDescriptor().findFieldByNumber(NestedMessage.BB_FIELD_NUMBER);
119     fieldBuilder.setField(field, expected);
120     assertThat(builder.build().getExtension(UnittestProto.optionalNestedMessageExtension).getBb())
121         .isEqualTo(expected);
122 
123     // fieldBuilder still updates the builder after builder build() has been called.
124     expected += 100;
125     fieldBuilder.setField(field, expected);
126     assertThat(builder.build().getExtension(UnittestProto.optionalNestedMessageExtension).getBb())
127         .isEqualTo(expected);
128   }
129 
130   @Test
testGetFieldBuilderWithExistingBuilder()131   public void testGetFieldBuilderWithExistingBuilder() {
132     TestAllExtensions.Builder builder = TestAllExtensions.newBuilder();
133     NestedMessage.Builder nestedMessageBuilder = NestedMessage.newBuilder().setBb(123);
134     builder.setField(
135         UnittestProto.optionalNestedMessageExtension.getDescriptor(), nestedMessageBuilder);
136     Message.Builder fieldBuilder =
137         builder.getFieldBuilder(UnittestProto.optionalNestedMessageExtension.getDescriptor());
138     int expected = 7432;
139     FieldDescriptor field =
140         NestedMessage.getDescriptor().findFieldByNumber(NestedMessage.BB_FIELD_NUMBER);
141     fieldBuilder.setField(field, expected);
142     assertThat(builder.build().getExtension(UnittestProto.optionalNestedMessageExtension).getBb())
143         .isEqualTo(expected);
144 
145     // Existing nestedMessageBuilder will also update builder.
146     expected += 100;
147     nestedMessageBuilder.setBb(expected);
148     assertThat(builder.build().getExtension(UnittestProto.optionalNestedMessageExtension).getBb())
149         .isEqualTo(expected);
150 
151     // fieldBuilder still updates the builder.
152     expected += 100;
153     fieldBuilder.setField(field, expected);
154     assertThat(builder.build().getExtension(UnittestProto.optionalNestedMessageExtension).getBb())
155         .isEqualTo(expected);
156   }
157 
158   @Test
testGetRepeatedFieldBuilderForExtensionField()159   public void testGetRepeatedFieldBuilderForExtensionField() {
160     TestAllExtensions.Builder builder = TestAllExtensions.newBuilder();
161     builder.addExtension(
162         UnittestProto.repeatedNestedMessageExtension,
163         NestedMessage.newBuilder().setBb(123).build());
164     Message.Builder fieldBuilder =
165         builder.getRepeatedFieldBuilder(
166             UnittestProto.repeatedNestedMessageExtension.getDescriptor(), 0);
167     int expected = 7432;
168     FieldDescriptor field =
169         NestedMessage.getDescriptor().findFieldByNumber(NestedMessage.BB_FIELD_NUMBER);
170     fieldBuilder.setField(field, expected);
171     assertThat(
172             builder.build().getExtension(UnittestProto.repeatedNestedMessageExtension, 0).getBb())
173         .isEqualTo(expected);
174 
175     // fieldBuilder still updates the builder after builder build() has been called.
176     expected += 100;
177     fieldBuilder.setField(field, expected);
178     assertThat(
179             builder.build().getExtension(UnittestProto.repeatedNestedMessageExtension, 0).getBb())
180         .isEqualTo(expected);
181   }
182 
183   @Test
testGetRepeatedFieldBuilderForExistingBuilder()184   public void testGetRepeatedFieldBuilderForExistingBuilder() {
185     TestAllExtensions.Builder builder = TestAllExtensions.newBuilder();
186     NestedMessage.Builder nestedMessageBuilder = NestedMessage.newBuilder().setBb(123);
187     builder.addRepeatedField(
188         UnittestProto.repeatedNestedMessageExtension.getDescriptor(), nestedMessageBuilder);
189     Message.Builder fieldBuilder =
190         builder.getRepeatedFieldBuilder(
191             UnittestProto.repeatedNestedMessageExtension.getDescriptor(), 0);
192     int expected = 7432;
193     FieldDescriptor field =
194         NestedMessage.getDescriptor().findFieldByNumber(NestedMessage.BB_FIELD_NUMBER);
195     fieldBuilder.setField(field, expected);
196     assertThat(
197             builder.build().getExtension(UnittestProto.repeatedNestedMessageExtension, 0).getBb())
198         .isEqualTo(expected);
199 
200     // Existing nestedMessageBuilder will also update builder.
201     expected += 100;
202     nestedMessageBuilder.setBb(expected);
203     assertThat(
204             builder.build().getExtension(UnittestProto.repeatedNestedMessageExtension, 0).getBb())
205         .isEqualTo(expected);
206 
207     // fieldBuilder still updates the builder.
208     expected += 100;
209     fieldBuilder.setField(field, expected);
210     assertThat(
211             builder.build().getExtension(UnittestProto.repeatedNestedMessageExtension, 0).getBb())
212         .isEqualTo(expected);
213   }
214 
215   @Test
testGetExtensionFieldOutOfBound()216   public void testGetExtensionFieldOutOfBound() {
217     TestAllExtensions.Builder builder = TestAllExtensions.newBuilder();
218 
219     assertThrows(
220         "Expected IndexOutOfBoundsException to be thrown",
221         IndexOutOfBoundsException.class,
222         () ->
223             builder.getRepeatedField(
224                 UnittestProto.repeatedNestedMessageExtension.getDescriptor(), 0));
225     assertThrows(
226         "Expected IndexOutOfBoundsException to be thrown",
227         IndexOutOfBoundsException.class,
228         () -> builder.getExtension(UnittestProto.repeatedNestedMessageExtension, 0));
229     TestAllExtensions extensionsMessage = builder.build();
230     assertThrows(
231         "Expected IndexOutOfBoundsException to be thrown",
232         IndexOutOfBoundsException.class,
233         () ->
234             extensionsMessage.getRepeatedField(
235                 UnittestProto.repeatedNestedMessageExtension.getDescriptor(), 0));
236     assertThrows(
237         "Expected IndexOutOfBoundsException to be thrown",
238         IndexOutOfBoundsException.class,
239         () -> extensionsMessage.getExtension(UnittestProto.repeatedNestedMessageExtension, 0));
240   }
241 
242   @Test
testDefaultInstance()243   public void testDefaultInstance() throws Exception {
244     assertThat(TestAllTypes.getDefaultInstance())
245         .isSameInstanceAs(TestAllTypes.getDefaultInstance().getDefaultInstanceForType());
246     assertThat(TestAllTypes.getDefaultInstance())
247         .isSameInstanceAs(TestAllTypes.newBuilder().getDefaultInstanceForType());
248   }
249 
250   @Test
testMessageOrBuilder()251   public void testMessageOrBuilder() throws Exception {
252     TestAllTypes.Builder builder = TestAllTypes.newBuilder();
253     TestUtil.setAllFields(builder);
254     TestAllTypes message = builder.build();
255     TestUtil.assertAllFieldsSet(message);
256   }
257 
258   @Test
testUsingBuilderMultipleTimes()259   public void testUsingBuilderMultipleTimes() throws Exception {
260     TestAllTypes.Builder builder = TestAllTypes.newBuilder();
261     // primitive field scalar and repeated
262     builder.setOptionalSfixed64(100);
263     builder.addRepeatedInt32(100);
264     // enum field scalar and repeated
265     builder.setOptionalImportEnum(UnittestImport.ImportEnum.IMPORT_BAR);
266     builder.addRepeatedImportEnum(UnittestImport.ImportEnum.IMPORT_BAR);
267     // proto field scalar and repeated
268     builder.setOptionalForeignMessage(ForeignMessage.newBuilder().setC(1));
269     builder.addRepeatedForeignMessage(ForeignMessage.newBuilder().setC(1));
270 
271     TestAllTypes value1 = builder.build();
272 
273     assertThat(value1.getOptionalSfixed64()).isEqualTo(100);
274     assertThat(value1.getRepeatedInt32(0)).isEqualTo(100);
275     assertThat(value1.getOptionalImportEnum()).isEqualTo(UnittestImport.ImportEnum.IMPORT_BAR);
276     assertThat(value1.getRepeatedImportEnum(0)).isEqualTo(UnittestImport.ImportEnum.IMPORT_BAR);
277     assertThat(value1.getOptionalForeignMessage().getC()).isEqualTo(1);
278     assertThat(value1.getRepeatedForeignMessage(0).getC()).isEqualTo(1);
279 
280     // Make sure that builder didn't update previously created values
281     builder.setOptionalSfixed64(200);
282     builder.setRepeatedInt32(0, 200);
283     builder.setOptionalImportEnum(UnittestImport.ImportEnum.IMPORT_FOO);
284     builder.setRepeatedImportEnum(0, UnittestImport.ImportEnum.IMPORT_FOO);
285     builder.setOptionalForeignMessage(ForeignMessage.newBuilder().setC(2));
286     builder.setRepeatedForeignMessage(0, ForeignMessage.newBuilder().setC(2));
287 
288     TestAllTypes value2 = builder.build();
289 
290     // Make sure value1 didn't change.
291     assertThat(value1.getOptionalSfixed64()).isEqualTo(100);
292     assertThat(value1.getRepeatedInt32(0)).isEqualTo(100);
293     assertThat(value1.getOptionalImportEnum()).isEqualTo(UnittestImport.ImportEnum.IMPORT_BAR);
294     assertThat(value1.getRepeatedImportEnum(0)).isEqualTo(UnittestImport.ImportEnum.IMPORT_BAR);
295     assertThat(value1.getOptionalForeignMessage().getC()).isEqualTo(1);
296     assertThat(value1.getRepeatedForeignMessage(0).getC()).isEqualTo(1);
297 
298     // Make sure value2 is correct
299     assertThat(value2.getOptionalSfixed64()).isEqualTo(200);
300     assertThat(value2.getRepeatedInt32(0)).isEqualTo(200);
301     assertThat(value2.getOptionalImportEnum()).isEqualTo(UnittestImport.ImportEnum.IMPORT_FOO);
302     assertThat(value2.getRepeatedImportEnum(0)).isEqualTo(UnittestImport.ImportEnum.IMPORT_FOO);
303     assertThat(value2.getOptionalForeignMessage().getC()).isEqualTo(2);
304     assertThat(value2.getRepeatedForeignMessage(0).getC()).isEqualTo(2);
305   }
306 
307   @Test
testProtosShareRepeatedArraysIfDidntChange()308   public void testProtosShareRepeatedArraysIfDidntChange() throws Exception {
309     TestAllTypes.Builder builder = TestAllTypes.newBuilder();
310     builder.addRepeatedInt32(100);
311     builder.addRepeatedForeignMessage(ForeignMessage.getDefaultInstance());
312 
313     TestAllTypes value1 = builder.build();
314     TestAllTypes value2 = value1.toBuilder().build();
315 
316     assertThat(value1.getRepeatedInt32List()).isSameInstanceAs(value2.getRepeatedInt32List());
317     assertThat(value1.getRepeatedForeignMessageList())
318         .isSameInstanceAs(value2.getRepeatedForeignMessageList());
319   }
320 
321   @Test
testRepeatedArraysAreImmutable()322   public void testRepeatedArraysAreImmutable() throws Exception {
323     TestAllTypes.Builder builder = TestAllTypes.newBuilder();
324     builder.addRepeatedInt32(100);
325     builder.addRepeatedImportEnum(UnittestImport.ImportEnum.IMPORT_BAR);
326     builder.addRepeatedForeignMessage(ForeignMessage.getDefaultInstance());
327     assertIsUnmodifiable(builder.getRepeatedInt32List());
328     assertIsUnmodifiable(builder.getRepeatedImportEnumList());
329     assertIsUnmodifiable(builder.getRepeatedForeignMessageList());
330     assertIsUnmodifiable(builder.getRepeatedFloatList());
331 
332     TestAllTypes value = builder.build();
333     assertIsUnmodifiable(value.getRepeatedInt32List());
334     assertIsUnmodifiable(value.getRepeatedImportEnumList());
335     assertIsUnmodifiable(value.getRepeatedForeignMessageList());
336     assertIsUnmodifiable(value.getRepeatedFloatList());
337   }
338 
339   @Test
testParsedMessagesAreImmutable()340   public void testParsedMessagesAreImmutable() throws Exception {
341     TestAllTypes value = TestAllTypes.parseFrom(TestUtil.getAllSet().toByteString());
342     assertIsUnmodifiable(value.getRepeatedInt32List());
343     assertIsUnmodifiable(value.getRepeatedInt64List());
344     assertIsUnmodifiable(value.getRepeatedUint32List());
345     assertIsUnmodifiable(value.getRepeatedUint64List());
346     assertIsUnmodifiable(value.getRepeatedSint32List());
347     assertIsUnmodifiable(value.getRepeatedSint64List());
348     assertIsUnmodifiable(value.getRepeatedFixed32List());
349     assertIsUnmodifiable(value.getRepeatedFixed64List());
350     assertIsUnmodifiable(value.getRepeatedSfixed32List());
351     assertIsUnmodifiable(value.getRepeatedSfixed64List());
352     assertIsUnmodifiable(value.getRepeatedFloatList());
353     assertIsUnmodifiable(value.getRepeatedDoubleList());
354     assertIsUnmodifiable(value.getRepeatedBoolList());
355     assertIsUnmodifiable(value.getRepeatedStringList());
356     assertIsUnmodifiable(value.getRepeatedBytesList());
357     assertIsUnmodifiable(value.getRepeatedGroupList());
358     assertIsUnmodifiable(value.getRepeatedNestedMessageList());
359     assertIsUnmodifiable(value.getRepeatedForeignMessageList());
360     assertIsUnmodifiable(value.getRepeatedImportMessageList());
361     assertIsUnmodifiable(value.getRepeatedNestedEnumList());
362     assertIsUnmodifiable(value.getRepeatedForeignEnumList());
363     assertIsUnmodifiable(value.getRepeatedImportEnumList());
364   }
365 
assertIsUnmodifiable(List<?> list)366   private void assertIsUnmodifiable(List<?> list) {
367     if (list == Collections.emptyList()) {
368       // OKAY -- Need to check this b/c EmptyList allows you to call clear.
369     } else {
370       assertThrows(
371           "List wasn't immutable", UnsupportedOperationException.class, () -> list.clear());
372     }
373   }
374 
375   @Test
testSettersRejectNull()376   public void testSettersRejectNull() throws Exception {
377     TestAllTypes.Builder builder = TestAllTypes.newBuilder();
378 
379     assertThrows(
380         "Exception was not thrown",
381         NullPointerException.class,
382         () -> builder.setOptionalString(null));
383     assertThrows(
384         "Exception was not thrown",
385         NullPointerException.class,
386         () -> builder.setOptionalNestedMessage((TestAllTypes.NestedMessage) null));
387     assertThrows(
388         "Exception was not thrown",
389         NullPointerException.class,
390         () -> builder.setOptionalNestedMessage((TestAllTypes.NestedMessage.Builder) null));
391     assertThrows(
392         "Exception was not thrown",
393         NullPointerException.class,
394         () -> builder.setOptionalNestedEnum(null));
395     assertThrows(
396         "Exception was not thrown",
397         NullPointerException.class,
398         () -> builder.addRepeatedString(null));
399     assertThrows(
400         "Exception was not thrown",
401         NullPointerException.class,
402         () -> builder.addRepeatedBytes(null));
403     assertThrows(
404         "Exception was not thrown",
405         NullPointerException.class,
406         () -> builder.addRepeatedNestedMessage((TestAllTypes.NestedMessage) null));
407     assertThrows(
408         "Exception was not thrown",
409         NullPointerException.class,
410         () -> builder.addRepeatedNestedMessage((TestAllTypes.NestedMessage.Builder) null));
411     assertThrows(
412         "Exception was not thrown",
413         NullPointerException.class,
414         () -> builder.addRepeatedNestedEnum(null));
415   }
416 
417   @Test
testRepeatedSetters()418   public void testRepeatedSetters() throws Exception {
419     TestAllTypes.Builder builder = TestAllTypes.newBuilder();
420     TestUtil.setAllFields(builder);
421     TestUtil.modifyRepeatedFields(builder);
422     TestAllTypes message = builder.build();
423     TestUtil.assertRepeatedFieldsModified(message);
424   }
425 
426   @Test
testRepeatedSettersRejectNull()427   public void testRepeatedSettersRejectNull() throws Exception {
428     TestAllTypes.Builder builder = TestAllTypes.newBuilder();
429 
430     builder.addRepeatedString("one");
431     builder.addRepeatedString("two");
432     assertThrows(
433         "Exception was not thrown",
434         NullPointerException.class,
435         () -> builder.setRepeatedString(1, null));
436 
437     builder.addRepeatedBytes(TestUtil.toBytes("one"));
438     builder.addRepeatedBytes(TestUtil.toBytes("two"));
439     assertThrows(
440         "Exception was not thrown",
441         NullPointerException.class,
442         () -> builder.setRepeatedBytes(1, null));
443 
444     builder.addRepeatedNestedMessage(TestAllTypes.NestedMessage.newBuilder().setBb(218).build());
445     builder.addRepeatedNestedMessage(TestAllTypes.NestedMessage.newBuilder().setBb(456).build());
446     assertThrows(
447         "Exception was not thrown",
448         NullPointerException.class,
449         () -> builder.setRepeatedNestedMessage(1, (TestAllTypes.NestedMessage) null));
450     assertThrows(
451         "Exception was not thrown",
452         NullPointerException.class,
453         () -> builder.setRepeatedNestedMessage(1, (TestAllTypes.NestedMessage.Builder) null));
454 
455     builder.addRepeatedNestedEnum(TestAllTypes.NestedEnum.FOO);
456     builder.addRepeatedNestedEnum(TestAllTypes.NestedEnum.BAR);
457     assertThrows(
458         "Exception was not thrown",
459         NullPointerException.class,
460         () -> builder.setRepeatedNestedEnum(1, null));
461   }
462 
463   @Test
testRepeatedAppend()464   public void testRepeatedAppend() throws Exception {
465     TestAllTypes.Builder builder = TestAllTypes.newBuilder();
466 
467     builder.addAllRepeatedInt32(Arrays.asList(1, 2, 3, 4));
468     builder.addAllRepeatedForeignEnum(Arrays.asList(ForeignEnum.FOREIGN_BAZ));
469 
470     ForeignMessage foreignMessage = ForeignMessage.newBuilder().setC(12).build();
471     builder.addAllRepeatedForeignMessage(Arrays.asList(foreignMessage));
472 
473     TestAllTypes message = builder.build();
474     assertThat(Arrays.asList(1, 2, 3, 4)).isEqualTo(message.getRepeatedInt32List());
475     assertThat(Arrays.asList(ForeignEnum.FOREIGN_BAZ))
476         .isEqualTo(message.getRepeatedForeignEnumList());
477     assertThat(message.getRepeatedForeignMessageCount()).isEqualTo(1);
478     assertThat(message.getRepeatedForeignMessage(0).getC()).isEqualTo(12);
479   }
480 
481   @Test
testRepeatedAppendRejectsNull()482   public void testRepeatedAppendRejectsNull() throws Exception {
483     TestAllTypes.Builder builder = TestAllTypes.newBuilder();
484 
485     ForeignMessage foreignMessage = ForeignMessage.newBuilder().setC(12).build();
486     assertThrows(
487         "Exception was not thrown",
488         NullPointerException.class,
489         () ->
490             builder.addAllRepeatedForeignMessage(
491                 Arrays.asList(foreignMessage, (ForeignMessage) null)));
492     assertThrows(
493         "Exception was not thrown",
494         NullPointerException.class,
495         () -> builder.addAllRepeatedForeignEnum(Arrays.asList(ForeignEnum.FOREIGN_BAZ, null)));
496     assertThrows(
497         "Exception was not thrown",
498         NullPointerException.class,
499         () -> builder.addAllRepeatedString(Arrays.asList("one", null)));
500     assertThrows(
501         "Exception was not thrown",
502         NullPointerException.class,
503         () -> builder.addAllRepeatedBytes(Arrays.asList(TestUtil.toBytes("one"), null)));
504   }
505 
506   @Test
testRepeatedAppendIterateOnlyOnce()507   public void testRepeatedAppendIterateOnlyOnce() throws Exception {
508     // Create a Iterable that can only be iterated once.
509     Iterable<String> stringIterable =
510         new Iterable<String>() {
511           private boolean called = false;
512 
513           @Override
514           public Iterator<String> iterator() {
515             if (called) {
516               throw new IllegalStateException();
517             }
518             called = true;
519             return Arrays.asList("one", "two", "three").iterator();
520           }
521         };
522     TestAllTypes.Builder builder = TestAllTypes.newBuilder();
523     builder.addAllRepeatedString(stringIterable);
524     assertThat(builder.getRepeatedStringCount()).isEqualTo(3);
525     assertThat(builder.getRepeatedString(0)).isEqualTo("one");
526     assertThat(builder.getRepeatedString(1)).isEqualTo("two");
527     assertThat(builder.getRepeatedString(2)).isEqualTo("three");
528 
529     assertThrows(
530         "Exception was not thrown",
531         IllegalStateException.class,
532         () -> builder.addAllRepeatedString(stringIterable));
533   }
534 
535   @Test
testMergeFromOtherRejectsNull()536   public void testMergeFromOtherRejectsNull() throws Exception {
537     TestAllTypes.Builder builder = TestAllTypes.newBuilder();
538     assertThrows(
539         "Exception was not thrown",
540         NullPointerException.class,
541         () -> builder.mergeFrom((TestAllTypes) null));
542   }
543 
544   @Test
testSettingForeignMessageUsingBuilder()545   public void testSettingForeignMessageUsingBuilder() throws Exception {
546     TestAllTypes message =
547         TestAllTypes.newBuilder()
548             // Pass builder for foreign message instance.
549             .setOptionalForeignMessage(ForeignMessage.newBuilder().setC(123))
550             .build();
551     TestAllTypes expectedMessage =
552         TestAllTypes.newBuilder()
553             // Create expected version passing foreign message instance explicitly.
554             .setOptionalForeignMessage(ForeignMessage.newBuilder().setC(123).build())
555             .build();
556     // TODO: Upgrade to using real #equals method once implemented
557     assertThat(message.toString()).isEqualTo(expectedMessage.toString());
558   }
559 
560   @Test
testSettingRepeatedForeignMessageUsingBuilder()561   public void testSettingRepeatedForeignMessageUsingBuilder() throws Exception {
562     TestAllTypes message =
563         TestAllTypes.newBuilder()
564             // Pass builder for foreign message instance.
565             .addRepeatedForeignMessage(ForeignMessage.newBuilder().setC(456))
566             .build();
567     TestAllTypes expectedMessage =
568         TestAllTypes.newBuilder()
569             // Create expected version passing foreign message instance explicitly.
570             .addRepeatedForeignMessage(ForeignMessage.newBuilder().setC(456).build())
571             .build();
572     assertThat(message.toString()).isEqualTo(expectedMessage.toString());
573   }
574 
575   @Test
testDefaults()576   public void testDefaults() throws Exception {
577     TestUtil.assertClear(TestAllTypes.getDefaultInstance());
578     TestUtil.assertClear(TestAllTypes.newBuilder().build());
579 
580     TestExtremeDefaultValues message = TestExtremeDefaultValues.getDefaultInstance();
581     assertThat(message.getUtf8String()).isEqualTo("\u1234");
582     assertThat(message.getInfDouble()).isEqualTo(Double.POSITIVE_INFINITY);
583     assertThat(message.getNegInfDouble()).isEqualTo(Double.NEGATIVE_INFINITY);
584     assertThat(Double.isNaN(message.getNanDouble())).isTrue();
585     assertThat(message.getInfFloat()).isEqualTo(Float.POSITIVE_INFINITY);
586     assertThat(message.getNegInfFloat()).isEqualTo(Float.NEGATIVE_INFINITY);
587     assertThat(Float.isNaN(message.getNanFloat())).isTrue();
588     assertThat(message.getCppTrigraph()).isEqualTo("? ? ?? ?? ??? ??/ ??-");
589   }
590 
591   @Test
testClear()592   public void testClear() throws Exception {
593     TestAllTypes.Builder builder = TestAllTypes.newBuilder();
594     TestUtil.assertClear(builder);
595     TestUtil.setAllFields(builder);
596     builder.clear();
597     TestUtil.assertClear(builder);
598   }
599 
600   @Test
testReflectionGetters()601   public void testReflectionGetters() throws Exception {
602     TestAllTypes.Builder builder = TestAllTypes.newBuilder();
603     TestUtil.setAllFields(builder);
604     reflectionTester.assertAllFieldsSetViaReflection(builder);
605 
606     TestAllTypes message = builder.build();
607     reflectionTester.assertAllFieldsSetViaReflection(message);
608   }
609 
610   @Test
testReflectionSetters()611   public void testReflectionSetters() throws Exception {
612     TestAllTypes.Builder builder = TestAllTypes.newBuilder();
613     reflectionTester.setAllFieldsViaReflection(builder);
614     TestUtil.assertAllFieldsSet(builder);
615 
616     TestAllTypes message = builder.build();
617     TestUtil.assertAllFieldsSet(message);
618   }
619 
620   @Test
testReflectionSettersRejectNull()621   public void testReflectionSettersRejectNull() throws Exception {
622     TestAllTypes.Builder builder = TestAllTypes.newBuilder();
623     reflectionTester.assertReflectionSettersRejectNull(builder);
624   }
625 
626   @Test
testReflectionRepeatedSetters()627   public void testReflectionRepeatedSetters() throws Exception {
628     TestAllTypes.Builder builder = TestAllTypes.newBuilder();
629     reflectionTester.setAllFieldsViaReflection(builder);
630     reflectionTester.modifyRepeatedFieldsViaReflection(builder);
631     TestUtil.assertRepeatedFieldsModified(builder);
632 
633     TestAllTypes message = builder.build();
634     TestUtil.assertRepeatedFieldsModified(message);
635   }
636 
637   @Test
testReflectionRepeatedSettersRejectNull()638   public void testReflectionRepeatedSettersRejectNull() throws Exception {
639     TestAllTypes.Builder builder = TestAllTypes.newBuilder();
640     reflectionTester.assertReflectionRepeatedSettersRejectNull(builder);
641   }
642 
643   @Test
testReflectionDefaults()644   public void testReflectionDefaults() throws Exception {
645     reflectionTester.assertClearViaReflection(TestAllTypes.getDefaultInstance());
646     reflectionTester.assertClearViaReflection(TestAllTypes.newBuilder().build());
647   }
648 
649   @Test
testReflectionGetOneof()650   public void testReflectionGetOneof() throws Exception {
651     TestAllTypes.Builder builder = TestAllTypes.newBuilder();
652     reflectionTester.setAllFieldsViaReflection(builder);
653     Descriptors.OneofDescriptor oneof = TestAllTypes.getDescriptor().getOneofs().get(0);
654     Descriptors.FieldDescriptor field = TestAllTypes.getDescriptor().findFieldByName("oneof_bytes");
655     assertThat(field).isSameInstanceAs(builder.getOneofFieldDescriptor(oneof));
656 
657     TestAllTypes message = builder.build();
658     assertThat(field).isSameInstanceAs(message.getOneofFieldDescriptor(oneof));
659   }
660 
661   @Test
testReflectionClearOneof()662   public void testReflectionClearOneof() throws Exception {
663     TestAllTypes.Builder builder = TestAllTypes.newBuilder();
664     reflectionTester.setAllFieldsViaReflection(builder);
665     Descriptors.OneofDescriptor oneof = TestAllTypes.getDescriptor().getOneofs().get(0);
666     Descriptors.FieldDescriptor field = TestAllTypes.getDescriptor().findFieldByName("oneof_bytes");
667 
668     assertThat(builder.hasOneof(oneof)).isTrue();
669     assertThat(builder.hasField(field)).isTrue();
670     builder.clearOneof(oneof);
671     assertThat(builder.hasOneof(oneof)).isFalse();
672     assertThat(builder.hasField(field)).isFalse();
673   }
674 
675   @Test
testEnumInterface()676   public void testEnumInterface() throws Exception {
677     assertThat(TestAllTypes.getDefaultInstance().getDefaultNestedEnum())
678         .isInstanceOf(ProtocolMessageEnum.class);
679   }
680 
681   @Test
testEnumMap()682   public void testEnumMap() throws Exception {
683     Internal.EnumLiteMap<ForeignEnum> map = ForeignEnum.internalGetValueMap();
684 
685     for (ForeignEnum value : ForeignEnum.values()) {
686       assertThat(map.findValueByNumber(value.getNumber())).isEqualTo(value);
687     }
688 
689     assertThat(map.findValueByNumber(12345) == null).isTrue();
690   }
691 
692   @Test
testParsePackedToUnpacked()693   public void testParsePackedToUnpacked() throws Exception {
694     TestUnpackedTypes.Builder builder = TestUnpackedTypes.newBuilder();
695     TestUnpackedTypes message = builder.mergeFrom(TestUtil.getPackedSet().toByteString()).build();
696     TestUtil.assertUnpackedFieldsSet(message);
697   }
698 
699   @Test
testParseUnpackedToPacked()700   public void testParseUnpackedToPacked() throws Exception {
701     TestPackedTypes.Builder builder = TestPackedTypes.newBuilder();
702     TestPackedTypes message = builder.mergeFrom(TestUtil.getUnpackedSet().toByteString()).build();
703     TestUtil.assertPackedFieldsSet(message);
704   }
705 
706   // =================================================================
707   // Extensions.
708 
709   TestUtil.ReflectionTester extensionsReflectionTester =
710       new TestUtil.ReflectionTester(
711           TestAllExtensions.getDescriptor(), TestUtil.getFullExtensionRegistry());
712 
713   @Test
testExtensionMessageOrBuilder()714   public void testExtensionMessageOrBuilder() throws Exception {
715     TestAllExtensions.Builder builder = TestAllExtensions.newBuilder();
716     TestUtil.setAllExtensions(builder);
717     TestAllExtensions message = builder.build();
718     TestUtil.assertAllExtensionsSet(message);
719   }
720 
721   @Test
testGetBuilderForExtensionField()722   public void testGetBuilderForExtensionField() {
723     TestAllExtensions.Builder builder = TestAllExtensions.newBuilder();
724     Message.Builder fieldBuilder =
725         builder.newBuilderForField(UnittestProto.optionalNestedMessageExtension.getDescriptor());
726     final int expected = 7432;
727     FieldDescriptor field =
728         NestedMessage.getDescriptor().findFieldByNumber(NestedMessage.BB_FIELD_NUMBER);
729     fieldBuilder.setField(field, expected);
730     assertThat(fieldBuilder.build().getField(field)).isEqualTo(expected);
731   }
732 
733   @Test
testGetBuilderForNonMessageExtensionField()734   public void testGetBuilderForNonMessageExtensionField() {
735     TestAllExtensions.Builder builder = TestAllExtensions.newBuilder();
736     // This should throw an exception because the extension field is not a message.
737     assertThrows(
738         "Exception was not thrown",
739         UnsupportedOperationException.class,
740         () -> builder.newBuilderForField(UnittestProto.optionalInt32Extension.getDescriptor()));
741   }
742 
743   @Test
testExtensionRepeatedSetters()744   public void testExtensionRepeatedSetters() throws Exception {
745     TestAllExtensions.Builder builder = TestAllExtensions.newBuilder();
746     TestUtil.setAllExtensions(builder);
747     TestUtil.modifyRepeatedExtensions(builder);
748     TestAllExtensions message = builder.build();
749     TestUtil.assertRepeatedExtensionsModified(message);
750   }
751 
752   @Test
testExtensionDefaults()753   public void testExtensionDefaults() throws Exception {
754     TestUtil.assertExtensionsClear(TestAllExtensions.getDefaultInstance());
755     TestUtil.assertExtensionsClear(TestAllExtensions.newBuilder().build());
756   }
757 
758   @Test
testUnsetRepeatedExtensionGetField()759   public void testUnsetRepeatedExtensionGetField() {
760     TestAllExtensions message = TestAllExtensions.getDefaultInstance();
761     Object value;
762 
763     value = message.getField(UnittestProto.repeatedStringExtension.getDescriptor());
764     assertThat(value instanceof List).isTrue();
765     assertThat(((List<?>) value).isEmpty()).isTrue();
766     assertIsUnmodifiable((List<?>) value);
767 
768     value = message.getField(UnittestProto.repeatedNestedMessageExtension.getDescriptor());
769     assertThat(value instanceof List).isTrue();
770     assertThat(((List<?>) value).isEmpty()).isTrue();
771     assertIsUnmodifiable((List<?>) value);
772   }
773 
774   @Test
testExtensionReflectionGetters()775   public void testExtensionReflectionGetters() throws Exception {
776     TestAllExtensions.Builder builder = TestAllExtensions.newBuilder();
777     TestUtil.setAllExtensions(builder);
778     extensionsReflectionTester.assertAllFieldsSetViaReflection(builder);
779 
780     TestAllExtensions message = builder.build();
781     extensionsReflectionTester.assertAllFieldsSetViaReflection(message);
782   }
783 
784   @Test
testExtensionReflectionSetters()785   public void testExtensionReflectionSetters() throws Exception {
786     TestAllExtensions.Builder builder = TestAllExtensions.newBuilder();
787     extensionsReflectionTester.setAllFieldsViaReflection(builder);
788     TestUtil.assertAllExtensionsSet(builder);
789 
790     TestAllExtensions message = builder.build();
791     TestUtil.assertAllExtensionsSet(message);
792   }
793 
794   @Test
testExtensionReflectionSettersRejectNull()795   public void testExtensionReflectionSettersRejectNull() throws Exception {
796     TestAllExtensions.Builder builder = TestAllExtensions.newBuilder();
797     extensionsReflectionTester.assertReflectionSettersRejectNull(builder);
798   }
799 
800   @Test
testExtensionReflectionRepeatedSetters()801   public void testExtensionReflectionRepeatedSetters() throws Exception {
802     TestAllExtensions.Builder builder = TestAllExtensions.newBuilder();
803     extensionsReflectionTester.setAllFieldsViaReflection(builder);
804     extensionsReflectionTester.modifyRepeatedFieldsViaReflection(builder);
805     TestUtil.assertRepeatedExtensionsModified(builder);
806 
807     TestAllExtensions message = builder.build();
808     TestUtil.assertRepeatedExtensionsModified(message);
809   }
810 
811   @Test
testExtensionReflectionRepeatedSettersRejectNull()812   public void testExtensionReflectionRepeatedSettersRejectNull() throws Exception {
813     TestAllExtensions.Builder builder = TestAllExtensions.newBuilder();
814     extensionsReflectionTester.assertReflectionRepeatedSettersRejectNull(builder);
815   }
816 
817   @Test
testExtensionReflectionDefaults()818   public void testExtensionReflectionDefaults() throws Exception {
819     extensionsReflectionTester.assertClearViaReflection(TestAllExtensions.getDefaultInstance());
820     extensionsReflectionTester.assertClearViaReflection(TestAllExtensions.newBuilder().build());
821   }
822 
823   @Test
testClearExtension()824   public void testClearExtension() throws Exception {
825     // clearExtension() is not actually used in TestUtil, so try it manually.
826     assertThat(
827             TestAllExtensions.newBuilder()
828                 .setExtension(UnittestProto.optionalInt32Extension, 1)
829                 .clearExtension(UnittestProto.optionalInt32Extension)
830                 .hasExtension(UnittestProto.optionalInt32Extension))
831         .isFalse();
832     assertThat(
833             TestAllExtensions.newBuilder()
834                 .addExtension(UnittestProto.repeatedInt32Extension, 1)
835                 .clearExtension(UnittestProto.repeatedInt32Extension)
836                 .getExtensionCount(UnittestProto.repeatedInt32Extension))
837         .isEqualTo(0);
838   }
839 
840   @Test
testExtensionCopy()841   public void testExtensionCopy() throws Exception {
842     TestAllExtensions original = TestUtil.getAllExtensionsSet();
843     TestAllExtensions copy = TestAllExtensions.newBuilder(original).build();
844     TestUtil.assertAllExtensionsSet(copy);
845   }
846 
847   @Test
testExtensionMergeFrom()848   public void testExtensionMergeFrom() throws Exception {
849     TestAllExtensions original =
850         TestAllExtensions.newBuilder()
851             .setExtension(UnittestProto.optionalInt32Extension, 1)
852             .build();
853     TestAllExtensions merged = TestAllExtensions.newBuilder().mergeFrom(original).build();
854     assertThat(merged.hasExtension(UnittestProto.optionalInt32Extension)).isTrue();
855     assertThat((int) merged.getExtension(UnittestProto.optionalInt32Extension)).isEqualTo(1);
856   }
857 
858   // =================================================================
859   // multiple_files_test
860 
861   // Test that custom options of an file level enum are properly initialized.
862   // This test needs to be put before any other access to MultipleFilesTestProto
863   // or messages defined in multiple_files_test.proto because the class loading
864   // order affects initialization process of custom options.
865   @Test
testEnumValueOptionsInMultipleFilesMode()866   public void testEnumValueOptionsInMultipleFilesMode() throws Exception {
867     assertThat(
868             EnumWithNoOuter.FOO
869                 .getValueDescriptor()
870                 .getOptions()
871                 .getExtension(MultipleFilesTestProto.enumValueOption)
872                 .intValue())
873         .isEqualTo(12345);
874   }
875 
876   @Test
testMultipleFilesOption()877   public void testMultipleFilesOption() throws Exception {
878     // We mostly just want to check that things compile.
879     MessageWithNoOuter message =
880         MessageWithNoOuter.newBuilder()
881             .setNested(MessageWithNoOuter.NestedMessage.newBuilder().setI(1))
882             .addForeign(TestAllTypes.newBuilder().setOptionalInt32(1))
883             .setNestedEnum(MessageWithNoOuter.NestedEnum.BAZ)
884             .setForeignEnum(EnumWithNoOuter.BAR)
885             .build();
886     assertThat(MessageWithNoOuter.parseFrom(message.toByteString())).isEqualTo(message);
887 
888     assertThat(MessageWithNoOuter.getDescriptor().getFile())
889         .isEqualTo(MultipleFilesTestProto.getDescriptor());
890 
891     Descriptors.FieldDescriptor field =
892         MessageWithNoOuter.getDescriptor().findFieldByName("foreign_enum");
893     assertThat(message.getField(field)).isEqualTo(EnumWithNoOuter.BAR.getValueDescriptor());
894 
895     assertThat(ServiceWithNoOuter.getDescriptor().getFile())
896         .isEqualTo(MultipleFilesTestProto.getDescriptor());
897 
898     assertThat(
899             TestAllExtensions.getDefaultInstance()
900                 .hasExtension(MultipleFilesTestProto.extensionWithOuter))
901         .isFalse();
902   }
903 
904   @Test
testOptionalFieldWithRequiredSubfieldsOptimizedForSize()905   public void testOptionalFieldWithRequiredSubfieldsOptimizedForSize() throws Exception {
906     TestOptionalOptimizedForSize message = TestOptionalOptimizedForSize.getDefaultInstance();
907     assertThat(message.isInitialized()).isTrue();
908 
909     message =
910         TestOptionalOptimizedForSize.newBuilder()
911             .setO(TestRequiredOptimizedForSize.newBuilder().buildPartial())
912             .buildPartial();
913     assertThat(message.isInitialized()).isFalse();
914 
915     message =
916         TestOptionalOptimizedForSize.newBuilder()
917             .setO(TestRequiredOptimizedForSize.newBuilder().setX(5).buildPartial())
918             .buildPartial();
919     assertThat(message.isInitialized()).isTrue();
920   }
921 
922   @Test
testUninitializedExtensionInOptimizedForSize()923   public void testUninitializedExtensionInOptimizedForSize() throws Exception {
924     TestOptimizedForSize.Builder builder = TestOptimizedForSize.newBuilder();
925     builder.setExtension(
926         TestOptimizedForSize.testExtension2,
927         TestRequiredOptimizedForSize.newBuilder().buildPartial());
928     assertThat(builder.isInitialized()).isFalse();
929     assertThat(builder.buildPartial().isInitialized()).isFalse();
930 
931     builder = TestOptimizedForSize.newBuilder();
932     builder.setExtension(
933         TestOptimizedForSize.testExtension2,
934         TestRequiredOptimizedForSize.newBuilder().setX(10).buildPartial());
935     assertThat(builder.isInitialized()).isTrue();
936     assertThat(builder.buildPartial().isInitialized()).isTrue();
937   }
938 
939   @Test
testToBuilder()940   public void testToBuilder() throws Exception {
941     TestAllTypes.Builder builder = TestAllTypes.newBuilder();
942     TestUtil.setAllFields(builder);
943     TestAllTypes message = builder.build();
944     TestUtil.assertAllFieldsSet(message);
945     TestUtil.assertAllFieldsSet(message.toBuilder().build());
946   }
947 
948   @Test
testFieldConstantValues()949   public void testFieldConstantValues() throws Exception {
950     assertThat(TestAllTypes.NestedMessage.BB_FIELD_NUMBER).isEqualTo(1);
951     assertThat(TestAllTypes.OPTIONAL_INT32_FIELD_NUMBER).isEqualTo(1);
952     assertThat(TestAllTypes.OPTIONALGROUP_FIELD_NUMBER).isEqualTo(16);
953     assertThat(TestAllTypes.OPTIONAL_NESTED_MESSAGE_FIELD_NUMBER).isEqualTo(18);
954     assertThat(TestAllTypes.OPTIONAL_NESTED_ENUM_FIELD_NUMBER).isEqualTo(21);
955     assertThat(TestAllTypes.REPEATED_INT32_FIELD_NUMBER).isEqualTo(31);
956     assertThat(TestAllTypes.REPEATEDGROUP_FIELD_NUMBER).isEqualTo(46);
957     assertThat(TestAllTypes.REPEATED_NESTED_MESSAGE_FIELD_NUMBER).isEqualTo(48);
958     assertThat(TestAllTypes.REPEATED_NESTED_ENUM_FIELD_NUMBER).isEqualTo(51);
959   }
960 
961   @Test
testExtensionConstantValues()962   public void testExtensionConstantValues() throws Exception {
963     assertThat(UnittestProto.TestRequired.SINGLE_FIELD_NUMBER).isEqualTo(1000);
964     assertThat(UnittestProto.TestRequired.MULTI_FIELD_NUMBER).isEqualTo(1001);
965     assertThat(UnittestProto.OPTIONAL_INT32_EXTENSION_FIELD_NUMBER).isEqualTo(1);
966     assertThat(UnittestProto.OPTIONALGROUP_EXTENSION_FIELD_NUMBER).isEqualTo(16);
967     assertThat(UnittestProto.OPTIONAL_NESTED_MESSAGE_EXTENSION_FIELD_NUMBER).isEqualTo(18);
968     assertThat(UnittestProto.OPTIONAL_NESTED_ENUM_EXTENSION_FIELD_NUMBER).isEqualTo(21);
969     assertThat(UnittestProto.REPEATED_INT32_EXTENSION_FIELD_NUMBER).isEqualTo(31);
970     assertThat(UnittestProto.REPEATEDGROUP_EXTENSION_FIELD_NUMBER).isEqualTo(46);
971     assertThat(UnittestProto.REPEATED_NESTED_MESSAGE_EXTENSION_FIELD_NUMBER).isEqualTo(48);
972     assertThat(UnittestProto.REPEATED_NESTED_ENUM_EXTENSION_FIELD_NUMBER).isEqualTo(51);
973   }
974 
975   @Test
testRecursiveMessageDefaultInstance()976   public void testRecursiveMessageDefaultInstance() throws Exception {
977     UnittestProto.TestRecursiveMessage message =
978         UnittestProto.TestRecursiveMessage.getDefaultInstance();
979     assertThat(message).isNotNull();
980     assertThat(message.getA()).isEqualTo(message);
981   }
982 
983   @Test
testSerialize()984   public void testSerialize() throws Exception {
985     ByteArrayOutputStream baos = new ByteArrayOutputStream();
986     TestAllTypes.Builder builder = TestAllTypes.newBuilder();
987     TestUtil.setAllFields(builder);
988     TestAllTypes expected = builder.build();
989     try (ObjectOutputStream out = new ObjectOutputStream(baos)) {
990       out.writeObject(expected);
991     }
992     ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
993     ObjectInputStream in = new ObjectInputStream(bais);
994     TestAllTypes actual = (TestAllTypes) in.readObject();
995     assertThat(actual).isEqualTo(expected);
996   }
997 
998   @Test
testSerializePartial()999   public void testSerializePartial() throws Exception {
1000     ByteArrayOutputStream baos = new ByteArrayOutputStream();
1001     TestAllTypes.Builder builder = TestAllTypes.newBuilder();
1002     TestAllTypes expected = builder.buildPartial();
1003     ObjectOutputStream out = new ObjectOutputStream(baos);
1004     try {
1005       out.writeObject(expected);
1006     } finally {
1007       out.close();
1008     }
1009     ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
1010     ObjectInputStream in = new ObjectInputStream(bais);
1011     TestAllTypes actual = (TestAllTypes) in.readObject();
1012     assertThat(actual).isEqualTo(expected);
1013   }
1014 
1015   @Test
testDeserializeWithoutClassField()1016   public void testDeserializeWithoutClassField() throws Exception {
1017     // serialized form for version <=3.6.0
1018     // just includes messageClassName and asBytes
1019 
1020     // Int32Value.newBuilder().setValue(123).build()
1021     byte[] int32ValueBytes =
1022         new byte[] {
1023           -84, -19, 0, 5, 115, 114, 0, 55, 99, 111, 109, 46, 103, 111, 111, 103, 108, 101, 46, 112,
1024           114, 111, 116, 111, 98, 117, 102, 46, 71, 101, 110, 101, 114, 97, 116, 101, 100, 77, 101,
1025           115, 115, 97, 103, 101, 76, 105, 116, 101, 36, 83, 101, 114, 105, 97, 108, 105, 122, 101,
1026           100, 70, 111, 114, 109, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 91, 0, 7, 97, 115, 66, 121, 116,
1027           101, 115, 116, 0, 2, 91, 66, 76, 0, 16, 109, 101, 115, 115, 97, 103, 101, 67, 108, 97,
1028           115, 115, 78, 97, 109, 101, 116, 0, 18, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47,
1029           83, 116, 114, 105, 110, 103, 59, 120, 112, 117, 114, 0, 2, 91, 66, -84, -13, 23, -8, 6, 8,
1030           84, -32, 2, 0, 0, 120, 112, 0, 0, 0, 2, 8, 123, 116, 0, 30, 99, 111, 109, 46, 103, 111,
1031           111, 103, 108, 101, 46, 112, 114, 111, 116, 111, 98, 117, 102, 46, 73, 110, 116, 51, 50,
1032           86, 97, 108, 117, 101
1033         };
1034 
1035     ByteArrayInputStream bais = new ByteArrayInputStream(int32ValueBytes);
1036     ObjectInputStream in = new ObjectInputStream(bais);
1037     Int32Value int32Value = (Int32Value) in.readObject();
1038     assertThat(int32Value.getValue()).isEqualTo(123);
1039   }
1040 
1041   @Test
testDeserializeWithClassField()1042   public void testDeserializeWithClassField() throws Exception {
1043     // serialized form for version > 3.6.0
1044     // includes messageClass, messageClassName (for compatibility), and asBytes
1045 
1046     // Int32Value.newBuilder().setValue(123).build()
1047     byte[] int32ValueBytes =
1048         new byte[] {
1049           -84, -19, 0, 5, 115, 114, 0, 55, 99, 111, 109, 46, 103, 111, 111, 103, 108, 101, 46, 112,
1050           114, 111, 116, 111, 98, 117, 102, 46, 71, 101, 110, 101, 114, 97, 116, 101, 100, 77, 101,
1051           115, 115, 97, 103, 101, 76, 105, 116, 101, 36, 83, 101, 114, 105, 97, 108, 105, 122, 101,
1052           100, 70, 111, 114, 109, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 3, 91, 0, 7, 97, 115, 66, 121, 116,
1053           101, 115, 116, 0, 2, 91, 66, 76, 0, 12, 109, 101, 115, 115, 97, 103, 101, 67, 108, 97,
1054           115, 115, 116, 0, 17, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 67, 108, 97, 115,
1055           115, 59, 76, 0, 16, 109, 101, 115, 115, 97, 103, 101, 67, 108, 97, 115, 115, 78, 97, 109,
1056           101, 116, 0, 18, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 83, 116, 114, 105, 110,
1057           103, 59, 120, 112, 117, 114, 0, 2, 91, 66, -84, -13, 23, -8, 6, 8, 84, -32, 2, 0, 0, 120,
1058           112, 0, 0, 0, 2, 8, 123, 118, 114, 0, 30, 99, 111, 109, 46, 103, 111, 111, 103, 108, 101,
1059           46, 112, 114, 111, 116, 111, 98, 117, 102, 46, 73, 110, 116, 51, 50, 86, 97, 108, 117,
1060           101, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 66, 0, 21, 109, 101, 109, 111, 105, 122, 101, 100,
1061           73, 115, 73, 110, 105, 116, 105, 97, 108, 105, 122, 101, 100, 73, 0, 6, 118, 97, 108, 117,
1062           101, 95, 120, 114, 0, 38, 99, 111, 109, 46, 103, 111, 111, 103, 108, 101, 46, 112, 114,
1063           111, 116, 111, 98, 117, 102, 46, 71, 101, 110, 101, 114, 97, 116, 101, 100, 77, 101, 115,
1064           115, 97, 103, 101, 86, 51, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 1, 76, 0, 13, 117, 110, 107, 110,
1065           111, 119, 110, 70, 105, 101, 108, 100, 115, 116, 0, 37, 76, 99, 111, 109, 47, 103, 111,
1066           111, 103, 108, 101, 47, 112, 114, 111, 116, 111, 98, 117, 102, 47, 85, 110, 107, 110, 111,
1067           119, 110, 70, 105, 101, 108, 100, 83, 101, 116, 59, 120, 112, 116, 0, 30, 99, 111, 109,
1068           46, 103, 111, 111, 103, 108, 101, 46, 112, 114, 111, 116, 111, 98, 117, 102, 46, 73, 110,
1069           116, 51, 50, 86, 97, 108, 117, 101
1070         };
1071 
1072     ByteArrayInputStream bais = new ByteArrayInputStream(int32ValueBytes);
1073     ObjectInputStream in = new ObjectInputStream(bais);
1074     Int32Value int32Value = (Int32Value) in.readObject();
1075     assertThat(int32Value.getValue()).isEqualTo(123);
1076   }
1077 
1078   @Test
testEnumValues()1079   public void testEnumValues() {
1080     assertThat(TestAllTypes.NestedEnum.BAR.getNumber())
1081         .isEqualTo(TestAllTypes.NestedEnum.BAR_VALUE);
1082     assertThat(TestAllTypes.NestedEnum.BAZ.getNumber())
1083         .isEqualTo(TestAllTypes.NestedEnum.BAZ_VALUE);
1084     assertThat(TestAllTypes.NestedEnum.FOO.getNumber())
1085         .isEqualTo(TestAllTypes.NestedEnum.FOO_VALUE);
1086   }
1087 
1088   @Test
testNonNestedExtensionInitialization()1089   public void testNonNestedExtensionInitialization() {
1090     assertThat(NonNestedExtension.nonNestedExtension.getMessageDefaultInstance())
1091         .isInstanceOf(MyNonNestedExtension.class);
1092     assertThat(NonNestedExtension.nonNestedExtension.getDescriptor().getName())
1093         .isEqualTo("nonNestedExtension");
1094   }
1095 
1096   @Test
testNestedExtensionInitialization()1097   public void testNestedExtensionInitialization() {
1098     assertThat(MyNestedExtension.recursiveExtension.getMessageDefaultInstance())
1099         .isInstanceOf(MessageToBeExtended.class);
1100     assertThat(MyNestedExtension.recursiveExtension.getDescriptor().getName())
1101         .isEqualTo("recursiveExtension");
1102   }
1103 
1104   @Test
testInvalidations()1105   public void testInvalidations() throws Exception {
1106     GeneratedMessage.setAlwaysUseFieldBuildersForTesting(true);
1107     TestAllTypes.NestedMessage nestedMessage1 = TestAllTypes.NestedMessage.newBuilder().build();
1108     TestAllTypes.NestedMessage nestedMessage2 = TestAllTypes.NestedMessage.newBuilder().build();
1109 
1110     // Set all three flavors (enum, primitive, message and singular/repeated)
1111     // and verify no invalidations fired
1112     TestUtil.MockBuilderParent mockParent = new TestUtil.MockBuilderParent();
1113 
1114     TestAllTypes.Builder builder =
1115         (TestAllTypes.Builder)
1116             ((AbstractMessage) TestAllTypes.getDefaultInstance()).newBuilderForType(mockParent);
1117     builder.setOptionalInt32(1);
1118     builder.setOptionalNestedEnum(TestAllTypes.NestedEnum.BAR);
1119     builder.setOptionalNestedMessage(nestedMessage1);
1120     builder.addRepeatedInt32(1);
1121     builder.addRepeatedNestedEnum(TestAllTypes.NestedEnum.BAR);
1122     builder.addRepeatedNestedMessage(nestedMessage1);
1123     assertThat(mockParent.getInvalidationCount()).isEqualTo(0);
1124 
1125     // Now tell it we want changes and make sure it's only fired once
1126     // And do this for each flavor
1127 
1128     // primitive single
1129     builder.buildPartial();
1130     builder.setOptionalInt32(2);
1131     builder.setOptionalInt32(3);
1132     assertThat(mockParent.getInvalidationCount()).isEqualTo(1);
1133 
1134     // enum single
1135     builder.buildPartial();
1136     builder.setOptionalNestedEnum(TestAllTypes.NestedEnum.BAZ);
1137     builder.setOptionalNestedEnum(TestAllTypes.NestedEnum.BAR);
1138     assertThat(mockParent.getInvalidationCount()).isEqualTo(2);
1139 
1140     // message single
1141     builder.buildPartial();
1142     builder.setOptionalNestedMessage(nestedMessage2);
1143     builder.setOptionalNestedMessage(nestedMessage1);
1144     assertThat(mockParent.getInvalidationCount()).isEqualTo(3);
1145 
1146     // primitive repeated
1147     builder.buildPartial();
1148     builder.addRepeatedInt32(2);
1149     builder.addRepeatedInt32(3);
1150     assertThat(mockParent.getInvalidationCount()).isEqualTo(4);
1151 
1152     // enum repeated
1153     builder.buildPartial();
1154     builder.addRepeatedNestedEnum(TestAllTypes.NestedEnum.BAZ);
1155     builder.addRepeatedNestedEnum(TestAllTypes.NestedEnum.BAZ);
1156     assertThat(mockParent.getInvalidationCount()).isEqualTo(5);
1157 
1158     // message repeated
1159     builder.buildPartial();
1160     builder.addRepeatedNestedMessage(nestedMessage2);
1161     builder.addRepeatedNestedMessage(nestedMessage1);
1162     assertThat(mockParent.getInvalidationCount()).isEqualTo(6);
1163   }
1164 
1165   @Test
testInvalidations_Extensions()1166   public void testInvalidations_Extensions() throws Exception {
1167     TestUtil.MockBuilderParent mockParent = new TestUtil.MockBuilderParent();
1168 
1169     TestAllExtensions.Builder builder =
1170         (TestAllExtensions.Builder)
1171             ((AbstractMessage) TestAllExtensions.getDefaultInstance())
1172                 .newBuilderForType(mockParent);
1173 
1174     builder.addExtension(UnittestProto.repeatedInt32Extension, 1);
1175     builder.setExtension(UnittestProto.repeatedInt32Extension, 0, 2);
1176     builder.clearExtension(UnittestProto.repeatedInt32Extension);
1177     assertThat(mockParent.getInvalidationCount()).isEqualTo(0);
1178 
1179     // Now tell it we want changes and make sure it's only fired once
1180     builder.buildPartial();
1181     builder.addExtension(UnittestProto.repeatedInt32Extension, 2);
1182     builder.addExtension(UnittestProto.repeatedInt32Extension, 3);
1183     assertThat(mockParent.getInvalidationCount()).isEqualTo(1);
1184 
1185     builder.buildPartial();
1186     builder.setExtension(UnittestProto.repeatedInt32Extension, 0, 4);
1187     builder.setExtension(UnittestProto.repeatedInt32Extension, 1, 5);
1188     assertThat(mockParent.getInvalidationCount()).isEqualTo(2);
1189 
1190     builder.buildPartial();
1191     builder.clearExtension(UnittestProto.repeatedInt32Extension);
1192     builder.clearExtension(UnittestProto.repeatedInt32Extension);
1193     assertThat(mockParent.getInvalidationCount()).isEqualTo(3);
1194   }
1195 
1196   @Test
testBaseMessageOrBuilder()1197   public void testBaseMessageOrBuilder() {
1198     // Mostly just makes sure the base interface exists and has some methods.
1199     TestAllTypes.Builder builder = TestAllTypes.newBuilder();
1200     TestAllTypes message = builder.buildPartial();
1201     TestAllTypesOrBuilder messageAsInterface = (TestAllTypesOrBuilder) message;
1202 
1203     assertThat(messageAsInterface.getDefaultBool()).isEqualTo(messageAsInterface.getDefaultBool());
1204     assertThat(messageAsInterface.getOptionalDouble())
1205         .isEqualTo(messageAsInterface.getOptionalDouble());
1206   }
1207 
1208   @Test
testMessageOrBuilderGetters()1209   public void testMessageOrBuilderGetters() {
1210     TestAllTypes.Builder builder = TestAllTypes.newBuilder();
1211 
1212     // single fields
1213     assertThat(ForeignMessage.getDefaultInstance())
1214         .isSameInstanceAs(builder.getOptionalForeignMessageOrBuilder());
1215     ForeignMessage.Builder subBuilder = builder.getOptionalForeignMessageBuilder();
1216     assertThat(subBuilder).isSameInstanceAs(builder.getOptionalForeignMessageOrBuilder());
1217 
1218     // repeated fields
1219     ForeignMessage m0 = ForeignMessage.newBuilder().buildPartial();
1220     ForeignMessage m1 = ForeignMessage.newBuilder().buildPartial();
1221     ForeignMessage m2 = ForeignMessage.newBuilder().buildPartial();
1222     builder.addRepeatedForeignMessage(m0);
1223     builder.addRepeatedForeignMessage(m1);
1224     builder.addRepeatedForeignMessage(m2);
1225     assertThat(m0).isSameInstanceAs(builder.getRepeatedForeignMessageOrBuilder(0));
1226     assertThat(m1).isSameInstanceAs(builder.getRepeatedForeignMessageOrBuilder(1));
1227     assertThat(m2).isSameInstanceAs(builder.getRepeatedForeignMessageOrBuilder(2));
1228     ForeignMessage.Builder b0 = builder.getRepeatedForeignMessageBuilder(0);
1229     ForeignMessage.Builder b1 = builder.getRepeatedForeignMessageBuilder(1);
1230     assertThat(b0).isSameInstanceAs(builder.getRepeatedForeignMessageOrBuilder(0));
1231     assertThat(b1).isSameInstanceAs(builder.getRepeatedForeignMessageOrBuilder(1));
1232     assertThat(m2).isSameInstanceAs(builder.getRepeatedForeignMessageOrBuilder(2));
1233 
1234     List<? extends ForeignMessageOrBuilder> messageOrBuilderList =
1235         builder.getRepeatedForeignMessageOrBuilderList();
1236     assertThat(b0).isSameInstanceAs(messageOrBuilderList.get(0));
1237     assertThat(b1).isSameInstanceAs(messageOrBuilderList.get(1));
1238     assertThat(m2).isSameInstanceAs(messageOrBuilderList.get(2));
1239   }
1240 
1241   @Test
testGetFieldBuilder()1242   public void testGetFieldBuilder() {
1243     Descriptor descriptor = TestAllTypes.getDescriptor();
1244 
1245     FieldDescriptor fieldDescriptor = descriptor.findFieldByName("optional_nested_message");
1246     FieldDescriptor foreignFieldDescriptor = descriptor.findFieldByName("optional_foreign_message");
1247     FieldDescriptor importFieldDescriptor = descriptor.findFieldByName("optional_import_message");
1248 
1249     // Mutate the message with new field builder
1250     // Mutate nested message
1251     TestAllTypes.Builder builder1 = TestAllTypes.newBuilder();
1252     Message.Builder fieldBuilder1 =
1253         builder1
1254             .newBuilderForField(fieldDescriptor)
1255             .mergeFrom((Message) builder1.getField(fieldDescriptor));
1256     fieldBuilder1.setField(NESTED_MESSAGE_BB_FIELD, 1);
1257     builder1.setField(fieldDescriptor, fieldBuilder1.build());
1258 
1259     // Mutate foreign message
1260     Message.Builder foreignFieldBuilder1 =
1261         builder1
1262             .newBuilderForField(foreignFieldDescriptor)
1263             .mergeFrom((Message) builder1.getField(foreignFieldDescriptor));
1264     FieldDescriptor subForeignFieldDescriptor1 =
1265         foreignFieldBuilder1.getDescriptorForType().findFieldByName("c");
1266     foreignFieldBuilder1.setField(subForeignFieldDescriptor1, 2);
1267     builder1.setField(foreignFieldDescriptor, foreignFieldBuilder1.build());
1268 
1269     // Mutate import message
1270     Message.Builder importFieldBuilder1 =
1271         builder1
1272             .newBuilderForField(importFieldDescriptor)
1273             .mergeFrom((Message) builder1.getField(importFieldDescriptor));
1274     FieldDescriptor subImportFieldDescriptor1 =
1275         importFieldBuilder1.getDescriptorForType().findFieldByName("d");
1276     importFieldBuilder1.setField(subImportFieldDescriptor1, 3);
1277     builder1.setField(importFieldDescriptor, importFieldBuilder1.build());
1278 
1279     Message newMessage1 = builder1.build();
1280 
1281     // Mutate the message with existing field builder
1282     // Mutate nested message
1283     TestAllTypes.Builder builder2 = TestAllTypes.newBuilder();
1284     Message.Builder fieldBuilder2 = builder2.getFieldBuilder(fieldDescriptor);
1285     fieldBuilder2.setField(NESTED_MESSAGE_BB_FIELD, 1);
1286     builder2.setField(fieldDescriptor, fieldBuilder2.build());
1287 
1288     // Mutate foreign message
1289     Message.Builder foreignFieldBuilder2 =
1290         builder2
1291             .newBuilderForField(foreignFieldDescriptor)
1292             .mergeFrom((Message) builder2.getField(foreignFieldDescriptor));
1293     FieldDescriptor subForeignFieldDescriptor2 =
1294         foreignFieldBuilder2.getDescriptorForType().findFieldByName("c");
1295     foreignFieldBuilder2.setField(subForeignFieldDescriptor2, 2);
1296     builder2.setField(foreignFieldDescriptor, foreignFieldBuilder2.build());
1297 
1298     // Mutate import message
1299     Message.Builder importFieldBuilder2 =
1300         builder2
1301             .newBuilderForField(importFieldDescriptor)
1302             .mergeFrom((Message) builder2.getField(importFieldDescriptor));
1303     FieldDescriptor subImportFieldDescriptor2 =
1304         importFieldBuilder2.getDescriptorForType().findFieldByName("d");
1305     importFieldBuilder2.setField(subImportFieldDescriptor2, 3);
1306     builder2.setField(importFieldDescriptor, importFieldBuilder2.build());
1307 
1308     Message newMessage2 = builder2.build();
1309 
1310     // These two messages should be equal.
1311     assertThat(newMessage1).isEqualTo(newMessage2);
1312   }
1313 
1314   @Test
testGetFieldBuilderWithInitializedValue()1315   public void testGetFieldBuilderWithInitializedValue() {
1316     Descriptor descriptor = TestAllTypes.getDescriptor();
1317     FieldDescriptor fieldDescriptor = descriptor.findFieldByName("optional_nested_message");
1318 
1319     // Before setting field, builder is initialized by default value.
1320     TestAllTypes.Builder builder = TestAllTypes.newBuilder();
1321     NestedMessage.Builder fieldBuilder =
1322         (NestedMessage.Builder) builder.getFieldBuilder(fieldDescriptor);
1323     assertThat(fieldBuilder.getBb()).isEqualTo(0);
1324 
1325     // Setting field value with new field builder instance.
1326     builder = TestAllTypes.newBuilder();
1327     NestedMessage.Builder newFieldBuilder = builder.getOptionalNestedMessageBuilder();
1328     newFieldBuilder.setBb(2);
1329     // Then get the field builder instance by getFieldBuilder().
1330     fieldBuilder = (NestedMessage.Builder) builder.getFieldBuilder(fieldDescriptor);
1331     // It should contain new value.
1332     assertThat(fieldBuilder.getBb()).isEqualTo(2);
1333     // These two builder should be equal.
1334     assertThat(fieldBuilder).isSameInstanceAs(newFieldBuilder);
1335   }
1336 
1337   @Test
testGetFieldBuilderNotSupportedException()1338   public void testGetFieldBuilderNotSupportedException() {
1339     Descriptor descriptor = TestAllTypes.getDescriptor();
1340     TestAllTypes.Builder builder = TestAllTypes.newBuilder();
1341     assertThrows(
1342         "Exception was not thrown",
1343         UnsupportedOperationException.class,
1344         () -> builder.getFieldBuilder(descriptor.findFieldByName("optional_int32")));
1345     assertThrows(
1346         "Exception was not thrown",
1347         UnsupportedOperationException.class,
1348         () -> builder.getFieldBuilder(descriptor.findFieldByName("optional_nested_enum")));
1349     assertThrows(
1350         "Exception was not thrown",
1351         UnsupportedOperationException.class,
1352         () -> builder.getFieldBuilder(descriptor.findFieldByName("repeated_int32")));
1353     assertThrows(
1354         "Exception was not thrown",
1355         UnsupportedOperationException.class,
1356         () -> builder.getFieldBuilder(descriptor.findFieldByName("repeated_nested_enum")));
1357     assertThrows(
1358         "Exception was not thrown",
1359         UnsupportedOperationException.class,
1360         () -> builder.getFieldBuilder(descriptor.findFieldByName("repeated_nested_message")));
1361   }
1362 
1363   // Test that when the default outer class name conflicts with another type
1364   // defined in the proto the compiler will append a suffix to avoid the
1365   // conflict.
1366   @Test
testConflictingOuterClassName()1367   public void testConflictingOuterClassName() {
1368     // We just need to make sure we can refer to the outer class with the
1369     // expected name. There is nothing else to test.
1370     OuterClassNameTestOuterClass.OuterClassNameTest message =
1371         OuterClassNameTestOuterClass.OuterClassNameTest.newBuilder().build();
1372     assertThat(message.getDescriptorForType())
1373         .isSameInstanceAs(OuterClassNameTestOuterClass.OuterClassNameTest.getDescriptor());
1374 
1375     OuterClassNameTest2OuterClass.TestMessage2.NestedMessage.OuterClassNameTest2 message2 =
1376         OuterClassNameTest2OuterClass.TestMessage2.NestedMessage.OuterClassNameTest2.newBuilder()
1377             .build();
1378     assertThat(message2.getSerializedSize()).isEqualTo(0);
1379 
1380     OuterClassNameTest3OuterClass.TestMessage3.NestedMessage.OuterClassNameTest3 enumValue =
1381         OuterClassNameTest3OuterClass.TestMessage3.NestedMessage.OuterClassNameTest3.DUMMY_VALUE;
1382     assertThat(enumValue.getNumber()).isEqualTo(1);
1383   }
1384 
1385   // =================================================================
1386   // oneof generated code test
1387   @Test
1388   @SuppressWarnings("RedundantSetterCall")
testOneofEnumCase()1389   public void testOneofEnumCase() throws Exception {
1390     TestOneof2 message =
1391         TestOneof2.newBuilder().setFooInt(123).setFooString("foo").setFooCord("bar").build();
1392     TestUtil.assertAtMostOneFieldSetOneof(message);
1393   }
1394 
1395   @Test
testClearOneof()1396   public void testClearOneof() throws Exception {
1397     TestOneof2.Builder builder = TestOneof2.newBuilder().setFooInt(123);
1398     assertThat(builder.getFooCase()).isEqualTo(TestOneof2.FooCase.FOO_INT);
1399     builder.clearFoo();
1400     assertThat(builder.getFooCase()).isEqualTo(TestOneof2.FooCase.FOO_NOT_SET);
1401   }
1402 
1403   @Test
1404   @SuppressWarnings("RedundantSetterCall")
testSetOneofClearsOthers()1405   public void testSetOneofClearsOthers() throws Exception {
1406     TestOneof2.Builder builder = TestOneof2.newBuilder();
1407     TestOneof2 message = builder.setFooInt(123).setFooString("foo").buildPartial();
1408     assertThat(message.hasFooString()).isTrue();
1409     TestUtil.assertAtMostOneFieldSetOneof(message);
1410 
1411     message = builder.setFooCord("bar").buildPartial();
1412     assertThat(message.hasFooCord()).isTrue();
1413     TestUtil.assertAtMostOneFieldSetOneof(message);
1414 
1415     message = builder.setFooStringPiece("baz").buildPartial();
1416     assertThat(message.hasFooStringPiece()).isTrue();
1417     TestUtil.assertAtMostOneFieldSetOneof(message);
1418 
1419     message = builder.setFooBytes(TestUtil.toBytes("moo")).buildPartial();
1420     assertThat(message.hasFooBytes()).isTrue();
1421     TestUtil.assertAtMostOneFieldSetOneof(message);
1422 
1423     message = builder.setFooEnum(TestOneof2.NestedEnum.FOO).buildPartial();
1424     assertThat(message.hasFooEnum()).isTrue();
1425     TestUtil.assertAtMostOneFieldSetOneof(message);
1426 
1427     message =
1428         builder
1429             .setFooMessage(TestOneof2.NestedMessage.newBuilder().setMooInt(234).build())
1430             .buildPartial();
1431     assertThat(message.hasFooMessage()).isTrue();
1432     TestUtil.assertAtMostOneFieldSetOneof(message);
1433 
1434     message = builder.setFooInt(123).buildPartial();
1435     assertThat(message.hasFooInt()).isTrue();
1436     TestUtil.assertAtMostOneFieldSetOneof(message);
1437   }
1438 
1439   @Test
testOneofTypes()1440   public void testOneofTypes() throws Exception {
1441     // Primitive
1442     {
1443       TestOneof2.Builder builder = TestOneof2.newBuilder();
1444       assertThat(builder.getFooInt()).isEqualTo(0);
1445       assertThat(builder.hasFooInt()).isFalse();
1446       assertThat(builder.setFooInt(123).hasFooInt()).isTrue();
1447       assertThat(builder.getFooInt()).isEqualTo(123);
1448       TestOneof2 message = builder.buildPartial();
1449       assertThat(message.hasFooInt()).isTrue();
1450       assertThat(message.getFooInt()).isEqualTo(123);
1451 
1452       assertThat(builder.clearFooInt().hasFooInt()).isFalse();
1453       TestOneof2 message2 = builder.build();
1454       assertThat(message2.hasFooInt()).isFalse();
1455       assertThat(message2.getFooInt()).isEqualTo(0);
1456     }
1457 
1458     // Enum
1459     {
1460       TestOneof2.Builder builder = TestOneof2.newBuilder();
1461       assertThat(builder.getFooEnum()).isEqualTo(TestOneof2.NestedEnum.FOO);
1462       assertThat(builder.setFooEnum(TestOneof2.NestedEnum.BAR).hasFooEnum()).isTrue();
1463       assertThat(builder.getFooEnum()).isEqualTo(TestOneof2.NestedEnum.BAR);
1464       TestOneof2 message = builder.buildPartial();
1465       assertThat(message.hasFooEnum()).isTrue();
1466       assertThat(message.getFooEnum()).isEqualTo(TestOneof2.NestedEnum.BAR);
1467 
1468       assertThat(builder.clearFooEnum().hasFooEnum()).isFalse();
1469       TestOneof2 message2 = builder.build();
1470       assertThat(message2.hasFooEnum()).isFalse();
1471       assertThat(message2.getFooEnum()).isEqualTo(TestOneof2.NestedEnum.FOO);
1472     }
1473 
1474     // String
1475     {
1476       TestOneof2.Builder builder = TestOneof2.newBuilder();
1477       assertThat(builder.getFooString()).isEmpty();
1478       builder.setFooString("foo");
1479       assertThat(builder.hasFooString()).isTrue();
1480       assertThat(builder.getFooString()).isEqualTo("foo");
1481       TestOneof2 message = builder.buildPartial();
1482       assertThat(message.hasFooString()).isTrue();
1483       assertThat(message.getFooString()).isEqualTo("foo");
1484       assertThat(TestUtil.toBytes("foo")).isEqualTo(message.getFooStringBytes());
1485 
1486       assertThat(builder.clearFooString().hasFooString()).isFalse();
1487       TestOneof2 message2 = builder.buildPartial();
1488       assertThat(message2.hasFooString()).isFalse();
1489       assertThat(message2.getFooString()).isEmpty();
1490       assertThat(message2.getFooStringBytes()).isEqualTo(TestUtil.toBytes(""));
1491 
1492       // Get method should not change the oneof value.
1493       builder.setFooInt(123);
1494       assertThat(builder.getFooString()).isEmpty();
1495       assertThat(builder.getFooStringBytes()).isEqualTo(TestUtil.toBytes(""));
1496       assertThat(builder.getFooInt()).isEqualTo(123);
1497 
1498       message = builder.build();
1499       assertThat(message.getFooString()).isEmpty();
1500       assertThat(TestUtil.toBytes("")).isEqualTo(message.getFooStringBytes());
1501       assertThat(message.getFooInt()).isEqualTo(123);
1502     }
1503 
1504     // Cord
1505     {
1506       TestOneof2.Builder builder = TestOneof2.newBuilder();
1507       assertThat(builder.getFooCord()).isEmpty();
1508       builder.setFooCord("foo");
1509       assertThat(builder.hasFooCord()).isTrue();
1510       assertThat(builder.getFooCord()).isEqualTo("foo");
1511       TestOneof2 message = builder.buildPartial();
1512       assertThat(message.hasFooCord()).isTrue();
1513       assertThat(message.getFooCord()).isEqualTo("foo");
1514       assertThat(TestUtil.toBytes("foo")).isEqualTo(message.getFooCordBytes());
1515 
1516       assertThat(builder.clearFooCord().hasFooCord()).isFalse();
1517       TestOneof2 message2 = builder.build();
1518       assertThat(message2.hasFooCord()).isFalse();
1519       assertThat(message2.getFooCord()).isEmpty();
1520       assertThat(message2.getFooCordBytes()).isEqualTo(TestUtil.toBytes(""));
1521     }
1522 
1523     // StringPiece
1524     {
1525       TestOneof2.Builder builder = TestOneof2.newBuilder();
1526       assertThat(builder.getFooStringPiece()).isEmpty();
1527       builder.setFooStringPiece("foo");
1528       assertThat(builder.hasFooStringPiece()).isTrue();
1529       assertThat(builder.getFooStringPiece()).isEqualTo("foo");
1530       TestOneof2 message = builder.buildPartial();
1531       assertThat(message.hasFooStringPiece()).isTrue();
1532       assertThat(message.getFooStringPiece()).isEqualTo("foo");
1533       assertThat(TestUtil.toBytes("foo")).isEqualTo(message.getFooStringPieceBytes());
1534 
1535       assertThat(builder.clearFooStringPiece().hasFooStringPiece()).isFalse();
1536       TestOneof2 message2 = builder.build();
1537       assertThat(message2.hasFooStringPiece()).isFalse();
1538       assertThat(message2.getFooStringPiece()).isEmpty();
1539       assertThat(message2.getFooStringPieceBytes()).isEqualTo(TestUtil.toBytes(""));
1540     }
1541 
1542     // Message
1543     {
1544       // set
1545       TestOneof2.Builder builder = TestOneof2.newBuilder();
1546       assertThat(builder.getFooMessage().getMooInt()).isEqualTo(0);
1547       builder.setFooMessage(TestOneof2.NestedMessage.newBuilder().setMooInt(234).build());
1548       assertThat(builder.hasFooMessage()).isTrue();
1549       assertThat(builder.getFooMessage().getMooInt()).isEqualTo(234);
1550       TestOneof2 message = builder.buildPartial();
1551       assertThat(message.hasFooMessage()).isTrue();
1552       assertThat(message.getFooMessage().getMooInt()).isEqualTo(234);
1553 
1554       // clear
1555       assertThat(builder.clearFooMessage().hasFooString()).isFalse();
1556       message = builder.build();
1557       assertThat(message.hasFooMessage()).isFalse();
1558       assertThat(message.getFooMessage().getMooInt()).isEqualTo(0);
1559 
1560       // nested builder
1561       builder = TestOneof2.newBuilder();
1562       assertThat(builder.getFooMessageOrBuilder())
1563           .isSameInstanceAs(TestOneof2.NestedMessage.getDefaultInstance());
1564       assertThat(builder.hasFooMessage()).isFalse();
1565       builder.getFooMessageBuilder().setMooInt(123);
1566       assertThat(builder.hasFooMessage()).isTrue();
1567       assertThat(builder.getFooMessage().getMooInt()).isEqualTo(123);
1568       message = builder.build();
1569       assertThat(message.hasFooMessage()).isTrue();
1570       assertThat(message.getFooMessage().getMooInt()).isEqualTo(123);
1571     }
1572 
1573     // LazyMessage is tested in LazyMessageLiteTest.java
1574   }
1575 
1576   @Test
testOneofMergeNonMessage()1577   public void testOneofMergeNonMessage() throws Exception {
1578     // Primitive Type
1579     {
1580       TestOneof2.Builder builder = TestOneof2.newBuilder();
1581       TestOneof2 message = builder.setFooInt(123).build();
1582       TestOneof2 message2 = TestOneof2.newBuilder().mergeFrom(message).build();
1583       assertThat(message2.hasFooInt()).isTrue();
1584       assertThat(message2.getFooInt()).isEqualTo(123);
1585     }
1586 
1587     // String
1588     {
1589       TestOneof2.Builder builder = TestOneof2.newBuilder();
1590       TestOneof2 message = builder.setFooString("foo").build();
1591       TestOneof2 message2 = TestOneof2.newBuilder().mergeFrom(message).build();
1592       assertThat(message2.hasFooString()).isTrue();
1593       assertThat(message2.getFooString()).isEqualTo("foo");
1594     }
1595 
1596     // Enum
1597     {
1598       TestOneof2.Builder builder = TestOneof2.newBuilder();
1599       TestOneof2 message = builder.setFooEnum(TestOneof2.NestedEnum.BAR).build();
1600       TestOneof2 message2 = TestOneof2.newBuilder().mergeFrom(message).build();
1601       assertThat(message2.hasFooEnum()).isTrue();
1602       assertThat(message2.getFooEnum()).isEqualTo(TestOneof2.NestedEnum.BAR);
1603     }
1604   }
1605 
1606   @Test
testOneofMergeMessage_mergeIntoNewBuilder()1607   public void testOneofMergeMessage_mergeIntoNewBuilder() {
1608     TestOneof2.Builder builder = TestOneof2.newBuilder();
1609     TestOneof2 message =
1610         builder.setFooMessage(TestOneof2.NestedMessage.newBuilder().setMooInt(234).build()).build();
1611     TestOneof2 message2 = TestOneof2.newBuilder().mergeFrom(message).build();
1612     assertThat(message2.hasFooMessage()).isTrue();
1613     assertThat(message2.getFooMessage().getMooInt()).isEqualTo(234);
1614   }
1615 
1616   @Test
testOneofMergeMessage_mergeWithGetMessageBuilder()1617   public void testOneofMergeMessage_mergeWithGetMessageBuilder() {
1618     TestOneof2.Builder builder = TestOneof2.newBuilder();
1619     builder.getFooMessageBuilder().addCorgeInt(1);
1620     assertThat(builder.mergeFrom(MESSAGE_TO_MERGE_FROM).build()).isEqualTo(EXPECTED_MERGED_MESSAGE);
1621   }
1622 
1623   @Test
testOneofMergeMessage_mergeIntoMessageBuiltWithGetMessageBuilder()1624   public void testOneofMergeMessage_mergeIntoMessageBuiltWithGetMessageBuilder() {
1625     TestOneof2.Builder builder = TestOneof2.newBuilder();
1626     builder.getFooMessageBuilder().addCorgeInt(1);
1627     TestOneof2 message = builder.build();
1628     assertThat(message.toBuilder().mergeFrom(MESSAGE_TO_MERGE_FROM).build())
1629         .isEqualTo(EXPECTED_MERGED_MESSAGE);
1630   }
1631 
1632   @Test
testOneofMergeMessage_mergeWithoutGetMessageBuilder()1633   public void testOneofMergeMessage_mergeWithoutGetMessageBuilder() {
1634     TestOneof2.Builder builder =
1635         TestOneof2.newBuilder().setFooMessage(TestOneof2.NestedMessage.newBuilder().addCorgeInt(1));
1636     assertThat(builder.mergeFrom(MESSAGE_TO_MERGE_FROM).build()).isEqualTo(EXPECTED_MERGED_MESSAGE);
1637   }
1638 
1639   @Test
testOneofSerialization()1640   public void testOneofSerialization() throws Exception {
1641     // Primitive Type
1642     {
1643       TestOneof2.Builder builder = TestOneof2.newBuilder();
1644       TestOneof2 message = builder.setFooInt(123).build();
1645       ByteString serialized = message.toByteString();
1646       TestOneof2 message2 = TestOneof2.parseFrom(serialized);
1647       assertThat(message2.hasFooInt()).isTrue();
1648       assertThat(message2.getFooInt()).isEqualTo(123);
1649     }
1650 
1651     // String
1652     {
1653       TestOneof2.Builder builder = TestOneof2.newBuilder();
1654       TestOneof2 message = builder.setFooString("foo").build();
1655       ByteString serialized = message.toByteString();
1656       TestOneof2 message2 = TestOneof2.parseFrom(serialized);
1657       assertThat(message2.hasFooString()).isTrue();
1658       assertThat(message2.getFooString()).isEqualTo("foo");
1659     }
1660 
1661     // Enum
1662     {
1663       TestOneof2.Builder builder = TestOneof2.newBuilder();
1664       TestOneof2 message = builder.setFooEnum(TestOneof2.NestedEnum.BAR).build();
1665       ByteString serialized = message.toByteString();
1666       TestOneof2 message2 = TestOneof2.parseFrom(serialized);
1667       assertThat(message2.hasFooEnum()).isTrue();
1668       assertThat(message2.getFooEnum()).isEqualTo(TestOneof2.NestedEnum.BAR);
1669     }
1670 
1671     // Message
1672     {
1673       TestOneof2.Builder builder = TestOneof2.newBuilder();
1674       TestOneof2 message =
1675           builder
1676               .setFooMessage(TestOneof2.NestedMessage.newBuilder().setMooInt(234).build())
1677               .build();
1678       ByteString serialized = message.toByteString();
1679       TestOneof2 message2 = TestOneof2.parseFrom(serialized);
1680       assertThat(message2.hasFooMessage()).isTrue();
1681       assertThat(message2.getFooMessage().getMooInt()).isEqualTo(234);
1682     }
1683   }
1684 
1685   @Test
testOneofNestedBuilderOnChangePropagation()1686   public void testOneofNestedBuilderOnChangePropagation() {
1687     NestedTestAllTypes.Builder parentBuilder = NestedTestAllTypes.newBuilder();
1688     TestAllTypes.Builder builder = parentBuilder.getPayloadBuilder();
1689     builder.getOneofNestedMessageBuilder();
1690     assertThat(builder.hasOneofNestedMessage()).isTrue();
1691     assertThat(parentBuilder.hasPayload()).isTrue();
1692     NestedTestAllTypes message = parentBuilder.build();
1693     assertThat(message.hasPayload()).isTrue();
1694     assertThat(message.getPayload().hasOneofNestedMessage()).isTrue();
1695   }
1696 
1697   @Test
testOneofParseFailurePropagatesUnderlyingException()1698   public void testOneofParseFailurePropagatesUnderlyingException() {
1699     final byte[] bytes = TestOneof2.newBuilder().setFooInt(123).build().toByteArray();
1700     final IOException injectedException = new IOException("oh no");
1701     CodedInputStream failingInputStream =
1702         CodedInputStream.newInstance(
1703             new InputStream() {
1704               boolean first = true;
1705 
1706               @Override
1707               public int read(byte[] b, int off, int len) throws IOException {
1708                 if (!first) {
1709                   throw injectedException;
1710                 }
1711                 first = false;
1712                 System.arraycopy(bytes, 0, b, off, len);
1713                 return len;
1714               }
1715 
1716               @Override
1717               public int read() {
1718                 throw new UnsupportedOperationException();
1719               }
1720             },
1721             bytes.length - 1);
1722     TestOneof2.Builder builder = TestOneof2.newBuilder();
1723 
1724     try {
1725       builder.mergeFrom(failingInputStream, ExtensionRegistry.getEmptyRegistry());
1726       assertWithMessage("Expected mergeFrom to fail").fail();
1727     } catch (IOException e) {
1728       assertThat(e).isSameInstanceAs(injectedException);
1729     }
1730   }
1731 
1732   @Test
testGetRepeatedFieldBuilder()1733   public void testGetRepeatedFieldBuilder() {
1734     Descriptor descriptor = TestAllTypes.getDescriptor();
1735 
1736     FieldDescriptor fieldDescriptor = descriptor.findFieldByName("repeated_nested_message");
1737     FieldDescriptor foreignFieldDescriptor = descriptor.findFieldByName("repeated_foreign_message");
1738     FieldDescriptor importFieldDescriptor = descriptor.findFieldByName("repeated_import_message");
1739 
1740     // Mutate the message with new field builder
1741     // Mutate nested message
1742     TestAllTypes.Builder builder1 = TestAllTypes.newBuilder();
1743     Message.Builder fieldBuilder1 = builder1.newBuilderForField(fieldDescriptor);
1744     fieldBuilder1.setField(NESTED_MESSAGE_BB_FIELD, 1);
1745     builder1.addRepeatedField(fieldDescriptor, fieldBuilder1.build());
1746 
1747     // Mutate foreign message
1748     Message.Builder foreignFieldBuilder1 = builder1.newBuilderForField(foreignFieldDescriptor);
1749     FieldDescriptor subForeignFieldDescriptor1 =
1750         foreignFieldBuilder1.getDescriptorForType().findFieldByName("c");
1751     foreignFieldBuilder1.setField(subForeignFieldDescriptor1, 2);
1752     builder1.addRepeatedField(foreignFieldDescriptor, foreignFieldBuilder1.build());
1753 
1754     // Mutate import message
1755     Message.Builder importFieldBuilder1 = builder1.newBuilderForField(importFieldDescriptor);
1756     FieldDescriptor subImportFieldDescriptor1 =
1757         importFieldBuilder1.getDescriptorForType().findFieldByName("d");
1758     importFieldBuilder1.setField(subImportFieldDescriptor1, 3);
1759     builder1.addRepeatedField(importFieldDescriptor, importFieldBuilder1.build());
1760 
1761     Message newMessage1 = builder1.build();
1762 
1763     // Mutate the message with existing field builder
1764     // Mutate nested message
1765     TestAllTypes.Builder builder2 = TestAllTypes.newBuilder();
1766     builder2.addRepeatedNestedMessageBuilder();
1767     Message.Builder fieldBuilder2 = builder2.getRepeatedFieldBuilder(fieldDescriptor, 0);
1768     fieldBuilder2.setField(NESTED_MESSAGE_BB_FIELD, 1);
1769 
1770     // Mutate foreign message
1771     Message.Builder foreignFieldBuilder2 = builder2.newBuilderForField(foreignFieldDescriptor);
1772     FieldDescriptor subForeignFieldDescriptor2 =
1773         foreignFieldBuilder2.getDescriptorForType().findFieldByName("c");
1774     foreignFieldBuilder2.setField(subForeignFieldDescriptor2, 2);
1775     builder2.addRepeatedField(foreignFieldDescriptor, foreignFieldBuilder2.build());
1776 
1777     // Mutate import message
1778     Message.Builder importFieldBuilder2 = builder2.newBuilderForField(importFieldDescriptor);
1779     FieldDescriptor subImportFieldDescriptor2 =
1780         importFieldBuilder2.getDescriptorForType().findFieldByName("d");
1781     importFieldBuilder2.setField(subImportFieldDescriptor2, 3);
1782     builder2.addRepeatedField(importFieldDescriptor, importFieldBuilder2.build());
1783 
1784     Message newMessage2 = builder2.build();
1785 
1786     // These two messages should be equal.
1787     assertThat(newMessage1).isEqualTo(newMessage2);
1788   }
1789 
1790   @Test
testGetRepeatedFieldBuilderWithInitializedValue()1791   public void testGetRepeatedFieldBuilderWithInitializedValue() {
1792     Descriptor descriptor = TestAllTypes.getDescriptor();
1793     FieldDescriptor fieldDescriptor = descriptor.findFieldByName("repeated_nested_message");
1794 
1795     // Before setting field, builder is initialized by default value.
1796     TestAllTypes.Builder builder = TestAllTypes.newBuilder();
1797     builder.addRepeatedNestedMessageBuilder();
1798     NestedMessage.Builder fieldBuilder =
1799         (NestedMessage.Builder) builder.getRepeatedFieldBuilder(fieldDescriptor, 0);
1800     assertThat(fieldBuilder.getBb()).isEqualTo(0);
1801 
1802     // Setting field value with new field builder instance.
1803     builder = TestAllTypes.newBuilder();
1804     NestedMessage.Builder newFieldBuilder = builder.addRepeatedNestedMessageBuilder();
1805     newFieldBuilder.setBb(2);
1806     // Then get the field builder instance by getRepeatedFieldBuilder().
1807     fieldBuilder = (NestedMessage.Builder) builder.getRepeatedFieldBuilder(fieldDescriptor, 0);
1808     // It should contain new value.
1809     assertThat(fieldBuilder.getBb()).isEqualTo(2);
1810     // These two builder should be equal.
1811     assertThat(fieldBuilder).isSameInstanceAs(newFieldBuilder);
1812   }
1813 
1814   @Test
testGetRepeatedFieldBuilderNotSupportedException()1815   public void testGetRepeatedFieldBuilderNotSupportedException() {
1816     Descriptor descriptor = TestAllTypes.getDescriptor();
1817     TestAllTypes.Builder builder = TestAllTypes.newBuilder();
1818 
1819     assertThrows(
1820         "Exception was not thrown",
1821         UnsupportedOperationException.class,
1822         () -> builder.getRepeatedFieldBuilder(descriptor.findFieldByName("repeated_int32"), 0));
1823     assertThrows(
1824         "Exception was not thrown",
1825         UnsupportedOperationException.class,
1826         () ->
1827             builder.getRepeatedFieldBuilder(descriptor.findFieldByName("repeated_nested_enum"), 0));
1828     assertThrows(
1829         "Exception was not thrown",
1830         UnsupportedOperationException.class,
1831         () -> builder.getRepeatedFieldBuilder(descriptor.findFieldByName("optional_int32"), 0));
1832     assertThrows(
1833         "Exception was not thrown",
1834         UnsupportedOperationException.class,
1835         () ->
1836             builder.getRepeatedFieldBuilder(descriptor.findFieldByName("optional_nested_enum"), 0));
1837     assertThrows(
1838         "Exception was not thrown",
1839         UnsupportedOperationException.class,
1840         () ->
1841             builder.getRepeatedFieldBuilder(
1842                 descriptor.findFieldByName("optional_nested_message"), 0));
1843   }
1844 
1845   private static final FieldDescriptor OPTIONAL_NESTED_MESSAGE_EXTENSION =
1846       UnittestProto.getDescriptor().findExtensionByName("optional_nested_message_extension");
1847   private static final FieldDescriptor REPEATED_NESTED_MESSAGE_EXTENSION =
1848       UnittestProto.getDescriptor().findExtensionByName("repeated_nested_message_extension");
1849 
1850   // A compile-time check that TestAllExtensions.Builder does in fact extend
1851   // GeneratedMessage.ExtendableBuilder. The tests below assume that it does.
1852   static {
1853     @SuppressWarnings("unused")
1854     Class<? extends GeneratedMessage.ExtendableBuilder<?, ?>> ignored =
1855         TestAllExtensions.Builder.class;
1856   }
1857 
1858   @Test
1859   public void
extendableBuilder_extensionFieldContainingBuilder_setRepeatedFieldOverwritesElement()1860       extendableBuilder_extensionFieldContainingBuilder_setRepeatedFieldOverwritesElement() {
1861     TestAllExtensions.Builder builder = TestAllExtensions.newBuilder();
1862     builder.addRepeatedField(REPEATED_NESTED_MESSAGE_EXTENSION, NestedMessage.getDefaultInstance());
1863     // Calling getRepeatedFieldBuilder and ignoring the returned Builder should have no
1864     // externally-visible effect, but internally it sets the stored field element to a builder.
1865     builder.getRepeatedFieldBuilder(REPEATED_NESTED_MESSAGE_EXTENSION, 0);
1866 
1867     NestedMessage setNestedMessage = NestedMessage.newBuilder().setBb(100).build();
1868     builder.setRepeatedField(REPEATED_NESTED_MESSAGE_EXTENSION, 0, setNestedMessage);
1869 
1870     assertThat(builder.getRepeatedField(REPEATED_NESTED_MESSAGE_EXTENSION, 0))
1871         .isEqualTo(setNestedMessage);
1872   }
1873 
1874   @Test
extendableBuilder_extensionFieldContainingBuilder_addRepeatedFieldAppendsToField()1875   public void extendableBuilder_extensionFieldContainingBuilder_addRepeatedFieldAppendsToField() {
1876     TestAllExtensions.Builder builder = TestAllExtensions.newBuilder();
1877     builder.addRepeatedField(REPEATED_NESTED_MESSAGE_EXTENSION, NestedMessage.getDefaultInstance());
1878     // Calling getRepeatedFieldBuilder and ignoring the returned Builder should have no
1879     // externally-visible effect, but internally it sets the stored field element to a builder.
1880     builder.getRepeatedFieldBuilder(REPEATED_NESTED_MESSAGE_EXTENSION, 0);
1881 
1882     builder.addRepeatedField(REPEATED_NESTED_MESSAGE_EXTENSION, NestedMessage.getDefaultInstance());
1883 
1884     assertThat((List<?>) builder.getField(REPEATED_NESTED_MESSAGE_EXTENSION)).hasSize(2);
1885   }
1886 
1887   @Test
extendableBuilder_mergeFrom_optionalField_changesReflectedInExistingBuilder()1888   public void extendableBuilder_mergeFrom_optionalField_changesReflectedInExistingBuilder() {
1889     TestAllExtensions.Builder builder = TestAllExtensions.newBuilder();
1890     Message.Builder nestedMessageBuilder =
1891         builder.getFieldBuilder(OPTIONAL_NESTED_MESSAGE_EXTENSION);
1892 
1893     builder.mergeFrom(
1894         TestAllExtensions.newBuilder()
1895             .setField(OPTIONAL_NESTED_MESSAGE_EXTENSION, NestedMessage.newBuilder().setBb(100))
1896             .build());
1897 
1898     assertThat(nestedMessageBuilder.getField(NESTED_MESSAGE_BB_FIELD)).isEqualTo(100);
1899   }
1900 
1901   @Test
extendableBuilder_mergeFrom_optionalField_doesNotInvalidateExistingBuilder()1902   public void extendableBuilder_mergeFrom_optionalField_doesNotInvalidateExistingBuilder() {
1903     TestAllExtensions.Builder builder = TestAllExtensions.newBuilder();
1904     Message.Builder nestedMessageBuilder =
1905         builder.getFieldBuilder(OPTIONAL_NESTED_MESSAGE_EXTENSION);
1906 
1907     builder.mergeFrom(
1908         TestAllExtensions.newBuilder()
1909             .setField(OPTIONAL_NESTED_MESSAGE_EXTENSION, NestedMessage.newBuilder().setBb(100))
1910             .build());
1911 
1912     // Changes to nestedMessageBuilder should still be reflected in the parent builder.
1913     nestedMessageBuilder.setField(NESTED_MESSAGE_BB_FIELD, 200);
1914 
1915     assertThat(builder.build())
1916         .isEqualTo(
1917             TestAllExtensions.newBuilder()
1918                 .setField(OPTIONAL_NESTED_MESSAGE_EXTENSION, NestedMessage.newBuilder().setBb(200))
1919                 .build());
1920   }
1921 
1922   @Test
extendableBuilder_mergeFrom_repeatedField_doesNotInvalidateExistingBuilder()1923   public void extendableBuilder_mergeFrom_repeatedField_doesNotInvalidateExistingBuilder() {
1924     TestAllExtensions.Builder builder = TestAllExtensions.newBuilder();
1925     builder.addRepeatedField(REPEATED_NESTED_MESSAGE_EXTENSION, NestedMessage.getDefaultInstance());
1926     Message.Builder nestedMessageBuilder =
1927         builder.getRepeatedFieldBuilder(REPEATED_NESTED_MESSAGE_EXTENSION, 0);
1928 
1929     builder.mergeFrom(
1930         TestAllExtensions.newBuilder()
1931             .addRepeatedField(REPEATED_NESTED_MESSAGE_EXTENSION, NestedMessage.getDefaultInstance())
1932             .build());
1933 
1934     // Changes to nestedMessageBuilder should still be reflected in the parent builder.
1935     nestedMessageBuilder.setField(NESTED_MESSAGE_BB_FIELD, 100);
1936 
1937     assertThat(builder.getRepeatedField(REPEATED_NESTED_MESSAGE_EXTENSION, 0))
1938         .isEqualTo(NestedMessage.newBuilder().setBb(100).build());
1939   }
1940 
1941   @Test
getAllFields_repeatedFieldsAreNotMutable()1942   public void getAllFields_repeatedFieldsAreNotMutable() {
1943     TestAllTypes testMsg =
1944         TestAllTypes.newBuilder()
1945             .addRepeatedInt32(1)
1946             .addRepeatedInt32(2)
1947             .addRepeatedNestedMessage(NestedMessage.newBuilder().setBb(111).build())
1948             .build();
1949 
1950     FieldDescriptor repeatedInt32Field =
1951         TestAllTypes.getDescriptor().findFieldByNumber(TestAllTypes.REPEATED_INT32_FIELD_NUMBER);
1952     FieldDescriptor repeatedMsgField =
1953         TestAllTypes.getDescriptor()
1954             .findFieldByNumber(TestAllTypes.REPEATED_NESTED_MESSAGE_FIELD_NUMBER);
1955     Map<FieldDescriptor, Object> allFields = testMsg.getAllFields();
1956     List<?> list = (List<?>) allFields.get(repeatedInt32Field);
1957     assertThat(list).hasSize(2);
1958     assertThrows(UnsupportedOperationException.class, list::clear);
1959     list = (List<?>) allFields.get(repeatedMsgField);
1960     assertThat(list).hasSize(1);
1961     assertThrows(UnsupportedOperationException.class, list::clear);
1962 
1963     TestAllTypes.Builder builder = testMsg.toBuilder();
1964     allFields = builder.getAllFields();
1965     list = (List<?>) allFields.get(repeatedInt32Field);
1966     assertThat(list).hasSize(2);
1967     assertThrows(UnsupportedOperationException.class, list::clear);
1968     builder.clearField(repeatedInt32Field);
1969     assertThat(list).hasSize(2);
1970     list = (List<?>) allFields.get(repeatedMsgField);
1971     assertThat(list).hasSize(1);
1972     assertThrows(UnsupportedOperationException.class, list::clear);
1973     builder.clearField(repeatedMsgField);
1974     assertThat(list).hasSize(1);
1975   }
1976 }
1977