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