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