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