• 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 
12 import com.google.protobuf.Descriptors.Descriptor;
13 import com.google.protobuf.Descriptors.EnumDescriptor;
14 import com.google.protobuf.Descriptors.EnumValueDescriptor;
15 import com.google.protobuf.Descriptors.FieldDescriptor;
16 import com.google.protobuf.Descriptors.OneofDescriptor;
17 import com.google.protobuf.FieldPresenceTestProto.TestAllTypes;
18 import com.google.protobuf.FieldPresenceTestProto.TestOptionalFieldsOnly;
19 import com.google.protobuf.FieldPresenceTestProto.TestRepeatedFieldsOnly;
20 import com.google.protobuf.testing.proto.TestProto3Optional;
21 import protobuf_unittest.UnittestProto;
22 import org.junit.Test;
23 import org.junit.runner.RunWith;
24 import org.junit.runners.JUnit4;
25 
26 /**
27  * Unit tests for protos that doesn't support field presence test for optional non-message fields.
28  */
29 @RunWith(JUnit4.class)
30 public class FieldPresenceTest {
hasMethod(Class<?> clazz, String name)31   private static boolean hasMethod(Class<?> clazz, String name) {
32     try {
33       if (clazz.getMethod(name) != null) {
34         return true;
35       } else {
36         return false;
37       }
38     } catch (NoSuchMethodException e) {
39       return false;
40     }
41   }
42 
assertHasMethodRemoved( Class<?> classWithFieldPresence, Class<?> classWithoutFieldPresence, String camelName)43   private static void assertHasMethodRemoved(
44       Class<?> classWithFieldPresence, Class<?> classWithoutFieldPresence, String camelName) {
45     assertThat(hasMethod(classWithFieldPresence, "get" + camelName)).isTrue();
46     assertThat(hasMethod(classWithFieldPresence, "has" + camelName)).isTrue();
47     assertThat(hasMethod(classWithoutFieldPresence, "get" + camelName)).isTrue();
48     assertThat(hasMethod(classWithoutFieldPresence, "has" + camelName)).isFalse();
49   }
50 
assertHasMethodExisting(Class<?> clazz, String camelName)51   private static void assertHasMethodExisting(Class<?> clazz, String camelName) {
52     assertThat(hasMethod(clazz, "get" + camelName)).isTrue();
53     assertThat(hasMethod(clazz, "has" + camelName)).isTrue();
54   }
55 
56   @Test
testHasMethod()57   public void testHasMethod() {
58     // Optional non-message fields don't have a hasFoo() method generated.
59     assertHasMethodRemoved(UnittestProto.TestAllTypes.class, TestAllTypes.class, "OptionalInt32");
60     assertHasMethodRemoved(UnittestProto.TestAllTypes.class, TestAllTypes.class, "OptionalString");
61     assertHasMethodRemoved(UnittestProto.TestAllTypes.class, TestAllTypes.class, "OptionalBytes");
62     assertHasMethodRemoved(
63         UnittestProto.TestAllTypes.class, TestAllTypes.class, "OptionalNestedEnum");
64 
65     assertHasMethodRemoved(
66         UnittestProto.TestAllTypes.Builder.class, TestAllTypes.Builder.class, "OptionalInt32");
67     assertHasMethodRemoved(
68         UnittestProto.TestAllTypes.Builder.class, TestAllTypes.Builder.class, "OptionalString");
69     assertHasMethodRemoved(
70         UnittestProto.TestAllTypes.Builder.class, TestAllTypes.Builder.class, "OptionalBytes");
71     assertHasMethodRemoved(
72         UnittestProto.TestAllTypes.Builder.class, TestAllTypes.Builder.class, "OptionalNestedEnum");
73 
74     // message fields still have the hasFoo() method generated.
75     assertThat(TestAllTypes.getDefaultInstance().hasOptionalNestedMessage()).isFalse();
76     assertThat(TestAllTypes.newBuilder().hasOptionalNestedMessage()).isFalse();
77 
78     // oneof fields support hasFoo() methods for non-message types.
79     assertHasMethodExisting(TestAllTypes.class, "OneofUint32");
80     assertHasMethodExisting(TestAllTypes.class, "OneofString");
81     assertHasMethodExisting(TestAllTypes.class, "OneofBytes");
82     assertThat(TestAllTypes.getDefaultInstance().hasOneofNestedMessage()).isFalse();
83     assertThat(TestAllTypes.newBuilder().hasOneofNestedMessage()).isFalse();
84 
85     assertHasMethodExisting(TestAllTypes.Builder.class, "OneofUint32");
86     assertHasMethodExisting(TestAllTypes.Builder.class, "OneofString");
87     assertHasMethodExisting(TestAllTypes.Builder.class, "OneofBytes");
88   }
89 
90   @Test
testHasMethodForProto3Optional()91   public void testHasMethodForProto3Optional() throws Exception {
92     assertThat(TestProto3Optional.getDefaultInstance().hasOptionalInt32()).isFalse();
93     assertThat(TestProto3Optional.getDefaultInstance().hasOptionalInt64()).isFalse();
94     assertThat(TestProto3Optional.getDefaultInstance().hasOptionalUint32()).isFalse();
95     assertThat(TestProto3Optional.getDefaultInstance().hasOptionalUint64()).isFalse();
96     assertThat(TestProto3Optional.getDefaultInstance().hasOptionalSint32()).isFalse();
97     assertThat(TestProto3Optional.getDefaultInstance().hasOptionalSint64()).isFalse();
98     assertThat(TestProto3Optional.getDefaultInstance().hasOptionalFixed32()).isFalse();
99     assertThat(TestProto3Optional.getDefaultInstance().hasOptionalFixed64()).isFalse();
100     assertThat(TestProto3Optional.getDefaultInstance().hasOptionalFloat()).isFalse();
101     assertThat(TestProto3Optional.getDefaultInstance().hasOptionalDouble()).isFalse();
102     assertThat(TestProto3Optional.getDefaultInstance().hasOptionalBool()).isFalse();
103     assertThat(TestProto3Optional.getDefaultInstance().hasOptionalString()).isFalse();
104     assertThat(TestProto3Optional.getDefaultInstance().hasOptionalBytes()).isFalse();
105 
106     TestProto3Optional.Builder builder = TestProto3Optional.newBuilder().setOptionalInt32(0);
107     assertThat(builder.hasOptionalInt32()).isTrue();
108     assertThat(builder.build().hasOptionalInt32()).isTrue();
109 
110     TestProto3Optional.Builder otherBuilder = TestProto3Optional.newBuilder().setOptionalInt32(1);
111     otherBuilder.mergeFrom(builder.build());
112     assertThat(otherBuilder.hasOptionalInt32()).isTrue();
113     assertThat(otherBuilder.getOptionalInt32()).isEqualTo(0);
114 
115     TestProto3Optional.Builder builder3 =
116         TestProto3Optional.newBuilder().setOptionalNestedEnumValue(5);
117     assertThat(builder3.hasOptionalNestedEnum()).isTrue();
118 
119     TestProto3Optional.Builder builder4 =
120         TestProto3Optional.newBuilder().setOptionalNestedEnum(TestProto3Optional.NestedEnum.FOO);
121     assertThat(builder4.hasOptionalNestedEnum()).isTrue();
122 
123     TestProto3Optional proto = TestProto3Optional.parseFrom(builder.build().toByteArray());
124     assertThat(proto.hasOptionalInt32()).isTrue();
125     assertThat(proto.toBuilder().hasOptionalInt32()).isTrue();
126   }
127 
assertProto3OptionalReflection(String name)128   private static void assertProto3OptionalReflection(String name) throws Exception {
129     FieldDescriptor fieldDescriptor = TestProto3Optional.getDescriptor().findFieldByName(name);
130     OneofDescriptor oneofDescriptor = fieldDescriptor.getContainingOneof();
131     assertThat(fieldDescriptor.getContainingOneof()).isNotNull();
132     assertThat(fieldDescriptor.hasOptionalKeyword()).isTrue();
133     assertThat(fieldDescriptor.hasPresence()).isTrue();
134 
135     assertThat(TestProto3Optional.getDefaultInstance().hasOneof(oneofDescriptor)).isFalse();
136     assertThat(TestProto3Optional.getDefaultInstance().getOneofFieldDescriptor(oneofDescriptor))
137         .isNull();
138 
139     TestProto3Optional.Builder builder = TestProto3Optional.newBuilder();
140     builder.setField(fieldDescriptor, fieldDescriptor.getDefaultValue());
141     assertThat(builder.hasField(fieldDescriptor)).isTrue();
142     assertThat(builder.getField(fieldDescriptor)).isEqualTo(fieldDescriptor.getDefaultValue());
143     assertThat(builder.build().hasField(fieldDescriptor)).isTrue();
144     assertThat(builder.build().getField(fieldDescriptor))
145         .isEqualTo(fieldDescriptor.getDefaultValue());
146     assertThat(builder.hasOneof(oneofDescriptor)).isTrue();
147     assertThat(builder.getOneofFieldDescriptor(oneofDescriptor)).isEqualTo(fieldDescriptor);
148     assertThat(builder.build().hasOneof(oneofDescriptor)).isTrue();
149     assertThat(builder.build().getOneofFieldDescriptor(oneofDescriptor)).isEqualTo(fieldDescriptor);
150 
151     TestProto3Optional.Builder otherBuilder = TestProto3Optional.newBuilder();
152     otherBuilder.mergeFrom(builder.build());
153     assertThat(otherBuilder.hasField(fieldDescriptor)).isTrue();
154     assertThat(otherBuilder.getField(fieldDescriptor)).isEqualTo(fieldDescriptor.getDefaultValue());
155 
156     TestProto3Optional proto = TestProto3Optional.parseFrom(builder.build().toByteArray());
157     assertThat(proto.hasField(fieldDescriptor)).isTrue();
158     assertThat(proto.toBuilder().hasField(fieldDescriptor)).isTrue();
159 
160     DynamicMessage.Builder dynamicBuilder =
161         DynamicMessage.newBuilder(TestProto3Optional.getDescriptor());
162     dynamicBuilder.setField(fieldDescriptor, fieldDescriptor.getDefaultValue());
163     assertThat(dynamicBuilder.hasField(fieldDescriptor)).isTrue();
164     assertThat(dynamicBuilder.getField(fieldDescriptor))
165         .isEqualTo(fieldDescriptor.getDefaultValue());
166     assertThat(dynamicBuilder.build().hasField(fieldDescriptor)).isTrue();
167     assertThat(dynamicBuilder.build().getField(fieldDescriptor))
168         .isEqualTo(fieldDescriptor.getDefaultValue());
169     assertThat(dynamicBuilder.hasOneof(oneofDescriptor)).isTrue();
170     assertThat(dynamicBuilder.getOneofFieldDescriptor(oneofDescriptor)).isEqualTo(fieldDescriptor);
171     assertThat(dynamicBuilder.build().hasOneof(oneofDescriptor)).isTrue();
172     assertThat(dynamicBuilder.build().getOneofFieldDescriptor(oneofDescriptor))
173         .isEqualTo(fieldDescriptor);
174 
175     DynamicMessage.Builder otherDynamicBuilder =
176         DynamicMessage.newBuilder(TestProto3Optional.getDescriptor());
177     otherDynamicBuilder.mergeFrom(dynamicBuilder.build());
178     assertThat(otherDynamicBuilder.hasField(fieldDescriptor)).isTrue();
179     assertThat(otherDynamicBuilder.getField(fieldDescriptor))
180         .isEqualTo(fieldDescriptor.getDefaultValue());
181 
182     DynamicMessage dynamicProto =
183         DynamicMessage.parseFrom(TestProto3Optional.getDescriptor(), builder.build().toByteArray());
184     assertThat(dynamicProto.hasField(fieldDescriptor)).isTrue();
185     assertThat(dynamicProto.toBuilder().hasField(fieldDescriptor)).isTrue();
186   }
187 
188   @Test
testProto3Optional_reflection()189   public void testProto3Optional_reflection() throws Exception {
190     assertProto3OptionalReflection("optional_int32");
191     assertProto3OptionalReflection("optional_int64");
192     assertProto3OptionalReflection("optional_uint32");
193     assertProto3OptionalReflection("optional_uint64");
194     assertProto3OptionalReflection("optional_sint32");
195     assertProto3OptionalReflection("optional_sint64");
196     assertProto3OptionalReflection("optional_fixed32");
197     assertProto3OptionalReflection("optional_fixed64");
198     assertProto3OptionalReflection("optional_float");
199     assertProto3OptionalReflection("optional_double");
200     assertProto3OptionalReflection("optional_bool");
201     assertProto3OptionalReflection("optional_string");
202     assertProto3OptionalReflection("optional_bytes");
203   }
204 
205   @Test
testOneofEquals()206   public void testOneofEquals() throws Exception {
207     TestAllTypes.Builder builder = TestAllTypes.newBuilder();
208     TestAllTypes message1 = builder.build();
209     // Set message2's oneof_uint32 field to default value. The two
210     // messages should be different when check with oneof case.
211     builder.setOneofUint32(0);
212     TestAllTypes message2 = builder.build();
213     assertThat(message1.equals(message2)).isFalse();
214   }
215 
216   @Test
testLazyField()217   public void testLazyField() throws Exception {
218     // Test default constructed message.
219     TestAllTypes.Builder builder = TestAllTypes.newBuilder();
220     TestAllTypes message = builder.build();
221     assertThat(message.hasOptionalLazyMessage()).isFalse();
222     assertThat(message.getSerializedSize()).isEqualTo(0);
223     assertThat(message.toByteString()).isEqualTo(ByteString.EMPTY);
224 
225     // Set default instance to the field.
226     builder.setOptionalLazyMessage(TestAllTypes.NestedMessage.getDefaultInstance());
227     message = builder.build();
228     assertThat(message.hasOptionalLazyMessage()).isTrue();
229     assertThat(message.getSerializedSize()).isEqualTo(2);
230 
231     // Test parse zero-length from wire sets the presence.
232     TestAllTypes parsed = TestAllTypes.parseFrom(message.toByteString());
233     assertThat(parsed.hasOptionalLazyMessage()).isTrue();
234     assertThat(parsed.getOptionalLazyMessage()).isEqualTo(message.getOptionalLazyMessage());
235   }
236 
237   @Test
testFieldPresence()238   public void testFieldPresence() {
239     // Optional non-message fields set to their default value are treated the
240     // same way as not set.
241 
242     // Serialization will ignore such fields.
243     TestAllTypes.Builder builder = TestAllTypes.newBuilder();
244     builder.setOptionalInt32(0);
245     builder.setOptionalString("");
246     builder.setOptionalBytes(ByteString.EMPTY);
247     builder.setOptionalNestedEnum(TestAllTypes.NestedEnum.FOO);
248     TestAllTypes message = builder.build();
249     assertThat(message.getSerializedSize()).isEqualTo(0);
250 
251     // mergeFrom() will ignore such fields.
252     TestAllTypes.Builder a = TestAllTypes.newBuilder();
253     a.setOptionalInt32(1);
254     a.setOptionalString("x");
255     a.setOptionalBytes(ByteString.copyFromUtf8("y"));
256     a.setOptionalNestedEnum(TestAllTypes.NestedEnum.BAR);
257     TestAllTypes.Builder b = TestAllTypes.newBuilder();
258     b.setOptionalInt32(0);
259     b.setOptionalString("");
260     b.setOptionalBytes(ByteString.EMPTY);
261     b.setOptionalNestedEnum(TestAllTypes.NestedEnum.FOO);
262     a.mergeFrom(b.build());
263     message = a.build();
264     assertThat(message.getOptionalInt32()).isEqualTo(1);
265     assertThat(message.getOptionalString()).isEqualTo("x");
266     assertThat(message.getOptionalBytes()).isEqualTo(ByteString.copyFromUtf8("y"));
267     assertThat(message.getOptionalNestedEnum()).isEqualTo(TestAllTypes.NestedEnum.BAR);
268 
269     // equals()/hashCode() should produce the same results.
270     TestAllTypes empty = TestAllTypes.getDefaultInstance();
271     message = builder.build();
272     assertThat(empty).isEqualTo(message);
273     assertThat(message).isEqualTo(empty);
274     assertThat(message.hashCode()).isEqualTo(empty.hashCode());
275   }
276 
277   @Test
testFieldPresenceByReflection()278   public void testFieldPresenceByReflection() {
279     Descriptor descriptor = TestAllTypes.getDescriptor();
280     FieldDescriptor optionalInt32Field = descriptor.findFieldByName("optional_int32");
281     FieldDescriptor optionalStringField = descriptor.findFieldByName("optional_string");
282     FieldDescriptor optionalBytesField = descriptor.findFieldByName("optional_bytes");
283     FieldDescriptor optionalNestedEnumField = descriptor.findFieldByName("optional_nested_enum");
284 
285     // Field not present.
286     TestAllTypes message = TestAllTypes.getDefaultInstance();
287     assertThat(message.hasField(optionalInt32Field)).isFalse();
288     assertThat(message.hasField(optionalStringField)).isFalse();
289     assertThat(message.hasField(optionalBytesField)).isFalse();
290     assertThat(message.hasField(optionalNestedEnumField)).isFalse();
291     assertThat(message.getAllFields()).isEmpty();
292 
293     // Field set to default value is seen as not present.
294     message =
295         TestAllTypes.newBuilder()
296             .setOptionalInt32(0)
297             .setOptionalString("")
298             .setOptionalBytes(ByteString.EMPTY)
299             .setOptionalNestedEnum(TestAllTypes.NestedEnum.FOO)
300             .build();
301     assertThat(message.hasField(optionalInt32Field)).isFalse();
302     assertThat(message.hasField(optionalStringField)).isFalse();
303     assertThat(message.hasField(optionalBytesField)).isFalse();
304     assertThat(message.hasField(optionalNestedEnumField)).isFalse();
305     assertThat(message.getAllFields()).isEmpty();
306 
307     // Field set to non-default value is seen as present.
308     message =
309         TestAllTypes.newBuilder()
310             .setOptionalInt32(1)
311             .setOptionalString("x")
312             .setOptionalBytes(ByteString.copyFromUtf8("y"))
313             .setOptionalNestedEnum(TestAllTypes.NestedEnum.BAR)
314             .build();
315     assertThat(message.hasField(optionalInt32Field)).isTrue();
316     assertThat(message.hasField(optionalStringField)).isTrue();
317     assertThat(message.hasField(optionalBytesField)).isTrue();
318     assertThat(message.hasField(optionalNestedEnumField)).isTrue();
319     assertThat(message.getAllFields()).hasSize(4);
320   }
321 
322   @Test
testFieldPresenceDynamicMessage()323   public void testFieldPresenceDynamicMessage() {
324     Descriptor descriptor = TestAllTypes.getDescriptor();
325     FieldDescriptor optionalInt32Field = descriptor.findFieldByName("optional_int32");
326     FieldDescriptor optionalStringField = descriptor.findFieldByName("optional_string");
327     FieldDescriptor optionalBytesField = descriptor.findFieldByName("optional_bytes");
328     FieldDescriptor optionalNestedEnumField = descriptor.findFieldByName("optional_nested_enum");
329     EnumDescriptor enumDescriptor = optionalNestedEnumField.getEnumType();
330     EnumValueDescriptor defaultEnumValueDescriptor = enumDescriptor.getValues().get(0);
331     EnumValueDescriptor nonDefaultEnumValueDescriptor = enumDescriptor.getValues().get(1);
332 
333     DynamicMessage defaultInstance = DynamicMessage.getDefaultInstance(descriptor);
334     // Field not present.
335     DynamicMessage message = defaultInstance.newBuilderForType().build();
336     assertThat(message.hasField(optionalInt32Field)).isFalse();
337     assertThat(message.hasField(optionalStringField)).isFalse();
338     assertThat(message.hasField(optionalBytesField)).isFalse();
339     assertThat(message.hasField(optionalNestedEnumField)).isFalse();
340     assertThat(message.getAllFields()).isEmpty();
341 
342     // Field set to non-default value is seen as present.
343     message =
344         defaultInstance
345             .newBuilderForType()
346             .setField(optionalInt32Field, 1)
347             .setField(optionalStringField, "x")
348             .setField(optionalBytesField, ByteString.copyFromUtf8("y"))
349             .setField(optionalNestedEnumField, nonDefaultEnumValueDescriptor)
350             .build();
351     assertThat(message.hasField(optionalInt32Field)).isTrue();
352     assertThat(message.hasField(optionalStringField)).isTrue();
353     assertThat(message.hasField(optionalBytesField)).isTrue();
354     assertThat(message.hasField(optionalNestedEnumField)).isTrue();
355     assertThat(message.getAllFields()).hasSize(4);
356 
357     // Field set to default value is seen as not present.
358     message =
359         message
360             .toBuilder()
361             .setField(optionalInt32Field, 0)
362             .setField(optionalStringField, "")
363             .setField(optionalBytesField, ByteString.EMPTY)
364             .setField(optionalNestedEnumField, defaultEnumValueDescriptor)
365             .build();
366     assertThat(message.hasField(optionalInt32Field)).isFalse();
367     assertThat(message.hasField(optionalStringField)).isFalse();
368     assertThat(message.hasField(optionalBytesField)).isFalse();
369     assertThat(message.hasField(optionalNestedEnumField)).isFalse();
370     assertThat(message.getAllFields()).isEmpty();
371   }
372 
373   @Test
testMessageField()374   public void testMessageField() {
375     TestAllTypes.Builder builder = TestAllTypes.newBuilder();
376     assertThat(builder.hasOptionalNestedMessage()).isFalse();
377     assertThat(builder.build().hasOptionalNestedMessage()).isFalse();
378 
379     TestAllTypes.NestedMessage.Builder nestedBuilder = builder.getOptionalNestedMessageBuilder();
380     assertThat(builder.hasOptionalNestedMessage()).isTrue();
381     assertThat(builder.build().hasOptionalNestedMessage()).isTrue();
382 
383     nestedBuilder.setValue(1);
384     assertThat(builder.build().getOptionalNestedMessage().getValue()).isEqualTo(1);
385 
386     builder.clearOptionalNestedMessage();
387     assertThat(builder.hasOptionalNestedMessage()).isFalse();
388     assertThat(builder.build().hasOptionalNestedMessage()).isFalse();
389 
390     // Unlike non-message fields, if we set a message field to its default value (i.e.,
391     // default instance), the field should be seen as present.
392     builder.setOptionalNestedMessage(TestAllTypes.NestedMessage.getDefaultInstance());
393     assertThat(builder.hasOptionalNestedMessage()).isTrue();
394     assertThat(builder.build().hasOptionalNestedMessage()).isTrue();
395   }
396 
397   @Test
testSerializeAndParse()398   public void testSerializeAndParse() throws Exception {
399     TestAllTypes.Builder builder = TestAllTypes.newBuilder();
400     builder.setOptionalInt32(1234);
401     builder.setOptionalString("hello");
402     builder.setOptionalNestedMessage(TestAllTypes.NestedMessage.getDefaultInstance());
403     // Set an oneof field to its default value and expect it to be serialized (i.e.,
404     // an oneof field set to the default value should be treated as present).
405     builder.setOneofInt32(0);
406     ByteString data = builder.build().toByteString();
407 
408     TestAllTypes message = TestAllTypes.parseFrom(data);
409     assertThat(message.getOptionalInt32()).isEqualTo(1234);
410     assertThat(message.getOptionalString()).isEqualTo("hello");
411     // Fields not set will have the default value.
412     assertThat(message.getOptionalBytes()).isEqualTo(ByteString.EMPTY);
413     assertThat(message.getOptionalNestedEnum()).isEqualTo(TestAllTypes.NestedEnum.FOO);
414     // The message field is set despite that it's set with a default instance.
415     assertThat(message.hasOptionalNestedMessage()).isTrue();
416     assertThat(message.getOptionalNestedMessage().getValue()).isEqualTo(0);
417     // The oneof field set to its default value is also present.
418     assertThat(message.getOneofFieldCase()).isEqualTo(TestAllTypes.OneofFieldCase.ONEOF_INT32);
419   }
420 
421   // Regression test for b/16173397
422   // Make sure we haven't screwed up the code generation for repeated fields.
423   @Test
testRepeatedFields()424   public void testRepeatedFields() throws Exception {
425     TestAllTypes.Builder builder = TestAllTypes.newBuilder();
426     builder.setOptionalInt32(1234);
427     builder.setOptionalString("hello");
428     builder.setOptionalNestedMessage(TestAllTypes.NestedMessage.getDefaultInstance());
429     builder.addRepeatedInt32(4321);
430     builder.addRepeatedString("world");
431     builder.addRepeatedNestedMessage(TestAllTypes.NestedMessage.getDefaultInstance());
432     ByteString data = builder.build().toByteString();
433 
434     TestOptionalFieldsOnly optionalOnlyMessage = TestOptionalFieldsOnly.parseFrom(data);
435     assertThat(optionalOnlyMessage.getOptionalInt32()).isEqualTo(1234);
436     assertThat(optionalOnlyMessage.getOptionalString()).isEqualTo("hello");
437     assertThat(optionalOnlyMessage.hasOptionalNestedMessage()).isTrue();
438     assertThat(optionalOnlyMessage.getOptionalNestedMessage().getValue()).isEqualTo(0);
439 
440     TestRepeatedFieldsOnly repeatedOnlyMessage = TestRepeatedFieldsOnly.parseFrom(data);
441     assertThat(repeatedOnlyMessage.getRepeatedInt32Count()).isEqualTo(1);
442     assertThat(repeatedOnlyMessage.getRepeatedInt32(0)).isEqualTo(4321);
443     assertThat(repeatedOnlyMessage.getRepeatedStringCount()).isEqualTo(1);
444     assertThat(repeatedOnlyMessage.getRepeatedString(0)).isEqualTo("world");
445     assertThat(repeatedOnlyMessage.getRepeatedNestedMessageCount()).isEqualTo(1);
446     assertThat(repeatedOnlyMessage.getRepeatedNestedMessage(0).getValue()).isEqualTo(0);
447   }
448 
449   @Test
testIsInitialized()450   public void testIsInitialized() throws Exception {
451     TestAllTypes.Builder builder = TestAllTypes.newBuilder();
452 
453     // Test optional proto2 message fields.
454     UnittestProto.TestRequired.Builder proto2Builder = builder.getOptionalProto2MessageBuilder();
455     assertThat(builder.isInitialized()).isFalse();
456     assertThat(builder.buildPartial().isInitialized()).isFalse();
457 
458     proto2Builder.setA(1).setB(2).setC(3);
459     assertThat(builder.isInitialized()).isTrue();
460     assertThat(builder.buildPartial().isInitialized()).isTrue();
461 
462     // Test oneof proto2 message fields.
463     proto2Builder = builder.getOneofProto2MessageBuilder();
464     assertThat(builder.isInitialized()).isFalse();
465     assertThat(builder.buildPartial().isInitialized()).isFalse();
466 
467     proto2Builder.setA(1).setB(2).setC(3);
468     assertThat(builder.isInitialized()).isTrue();
469     assertThat(builder.buildPartial().isInitialized()).isTrue();
470 
471     // Test repeated proto2 message fields.
472     proto2Builder = builder.addRepeatedProto2MessageBuilder();
473     assertThat(builder.isInitialized()).isFalse();
474     assertThat(builder.buildPartial().isInitialized()).isFalse();
475 
476     proto2Builder.setA(1).setB(2).setC(3);
477     assertThat(builder.isInitialized()).isTrue();
478     assertThat(builder.buildPartial().isInitialized()).isTrue();
479   }
480 }
481