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