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 13 import protobuf_unittest.UnittestProto; 14 import protobuf_unittest.UnittestProto.ForeignEnum; 15 import protobuf_unittest.UnittestProto.TestAllExtensions; 16 import protobuf_unittest.UnittestProto.TestAllTypes; 17 import protobuf_unittest.UnittestProto.TestEmptyMessage; 18 import protobuf_unittest.UnittestProto.TestEmptyMessageWithExtensions; 19 import protobuf_unittest.UnittestProto.TestPackedExtensions; 20 import protobuf_unittest.UnittestProto.TestPackedTypes; 21 import proto3_unittest.UnittestProto3; 22 import java.util.List; 23 import java.util.Map; 24 import org.junit.Assert; 25 import org.junit.Before; 26 import org.junit.Test; 27 import org.junit.runner.RunWith; 28 import org.junit.runners.JUnit4; 29 30 /** Tests related to unknown field handling. */ 31 @RunWith(JUnit4.class) 32 public class UnknownFieldSetTest { 33 34 @Before setUp()35 public void setUp() throws Exception { 36 descriptor = TestAllTypes.getDescriptor(); 37 allFields = TestUtil.getAllSet(); 38 allFieldsData = allFields.toByteString(); 39 emptyMessage = TestEmptyMessage.parseFrom(allFieldsData); 40 unknownFields = emptyMessage.getUnknownFields(); 41 } 42 getField(String name)43 private UnknownFieldSet.Field getField(String name) { 44 Descriptors.FieldDescriptor field = descriptor.findFieldByName(name); 45 assertThat(field).isNotNull(); 46 return unknownFields.getField(field.getNumber()); 47 } 48 49 // Constructs a protocol buffer which contains fields with all the same 50 // numbers as allFieldsData except that each field is some other wire 51 // type. getBizarroData()52 ByteString getBizarroData() throws Exception { 53 UnknownFieldSet.Builder bizarroFields = UnknownFieldSet.newBuilder(); 54 55 UnknownFieldSet.Field varintField = UnknownFieldSet.Field.newBuilder().addVarint(1).build(); 56 UnknownFieldSet.Field fixed32Field = UnknownFieldSet.Field.newBuilder().addFixed32(1).build(); 57 58 for (Map.Entry<Integer, UnknownFieldSet.Field> entry : unknownFields.asMap().entrySet()) { 59 if (entry.getValue().getVarintList().isEmpty()) { 60 // Original field is not a varint, so use a varint. 61 bizarroFields.addField(entry.getKey(), varintField); 62 } else { 63 // Original field *is* a varint, so use something else. 64 bizarroFields.addField(entry.getKey(), fixed32Field); 65 } 66 } 67 68 return bizarroFields.build().toByteString(); 69 } 70 71 Descriptors.Descriptor descriptor; 72 TestAllTypes allFields; 73 ByteString allFieldsData; 74 75 // An empty message that has been parsed from allFieldsData. So, it has 76 // unknown fields of every type. 77 TestEmptyMessage emptyMessage; 78 UnknownFieldSet unknownFields; 79 80 // ================================================================= 81 82 @Test testFixed32FieldBuildersAreReusable()83 public void testFixed32FieldBuildersAreReusable() { 84 UnknownFieldSet.Field.Builder fieldBuilder = UnknownFieldSet.Field.newBuilder(); 85 fieldBuilder.addFixed32(10); 86 UnknownFieldSet.Field first = fieldBuilder.build(); 87 UnknownFieldSet.Field second = fieldBuilder.build(); 88 fieldBuilder.addFixed32(11); 89 UnknownFieldSet.Field third = fieldBuilder.build(); 90 91 assertThat(first).isEqualTo(second); 92 assertThat(first).isNotEqualTo(third); 93 } 94 95 @Test testFixed64FieldBuildersAreReusable()96 public void testFixed64FieldBuildersAreReusable() { 97 UnknownFieldSet.Field.Builder fieldBuilder = UnknownFieldSet.Field.newBuilder(); 98 fieldBuilder.addFixed64(10); 99 UnknownFieldSet.Field first = fieldBuilder.build(); 100 UnknownFieldSet.Field second = fieldBuilder.build(); 101 fieldBuilder.addFixed64(11); 102 UnknownFieldSet.Field third = fieldBuilder.build(); 103 104 assertThat(first).isEqualTo(second); 105 assertThat(first).isNotEqualTo(third); 106 } 107 108 @Test testVarintFieldBuildersAreReusable()109 public void testVarintFieldBuildersAreReusable() { 110 UnknownFieldSet.Field.Builder fieldBuilder = UnknownFieldSet.Field.newBuilder(); 111 fieldBuilder.addVarint(10); 112 UnknownFieldSet.Field first = fieldBuilder.build(); 113 UnknownFieldSet.Field second = fieldBuilder.build(); 114 fieldBuilder.addVarint(11); 115 UnknownFieldSet.Field third = fieldBuilder.build(); 116 117 assertThat(first).isEqualTo(second); 118 assertThat(first).isNotEqualTo(third); 119 } 120 121 @Test testLengthDelimitedFieldBuildersAreReusable()122 public void testLengthDelimitedFieldBuildersAreReusable() { 123 UnknownFieldSet.Field.Builder fieldBuilder = UnknownFieldSet.Field.newBuilder(); 124 fieldBuilder.addLengthDelimited(ByteString.copyFromUtf8("foo")); 125 UnknownFieldSet.Field first = fieldBuilder.build(); 126 UnknownFieldSet.Field second = fieldBuilder.build(); 127 fieldBuilder.addLengthDelimited(ByteString.copyFromUtf8("bar")); 128 UnknownFieldSet.Field third = fieldBuilder.build(); 129 130 assertThat(first).isEqualTo(second); 131 assertThat(first).isNotEqualTo(third); 132 } 133 134 @Test testGroupFieldBuildersAreReusable()135 public void testGroupFieldBuildersAreReusable() { 136 UnknownFieldSet.Field.Builder fieldBuilder = UnknownFieldSet.Field.newBuilder(); 137 fieldBuilder.addGroup( 138 UnknownFieldSet.newBuilder() 139 .addField(10, UnknownFieldSet.Field.newBuilder().addVarint(10).build()) 140 .build()); 141 UnknownFieldSet.Field first = fieldBuilder.build(); 142 UnknownFieldSet.Field second = fieldBuilder.build(); 143 fieldBuilder.addGroup( 144 UnknownFieldSet.newBuilder() 145 .addField(11, UnknownFieldSet.Field.newBuilder().addVarint(11).build()) 146 .build()); 147 UnknownFieldSet.Field third = fieldBuilder.build(); 148 149 assertThat(first).isEqualTo(second); 150 assertThat(first).isNotEqualTo(third); 151 } 152 153 @Test testClone()154 public void testClone() { 155 UnknownFieldSet.Builder unknownSetBuilder = UnknownFieldSet.newBuilder(); 156 UnknownFieldSet.Field.Builder fieldBuilder = UnknownFieldSet.Field.newBuilder(); 157 fieldBuilder.addFixed32(10); 158 unknownSetBuilder.addField(8, fieldBuilder.build()); 159 // necessary to call clone twice to expose the bug 160 UnknownFieldSet.Builder clone1 = unknownSetBuilder.clone(); 161 UnknownFieldSet.Builder clone2 = unknownSetBuilder.clone(); // failure is a NullPointerException 162 assertThat(clone1).isNotSameInstanceAs(clone2); 163 } 164 165 @Test testClone_lengthDelimited()166 public void testClone_lengthDelimited() { 167 UnknownFieldSet.Builder destUnknownFieldSet = 168 UnknownFieldSet.newBuilder() 169 .addField(997, UnknownFieldSet.Field.newBuilder().addVarint(99).build()) 170 .addField( 171 999, 172 UnknownFieldSet.Field.newBuilder() 173 .addLengthDelimited(ByteString.copyFromUtf8("some data")) 174 .addLengthDelimited(ByteString.copyFromUtf8("some more data")) 175 .build()); 176 UnknownFieldSet clone = destUnknownFieldSet.clone().build(); 177 assertThat(clone.getField(997)).isNotNull(); 178 UnknownFieldSet.Field field999 = clone.getField(999); 179 List<ByteString> lengthDelimited = field999.getLengthDelimitedList(); 180 assertThat(lengthDelimited.get(0).toStringUtf8()).isEqualTo("some data"); 181 assertThat(lengthDelimited.get(1).toStringUtf8()).isEqualTo("some more data"); 182 183 UnknownFieldSet clone2 = destUnknownFieldSet.clone().build(); 184 assertThat(clone2.getField(997)).isNotNull(); 185 UnknownFieldSet.Field secondField = clone2.getField(999); 186 List<ByteString> lengthDelimited2 = secondField.getLengthDelimitedList(); 187 assertThat(lengthDelimited2.get(0).toStringUtf8()).isEqualTo("some data"); 188 assertThat(lengthDelimited2.get(1).toStringUtf8()).isEqualTo("some more data"); 189 } 190 191 @Test testReuse()192 public void testReuse() { 193 UnknownFieldSet.Builder builder = 194 UnknownFieldSet.newBuilder() 195 .addField(997, UnknownFieldSet.Field.newBuilder().addVarint(99).build()) 196 .addField( 197 999, 198 UnknownFieldSet.Field.newBuilder() 199 .addLengthDelimited(ByteString.copyFromUtf8("some data")) 200 .addLengthDelimited(ByteString.copyFromUtf8("some more data")) 201 .build()); 202 203 UnknownFieldSet fieldSet1 = builder.build(); 204 UnknownFieldSet fieldSet2 = builder.build(); 205 builder.addField(1000, UnknownFieldSet.Field.newBuilder().addVarint(-90).build()); 206 UnknownFieldSet fieldSet3 = builder.build(); 207 208 assertThat(fieldSet1).isEqualTo(fieldSet2); 209 assertThat(fieldSet1).isNotEqualTo(fieldSet3); 210 } 211 212 @Test 213 @SuppressWarnings("ModifiedButNotUsed") testAddField_zero()214 public void testAddField_zero() { 215 UnknownFieldSet.Field field = getField("optional_int32"); 216 try { 217 UnknownFieldSet.newBuilder().addField(0, field); 218 Assert.fail(); 219 } catch (IllegalArgumentException expected) { 220 assertThat(expected).hasMessageThat().isEqualTo("0 is not a valid field number."); 221 } 222 } 223 224 @Test 225 @SuppressWarnings("ModifiedButNotUsed") testAddField_negative()226 public void testAddField_negative() { 227 UnknownFieldSet.Field field = getField("optional_int32"); 228 try { 229 UnknownFieldSet.newBuilder().addField(-2, field); 230 Assert.fail(); 231 } catch (IllegalArgumentException expected) { 232 assertThat(expected).hasMessageThat().isEqualTo("-2 is not a valid field number."); 233 } 234 } 235 236 @Test 237 @SuppressWarnings("ModifiedButNotUsed") testClearField_negative()238 public void testClearField_negative() { 239 try { 240 UnknownFieldSet.newBuilder().clearField(-28); 241 Assert.fail(); 242 } catch (IllegalArgumentException expected) { 243 assertThat(expected).hasMessageThat().isEqualTo("-28 is not a valid field number."); 244 } 245 } 246 247 @Test 248 @SuppressWarnings("ModifiedButNotUsed") testMergeField_negative()249 public void testMergeField_negative() { 250 UnknownFieldSet.Field field = getField("optional_int32"); 251 try { 252 UnknownFieldSet.newBuilder().mergeField(-2, field); 253 Assert.fail(); 254 } catch (IllegalArgumentException expected) { 255 assertThat(expected).hasMessageThat().isEqualTo("-2 is not a valid field number."); 256 } 257 } 258 259 @Test 260 @SuppressWarnings("ModifiedButNotUsed") testMergeVarintField_negative()261 public void testMergeVarintField_negative() { 262 try { 263 UnknownFieldSet.newBuilder().mergeVarintField(-2, 78); 264 Assert.fail(); 265 } catch (IllegalArgumentException expected) { 266 assertThat(expected).hasMessageThat().isEqualTo("-2 is not a valid field number."); 267 } 268 } 269 270 @Test 271 @SuppressWarnings("ModifiedButNotUsed") testHasField_negative()272 public void testHasField_negative() { 273 assertThat(UnknownFieldSet.newBuilder().hasField(-2)).isFalse(); 274 } 275 276 @Test 277 @SuppressWarnings("ModifiedButNotUsed") testMergeLengthDelimitedField_negative()278 public void testMergeLengthDelimitedField_negative() { 279 ByteString byteString = ByteString.copyFromUtf8("some data"); 280 try { 281 UnknownFieldSet.newBuilder().mergeLengthDelimitedField(-2, byteString); 282 Assert.fail(); 283 } catch (IllegalArgumentException expected) { 284 assertThat(expected).hasMessageThat().isEqualTo("-2 is not a valid field number."); 285 } 286 } 287 288 @Test testAddField()289 public void testAddField() { 290 UnknownFieldSet.Field field = getField("optional_int32"); 291 UnknownFieldSet fieldSet = UnknownFieldSet.newBuilder().addField(1, field).build(); 292 assertThat(fieldSet.getField(1)).isEqualTo(field); 293 } 294 295 @Test testAddField_withReplacement()296 public void testAddField_withReplacement() { 297 UnknownFieldSet.Field first = UnknownFieldSet.Field.newBuilder().addFixed32(56).build(); 298 UnknownFieldSet.Field second = UnknownFieldSet.Field.newBuilder().addFixed32(25).build(); 299 UnknownFieldSet fieldSet = UnknownFieldSet.newBuilder() 300 .addField(1, first) 301 .addField(1, second) 302 .build(); 303 List<Integer> list = fieldSet.getField(1).getFixed32List(); 304 assertThat(list).hasSize(1); 305 assertThat(list.get(0)).isEqualTo(25); 306 } 307 308 @Test testVarint()309 public void testVarint() throws Exception { 310 UnknownFieldSet.Field field = getField("optional_int32"); 311 assertThat(field.getVarintList()).hasSize(1); 312 assertThat((long) field.getVarintList().get(0)).isEqualTo(allFields.getOptionalInt32()); 313 } 314 315 @Test testFixed32()316 public void testFixed32() throws Exception { 317 UnknownFieldSet.Field field = getField("optional_fixed32"); 318 assertThat(field.getFixed32List()).hasSize(1); 319 assertThat((int) field.getFixed32List().get(0)).isEqualTo(allFields.getOptionalFixed32()); 320 } 321 322 @Test testFixed64()323 public void testFixed64() throws Exception { 324 UnknownFieldSet.Field field = getField("optional_fixed64"); 325 assertThat(field.getFixed64List()).hasSize(1); 326 assertThat((long) field.getFixed64List().get(0)).isEqualTo(allFields.getOptionalFixed64()); 327 } 328 329 @Test testLengthDelimited()330 public void testLengthDelimited() throws Exception { 331 UnknownFieldSet.Field field = getField("optional_bytes"); 332 assertThat(field.getLengthDelimitedList()).hasSize(1); 333 assertThat(field.getLengthDelimitedList().get(0)).isEqualTo(allFields.getOptionalBytes()); 334 } 335 336 @Test testGroup()337 public void testGroup() throws Exception { 338 Descriptors.FieldDescriptor nestedFieldDescriptor = 339 TestAllTypes.OptionalGroup.getDescriptor().findFieldByName("a"); 340 assertThat(nestedFieldDescriptor).isNotNull(); 341 342 UnknownFieldSet.Field field = getField("optionalgroup"); 343 assertThat(field.getGroupList()).hasSize(1); 344 345 UnknownFieldSet group = field.getGroupList().get(0); 346 assertThat(group.asMap()).hasSize(1); 347 assertThat(group.hasField(nestedFieldDescriptor.getNumber())).isTrue(); 348 349 UnknownFieldSet.Field nestedField = group.getField(nestedFieldDescriptor.getNumber()); 350 assertThat(nestedField.getVarintList()).hasSize(1); 351 assertThat((long) nestedField.getVarintList().get(0)) 352 .isEqualTo(allFields.getOptionalGroup().getA()); 353 } 354 355 @Test testSerialize()356 public void testSerialize() throws Exception { 357 // Check that serializing the UnknownFieldSet produces the original data 358 // again. 359 ByteString data = emptyMessage.toByteString(); 360 assertThat(data).isEqualTo(allFieldsData); 361 } 362 363 @Test testCopyFrom()364 public void testCopyFrom() throws Exception { 365 TestEmptyMessage message = TestEmptyMessage.newBuilder().mergeFrom(emptyMessage).build(); 366 367 assertThat(message.toString()).isEqualTo(emptyMessage.toString()); 368 } 369 370 @Test testMergeFrom()371 public void testMergeFrom() throws Exception { 372 TestEmptyMessage source = 373 TestEmptyMessage.newBuilder() 374 .setUnknownFields( 375 UnknownFieldSet.newBuilder() 376 .addField(2, UnknownFieldSet.Field.newBuilder().addVarint(2).build()) 377 .addField(3, UnknownFieldSet.Field.newBuilder().addVarint(4).build()) 378 .build()) 379 .build(); 380 TestEmptyMessage destination = 381 TestEmptyMessage.newBuilder() 382 .setUnknownFields( 383 UnknownFieldSet.newBuilder() 384 .addField(1, UnknownFieldSet.Field.newBuilder().addVarint(1).build()) 385 .addField(3, UnknownFieldSet.Field.newBuilder().addVarint(3).build()) 386 .build()) 387 .mergeFrom(source) 388 .build(); 389 390 assertThat(destination.toString()).isEqualTo("1: 1\n2: 2\n3: 3\n3: 4\n"); 391 } 392 393 @Test testAsMap()394 public void testAsMap() throws Exception { 395 UnknownFieldSet.Builder builder = UnknownFieldSet.newBuilder().mergeFrom(unknownFields); 396 Map<Integer, UnknownFieldSet.Field> mapFromBuilder = builder.asMap(); 397 assertThat(mapFromBuilder).isNotEmpty(); 398 UnknownFieldSet fields = builder.build(); 399 Map<Integer, UnknownFieldSet.Field> mapFromFieldSet = fields.asMap(); 400 assertThat(mapFromFieldSet).containsExactlyEntriesIn(mapFromBuilder); 401 } 402 403 @Test testClear()404 public void testClear() throws Exception { 405 UnknownFieldSet fields = UnknownFieldSet.newBuilder().mergeFrom(unknownFields).clear().build(); 406 assertThat(fields.asMap()).isEmpty(); 407 } 408 409 @Test testClearMessage()410 public void testClearMessage() throws Exception { 411 TestEmptyMessage message = 412 TestEmptyMessage.newBuilder().mergeFrom(emptyMessage).clear().build(); 413 assertThat(message.getSerializedSize()).isEqualTo(0); 414 } 415 416 @Test testClearField()417 public void testClearField() throws Exception { 418 int fieldNumber = unknownFields.asMap().keySet().iterator().next(); 419 UnknownFieldSet fields = 420 UnknownFieldSet.newBuilder().mergeFrom(unknownFields).clearField(fieldNumber).build(); 421 assertThat(fields.hasField(fieldNumber)).isFalse(); 422 } 423 424 @Test testParseKnownAndUnknown()425 public void testParseKnownAndUnknown() throws Exception { 426 // Test mixing known and unknown fields when parsing. 427 428 UnknownFieldSet fields = 429 UnknownFieldSet.newBuilder(unknownFields) 430 .addField(123456, UnknownFieldSet.Field.newBuilder().addVarint(654321).build()) 431 .build(); 432 433 ByteString data = fields.toByteString(); 434 TestAllTypes destination = TestAllTypes.parseFrom(data); 435 436 TestUtil.assertAllFieldsSet(destination); 437 assertThat(destination.getUnknownFields().asMap()).hasSize(1); 438 439 UnknownFieldSet.Field field = destination.getUnknownFields().getField(123456); 440 assertThat(field.getVarintList()).hasSize(1); 441 assertThat((long) field.getVarintList().get(0)).isEqualTo(654321); 442 } 443 444 @Test testWrongTypeTreatedAsUnknown()445 public void testWrongTypeTreatedAsUnknown() throws Exception { 446 // Test that fields of the wrong wire type are treated like unknown fields 447 // when parsing. 448 449 ByteString bizarroData = getBizarroData(); 450 TestAllTypes allTypesMessage = TestAllTypes.parseFrom(bizarroData); 451 TestEmptyMessage emptyMessage = TestEmptyMessage.parseFrom(bizarroData); 452 453 // All fields should have been interpreted as unknown, so the debug strings 454 // should be the same. 455 assertThat(emptyMessage.toString()).isEqualTo(allTypesMessage.toString()); 456 } 457 458 @Test testUnknownExtensions()459 public void testUnknownExtensions() throws Exception { 460 // Make sure fields are properly parsed to the UnknownFieldSet even when 461 // they are declared as extension numbers. 462 463 TestEmptyMessageWithExtensions message = 464 TestEmptyMessageWithExtensions.parseFrom(allFieldsData); 465 466 assertThat(unknownFields.asMap()).hasSize(message.getUnknownFields().asMap().size()); 467 assertThat(allFieldsData).isEqualTo(message.toByteString()); 468 } 469 470 @Test testWrongExtensionTypeTreatedAsUnknown()471 public void testWrongExtensionTypeTreatedAsUnknown() throws Exception { 472 // Test that fields of the wrong wire type are treated like unknown fields 473 // when parsing extensions. 474 475 ByteString bizarroData = getBizarroData(); 476 TestAllExtensions allExtensionsMessage = TestAllExtensions.parseFrom(bizarroData); 477 TestEmptyMessage emptyMessage = TestEmptyMessage.parseFrom(bizarroData); 478 479 // All fields should have been interpreted as unknown, so the debug strings 480 // should be the same. 481 assertThat(emptyMessage.toString()).isEqualTo(allExtensionsMessage.toString()); 482 } 483 484 @Test testParseUnknownEnumValue()485 public void testParseUnknownEnumValue() throws Exception { 486 Descriptors.FieldDescriptor singularField = 487 TestAllTypes.getDescriptor().findFieldByName("optional_nested_enum"); 488 Descriptors.FieldDescriptor repeatedField = 489 TestAllTypes.getDescriptor().findFieldByName("repeated_nested_enum"); 490 assertThat(singularField).isNotNull(); 491 assertThat(repeatedField).isNotNull(); 492 493 ByteString data = 494 UnknownFieldSet.newBuilder() 495 .addField( 496 singularField.getNumber(), 497 UnknownFieldSet.Field.newBuilder() 498 .addVarint(TestAllTypes.NestedEnum.BAR.getNumber()) 499 .addVarint(5) // not valid 500 .build()) 501 .addField( 502 repeatedField.getNumber(), 503 UnknownFieldSet.Field.newBuilder() 504 .addVarint(TestAllTypes.NestedEnum.FOO.getNumber()) 505 .addVarint(4) // not valid 506 .addVarint(TestAllTypes.NestedEnum.BAZ.getNumber()) 507 .addVarint(6) // not valid 508 .build()) 509 .build() 510 .toByteString(); 511 512 { 513 TestAllTypes message = TestAllTypes.parseFrom(data); 514 assertThat(message.getOptionalNestedEnum()).isEqualTo(TestAllTypes.NestedEnum.BAR); 515 assertThat(message.getRepeatedNestedEnumList()) 516 .containsExactly(TestAllTypes.NestedEnum.FOO, TestAllTypes.NestedEnum.BAZ) 517 .inOrder(); 518 assertThat(message.getUnknownFields().getField(singularField.getNumber()).getVarintList()) 519 .containsExactly(5L); 520 assertThat(message.getUnknownFields().getField(repeatedField.getNumber()).getVarintList()) 521 .containsExactly(4L, 6L) 522 .inOrder(); 523 } 524 525 { 526 TestAllExtensions message = 527 TestAllExtensions.parseFrom(data, TestUtil.getExtensionRegistry()); 528 assertThat(message.getExtension(UnittestProto.optionalNestedEnumExtension)) 529 .isEqualTo(TestAllTypes.NestedEnum.BAR); 530 assertThat(message.getExtension(UnittestProto.repeatedNestedEnumExtension)) 531 .containsExactly(TestAllTypes.NestedEnum.FOO, TestAllTypes.NestedEnum.BAZ) 532 .inOrder(); 533 assertThat(message.getUnknownFields().getField(singularField.getNumber()).getVarintList()) 534 .containsExactly(5L); 535 assertThat(message.getUnknownFields().getField(repeatedField.getNumber()).getVarintList()) 536 .containsExactly(4L, 6L) 537 .inOrder(); 538 } 539 } 540 541 @Test testLargeVarint()542 public void testLargeVarint() throws Exception { 543 ByteString data = 544 UnknownFieldSet.newBuilder() 545 .addField(1, UnknownFieldSet.Field.newBuilder().addVarint(0x7FFFFFFFFFFFFFFFL).build()) 546 .build() 547 .toByteString(); 548 UnknownFieldSet parsed = UnknownFieldSet.parseFrom(data); 549 UnknownFieldSet.Field field = parsed.getField(1); 550 assertThat(field.getVarintList()).hasSize(1); 551 assertThat((long) field.getVarintList().get(0)).isEqualTo(0x7FFFFFFFFFFFFFFFL); 552 } 553 554 @Test testEqualsAndHashCode()555 public void testEqualsAndHashCode() { 556 UnknownFieldSet.Field fixed32Field = UnknownFieldSet.Field.newBuilder().addFixed32(1).build(); 557 UnknownFieldSet.Field fixed64Field = UnknownFieldSet.Field.newBuilder().addFixed64(1).build(); 558 UnknownFieldSet.Field varIntField = UnknownFieldSet.Field.newBuilder().addVarint(1).build(); 559 UnknownFieldSet.Field lengthDelimitedField = 560 UnknownFieldSet.Field.newBuilder().addLengthDelimited(ByteString.EMPTY).build(); 561 UnknownFieldSet.Field groupField = 562 UnknownFieldSet.Field.newBuilder().addGroup(unknownFields).build(); 563 564 UnknownFieldSet a = UnknownFieldSet.newBuilder().addField(1, fixed32Field).build(); 565 UnknownFieldSet b = UnknownFieldSet.newBuilder().addField(1, fixed64Field).build(); 566 UnknownFieldSet c = UnknownFieldSet.newBuilder().addField(1, varIntField).build(); 567 UnknownFieldSet d = UnknownFieldSet.newBuilder().addField(1, lengthDelimitedField).build(); 568 UnknownFieldSet e = UnknownFieldSet.newBuilder().addField(1, groupField).build(); 569 570 checkEqualsIsConsistent(a); 571 checkEqualsIsConsistent(b); 572 checkEqualsIsConsistent(c); 573 checkEqualsIsConsistent(d); 574 checkEqualsIsConsistent(e); 575 576 checkNotEqual(a, b); 577 checkNotEqual(a, c); 578 checkNotEqual(a, d); 579 checkNotEqual(a, e); 580 checkNotEqual(b, c); 581 checkNotEqual(b, d); 582 checkNotEqual(b, e); 583 checkNotEqual(c, d); 584 checkNotEqual(c, e); 585 checkNotEqual(d, e); 586 } 587 588 /** 589 * Asserts that the given field sets are not equal and have different hash codes. 590 * 591 * <p><b>Note:</b> It's valid for non-equal objects to have the same hash code, so this test is 592 * stricter than it needs to be. However, this should happen relatively rarely. 593 */ checkNotEqual(UnknownFieldSet s1, UnknownFieldSet s2)594 private void checkNotEqual(UnknownFieldSet s1, UnknownFieldSet s2) { 595 String equalsError = String.format("%s should not be equal to %s", s1, s2); 596 assertWithMessage(equalsError).that(s1).isNotEqualTo(s2); 597 assertWithMessage(equalsError).that(s2).isNotEqualTo(s1); 598 599 assertWithMessage("%s should have a different hash code from %s", s1, s2) 600 .that(s1.hashCode()) 601 .isNotEqualTo(s2.hashCode()); 602 } 603 604 /** Asserts that the given field sets are equal and have identical hash codes. */ checkEqualsIsConsistent(UnknownFieldSet set)605 private void checkEqualsIsConsistent(UnknownFieldSet set) { 606 // Object should be equal to itself. 607 assertThat(set.equals(set)).isTrue(); 608 609 // Object should be equal to a copy of itself. 610 UnknownFieldSet copy = UnknownFieldSet.newBuilder(set).build(); 611 assertThat(copy).isEqualTo(set); 612 assertThat(set).isEqualTo(copy); 613 assertThat(set.hashCode()).isEqualTo(copy.hashCode()); 614 } 615 616 // ================================================================= 617 618 @Test testProto3RoundTrip()619 public void testProto3RoundTrip() throws Exception { 620 ByteString data = getBizarroData(); 621 622 UnittestProto3.TestEmptyMessage message = 623 UnittestProto3.TestEmptyMessage.parseFrom(data, ExtensionRegistryLite.getEmptyRegistry()); 624 assertThat(message.toByteString()).isEqualTo(data); 625 626 message = UnittestProto3.TestEmptyMessage.newBuilder().mergeFrom(message).build(); 627 assertThat(message.toByteString()).isEqualTo(data); 628 629 assertThat(data) 630 .isEqualTo( 631 UnittestProto3.TestMessageWithDummy.parseFrom( 632 data, ExtensionRegistryLite.getEmptyRegistry()) 633 .toBuilder() 634 // force copy-on-write 635 .setDummy(true) 636 .build() 637 .toBuilder() 638 .clearDummy() 639 .build() 640 .toByteString()); 641 } 642 } 643