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.protobuf.UnittestLite.optionalForeignEnumExtensionLite; 34 35 import com.google.protobuf.UnittestLite.ForeignEnumLite; 36 import com.google.protobuf.UnittestLite.TestAllExtensionsLite; 37 import com.google.protobuf.UnittestLite.TestPackedExtensionsLite; 38 import map_test.MapForProto2TestProto; 39 import map_test.MapTestProto.TestMap; 40 import protobuf_unittest.UnittestMset.RawMessageSet; 41 import protobuf_unittest.UnittestMset.TestMessageSetExtension1; 42 import protobuf_unittest.UnittestMset.TestMessageSetExtension2; 43 import protobuf_unittest.UnittestProto; 44 import protobuf_unittest.UnittestProto.TestAllExtensions; 45 import protobuf_unittest.UnittestProto.TestAllTypes; 46 import protobuf_unittest.UnittestProto.TestExtensionInsideTable; 47 import protobuf_unittest.UnittestProto.TestFieldOrderings; 48 import protobuf_unittest.UnittestProto.TestOneof2; 49 import protobuf_unittest.UnittestProto.TestOneofBackwardsCompatible; 50 import protobuf_unittest.UnittestProto.TestPackedExtensions; 51 import protobuf_unittest.UnittestProto.TestPackedTypes; 52 import proto2_wireformat_unittest.UnittestMsetWireFormat.TestMessageSet; 53 import proto3_unittest.UnittestProto3; 54 import java.io.ByteArrayInputStream; 55 import java.io.ByteArrayOutputStream; 56 import java.io.IOException; 57 import java.io.InputStream; 58 import java.util.Arrays; 59 import java.util.List; 60 import junit.framework.TestCase; 61 62 public class WireFormatLiteTest extends TestCase { testSerializeExtensionsLite()63 public void testSerializeExtensionsLite() throws Exception { 64 // TestAllTypes and TestAllExtensions should have compatible wire formats, 65 // so if we serialize a TestAllExtensions then parse it as TestAllTypes 66 // it should work. 67 68 TestAllExtensionsLite message = TestUtilLite.getAllLiteExtensionsSet(); 69 ByteString rawBytes = message.toByteString(); 70 assertEquals(rawBytes.size(), message.getSerializedSize()); 71 72 TestAllTypes message2 = TestAllTypes.parseFrom(rawBytes); 73 74 TestUtil.assertAllFieldsSet(message2); 75 } 76 testSerializePackedExtensionsLite()77 public void testSerializePackedExtensionsLite() throws Exception { 78 // TestPackedTypes and TestPackedExtensions should have compatible wire 79 // formats; check that they serialize to the same string. 80 TestPackedExtensionsLite message = TestUtilLite.getLitePackedExtensionsSet(); 81 ByteString rawBytes = message.toByteString(); 82 83 TestPackedTypes message2 = TestUtil.getPackedSet(); 84 ByteString rawBytes2 = message2.toByteString(); 85 86 assertEquals(rawBytes, rawBytes2); 87 } 88 testParseExtensionsLite()89 public void testParseExtensionsLite() throws Exception { 90 // TestAllTypes and TestAllExtensions should have compatible wire formats, 91 // so if we serialize a TestAllTypes then parse it as TestAllExtensions 92 // it should work. 93 94 TestAllTypes message = TestUtil.getAllSet(); 95 ByteString rawBytes = message.toByteString(); 96 97 ExtensionRegistryLite registryLite = TestUtilLite.getExtensionRegistryLite(); 98 99 TestAllExtensionsLite message2 = TestAllExtensionsLite.parseFrom(rawBytes, registryLite); 100 TestUtil.assertAllExtensionsSet(message2); 101 message2 = TestAllExtensionsLite.parseFrom(message.toByteArray(), registryLite); 102 TestUtil.assertAllExtensionsSet(message2); 103 } 104 testParsePackedExtensionsLite()105 public void testParsePackedExtensionsLite() throws Exception { 106 // Ensure that packed extensions can be properly parsed. 107 TestPackedExtensionsLite message = TestUtilLite.getLitePackedExtensionsSet(); 108 ByteString rawBytes = message.toByteString(); 109 110 ExtensionRegistryLite registry = TestUtilLite.getExtensionRegistryLite(); 111 112 TestPackedExtensionsLite message2 = TestPackedExtensionsLite.parseFrom(rawBytes, registry); 113 TestUtil.assertPackedExtensionsSet(message2); 114 message2 = TestPackedExtensionsLite.parseFrom(message.toByteArray(), registry); 115 TestUtil.assertPackedExtensionsSet(message2); 116 } 117 testSerialization()118 public void testSerialization() throws Exception { 119 TestAllTypes message = TestUtil.getAllSet(); 120 121 ByteString rawBytes = message.toByteString(); 122 assertEquals(rawBytes.size(), message.getSerializedSize()); 123 124 TestAllTypes message2 = TestAllTypes.parseFrom(rawBytes); 125 126 TestUtil.assertAllFieldsSet(message2); 127 } 128 testSerializationPacked()129 public void testSerializationPacked() throws Exception { 130 TestPackedTypes message = TestUtil.getPackedSet(); 131 132 ByteString rawBytes = message.toByteString(); 133 assertEquals(rawBytes.size(), message.getSerializedSize()); 134 135 TestPackedTypes message2 = TestPackedTypes.parseFrom(rawBytes); 136 137 TestUtil.assertPackedFieldsSet(message2); 138 } 139 testSerializeExtensions()140 public void testSerializeExtensions() throws Exception { 141 // TestAllTypes and TestAllExtensions should have compatible wire formats, 142 // so if we serialize a TestAllExtensions then parse it as TestAllTypes 143 // it should work. 144 145 TestAllExtensions message = TestUtil.getAllExtensionsSet(); 146 ByteString rawBytes = message.toByteString(); 147 assertEquals(rawBytes.size(), message.getSerializedSize()); 148 149 TestAllTypes message2 = TestAllTypes.parseFrom(rawBytes); 150 151 TestUtil.assertAllFieldsSet(message2); 152 } 153 testSerializePackedExtensions()154 public void testSerializePackedExtensions() throws Exception { 155 // TestPackedTypes and TestPackedExtensions should have compatible wire 156 // formats; check that they serialize to the same string. 157 TestPackedExtensions message = TestUtil.getPackedExtensionsSet(); 158 ByteString rawBytes = message.toByteString(); 159 160 TestPackedTypes message2 = TestUtil.getPackedSet(); 161 ByteString rawBytes2 = message2.toByteString(); 162 163 assertEquals(rawBytes, rawBytes2); 164 } 165 testSerializationPackedWithoutGetSerializedSize()166 public void testSerializationPackedWithoutGetSerializedSize() throws Exception { 167 // Write directly to an OutputStream, without invoking getSerializedSize() 168 // This used to be a bug where the size of a packed field was incorrect, 169 // since getSerializedSize() was never invoked. 170 TestPackedTypes message = TestUtil.getPackedSet(); 171 172 // Directly construct a CodedOutputStream around the actual OutputStream, 173 // in case writeTo(OutputStream output) invokes getSerializedSize(); 174 ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); 175 CodedOutputStream codedOutput = CodedOutputStream.newInstance(outputStream); 176 177 message.writeTo(codedOutput); 178 179 codedOutput.flush(); 180 181 TestPackedTypes message2 = TestPackedTypes.parseFrom(outputStream.toByteArray()); 182 183 TestUtil.assertPackedFieldsSet(message2); 184 } 185 testParseExtensions()186 public void testParseExtensions() throws Exception { 187 // TestAllTypes and TestAllExtensions should have compatible wire formats, 188 // so if we serialize a TestAllTypes then parse it as TestAllExtensions 189 // it should work. 190 191 TestAllTypes message = TestUtil.getAllSet(); 192 ByteString rawBytes = message.toByteString(); 193 194 ExtensionRegistryLite registry = TestUtil.getExtensionRegistry(); 195 196 TestAllExtensions message2 = TestAllExtensions.parseFrom(rawBytes, registry); 197 198 TestUtil.assertAllExtensionsSet(message2); 199 } 200 testParsePackedExtensions()201 public void testParsePackedExtensions() throws Exception { 202 // Ensure that packed extensions can be properly parsed. 203 TestPackedExtensions message = TestUtil.getPackedExtensionsSet(); 204 ByteString rawBytes = message.toByteString(); 205 206 ExtensionRegistryLite registry = TestUtil.getExtensionRegistry(); 207 208 TestPackedExtensions message2 = TestPackedExtensions.parseFrom(rawBytes, registry); 209 210 TestUtil.assertPackedExtensionsSet(message2); 211 } 212 testSerializeDelimited()213 public void testSerializeDelimited() throws Exception { 214 ByteArrayOutputStream output = new ByteArrayOutputStream(); 215 TestUtil.getAllSet().writeDelimitedTo(output); 216 output.write(12); 217 TestUtil.getPackedSet().writeDelimitedTo(output); 218 output.write(34); 219 220 ByteArrayInputStream input = new ByteArrayInputStream(output.toByteArray()); 221 222 TestUtil.assertAllFieldsSet(TestAllTypes.parseDelimitedFrom(input)); 223 assertEquals(12, input.read()); 224 TestUtil.assertPackedFieldsSet(TestPackedTypes.parseDelimitedFrom(input)); 225 assertEquals(34, input.read()); 226 assertEquals(-1, input.read()); 227 228 // We're at EOF, so parsing again should return null. 229 assertNull(TestAllTypes.parseDelimitedFrom(input)); 230 } 231 getTestFieldOrderingsRegistry()232 private ExtensionRegistryLite getTestFieldOrderingsRegistry() { 233 ExtensionRegistryLite result = ExtensionRegistryLite.newInstance(); 234 result.add(UnittestProto.myExtensionInt); 235 result.add(UnittestProto.myExtensionString); 236 return result; 237 } 238 testParseMultipleExtensionRanges()239 public void testParseMultipleExtensionRanges() throws Exception { 240 // Make sure we can parse a message that contains multiple extensions 241 // ranges. 242 TestFieldOrderings source = 243 TestFieldOrderings.newBuilder() 244 .setMyInt(1) 245 .setMyString("foo") 246 .setMyFloat(1.0F) 247 .setExtension(UnittestProto.myExtensionInt, 23) 248 .setExtension(UnittestProto.myExtensionString, "bar") 249 .build(); 250 TestFieldOrderings dest = 251 TestFieldOrderings.parseFrom(source.toByteString(), getTestFieldOrderingsRegistry()); 252 assertEquals(source, dest); 253 } 254 getTestExtensionInsideTableRegistry()255 private static ExtensionRegistryLite getTestExtensionInsideTableRegistry() { 256 ExtensionRegistryLite result = ExtensionRegistryLite.newInstance(); 257 result.add(UnittestProto.testExtensionInsideTableExtension); 258 return result; 259 } 260 testExtensionInsideTable()261 public void testExtensionInsideTable() throws Exception { 262 // Make sure the extension within the range of table is parsed correctly in experimental 263 // runtime. 264 TestExtensionInsideTable source = 265 TestExtensionInsideTable.newBuilder() 266 .setField1(1) 267 .setExtension(UnittestProto.testExtensionInsideTableExtension, 23) 268 .build(); 269 TestExtensionInsideTable dest = 270 TestExtensionInsideTable.parseFrom( 271 source.toByteString(), getTestExtensionInsideTableRegistry()); 272 assertEquals(source, dest); 273 } 274 275 private static final int UNKNOWN_TYPE_ID = 1550055; 276 private static final int TYPE_ID_1 = 1545008; 277 private static final int TYPE_ID_2 = 1547769; 278 testSerializeMessageSetEagerly()279 public void testSerializeMessageSetEagerly() throws Exception { 280 testSerializeMessageSetWithFlag(true); 281 } 282 testSerializeMessageSetNotEagerly()283 public void testSerializeMessageSetNotEagerly() throws Exception { 284 testSerializeMessageSetWithFlag(false); 285 } 286 testSerializeMessageSetWithFlag(boolean eagerParsing)287 private void testSerializeMessageSetWithFlag(boolean eagerParsing) throws Exception { 288 ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); 289 CodedOutputStream output = CodedOutputStream.newInstance(byteArrayOutputStream); 290 output.writeRawMessageSetExtension(UNKNOWN_TYPE_ID, ByteString.copyFromUtf8("bar")); 291 output.flush(); 292 byte[] messageSetBytes = byteArrayOutputStream.toByteArray(); 293 294 ExtensionRegistryLite.setEagerlyParseMessageSets(eagerParsing); 295 // Set up a TestMessageSet with two known messages and an unknown one. 296 TestMessageSet messageSet = 297 TestMessageSet.newBuilder() 298 .setExtension( 299 TestMessageSetExtension1.messageSetExtension, 300 TestMessageSetExtension1.newBuilder().setI(123).build()) 301 .setExtension( 302 TestMessageSetExtension2.messageSetExtension, 303 TestMessageSetExtension2.newBuilder().setStr("foo").build()) 304 .mergeFrom(messageSetBytes) 305 .build(); 306 307 ByteString data = messageSet.toByteString(); 308 309 // Parse back using RawMessageSet and check the contents. 310 RawMessageSet raw = RawMessageSet.parseFrom(data); 311 312 assertEquals(3, raw.getItemCount()); 313 assertEquals(TYPE_ID_1, raw.getItem(0).getTypeId()); 314 assertEquals(TYPE_ID_2, raw.getItem(1).getTypeId()); 315 assertEquals(UNKNOWN_TYPE_ID, raw.getItem(2).getTypeId()); 316 317 TestMessageSetExtension1 message1 = 318 TestMessageSetExtension1.parseFrom(raw.getItem(0).getMessage()); 319 assertEquals(123, message1.getI()); 320 321 TestMessageSetExtension2 message2 = 322 TestMessageSetExtension2.parseFrom(raw.getItem(1).getMessage()); 323 assertEquals("foo", message2.getStr()); 324 325 assertEquals("bar", raw.getItem(2).getMessage().toStringUtf8()); 326 } 327 testParseMessageSetEagerly()328 public void testParseMessageSetEagerly() throws Exception { 329 testParseMessageSetWithFlag(true); 330 } 331 testParseMessageSetNotEagerly()332 public void testParseMessageSetNotEagerly() throws Exception { 333 testParseMessageSetWithFlag(false); 334 } 335 testParseMessageSetWithFlag(boolean eagerParsing)336 private void testParseMessageSetWithFlag(boolean eagerParsing) throws Exception { 337 ExtensionRegistryLite.setEagerlyParseMessageSets(eagerParsing); 338 ExtensionRegistryLite extensionRegistry = ExtensionRegistryLite.newInstance(); 339 extensionRegistry.add(TestMessageSetExtension1.messageSetExtension); 340 extensionRegistry.add(TestMessageSetExtension2.messageSetExtension); 341 342 // Set up a RawMessageSet with two known messages and an unknown one. 343 RawMessageSet raw = 344 RawMessageSet.newBuilder() 345 .addItem( 346 RawMessageSet.Item.newBuilder() 347 .setTypeId(TYPE_ID_1) 348 .setMessage( 349 TestMessageSetExtension1.newBuilder().setI(123).build().toByteString()) 350 .build()) 351 .addItem( 352 RawMessageSet.Item.newBuilder() 353 .setTypeId(TYPE_ID_2) 354 .setMessage( 355 TestMessageSetExtension2.newBuilder().setStr("foo").build().toByteString()) 356 .build()) 357 .addItem( 358 RawMessageSet.Item.newBuilder() 359 .setTypeId(UNKNOWN_TYPE_ID) 360 .setMessage(ByteString.copyFromUtf8("bar")) 361 .build()) 362 .build(); 363 364 ByteString data = raw.toByteString(); 365 366 // Parse as a TestMessageSet and check the contents. 367 TestMessageSet messageSet = TestMessageSet.parseFrom(data, extensionRegistry); 368 369 assertEquals(123, messageSet.getExtension(TestMessageSetExtension1.messageSetExtension).getI()); 370 assertEquals( 371 "foo", messageSet.getExtension(TestMessageSetExtension2.messageSetExtension).getStr()); 372 } 373 testParseMessageSetExtensionEagerly()374 public void testParseMessageSetExtensionEagerly() throws Exception { 375 testParseMessageSetExtensionWithFlag(true); 376 } 377 testParseMessageSetExtensionNotEagerly()378 public void testParseMessageSetExtensionNotEagerly() throws Exception { 379 testParseMessageSetExtensionWithFlag(false); 380 } 381 testParseMessageSetExtensionWithFlag(boolean eagerParsing)382 private void testParseMessageSetExtensionWithFlag(boolean eagerParsing) throws Exception { 383 ExtensionRegistryLite.setEagerlyParseMessageSets(eagerParsing); 384 ExtensionRegistryLite extensionRegistry = ExtensionRegistryLite.newInstance(); 385 extensionRegistry.add(TestMessageSetExtension1.messageSetExtension); 386 387 // Set up a RawMessageSet with a known messages. 388 int typeId1 = 1545008; 389 RawMessageSet raw = 390 RawMessageSet.newBuilder() 391 .addItem( 392 RawMessageSet.Item.newBuilder() 393 .setTypeId(typeId1) 394 .setMessage( 395 TestMessageSetExtension1.newBuilder().setI(123).build().toByteString()) 396 .build()) 397 .build(); 398 399 ByteString data = raw.toByteString(); 400 401 // Parse as a TestMessageSet and check the contents. 402 TestMessageSet messageSet = TestMessageSet.parseFrom(data, extensionRegistry); 403 assertEquals(123, messageSet.getExtension(TestMessageSetExtension1.messageSetExtension).getI()); 404 } 405 testMergeLazyMessageSetExtensionEagerly()406 public void testMergeLazyMessageSetExtensionEagerly() throws Exception { 407 testMergeLazyMessageSetExtensionWithFlag(true); 408 } 409 testMergeLazyMessageSetExtensionNotEagerly()410 public void testMergeLazyMessageSetExtensionNotEagerly() throws Exception { 411 testMergeLazyMessageSetExtensionWithFlag(false); 412 } 413 testMergeLazyMessageSetExtensionWithFlag(boolean eagerParsing)414 private void testMergeLazyMessageSetExtensionWithFlag(boolean eagerParsing) throws Exception { 415 ExtensionRegistryLite.setEagerlyParseMessageSets(eagerParsing); 416 ExtensionRegistryLite extensionRegistry = ExtensionRegistryLite.newInstance(); 417 extensionRegistry.add(TestMessageSetExtension1.messageSetExtension); 418 419 // Set up a RawMessageSet with a known messages. 420 int typeId1 = 1545008; 421 RawMessageSet raw = 422 RawMessageSet.newBuilder() 423 .addItem( 424 RawMessageSet.Item.newBuilder() 425 .setTypeId(typeId1) 426 .setMessage( 427 TestMessageSetExtension1.newBuilder().setI(123).build().toByteString()) 428 .build()) 429 .build(); 430 431 ByteString data = raw.toByteString(); 432 433 // Parse as a TestMessageSet and store value into lazy field 434 TestMessageSet messageSet = TestMessageSet.parseFrom(data, extensionRegistry); 435 // Merge lazy field check the contents. 436 messageSet = messageSet.toBuilder().mergeFrom(data, extensionRegistry).build(); 437 assertEquals(123, messageSet.getExtension(TestMessageSetExtension1.messageSetExtension).getI()); 438 } 439 testMergeMessageSetExtensionEagerly()440 public void testMergeMessageSetExtensionEagerly() throws Exception { 441 testMergeMessageSetExtensionWithFlag(true); 442 } 443 testMergeMessageSetExtensionNotEagerly()444 public void testMergeMessageSetExtensionNotEagerly() throws Exception { 445 testMergeMessageSetExtensionWithFlag(false); 446 } 447 testMergeMessageSetExtensionWithFlag(boolean eagerParsing)448 private void testMergeMessageSetExtensionWithFlag(boolean eagerParsing) throws Exception { 449 ExtensionRegistryLite.setEagerlyParseMessageSets(eagerParsing); 450 ExtensionRegistryLite extensionRegistry = ExtensionRegistryLite.newInstance(); 451 extensionRegistry.add(TestMessageSetExtension1.messageSetExtension); 452 453 // Set up a RawMessageSet with a known messages. 454 int typeId1 = 1545008; 455 RawMessageSet raw = 456 RawMessageSet.newBuilder() 457 .addItem( 458 RawMessageSet.Item.newBuilder() 459 .setTypeId(typeId1) 460 .setMessage( 461 TestMessageSetExtension1.newBuilder().setI(123).build().toByteString()) 462 .build()) 463 .build(); 464 465 // Serialize RawMessageSet unnormally (message value before type id) 466 ByteString.CodedBuilder out = ByteString.newCodedBuilder(raw.getSerializedSize()); 467 CodedOutputStream output = out.getCodedOutput(); 468 List<RawMessageSet.Item> items = raw.getItemList(); 469 for (RawMessageSet.Item item : items) { 470 output.writeTag(1, WireFormat.WIRETYPE_START_GROUP); 471 output.writeBytes(3, item.getMessage()); 472 output.writeInt32(2, item.getTypeId()); 473 output.writeTag(1, WireFormat.WIRETYPE_END_GROUP); 474 } 475 ByteString data = out.build(); 476 477 // Merge bytes into TestMessageSet and check the contents. 478 TestMessageSet messageSet = 479 TestMessageSet.newBuilder().mergeFrom(data, extensionRegistry).build(); 480 assertEquals(123, messageSet.getExtension(TestMessageSetExtension1.messageSetExtension).getI()); 481 } 482 483 // ================================================================ 484 // oneof testOneofWireFormat()485 public void testOneofWireFormat() throws Exception { 486 TestOneof2.Builder builder = TestOneof2.newBuilder(); 487 TestUtil.setOneof(builder); 488 TestOneof2 message = builder.build(); 489 ByteString rawBytes = message.toByteString(); 490 491 assertEquals(rawBytes.size(), message.getSerializedSize()); 492 493 TestOneof2 message2 = TestOneof2.parseFrom(rawBytes); 494 TestUtil.assertOneofSet(message2); 495 } 496 testOneofOnlyLastSet()497 public void testOneofOnlyLastSet() throws Exception { 498 TestOneofBackwardsCompatible source = 499 TestOneofBackwardsCompatible.newBuilder().setFooInt(100).setFooString("101").build(); 500 501 ByteString rawBytes = source.toByteString(); 502 TestOneof2 message = TestOneof2.parseFrom(rawBytes); 503 assertFalse(message.hasFooInt()); 504 assertTrue(message.hasFooString()); 505 } 506 assertInvalidWireFormat( MessageLite defaultInstance, byte[] data, int offset, int length)507 private void assertInvalidWireFormat( 508 MessageLite defaultInstance, byte[] data, int offset, int length) { 509 // Test all combinations: (builder vs parser) x (byte[] vs. InputStream). 510 try { 511 defaultInstance.newBuilderForType().mergeFrom(data, offset, length); 512 fail("Expected exception"); 513 } catch (InvalidProtocolBufferException e) { 514 // Pass. 515 } 516 try { 517 defaultInstance.getParserForType().parseFrom(data, offset, length); 518 fail("Expected exception"); 519 } catch (InvalidProtocolBufferException e) { 520 // Pass. 521 } 522 try { 523 InputStream input = new ByteArrayInputStream(data, offset, length); 524 defaultInstance.newBuilderForType().mergeFrom(input); 525 fail("Expected exception"); 526 } catch (IOException e) { 527 // Pass. 528 } 529 try { 530 InputStream input = new ByteArrayInputStream(data, offset, length); 531 defaultInstance.getParserForType().parseFrom(input); 532 fail("Expected exception"); 533 } catch (IOException e) { 534 // Pass. 535 } 536 } 537 assertInvalidWireFormat(MessageLite defaultInstance, byte[] data)538 private void assertInvalidWireFormat(MessageLite defaultInstance, byte[] data) { 539 assertInvalidWireFormat(defaultInstance, data, 0, data.length); 540 } 541 assertInvalidWireFormat(byte[] data)542 private void assertInvalidWireFormat(byte[] data) { 543 assertInvalidWireFormat(TestAllTypes.getDefaultInstance(), data); 544 assertInvalidWireFormat(UnittestProto3.TestAllTypes.getDefaultInstance(), data); 545 } 546 testParserRejectInvalidTag()547 public void testParserRejectInvalidTag() throws Exception { 548 byte[] invalidTags = 549 new byte[] { 550 // Zero tag is not allowed. 551 0, 552 // Invalid wire types. 553 (byte) WireFormat.makeTag(1, 6), 554 (byte) WireFormat.makeTag(1, 7), 555 // Field number 0 is not allowed. 556 (byte) WireFormat.makeTag(0, WireFormat.WIRETYPE_VARINT), 557 }; 558 for (byte invalidTag : invalidTags) { 559 // Add a trailing 0 to make sure the parsing actually fails on the tag. 560 byte[] data = new byte[] {invalidTag, 0}; 561 assertInvalidWireFormat(data); 562 563 // Invalid tag in an unknown group field. 564 data = 565 new byte[] { 566 (byte) WireFormat.makeTag(1, WireFormat.WIRETYPE_START_GROUP), 567 invalidTag, 568 0, 569 (byte) WireFormat.makeTag(1, WireFormat.WIRETYPE_END_GROUP), 570 }; 571 assertInvalidWireFormat(data); 572 573 // Invalid tag in a MessageSet item. 574 data = 575 new byte[] { 576 (byte) WireFormat.MESSAGE_SET_ITEM_TAG, 577 (byte) WireFormat.MESSAGE_SET_TYPE_ID_TAG, 578 100, // TYPE_ID = 100 579 (byte) WireFormat.MESSAGE_SET_MESSAGE_TAG, 580 0, // empty payload 581 invalidTag, 582 0, 583 (byte) WireFormat.MESSAGE_SET_ITEM_END_TAG, 584 }; 585 assertInvalidWireFormat(TestMessageSet.getDefaultInstance(), data); 586 587 // Invalid tag inside a MessageSet item's unknown group. 588 data = 589 new byte[] { 590 (byte) WireFormat.MESSAGE_SET_ITEM_TAG, 591 (byte) WireFormat.MESSAGE_SET_TYPE_ID_TAG, 592 100, // TYPE_ID = 100 593 (byte) WireFormat.MESSAGE_SET_MESSAGE_TAG, 594 0, // empty payload 595 (byte) WireFormat.makeTag(4, WireFormat.WIRETYPE_START_GROUP), 596 invalidTag, 597 0, 598 (byte) WireFormat.makeTag(4, WireFormat.WIRETYPE_END_GROUP), 599 (byte) WireFormat.MESSAGE_SET_ITEM_END_TAG, 600 }; 601 assertInvalidWireFormat(TestMessageSet.getDefaultInstance(), data); 602 603 // Invalid tag inside a map field. 604 data = 605 new byte[] { 606 (byte) WireFormat.makeTag(1, WireFormat.WIRETYPE_LENGTH_DELIMITED), 2, invalidTag, 0, 607 }; 608 assertInvalidWireFormat(TestMap.getDefaultInstance(), data); 609 } 610 } 611 testUnmatchedGroupTag()612 public void testUnmatchedGroupTag() throws Exception { 613 int startTag = WireFormat.makeTag(16, WireFormat.WIRETYPE_START_GROUP); 614 byte[] data = 615 new byte[] { 616 (byte) ((startTag & 0x7F) | 0x80), (byte) ((startTag >>> 7) & 0x7F), 617 }; 618 assertInvalidWireFormat(data); 619 620 // Unmatched group tags inside a MessageSet item. 621 data = 622 new byte[] { 623 (byte) WireFormat.MESSAGE_SET_ITEM_TAG, 624 (byte) WireFormat.MESSAGE_SET_TYPE_ID_TAG, 625 100, // TYPE_ID = 100 626 (byte) WireFormat.MESSAGE_SET_MESSAGE_TAG, 627 0, // empty payload 628 (byte) WireFormat.makeTag(4, WireFormat.WIRETYPE_START_GROUP), 629 }; 630 assertInvalidWireFormat(TestMessageSet.getDefaultInstance(), data); 631 } 632 assertAccepted(MessageLite defaultInstance, byte[] data)633 private void assertAccepted(MessageLite defaultInstance, byte[] data) throws Exception { 634 MessageLite message1 = defaultInstance.newBuilderForType().mergeFrom(data).build(); 635 MessageLite message2 = defaultInstance.getParserForType().parseFrom(data); 636 MessageLite message3 = 637 defaultInstance.newBuilderForType().mergeFrom(new ByteArrayInputStream(data)).build(); 638 MessageLite message4 = 639 defaultInstance.getParserForType().parseFrom(new ByteArrayInputStream(data)); 640 assertEquals(message1, message2); 641 assertEquals(message2, message3); 642 assertEquals(message3, message4); 643 } 644 testUnmatchedWireType()645 public void testUnmatchedWireType() throws Exception { 646 // Build a payload with all fields from 1 to 128 being varints. Parsing it into TestAllTypes 647 // or other message types should succeed even though the wire type doesn't match for some 648 // fields. 649 ByteArrayOutputStream output = new ByteArrayOutputStream(); 650 CodedOutputStream codedOutput = CodedOutputStream.newInstance(output); 651 for (int i = 1; i <= 128; i++) { 652 codedOutput.writeInt32(i, 0); 653 } 654 codedOutput.flush(); 655 byte[] data = output.toByteArray(); 656 // It can be parsed into any message type that doesn't have required fields. 657 assertAccepted(TestAllTypes.getDefaultInstance(), data); 658 assertAccepted(UnittestProto3.TestAllTypes.getDefaultInstance(), data); 659 assertAccepted(TestMap.getDefaultInstance(), data); 660 assertAccepted(MapForProto2TestProto.TestMap.getDefaultInstance(), data); 661 } 662 testParseTruncatedPackedFields()663 public void testParseTruncatedPackedFields() throws Exception { 664 TestPackedTypes all = TestUtil.getPackedSet(); 665 TestPackedTypes[] messages = 666 new TestPackedTypes[] { 667 TestPackedTypes.newBuilder().addAllPackedInt32(all.getPackedInt32List()).build(), 668 TestPackedTypes.newBuilder().addAllPackedInt64(all.getPackedInt64List()).build(), 669 TestPackedTypes.newBuilder().addAllPackedUint32(all.getPackedUint32List()).build(), 670 TestPackedTypes.newBuilder().addAllPackedUint64(all.getPackedUint64List()).build(), 671 TestPackedTypes.newBuilder().addAllPackedSint32(all.getPackedSint32List()).build(), 672 TestPackedTypes.newBuilder().addAllPackedSint64(all.getPackedSint64List()).build(), 673 TestPackedTypes.newBuilder().addAllPackedFixed32(all.getPackedFixed32List()).build(), 674 TestPackedTypes.newBuilder().addAllPackedFixed64(all.getPackedFixed64List()).build(), 675 TestPackedTypes.newBuilder().addAllPackedSfixed32(all.getPackedSfixed32List()).build(), 676 TestPackedTypes.newBuilder().addAllPackedSfixed64(all.getPackedSfixed64List()).build(), 677 TestPackedTypes.newBuilder().addAllPackedFloat(all.getPackedFloatList()).build(), 678 TestPackedTypes.newBuilder().addAllPackedDouble(all.getPackedDoubleList()).build(), 679 TestPackedTypes.newBuilder().addAllPackedEnum(all.getPackedEnumList()).build(), 680 }; 681 for (TestPackedTypes message : messages) { 682 byte[] data = message.toByteArray(); 683 // Parsing truncated payload should fail. 684 for (int i = 1; i < data.length; i++) { 685 assertInvalidWireFormat(TestPackedTypes.getDefaultInstance(), data, 0, i); 686 } 687 } 688 } 689 testParsePackedFieldsWithIncorrectLength()690 public void testParsePackedFieldsWithIncorrectLength() throws Exception { 691 // Set the length-prefix to 1 with a 4-bytes payload to test what happens when reading a packed 692 // element moves the reading position past the given length limit. It should result in an 693 // InvalidProtocolBufferException but an implementation may forget to check it especially for 694 // packed varint fields. 695 byte[] data = 696 new byte[] { 697 0, 698 0, // first two bytes is reserved for the tag. 699 1, // length is 1 700 (byte) 0x80, 701 (byte) 0x80, 702 (byte) 0x80, 703 (byte) 0x01, // a 4-bytes varint 704 }; 705 // All fields that can read a 4-bytes varint (all varint fields and fixed 32-bit fields). 706 int[] fieldNumbers = 707 new int[] { 708 TestPackedTypes.PACKED_INT32_FIELD_NUMBER, 709 TestPackedTypes.PACKED_INT64_FIELD_NUMBER, 710 TestPackedTypes.PACKED_UINT32_FIELD_NUMBER, 711 TestPackedTypes.PACKED_UINT64_FIELD_NUMBER, 712 TestPackedTypes.PACKED_SINT32_FIELD_NUMBER, 713 TestPackedTypes.PACKED_SINT64_FIELD_NUMBER, 714 TestPackedTypes.PACKED_FIXED32_FIELD_NUMBER, 715 TestPackedTypes.PACKED_SFIXED32_FIELD_NUMBER, 716 TestPackedTypes.PACKED_FLOAT_FIELD_NUMBER, 717 TestPackedTypes.PACKED_BOOL_FIELD_NUMBER, 718 TestPackedTypes.PACKED_ENUM_FIELD_NUMBER, 719 }; 720 for (int number : fieldNumbers) { 721 // Set the tag. 722 data[0] = 723 (byte) ((WireFormat.makeTag(number, WireFormat.WIRETYPE_LENGTH_DELIMITED) & 0x7F) | 0x80); 724 data[1] = 725 (byte) ((WireFormat.makeTag(number, WireFormat.WIRETYPE_LENGTH_DELIMITED) >>> 7) & 0x7F); 726 assertInvalidWireFormat(TestPackedTypes.getDefaultInstance(), data); 727 } 728 729 // Data with 8-bytes payload to test some fixed 64-bit fields. 730 byte[] data8Bytes = 731 new byte[] { 732 0, 733 0, // first two bytes is reserved for the tag. 734 1, // length is 1 735 (byte) 0x80, 736 (byte) 0x80, 737 (byte) 0x80, 738 (byte) 0x80, 739 (byte) 0x80, 740 (byte) 0x80, 741 (byte) 0x80, 742 (byte) 0x01, // a 8-bytes varint 743 }; 744 // All fields that can only read 8-bytes data. 745 int[] fieldNumbers8Bytes = 746 new int[] { 747 TestPackedTypes.PACKED_FIXED64_FIELD_NUMBER, 748 TestPackedTypes.PACKED_SFIXED64_FIELD_NUMBER, 749 TestPackedTypes.PACKED_DOUBLE_FIELD_NUMBER, 750 }; 751 for (int number : fieldNumbers8Bytes) { 752 // Set the tag. 753 data8Bytes[0] = 754 (byte) ((WireFormat.makeTag(number, WireFormat.WIRETYPE_LENGTH_DELIMITED) & 0x7F) | 0x80); 755 data8Bytes[1] = 756 (byte) ((WireFormat.makeTag(number, WireFormat.WIRETYPE_LENGTH_DELIMITED) >>> 7) & 0x7F); 757 assertInvalidWireFormat(TestPackedTypes.getDefaultInstance(), data8Bytes); 758 } 759 } 760 testParseVarintMinMax()761 public void testParseVarintMinMax() throws Exception { 762 TestAllTypes message = 763 TestAllTypes.newBuilder() 764 .setOptionalInt32(Integer.MIN_VALUE) 765 .addRepeatedInt32(Integer.MAX_VALUE) 766 .setOptionalInt64(Long.MIN_VALUE) 767 .addRepeatedInt64(Long.MAX_VALUE) 768 .build(); 769 TestAllTypes parsed = TestAllTypes.parseFrom(message.toByteArray()); 770 assertEquals(Integer.MIN_VALUE, parsed.getOptionalInt32()); 771 assertEquals(Integer.MAX_VALUE, parsed.getRepeatedInt32(0)); 772 assertEquals(Long.MIN_VALUE, parsed.getOptionalInt64()); 773 assertEquals(Long.MAX_VALUE, parsed.getRepeatedInt64(0)); 774 } 775 testParseAllVarintBits()776 public void testParseAllVarintBits() throws Exception { 777 for (int i = 0; i < 32; i++) { 778 final int value = 1 << i; 779 TestAllTypes message = TestAllTypes.newBuilder().setOptionalInt32(value).build(); 780 TestAllTypes parsed = TestAllTypes.parseFrom(message.toByteArray()); 781 assertEquals(value, parsed.getOptionalInt32()); 782 } 783 for (int i = 0; i < 64; i++) { 784 final long value = 1L << i; 785 TestAllTypes message = TestAllTypes.newBuilder().setOptionalInt64(value).build(); 786 TestAllTypes parsed = TestAllTypes.parseFrom(message.toByteArray()); 787 assertEquals(value, parsed.getOptionalInt64()); 788 } 789 } 790 testParseEmptyUnknownLengthDelimitedField()791 public void testParseEmptyUnknownLengthDelimitedField() throws Exception { 792 byte[] data = 793 new byte[] {(byte) WireFormat.makeTag(1, WireFormat.WIRETYPE_LENGTH_DELIMITED), 0}; 794 TestAllTypes parsed = TestAllTypes.parseFrom(data); 795 assertTrue(Arrays.equals(data, parsed.toByteArray())); 796 } 797 testParseEmptyString()798 public void testParseEmptyString() throws Exception { 799 TestAllTypes message = TestAllTypes.newBuilder().setOptionalString("").build(); 800 TestAllTypes parsed = TestAllTypes.parseFrom(message.toByteArray()); 801 assertEquals("", parsed.getOptionalString()); 802 } 803 testParseEmptyStringProto3()804 public void testParseEmptyStringProto3() throws Exception { 805 TestAllTypes message = TestAllTypes.newBuilder().setOptionalString("").build(); 806 // Note that we are parsing from a proto2 proto to a proto3 proto because empty string field is 807 // not serialized in proto3. 808 UnittestProto3.TestAllTypes parsed = 809 UnittestProto3.TestAllTypes.parseFrom(message.toByteArray()); 810 assertEquals("", parsed.getOptionalString()); 811 } 812 testParseEmptyBytes()813 public void testParseEmptyBytes() throws Exception { 814 TestAllTypes message = TestAllTypes.newBuilder().setOptionalBytes(ByteString.EMPTY).build(); 815 TestAllTypes parsed = TestAllTypes.parseFrom(message.toByteArray()); 816 assertEquals(ByteString.EMPTY, parsed.getOptionalBytes()); 817 } 818 testParseEmptyRepeatedStringField()819 public void testParseEmptyRepeatedStringField() throws Exception { 820 TestAllTypes message = 821 TestAllTypes.newBuilder() 822 .addRepeatedString("") 823 .addRepeatedString("") 824 .addRepeatedString("0") 825 .build(); 826 TestAllTypes parsed = TestAllTypes.parseFrom(message.toByteArray()); 827 assertEquals(3, parsed.getRepeatedStringCount()); 828 assertEquals("", parsed.getRepeatedString(0)); 829 assertEquals("", parsed.getRepeatedString(1)); 830 assertEquals("0", parsed.getRepeatedString(2)); 831 } 832 testParseEmptyRepeatedStringFieldProto3()833 public void testParseEmptyRepeatedStringFieldProto3() throws Exception { 834 TestAllTypes message = 835 TestAllTypes.newBuilder() 836 .addRepeatedString("") 837 .addRepeatedString("") 838 .addRepeatedString("0") 839 .addRepeatedBytes(ByteString.EMPTY) 840 .build(); 841 UnittestProto3.TestAllTypes parsed = 842 UnittestProto3.TestAllTypes.parseFrom(message.toByteArray()); 843 assertEquals(3, parsed.getRepeatedStringCount()); 844 assertEquals("", parsed.getRepeatedString(0)); 845 assertEquals("", parsed.getRepeatedString(1)); 846 assertEquals("0", parsed.getRepeatedString(2)); 847 } 848 testParseEmptyRepeatedBytesField()849 public void testParseEmptyRepeatedBytesField() throws Exception { 850 ByteString oneByte = ByteString.copyFrom(new byte[] {1}); 851 TestAllTypes message = 852 TestAllTypes.newBuilder() 853 .addRepeatedBytes(ByteString.EMPTY) 854 .addRepeatedBytes(ByteString.EMPTY) 855 .addRepeatedBytes(oneByte) 856 .build(); 857 TestAllTypes parsed = TestAllTypes.parseFrom(message.toByteArray()); 858 assertEquals(3, parsed.getRepeatedBytesCount()); 859 assertEquals(ByteString.EMPTY, parsed.getRepeatedBytes(0)); 860 assertEquals(ByteString.EMPTY, parsed.getRepeatedBytes(1)); 861 assertEquals(oneByte, parsed.getRepeatedBytes(2)); 862 } 863 testSkipUnknownFieldInMessageSetItem()864 public void testSkipUnknownFieldInMessageSetItem() throws Exception { 865 ByteArrayOutputStream output = new ByteArrayOutputStream(); 866 // MessageSet item's start tag. 867 output.write((byte) WireFormat.MESSAGE_SET_ITEM_TAG); 868 // Put all field types into the item. 869 TestUtil.getAllSet().writeTo(output); 870 // Closing the item with the real payload and closing tag. 871 output.write( 872 new byte[] { 873 (byte) WireFormat.MESSAGE_SET_TYPE_ID_TAG, 874 100, // TYPE_ID = 100 875 (byte) WireFormat.MESSAGE_SET_MESSAGE_TAG, 876 0, // empty payload 877 (byte) WireFormat.MESSAGE_SET_ITEM_END_TAG, 878 }); 879 byte[] data = output.toByteArray(); 880 TestMessageSet parsed = TestMessageSet.parseFrom(data); 881 882 // Convert to RawMessageSet for inspection. 883 RawMessageSet raw = RawMessageSet.parseFrom(parsed.toByteArray()); 884 assertEquals(1, raw.getItemCount()); 885 assertEquals(100, raw.getItem(0).getTypeId()); 886 assertEquals(0, raw.getItem(0).getMessage().size()); 887 } 888 testProto2UnknownEnumValuesInOptionalField()889 public void testProto2UnknownEnumValuesInOptionalField() throws Exception { 890 // Proto2 doesn't allow setting unknown enum values so we use proto3 to build a message with 891 // unknown enum values 892 UnittestProto3.TestAllTypes message = 893 UnittestProto3.TestAllTypes.newBuilder().setOptionalNestedEnumValue(4321).build(); 894 TestAllTypes parsed = TestAllTypes.parseFrom(message.toByteArray()); 895 assertFalse(parsed.hasOptionalNestedEnum()); 896 // Make sure unknown enum values are preserved. 897 UnittestProto3.TestAllTypes actual = 898 UnittestProto3.TestAllTypes.parseFrom(parsed.toByteArray()); 899 assertEquals(4321, actual.getOptionalNestedEnumValue()); 900 } 901 testProto2UnknownEnumValuesInRepeatedField()902 public void testProto2UnknownEnumValuesInRepeatedField() throws Exception { 903 // Proto2 doesn't allow setting unknown enum values so we use proto3 to build a message with 904 // unknown enum values 905 UnittestProto3.TestAllTypes message = 906 UnittestProto3.TestAllTypes.newBuilder().addRepeatedNestedEnumValue(5432).build(); 907 TestAllTypes parsed = TestAllTypes.parseFrom(message.toByteArray()); 908 assertEquals(0, parsed.getRepeatedNestedEnumCount()); 909 // Make sure unknown enum values are preserved. 910 UnittestProto3.TestAllTypes actual = 911 UnittestProto3.TestAllTypes.parseFrom(parsed.toByteArray()); 912 assertEquals(1, actual.getRepeatedNestedEnumCount()); 913 assertEquals(5432, actual.getRepeatedNestedEnumValue(0)); 914 } 915 testProto2UnknownEnumValuesInMapField()916 public void testProto2UnknownEnumValuesInMapField() throws Exception { 917 // Proto2 doesn't allow setting unknown enum values so we use proto3 to build a message with 918 // unknown enum values 919 TestMap message = TestMap.newBuilder().putInt32ToEnumFieldValue(1, 4321).build(); 920 MapForProto2TestProto.TestMap parsed = 921 MapForProto2TestProto.TestMap.parseFrom(message.toByteArray()); 922 assertEquals(0, parsed.getInt32ToEnumFieldMap().size()); 923 // Make sure unknown enum values are preserved. 924 TestMap actual = TestMap.parseFrom(parsed.toByteArray()); 925 assertEquals(1, actual.getInt32ToEnumFieldMap().size()); 926 assertEquals(4321, actual.getInt32ToEnumFieldValueOrThrow(1)); 927 } 928 testProto2UnknownEnumValuesInOneof()929 public void testProto2UnknownEnumValuesInOneof() throws Exception { 930 // Proto2 doesn't allow setting unknown enum values so we use proto3 to build a message with 931 // unknown enum values 932 UnittestProto3.TestOneof2 message = 933 UnittestProto3.TestOneof2.newBuilder().setFooEnumValue(1234).build(); 934 TestOneof2 parsed = TestOneof2.parseFrom(message.toByteArray()); 935 assertFalse(parsed.hasFooEnum()); 936 // Make sure unknown enum values are preserved. 937 UnittestProto3.TestOneof2 actual = UnittestProto3.TestOneof2.parseFrom(parsed.toByteArray()); 938 assertEquals(1234, actual.getFooEnumValue()); 939 } 940 testProto2UnknownEnumValuesInExtension()941 public void testProto2UnknownEnumValuesInExtension() throws Exception { 942 ExtensionRegistryLite extensionRegistry = TestUtilLite.getExtensionRegistryLite(); 943 // Raw bytes for "[.optional_foreign_enum_extension_lite]: 10" 944 final byte[] rawBytes = new byte[]{-80, 1, 10}; 945 TestAllExtensionsLite testAllExtensionsLite = 946 TestAllExtensionsLite.parseFrom(rawBytes, extensionRegistry); 947 assertEquals(ForeignEnumLite.FOREIGN_LITE_FOO, 948 testAllExtensionsLite.getExtension(optionalForeignEnumExtensionLite)); 949 final byte[] resultRawBytes = testAllExtensionsLite.toByteArray(); 950 assertEquals(rawBytes.length, resultRawBytes.length); 951 for (int i = 0; i < rawBytes.length; i++) { 952 assertEquals(rawBytes[i], resultRawBytes[i]); 953 } 954 } 955 testProto3UnknownEnumValuesInOptionalField()956 public void testProto3UnknownEnumValuesInOptionalField() throws Exception { 957 UnittestProto3.TestAllTypes message = 958 UnittestProto3.TestAllTypes.newBuilder().setOptionalNestedEnumValue(4321).build(); 959 UnittestProto3.TestAllTypes parsed = 960 UnittestProto3.TestAllTypes.parseFrom(message.toByteArray()); 961 assertEquals(4321, parsed.getOptionalNestedEnumValue()); 962 } 963 testProto3UnknownEnumValuesInRepeatedField()964 public void testProto3UnknownEnumValuesInRepeatedField() throws Exception { 965 UnittestProto3.TestAllTypes message = 966 UnittestProto3.TestAllTypes.newBuilder().addRepeatedNestedEnumValue(5432).build(); 967 UnittestProto3.TestAllTypes parsed = 968 UnittestProto3.TestAllTypes.parseFrom(message.toByteArray()); 969 assertEquals(1, parsed.getRepeatedNestedEnumCount()); 970 assertEquals(5432, parsed.getRepeatedNestedEnumValue(0)); 971 } 972 testProto3UnknownEnumValuesInMapField()973 public void testProto3UnknownEnumValuesInMapField() throws Exception { 974 TestMap message = TestMap.newBuilder().putInt32ToEnumFieldValue(1, 4321).build(); 975 TestMap parsed = TestMap.parseFrom(message.toByteArray()); 976 assertEquals(1, parsed.getInt32ToEnumFieldMap().size()); 977 assertEquals(4321, parsed.getInt32ToEnumFieldValueOrThrow(1)); 978 } 979 testProto3UnknownEnumValuesInOneof()980 public void testProto3UnknownEnumValuesInOneof() throws Exception { 981 UnittestProto3.TestOneof2 message = 982 UnittestProto3.TestOneof2.newBuilder().setFooEnumValue(1234).build(); 983 UnittestProto3.TestOneof2 parsed = UnittestProto3.TestOneof2.parseFrom(message.toByteArray()); 984 assertEquals(1234, parsed.getFooEnumValue()); 985 } 986 testProto3MessageFieldMergeBehavior()987 public void testProto3MessageFieldMergeBehavior() throws Exception { 988 UnittestProto3.NestedTestAllTypes message1 = 989 UnittestProto3.NestedTestAllTypes.newBuilder() 990 .setPayload( 991 UnittestProto3.TestAllTypes.newBuilder() 992 .setOptionalInt32(1234) 993 .setOptionalInt64(5678)) 994 .build(); 995 UnittestProto3.NestedTestAllTypes message2 = 996 UnittestProto3.NestedTestAllTypes.newBuilder() 997 .setPayload( 998 UnittestProto3.TestAllTypes.newBuilder() 999 .setOptionalInt32(4321) 1000 .setOptionalUint32(8765)) 1001 .build(); 1002 1003 UnittestProto3.NestedTestAllTypes merged = 1004 UnittestProto3.NestedTestAllTypes.newBuilder() 1005 .mergeFrom(message1.toByteArray()) 1006 .mergeFrom(message2.toByteArray()) 1007 .build(); 1008 // Field values coming later in the stream override earlier values. 1009 assertEquals(4321, merged.getPayload().getOptionalInt32()); 1010 // Field values present in either message should be present in the merged result. 1011 assertEquals(5678, merged.getPayload().getOptionalInt64()); 1012 assertEquals(8765, merged.getPayload().getOptionalUint32()); 1013 } 1014 testMergeFromPartialByteArray()1015 public void testMergeFromPartialByteArray() throws Exception { 1016 byte[] data = TestUtil.getAllSet().toByteArray(); 1017 byte[] dataWithPaddings = new byte[data.length + 2]; 1018 System.arraycopy(data, 0, dataWithPaddings, 1, data.length); 1019 // Parsing will fail if the builder (or parser) interprets offset or length incorrectly. 1020 TestAllTypes.newBuilder().mergeFrom(dataWithPaddings, 1, data.length); 1021 TestAllTypes.parser().parseFrom(dataWithPaddings, 1, data.length); 1022 } 1023 } 1024