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