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 org.junit.Assert.assertArrayEquals; 34 35 import com.google.protobuf.Descriptors.Descriptor; 36 import com.google.protobuf.Descriptors.EnumDescriptor; 37 import com.google.protobuf.Descriptors.EnumValueDescriptor; 38 import com.google.protobuf.Descriptors.FieldDescriptor; 39 import map_test.MapTestProto.BizarroTestMap; 40 import map_test.MapTestProto.ReservedAsMapField; 41 import map_test.MapTestProto.ReservedAsMapFieldWithEnumValue; 42 import map_test.MapTestProto.TestMap; 43 import map_test.MapTestProto.TestMap.MessageValue; 44 import map_test.MapTestProto.TestMapOrBuilder; 45 import map_test.MapTestProto.TestOnChangeEventPropagation; 46 import java.io.ByteArrayOutputStream; 47 import java.io.IOException; 48 import java.util.ArrayList; 49 import java.util.Arrays; 50 import java.util.HashMap; 51 import java.util.List; 52 import java.util.Map; 53 import junit.framework.TestCase; 54 55 /** Unit tests for map fields. */ 56 public class MapTest extends TestCase { 57 setMapValuesUsingMutableMap(TestMap.Builder builder)58 private void setMapValuesUsingMutableMap(TestMap.Builder builder) { 59 builder.getMutableInt32ToInt32Field().put(1, 11); 60 builder.getMutableInt32ToInt32Field().put(2, 22); 61 builder.getMutableInt32ToInt32Field().put(3, 33); 62 // 63 builder.getMutableInt32ToStringField().put(1, "11"); 64 builder.getMutableInt32ToStringField().put(2, "22"); 65 builder.getMutableInt32ToStringField().put(3, "33"); 66 // 67 builder.getMutableInt32ToBytesField().put(1, TestUtil.toBytes("11")); 68 builder.getMutableInt32ToBytesField().put(2, TestUtil.toBytes("22")); 69 builder.getMutableInt32ToBytesField().put(3, TestUtil.toBytes("33")); 70 // 71 builder.getMutableInt32ToEnumField().put(1, TestMap.EnumValue.FOO); 72 builder.getMutableInt32ToEnumField().put(2, TestMap.EnumValue.BAR); 73 builder.getMutableInt32ToEnumField().put(3, TestMap.EnumValue.BAZ); 74 // 75 builder.getMutableInt32ToMessageField().put( 76 1, MessageValue.newBuilder().setValue(11).build()); 77 builder.getMutableInt32ToMessageField().put( 78 2, MessageValue.newBuilder().setValue(22).build()); 79 builder.getMutableInt32ToMessageField().put( 80 3, MessageValue.newBuilder().setValue(33).build()); 81 // 82 builder.getMutableStringToInt32Field().put("1", 11); 83 builder.getMutableStringToInt32Field().put("2", 22); 84 builder.getMutableStringToInt32Field().put("3", 33); 85 } 86 setMapValuesUsingAccessors(TestMap.Builder builder)87 private void setMapValuesUsingAccessors(TestMap.Builder builder) { 88 builder 89 .putInt32ToInt32Field(1, 11) 90 .putInt32ToInt32Field(2, 22) 91 .putInt32ToInt32Field(3, 33) 92 .putInt32ToStringField(1, "11") 93 .putInt32ToStringField(2, "22") 94 .putInt32ToStringField(3, "33") 95 .putInt32ToBytesField(1, TestUtil.toBytes("11")) 96 .putInt32ToBytesField(2, TestUtil.toBytes("22")) 97 .putInt32ToBytesField(3, TestUtil.toBytes("33")) 98 .putInt32ToEnumField(1, TestMap.EnumValue.FOO) 99 .putInt32ToEnumField(2, TestMap.EnumValue.BAR) 100 .putInt32ToEnumField(3, TestMap.EnumValue.BAZ) 101 .putInt32ToMessageField(1, MessageValue.newBuilder().setValue(11).build()) 102 .putInt32ToMessageField(2, MessageValue.newBuilder().setValue(22).build()) 103 .putInt32ToMessageField(3, MessageValue.newBuilder().setValue(33).build()) 104 .putStringToInt32Field("1", 11) 105 .putStringToInt32Field("2", 22) 106 .putStringToInt32Field("3", 33); 107 } 108 testSetMapValues()109 public void testSetMapValues() { 110 TestMap.Builder usingMutableMapBuilder = TestMap.newBuilder(); 111 setMapValuesUsingMutableMap(usingMutableMapBuilder); 112 TestMap usingMutableMap = usingMutableMapBuilder.build(); 113 assertMapValuesSet(usingMutableMap); 114 115 TestMap.Builder usingAccessorsBuilder = TestMap.newBuilder(); 116 setMapValuesUsingAccessors(usingAccessorsBuilder); 117 TestMap usingAccessors = usingAccessorsBuilder.build(); 118 assertMapValuesSet(usingAccessors); 119 120 assertEquals(usingAccessors, usingMutableMap); 121 } 122 copyMapValues(TestMap source, TestMap.Builder destination)123 private void copyMapValues(TestMap source, TestMap.Builder destination) { 124 destination 125 .putAllInt32ToInt32Field(source.getInt32ToInt32FieldMap()) 126 .putAllInt32ToStringField(source.getInt32ToStringFieldMap()) 127 .putAllInt32ToBytesField(source.getInt32ToBytesFieldMap()) 128 .putAllInt32ToEnumField(source.getInt32ToEnumFieldMap()) 129 .putAllInt32ToMessageField(source.getInt32ToMessageFieldMap()) 130 .putAllStringToInt32Field(source.getStringToInt32FieldMap()); 131 } 132 assertMapValuesSet(TestMap message)133 private void assertMapValuesSet(TestMap message) { 134 assertEquals(3, message.getInt32ToInt32FieldMap().size()); 135 assertEquals(11, message.getInt32ToInt32FieldMap().get(1).intValue()); 136 assertEquals(22, message.getInt32ToInt32FieldMap().get(2).intValue()); 137 assertEquals(33, message.getInt32ToInt32FieldMap().get(3).intValue()); 138 139 assertEquals(3, message.getInt32ToStringFieldMap().size()); 140 assertEquals("11", message.getInt32ToStringFieldMap().get(1)); 141 assertEquals("22", message.getInt32ToStringFieldMap().get(2)); 142 assertEquals("33", message.getInt32ToStringFieldMap().get(3)); 143 144 assertEquals(3, message.getInt32ToBytesFieldMap().size()); 145 assertEquals(TestUtil.toBytes("11"), message.getInt32ToBytesFieldMap().get(1)); 146 assertEquals(TestUtil.toBytes("22"), message.getInt32ToBytesFieldMap().get(2)); 147 assertEquals(TestUtil.toBytes("33"), message.getInt32ToBytesFieldMap().get(3)); 148 149 assertEquals(3, message.getInt32ToEnumFieldMap().size()); 150 assertEquals(TestMap.EnumValue.FOO, message.getInt32ToEnumFieldMap().get(1)); 151 assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumFieldMap().get(2)); 152 assertEquals(TestMap.EnumValue.BAZ, message.getInt32ToEnumFieldMap().get(3)); 153 154 assertEquals(3, message.getInt32ToMessageFieldMap().size()); 155 assertEquals(11, message.getInt32ToMessageFieldMap().get(1).getValue()); 156 assertEquals(22, message.getInt32ToMessageFieldMap().get(2).getValue()); 157 assertEquals(33, message.getInt32ToMessageFieldMap().get(3).getValue()); 158 159 assertEquals(3, message.getStringToInt32FieldMap().size()); 160 assertEquals(11, message.getStringToInt32FieldMap().get("1").intValue()); 161 assertEquals(22, message.getStringToInt32FieldMap().get("2").intValue()); 162 assertEquals(33, message.getStringToInt32FieldMap().get("3").intValue()); 163 } 164 updateMapValuesUsingMutableMap(TestMap.Builder builder)165 private void updateMapValuesUsingMutableMap(TestMap.Builder builder) { 166 builder.getMutableInt32ToInt32Field().put(1, 111); 167 builder.getMutableInt32ToInt32Field().remove(2); 168 builder.getMutableInt32ToInt32Field().put(4, 44); 169 // 170 builder.getMutableInt32ToStringField().put(1, "111"); 171 builder.getMutableInt32ToStringField().remove(2); 172 builder.getMutableInt32ToStringField().put(4, "44"); 173 // 174 builder.getMutableInt32ToBytesField().put(1, TestUtil.toBytes("111")); 175 builder.getMutableInt32ToBytesField().remove(2); 176 builder.getMutableInt32ToBytesField().put(4, TestUtil.toBytes("44")); 177 // 178 builder.getMutableInt32ToEnumField().put(1, TestMap.EnumValue.BAR); 179 builder.getMutableInt32ToEnumField().remove(2); 180 builder.getMutableInt32ToEnumField().put(4, TestMap.EnumValue.QUX); 181 // 182 builder.getMutableInt32ToMessageField().put( 183 1, MessageValue.newBuilder().setValue(111).build()); 184 builder.getMutableInt32ToMessageField().remove(2); 185 builder.getMutableInt32ToMessageField().put( 186 4, MessageValue.newBuilder().setValue(44).build()); 187 // 188 builder.getMutableStringToInt32Field().put("1", 111); 189 builder.getMutableStringToInt32Field().remove("2"); 190 builder.getMutableStringToInt32Field().put("4", 44); 191 } 192 updateMapValuesUsingAccessors(TestMap.Builder builder)193 private void updateMapValuesUsingAccessors(TestMap.Builder builder) { 194 builder 195 .putInt32ToInt32Field(1, 111) 196 .removeInt32ToInt32Field(2) 197 .putInt32ToInt32Field(4, 44) 198 .putInt32ToStringField(1, "111") 199 .removeInt32ToStringField(2) 200 .putInt32ToStringField(4, "44") 201 .putInt32ToBytesField(1, TestUtil.toBytes("111")) 202 .removeInt32ToBytesField(2) 203 .putInt32ToBytesField(4, TestUtil.toBytes("44")) 204 .putInt32ToEnumField(1, TestMap.EnumValue.BAR) 205 .removeInt32ToEnumField(2) 206 .putInt32ToEnumField(4, TestMap.EnumValue.QUX) 207 .putInt32ToMessageField(1, MessageValue.newBuilder().setValue(111).build()) 208 .removeInt32ToMessageField(2) 209 .putInt32ToMessageField(4, MessageValue.newBuilder().setValue(44).build()) 210 .putStringToInt32Field("1", 111) 211 .removeStringToInt32Field("2") 212 .putStringToInt32Field("4", 44); 213 } 214 testUpdateMapValues()215 public void testUpdateMapValues() { 216 TestMap.Builder usingMutableMapBuilder = TestMap.newBuilder(); 217 setMapValuesUsingMutableMap(usingMutableMapBuilder); 218 TestMap usingMutableMap = usingMutableMapBuilder.build(); 219 assertMapValuesSet(usingMutableMap); 220 221 TestMap.Builder usingAccessorsBuilder = TestMap.newBuilder(); 222 setMapValuesUsingAccessors(usingAccessorsBuilder); 223 TestMap usingAccessors = usingAccessorsBuilder.build(); 224 assertMapValuesSet(usingAccessors); 225 226 assertEquals(usingAccessors, usingMutableMap); 227 // 228 usingMutableMapBuilder = usingMutableMap.toBuilder(); 229 updateMapValuesUsingMutableMap(usingMutableMapBuilder); 230 usingMutableMap = usingMutableMapBuilder.build(); 231 assertMapValuesUpdated(usingMutableMap); 232 233 usingAccessorsBuilder = usingAccessors.toBuilder(); 234 updateMapValuesUsingAccessors(usingAccessorsBuilder); 235 usingAccessors = usingAccessorsBuilder.build(); 236 assertMapValuesUpdated(usingAccessors); 237 238 assertEquals(usingAccessors, usingMutableMap); 239 } 240 assertMapValuesUpdated(TestMap message)241 private void assertMapValuesUpdated(TestMap message) { 242 assertEquals(3, message.getInt32ToInt32FieldMap().size()); 243 assertEquals(111, message.getInt32ToInt32FieldMap().get(1).intValue()); 244 assertEquals(33, message.getInt32ToInt32FieldMap().get(3).intValue()); 245 assertEquals(44, message.getInt32ToInt32FieldMap().get(4).intValue()); 246 247 assertEquals(3, message.getInt32ToStringFieldMap().size()); 248 assertEquals("111", message.getInt32ToStringFieldMap().get(1)); 249 assertEquals("33", message.getInt32ToStringFieldMap().get(3)); 250 assertEquals("44", message.getInt32ToStringFieldMap().get(4)); 251 252 assertEquals(3, message.getInt32ToBytesFieldMap().size()); 253 assertEquals(TestUtil.toBytes("111"), message.getInt32ToBytesFieldMap().get(1)); 254 assertEquals(TestUtil.toBytes("33"), message.getInt32ToBytesFieldMap().get(3)); 255 assertEquals(TestUtil.toBytes("44"), message.getInt32ToBytesFieldMap().get(4)); 256 257 assertEquals(3, message.getInt32ToEnumFieldMap().size()); 258 assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumFieldMap().get(1)); 259 assertEquals(TestMap.EnumValue.BAZ, message.getInt32ToEnumFieldMap().get(3)); 260 assertEquals(TestMap.EnumValue.QUX, message.getInt32ToEnumFieldMap().get(4)); 261 262 assertEquals(3, message.getInt32ToMessageFieldMap().size()); 263 assertEquals(111, message.getInt32ToMessageFieldMap().get(1).getValue()); 264 assertEquals(33, message.getInt32ToMessageFieldMap().get(3).getValue()); 265 assertEquals(44, message.getInt32ToMessageFieldMap().get(4).getValue()); 266 267 assertEquals(3, message.getStringToInt32FieldMap().size()); 268 assertEquals(111, message.getStringToInt32FieldMap().get("1").intValue()); 269 assertEquals(33, message.getStringToInt32FieldMap().get("3").intValue()); 270 assertEquals(44, message.getStringToInt32FieldMap().get("4").intValue()); 271 } 272 assertMapValuesCleared(TestMapOrBuilder testMapOrBuilder)273 private void assertMapValuesCleared(TestMapOrBuilder testMapOrBuilder) { 274 assertEquals(0, testMapOrBuilder.getInt32ToInt32Field().size()); 275 assertEquals(0, testMapOrBuilder.getInt32ToInt32FieldCount()); 276 assertEquals(0, testMapOrBuilder.getInt32ToStringField().size()); 277 assertEquals(0, testMapOrBuilder.getInt32ToStringFieldCount()); 278 assertEquals(0, testMapOrBuilder.getInt32ToBytesField().size()); 279 assertEquals(0, testMapOrBuilder.getInt32ToBytesFieldCount()); 280 assertEquals(0, testMapOrBuilder.getInt32ToEnumField().size()); 281 assertEquals(0, testMapOrBuilder.getInt32ToEnumFieldCount()); 282 assertEquals(0, testMapOrBuilder.getInt32ToMessageField().size()); 283 assertEquals(0, testMapOrBuilder.getInt32ToMessageFieldCount()); 284 assertEquals(0, testMapOrBuilder.getStringToInt32Field().size()); 285 assertEquals(0, testMapOrBuilder.getStringToInt32FieldCount()); 286 } 287 testGetMapIsImmutable()288 public void testGetMapIsImmutable() { 289 TestMap.Builder builder = TestMap.newBuilder(); 290 assertMapsAreImmutable(builder); 291 assertMapsAreImmutable(builder.build()); 292 293 setMapValuesUsingAccessors(builder); 294 assertMapsAreImmutable(builder); 295 assertMapsAreImmutable(builder.build()); 296 } 297 assertMapsAreImmutable(TestMapOrBuilder testMapOrBuilder)298 private void assertMapsAreImmutable(TestMapOrBuilder testMapOrBuilder) { 299 assertImmutable(testMapOrBuilder.getInt32ToInt32Field(), 1, 2); 300 assertImmutable(testMapOrBuilder.getInt32ToStringField(), 1, "2"); 301 assertImmutable(testMapOrBuilder.getInt32ToBytesField(), 1, TestUtil.toBytes("2")); 302 assertImmutable(testMapOrBuilder.getInt32ToEnumField(), 1, TestMap.EnumValue.FOO); 303 assertImmutable( 304 testMapOrBuilder.getInt32ToMessageField(), 1, MessageValue.getDefaultInstance()); 305 assertImmutable(testMapOrBuilder.getStringToInt32Field(), "1", 2); 306 } 307 assertImmutable(Map<K, V> map, K key, V value)308 private <K, V> void assertImmutable(Map<K, V> map, K key, V value) { 309 try { 310 map.put(key, value); 311 fail(); 312 } catch (UnsupportedOperationException e) { 313 // expected 314 } 315 } 316 testMutableMapLifecycle()317 public void testMutableMapLifecycle() { 318 TestMap.Builder builder = TestMap.newBuilder(); 319 Map<Integer, Integer> intMap = builder.getMutableInt32ToInt32Field(); 320 intMap.put(1, 2); 321 assertEquals(newMap(1, 2), builder.build().getInt32ToInt32Field()); 322 try { 323 intMap.put(2, 3); 324 fail(); 325 } catch (UnsupportedOperationException e) { 326 // expected 327 } 328 assertEquals(newMap(1, 2), builder.getInt32ToInt32Field()); 329 builder.getMutableInt32ToInt32Field().put(2, 3); 330 assertEquals(newMap(1, 2, 2, 3), builder.getInt32ToInt32Field()); 331 // 332 Map<Integer, TestMap.EnumValue> enumMap = builder.getMutableInt32ToEnumField(); 333 enumMap.put(1, TestMap.EnumValue.BAR); 334 assertEquals(newMap(1, TestMap.EnumValue.BAR), builder.build().getInt32ToEnumField()); 335 try { 336 enumMap.put(2, TestMap.EnumValue.FOO); 337 fail(); 338 } catch (UnsupportedOperationException e) { 339 // expected 340 } 341 assertEquals(newMap(1, TestMap.EnumValue.BAR), builder.getInt32ToEnumField()); 342 builder.getMutableInt32ToEnumField().put(2, TestMap.EnumValue.FOO); 343 assertEquals( 344 newMap(1, TestMap.EnumValue.BAR, 2, TestMap.EnumValue.FOO), 345 builder.getInt32ToEnumField()); 346 // 347 Map<Integer, String> stringMap = builder.getMutableInt32ToStringField(); 348 stringMap.put(1, "1"); 349 assertEquals(newMap(1, "1"), builder.build().getInt32ToStringField()); 350 try { 351 stringMap.put(2, "2"); 352 fail(); 353 } catch (UnsupportedOperationException e) { 354 // expected 355 } 356 assertEquals(newMap(1, "1"), builder.getInt32ToStringField()); 357 builder.putInt32ToStringField(2, "2"); 358 assertEquals( 359 newMap(1, "1", 2, "2"), 360 builder.getInt32ToStringField()); 361 // 362 Map<Integer, TestMap.MessageValue> messageMap = builder.getMutableInt32ToMessageField(); 363 messageMap.put(1, TestMap.MessageValue.getDefaultInstance()); 364 assertEquals(newMap(1, TestMap.MessageValue.getDefaultInstance()), 365 builder.build().getInt32ToMessageField()); 366 try { 367 messageMap.put(2, TestMap.MessageValue.getDefaultInstance()); 368 fail(); 369 } catch (UnsupportedOperationException e) { 370 // expected 371 } 372 assertEquals(newMap(1, TestMap.MessageValue.getDefaultInstance()), 373 builder.getInt32ToMessageField()); 374 builder.putInt32ToMessageField(2, TestMap.MessageValue.getDefaultInstance()); 375 assertEquals( 376 newMap(1, TestMap.MessageValue.getDefaultInstance(), 377 2, TestMap.MessageValue.getDefaultInstance()), 378 builder.getInt32ToMessageField()); 379 } 380 // testMutableMapLifecycle_collections()381 public void testMutableMapLifecycle_collections() { 382 TestMap.Builder builder = TestMap.newBuilder(); 383 Map<Integer, Integer> intMap = builder.getMutableInt32ToInt32Field(); 384 intMap.put(1, 2); 385 assertEquals(newMap(1, 2), builder.build().getInt32ToInt32Field()); 386 try { 387 intMap.remove(2); 388 fail(); 389 } catch (UnsupportedOperationException e) { 390 // expected 391 } 392 try { 393 intMap.entrySet().remove(new Object()); 394 fail(); 395 } catch (UnsupportedOperationException e) { 396 // expected 397 } 398 try { 399 intMap.entrySet().iterator().remove(); 400 fail(); 401 } catch (UnsupportedOperationException e) { 402 // expected 403 } 404 try { 405 intMap.keySet().remove(new Object()); 406 fail(); 407 } catch (UnsupportedOperationException e) { 408 // expected 409 } 410 try { 411 intMap.values().remove(new Object()); 412 fail(); 413 } catch (UnsupportedOperationException e) { 414 // expected 415 } 416 try { 417 intMap.values().iterator().remove(); 418 fail(); 419 } catch (UnsupportedOperationException e) { 420 // expected 421 } 422 assertEquals(newMap(1, 2), intMap); 423 assertEquals(newMap(1, 2), builder.getInt32ToInt32Field()); 424 assertEquals(newMap(1, 2), builder.build().getInt32ToInt32Field()); 425 } 426 testGettersAndSetters()427 public void testGettersAndSetters() throws Exception { 428 TestMap.Builder builder = TestMap.newBuilder(); 429 TestMap message = builder.build(); 430 assertMapValuesCleared(message); 431 432 builder = message.toBuilder(); 433 setMapValuesUsingAccessors(builder); 434 message = builder.build(); 435 assertMapValuesSet(message); 436 437 builder = message.toBuilder(); 438 updateMapValuesUsingAccessors(builder); 439 message = builder.build(); 440 assertMapValuesUpdated(message); 441 442 builder = message.toBuilder(); 443 builder.clear(); 444 assertMapValuesCleared(builder); 445 message = builder.build(); 446 assertMapValuesCleared(message); 447 } 448 testPutAll()449 public void testPutAll() throws Exception { 450 TestMap.Builder sourceBuilder = TestMap.newBuilder(); 451 setMapValuesUsingAccessors(sourceBuilder); 452 TestMap source = sourceBuilder.build(); 453 assertMapValuesSet(source); 454 455 TestMap.Builder destination = TestMap.newBuilder(); 456 copyMapValues(source, destination); 457 assertMapValuesSet(destination.build()); 458 } 459 testPutAllForUnknownEnumValues()460 public void testPutAllForUnknownEnumValues() throws Exception { 461 TestMap source = 462 TestMap.newBuilder() 463 .putAllInt32ToEnumFieldValue( 464 newMap( 465 0, 0, 466 1, 1, 467 2, 1000)) // unknown value. 468 .build(); 469 470 TestMap destination = 471 TestMap.newBuilder() 472 .putAllInt32ToEnumFieldValue(source.getInt32ToEnumFieldValueMap()) 473 .build(); 474 475 assertEquals(0, destination.getInt32ToEnumFieldValueMap().get(0).intValue()); 476 assertEquals(1, destination.getInt32ToEnumFieldValueMap().get(1).intValue()); 477 assertEquals(1000, destination.getInt32ToEnumFieldValueMap().get(2).intValue()); 478 assertEquals(3, destination.getInt32ToEnumFieldCount()); 479 } 480 testPutForUnknownEnumValues()481 public void testPutForUnknownEnumValues() throws Exception { 482 TestMap message = 483 TestMap.newBuilder() 484 .putInt32ToEnumFieldValue(0, 0) 485 .putInt32ToEnumFieldValue(1, 1) 486 .putInt32ToEnumFieldValue(2, 1000) // unknown value. 487 .build(); 488 assertEquals(0, message.getInt32ToEnumFieldValueOrThrow(0)); 489 assertEquals(1, message.getInt32ToEnumFieldValueOrThrow(1)); 490 assertEquals(1000, message.getInt32ToEnumFieldValueOrThrow(2)); 491 assertEquals(3, message.getInt32ToEnumFieldCount()); 492 } 493 testPutChecksNullKeysAndValues()494 public void testPutChecksNullKeysAndValues() throws Exception { 495 TestMap.Builder builder = TestMap.newBuilder(); 496 497 try { 498 builder.putInt32ToStringField(1, null); 499 fail(); 500 } catch (NullPointerException e) { 501 // expected. 502 } 503 504 try { 505 builder.putInt32ToBytesField(1, null); 506 fail(); 507 } catch (NullPointerException e) { 508 // expected. 509 } 510 511 try { 512 builder.putInt32ToEnumField(1, null); 513 fail(); 514 } catch (NullPointerException e) { 515 // expected. 516 } 517 518 try { 519 builder.putInt32ToMessageField(1, null); 520 fail(); 521 } catch (NullPointerException e) { 522 // expected. 523 } 524 525 try { 526 builder.putStringToInt32Field(null, 1); 527 fail(); 528 } catch (NullPointerException e) { 529 // expected. 530 } 531 } 532 testSerializeAndParse()533 public void testSerializeAndParse() throws Exception { 534 TestMap.Builder builder = TestMap.newBuilder(); 535 setMapValuesUsingAccessors(builder); 536 TestMap message = builder.build(); 537 assertEquals(message.getSerializedSize(), message.toByteString().size()); 538 message = TestMap.parser().parseFrom(message.toByteString()); 539 assertMapValuesSet(message); 540 541 builder = message.toBuilder(); 542 updateMapValuesUsingAccessors(builder); 543 message = builder.build(); 544 assertEquals(message.getSerializedSize(), message.toByteString().size()); 545 message = TestMap.parser().parseFrom(message.toByteString()); 546 assertMapValuesUpdated(message); 547 548 builder = message.toBuilder(); 549 builder.clear(); 550 message = builder.build(); 551 assertEquals(message.getSerializedSize(), message.toByteString().size()); 552 message = TestMap.parser().parseFrom(message.toByteString()); 553 assertMapValuesCleared(message); 554 } 555 tryParseTestMap(BizarroTestMap bizarroMap)556 private TestMap tryParseTestMap(BizarroTestMap bizarroMap) throws IOException { 557 ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); 558 CodedOutputStream output = CodedOutputStream.newInstance(byteArrayOutputStream); 559 bizarroMap.writeTo(output); 560 output.flush(); 561 return TestMap.parser().parseFrom(ByteString.copyFrom(byteArrayOutputStream.toByteArray())); 562 } 563 testParseError()564 public void testParseError() throws Exception { 565 ByteString bytes = TestUtil.toBytes("SOME BYTES"); 566 String stringKey = "a string key"; 567 568 TestMap map = 569 tryParseTestMap(BizarroTestMap.newBuilder().putInt32ToInt32Field(5, bytes).build()); 570 assertEquals(0, map.getInt32ToInt32FieldOrDefault(5, -1)); 571 572 map = tryParseTestMap(BizarroTestMap.newBuilder().putInt32ToStringField(stringKey, 5).build()); 573 assertEquals("", map.getInt32ToStringFieldOrDefault(0, null)); 574 575 map = tryParseTestMap(BizarroTestMap.newBuilder().putInt32ToBytesField(stringKey, 5).build()); 576 assertEquals(map.getInt32ToBytesFieldOrDefault(0, null), ByteString.EMPTY); 577 578 map = 579 tryParseTestMap(BizarroTestMap.newBuilder().putInt32ToEnumField(stringKey, bytes).build()); 580 assertEquals(TestMap.EnumValue.FOO, map.getInt32ToEnumFieldOrDefault(0, null)); 581 582 try { 583 tryParseTestMap(BizarroTestMap.newBuilder().putInt32ToMessageField(stringKey, bytes).build()); 584 fail(); 585 } catch (InvalidProtocolBufferException expected) { 586 assertTrue(expected.getUnfinishedMessage() instanceof TestMap); 587 map = (TestMap) expected.getUnfinishedMessage(); 588 assertTrue(map.getInt32ToMessageFieldMap().isEmpty()); 589 } 590 591 map = 592 tryParseTestMap( 593 BizarroTestMap.newBuilder().putStringToInt32Field(stringKey, bytes).build()); 594 assertEquals(0, map.getStringToInt32FieldOrDefault(stringKey, -1)); 595 } 596 testMergeFrom()597 public void testMergeFrom() throws Exception { 598 TestMap.Builder builder = TestMap.newBuilder(); 599 setMapValuesUsingAccessors(builder); 600 TestMap message = builder.build(); 601 602 TestMap.Builder other = TestMap.newBuilder(); 603 other.mergeFrom(message); 604 assertMapValuesSet(other.build()); 605 } 606 testEqualsAndHashCode()607 public void testEqualsAndHashCode() throws Exception { 608 // Test that generated equals() and hashCode() will disregard the order 609 // of map entries when comparing/hashing map fields. 610 611 // We can't control the order of elements in a HashMap. The best we can do 612 // here is to add elements in different order. 613 TestMap m1 = 614 TestMap.newBuilder() 615 .putInt32ToInt32Field(1, 2) 616 .putInt32ToInt32Field(3, 4) 617 .putInt32ToInt32Field(5, 6) 618 .build(); 619 620 TestMap.Builder b2 = 621 TestMap.newBuilder() 622 .putInt32ToInt32Field(5, 6) 623 .putInt32ToInt32Field(1, 2) 624 .putInt32ToInt32Field(3, 4); 625 TestMap m2 = b2.build(); 626 627 assertEquals(m1, m2); 628 assertEquals(m1.hashCode(), m2.hashCode()); 629 630 // Make sure we did compare map fields. 631 b2.putInt32ToInt32Field(1, 0); 632 m2 = b2.build(); 633 assertFalse(m1.equals(m2)); 634 // Don't check m1.hashCode() != m2.hashCode() because it's not guaranteed 635 // to be different. 636 637 // Regression test for b/18549190: if a map is a subset of the other map, 638 // equals() should return false. 639 b2.removeInt32ToInt32Field(1); 640 m2 = b2.build(); 641 assertFalse(m1.equals(m2)); 642 assertFalse(m2.equals(m1)); 643 } 644 testNestedBuilderOnChangeEventPropagation()645 public void testNestedBuilderOnChangeEventPropagation() { 646 TestOnChangeEventPropagation.Builder parent = TestOnChangeEventPropagation.newBuilder(); 647 parent.getOptionalMessageBuilder().putInt32ToInt32Field(1, 2); 648 TestOnChangeEventPropagation message = parent.build(); 649 assertEquals(2, message.getOptionalMessage().getInt32ToInt32FieldMap().get(1).intValue()); 650 651 // Make a change using nested builder. 652 parent.getOptionalMessageBuilder().putInt32ToInt32Field(1, 3); 653 654 // Should be able to observe the change. 655 message = parent.build(); 656 assertEquals(3, message.getOptionalMessage().getInt32ToInt32FieldMap().get(1).intValue()); 657 658 // Make another change using mergeFrom() 659 TestMap other = TestMap.newBuilder().putInt32ToInt32Field(1, 4).build(); 660 parent.getOptionalMessageBuilder().mergeFrom(other); 661 662 // Should be able to observe the change. 663 message = parent.build(); 664 assertEquals(4, message.getOptionalMessage().getInt32ToInt32FieldMap().get(1).intValue()); 665 666 // Make yet another change by clearing the nested builder. 667 parent.getOptionalMessageBuilder().clear(); 668 669 // Should be able to observe the change. 670 message = parent.build(); 671 assertEquals(0, message.getOptionalMessage().getInt32ToInt32FieldMap().size()); 672 } 673 testNestedBuilderOnChangeEventPropagationReflection()674 public void testNestedBuilderOnChangeEventPropagationReflection() { 675 FieldDescriptor intMapField = f("int32_to_int32_field"); 676 // Create an outer message builder with nested builder. 677 TestOnChangeEventPropagation.Builder parentBuilder = TestOnChangeEventPropagation.newBuilder(); 678 TestMap.Builder testMapBuilder = parentBuilder.getOptionalMessageBuilder(); 679 680 // Create a map entry message. 681 TestMap.Builder entryBuilder = TestMap.newBuilder().putInt32ToInt32Field(1, 1); 682 683 // Put the entry into the nested builder. 684 testMapBuilder.addRepeatedField(intMapField, entryBuilder.getRepeatedField(intMapField, 0)); 685 686 // Should be able to observe the change. 687 TestOnChangeEventPropagation message = parentBuilder.build(); 688 assertEquals(1, message.getOptionalMessage().getInt32ToInt32FieldMap().size()); 689 690 // Change the entry value. 691 entryBuilder.putInt32ToInt32Field(1, 4); 692 testMapBuilder = parentBuilder.getOptionalMessageBuilder(); 693 testMapBuilder.setRepeatedField(intMapField, 0, entryBuilder.getRepeatedField(intMapField, 0)); 694 695 // Should be able to observe the change. 696 message = parentBuilder.build(); 697 assertEquals(4, message.getOptionalMessage().getInt32ToInt32FieldMap().get(1).intValue()); 698 699 // Clear the nested builder. 700 testMapBuilder = parentBuilder.getOptionalMessageBuilder(); 701 testMapBuilder.clearField(intMapField); 702 703 // Should be able to observe the change. 704 message = parentBuilder.build(); 705 assertEquals(0, message.getOptionalMessage().getInt32ToInt32FieldMap().size()); 706 } 707 708 // The following methods are used to test reflection API. 709 f(String name)710 private static FieldDescriptor f(String name) { 711 return TestMap.getDescriptor().findFieldByName(name); 712 } 713 getFieldValue(Message mapEntry, String name)714 private static Object getFieldValue(Message mapEntry, String name) { 715 FieldDescriptor field = mapEntry.getDescriptorForType().findFieldByName(name); 716 return mapEntry.getField(field); 717 } 718 setFieldValue( Message.Builder mapEntry, String name, Object value)719 private static Message.Builder setFieldValue( 720 Message.Builder mapEntry, String name, Object value) { 721 FieldDescriptor field = mapEntry.getDescriptorForType().findFieldByName(name); 722 mapEntry.setField(field, value); 723 return mapEntry; 724 } 725 assertHasMapValues(Message message, String name, Map<?, ?> values)726 private static void assertHasMapValues(Message message, String name, Map<?, ?> values) { 727 FieldDescriptor field = f(name); 728 for (Object entry : (List<?>) message.getField(field)) { 729 Message mapEntry = (Message) entry; 730 Object key = getFieldValue(mapEntry, "key"); 731 Object value = getFieldValue(mapEntry, "value"); 732 assertTrue(values.containsKey(key)); 733 assertEquals(value, values.get(key)); 734 } 735 assertEquals(values.size(), message.getRepeatedFieldCount(field)); 736 for (int i = 0; i < message.getRepeatedFieldCount(field); i++) { 737 Message mapEntry = (Message) message.getRepeatedField(field, i); 738 Object key = getFieldValue(mapEntry, "key"); 739 Object value = getFieldValue(mapEntry, "value"); 740 assertTrue(values.containsKey(key)); 741 assertEquals(value, values.get(key)); 742 } 743 } 744 newMapEntry(Message.Builder builder, String name, K key, V value)745 private static <K, V> Message newMapEntry(Message.Builder builder, String name, K key, V value) { 746 FieldDescriptor field = builder.getDescriptorForType().findFieldByName(name); 747 Message.Builder entryBuilder = builder.newBuilderForField(field); 748 FieldDescriptor keyField = entryBuilder.getDescriptorForType().findFieldByName("key"); 749 FieldDescriptor valueField = entryBuilder.getDescriptorForType().findFieldByName("value"); 750 entryBuilder.setField(keyField, key); 751 entryBuilder.setField(valueField, value); 752 return entryBuilder.build(); 753 } 754 setMapValues(Message.Builder builder, String name, Map<?, ?> values)755 private static void setMapValues(Message.Builder builder, String name, Map<?, ?> values) { 756 List<Message> entryList = new ArrayList<>(); 757 for (Map.Entry<?, ?> entry : values.entrySet()) { 758 entryList.add(newMapEntry(builder, name, entry.getKey(), entry.getValue())); 759 } 760 FieldDescriptor field = builder.getDescriptorForType().findFieldByName(name); 761 builder.setField(field, entryList); 762 } 763 mapForValues(K key1, V value1, K key2, V value2)764 private static <K, V> Map<K, V> mapForValues(K key1, V value1, K key2, V value2) { 765 Map<K, V> map = new HashMap<>(); 766 map.put(key1, value1); 767 map.put(key2, value2); 768 return map; 769 } 770 testReflectionApi()771 public void testReflectionApi() throws Exception { 772 // In reflection API, map fields are just repeated message fields. 773 TestMap.Builder builder = 774 TestMap.newBuilder() 775 .putInt32ToInt32Field(1, 2) 776 .putInt32ToInt32Field(3, 4) 777 .putInt32ToMessageField(11, MessageValue.newBuilder().setValue(22).build()) 778 .putInt32ToMessageField(33, MessageValue.newBuilder().setValue(44).build()); 779 TestMap message = builder.build(); 780 781 // Test getField(), getRepeatedFieldCount(), getRepeatedField(). 782 assertHasMapValues(message, "int32_to_int32_field", mapForValues(1, 2, 3, 4)); 783 assertHasMapValues( 784 message, 785 "int32_to_message_field", 786 mapForValues( 787 11, MessageValue.newBuilder().setValue(22).build(), 788 33, MessageValue.newBuilder().setValue(44).build())); 789 790 // Test clearField() 791 builder.clearField(f("int32_to_int32_field")); 792 builder.clearField(f("int32_to_message_field")); 793 message = builder.build(); 794 assertEquals(0, message.getInt32ToInt32FieldMap().size()); 795 assertEquals(0, message.getInt32ToMessageFieldMap().size()); 796 797 // Test setField() 798 setMapValues(builder, "int32_to_int32_field", mapForValues(11, 22, 33, 44)); 799 setMapValues( 800 builder, 801 "int32_to_message_field", 802 mapForValues( 803 111, MessageValue.newBuilder().setValue(222).build(), 804 333, MessageValue.newBuilder().setValue(444).build())); 805 message = builder.build(); 806 assertEquals(22, message.getInt32ToInt32FieldMap().get(11).intValue()); 807 assertEquals(44, message.getInt32ToInt32FieldMap().get(33).intValue()); 808 assertEquals(222, message.getInt32ToMessageFieldMap().get(111).getValue()); 809 assertEquals(444, message.getInt32ToMessageFieldMap().get(333).getValue()); 810 811 // Test addRepeatedField 812 builder.addRepeatedField( 813 f("int32_to_int32_field"), newMapEntry(builder, "int32_to_int32_field", 55, 66)); 814 builder.addRepeatedField( 815 f("int32_to_message_field"), 816 newMapEntry( 817 builder, 818 "int32_to_message_field", 819 555, 820 MessageValue.newBuilder().setValue(666).build())); 821 message = builder.build(); 822 assertEquals(66, message.getInt32ToInt32FieldMap().get(55).intValue()); 823 assertEquals(666, message.getInt32ToMessageFieldMap().get(555).getValue()); 824 825 // Test addRepeatedField (overriding existing values) 826 builder.addRepeatedField( 827 f("int32_to_int32_field"), newMapEntry(builder, "int32_to_int32_field", 55, 55)); 828 builder.addRepeatedField( 829 f("int32_to_message_field"), 830 newMapEntry( 831 builder, 832 "int32_to_message_field", 833 555, 834 MessageValue.newBuilder().setValue(555).build())); 835 message = builder.build(); 836 assertEquals(55, message.getInt32ToInt32FieldMap().get(55).intValue()); 837 assertEquals(555, message.getInt32ToMessageFieldMap().get(555).getValue()); 838 839 // Test setRepeatedField 840 for (int i = 0; i < builder.getRepeatedFieldCount(f("int32_to_int32_field")); i++) { 841 Message mapEntry = (Message) builder.getRepeatedField(f("int32_to_int32_field"), i); 842 int oldKey = ((Integer) getFieldValue(mapEntry, "key")).intValue(); 843 int oldValue = ((Integer) getFieldValue(mapEntry, "value")).intValue(); 844 // Swap key with value for each entry. 845 Message.Builder mapEntryBuilder = mapEntry.toBuilder(); 846 setFieldValue(mapEntryBuilder, "key", oldValue); 847 setFieldValue(mapEntryBuilder, "value", oldKey); 848 builder.setRepeatedField(f("int32_to_int32_field"), i, mapEntryBuilder.build()); 849 } 850 message = builder.build(); 851 assertEquals(11, message.getInt32ToInt32FieldMap().get(22).intValue()); 852 assertEquals(33, message.getInt32ToInt32FieldMap().get(44).intValue()); 853 assertEquals(55, message.getInt32ToInt32FieldMap().get(55).intValue()); 854 } 855 856 // See additional coverage in TextFormatTest.java. testTextFormat()857 public void testTextFormat() throws Exception { 858 TestMap.Builder builder = TestMap.newBuilder(); 859 setMapValuesUsingAccessors(builder); 860 TestMap message = builder.build(); 861 862 String textData = TextFormat.printer().printToString(message); 863 864 builder = TestMap.newBuilder(); 865 TextFormat.merge(textData, builder); 866 message = builder.build(); 867 868 assertMapValuesSet(message); 869 } 870 testDynamicMessage()871 public void testDynamicMessage() throws Exception { 872 TestMap.Builder builder = TestMap.newBuilder(); 873 setMapValuesUsingAccessors(builder); 874 TestMap message = builder.build(); 875 876 Message dynamicDefaultInstance = DynamicMessage.getDefaultInstance(TestMap.getDescriptor()); 877 Message dynamicMessage = 878 dynamicDefaultInstance.newBuilderForType().mergeFrom(message.toByteString()).build(); 879 880 assertEquals(message, dynamicMessage); 881 assertEquals(message.hashCode(), dynamicMessage.hashCode()); 882 } 883 884 // Check that DynamicMessage handles map field serialization the same way as generated code 885 // regarding unset key and value field in a map entry. testDynamicMessageUnsetKeyAndValue()886 public void testDynamicMessageUnsetKeyAndValue() throws Exception { 887 FieldDescriptor field = f("int32_to_int32_field"); 888 889 Message dynamicDefaultInstance = DynamicMessage.getDefaultInstance(TestMap.getDescriptor()); 890 Message.Builder builder = dynamicDefaultInstance.newBuilderForType(); 891 // Add an entry without key and value. 892 builder.addRepeatedField(field, builder.newBuilderForField(field).build()); 893 Message message = builder.build(); 894 ByteString bytes = message.toByteString(); 895 // Parse it back to the same generated type. 896 Message generatedMessage = TestMap.parseFrom(bytes); 897 // Assert the serialized bytes are equivalent. 898 assertEquals(generatedMessage.toByteString(), bytes); 899 } 900 testReflectionEqualsAndHashCode()901 public void testReflectionEqualsAndHashCode() throws Exception { 902 // Test that generated equals() and hashCode() will disregard the order 903 // of map entries when comparing/hashing map fields. 904 905 // We use DynamicMessage to test reflection based equals()/hashCode(). 906 Message dynamicDefaultInstance = DynamicMessage.getDefaultInstance(TestMap.getDescriptor()); 907 FieldDescriptor field = f("int32_to_int32_field"); 908 909 Message.Builder b1 = dynamicDefaultInstance.newBuilderForType(); 910 b1.addRepeatedField(field, newMapEntry(b1, "int32_to_int32_field", 1, 2)); 911 b1.addRepeatedField(field, newMapEntry(b1, "int32_to_int32_field", 3, 4)); 912 b1.addRepeatedField(field, newMapEntry(b1, "int32_to_int32_field", 5, 6)); 913 Message m1 = b1.build(); 914 915 Message.Builder b2 = dynamicDefaultInstance.newBuilderForType(); 916 b2.addRepeatedField(field, newMapEntry(b2, "int32_to_int32_field", 5, 6)); 917 b2.addRepeatedField(field, newMapEntry(b2, "int32_to_int32_field", 1, 2)); 918 b2.addRepeatedField(field, newMapEntry(b2, "int32_to_int32_field", 3, 4)); 919 Message m2 = b2.build(); 920 921 assertEquals(m1, m2); 922 assertEquals(m1.hashCode(), m2.hashCode()); 923 924 // Make sure we did compare map fields. 925 b2.setRepeatedField(field, 0, newMapEntry(b1, "int32_to_int32_field", 0, 0)); 926 m2 = b2.build(); 927 assertFalse(m1.equals(m2)); 928 // Don't check m1.hashCode() != m2.hashCode() because it's not guaranteed 929 // to be different. 930 } 931 testUnknownEnumValues()932 public void testUnknownEnumValues() throws Exception { 933 TestMap.Builder builder = 934 TestMap.newBuilder() 935 .putAllInt32ToEnumFieldValue( 936 newMap( 937 0, 0, 938 1, 1, 939 2, 1000)); // unknown value. 940 TestMap message = builder.build(); 941 942 assertEquals(TestMap.EnumValue.FOO, message.getInt32ToEnumFieldMap().get(0)); 943 assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumFieldMap().get(1)); 944 assertEquals(TestMap.EnumValue.UNRECOGNIZED, message.getInt32ToEnumFieldMap().get(2)); 945 assertEquals(1000, message.getInt32ToEnumFieldValueMap().get(2).intValue()); 946 947 // Unknown enum values should be preserved after: 948 // 1. Serialization and parsing. 949 // 2. toBuild(). 950 // 3. mergeFrom(). 951 message = TestMap.parseFrom(message.toByteString()); 952 assertEquals(1000, message.getInt32ToEnumFieldValueMap().get(2).intValue()); 953 builder = message.toBuilder(); 954 assertEquals(1000, builder.getInt32ToEnumFieldValueMap().get(2).intValue()); 955 builder = TestMap.newBuilder().mergeFrom(message); 956 assertEquals(1000, builder.getInt32ToEnumFieldValueMap().get(2).intValue()); 957 958 // hashCode()/equals() should take unknown enum values into account. 959 builder.putAllInt32ToEnumFieldValue(newMap(2, 1001)); 960 TestMap message2 = builder.build(); 961 assertFalse(message.hashCode() == message2.hashCode()); 962 assertFalse(message.equals(message2)); 963 // Unknown values will be converted to UNRECOGNIZED so the resulted enum map 964 // should be the same. 965 assertEquals(message2.getInt32ToEnumFieldMap(), message.getInt32ToEnumFieldMap()); 966 } 967 testUnknownEnumValuesInReflectionApi()968 public void testUnknownEnumValuesInReflectionApi() throws Exception { 969 Descriptor descriptor = TestMap.getDescriptor(); 970 EnumDescriptor enumDescriptor = TestMap.EnumValue.getDescriptor(); 971 FieldDescriptor field = descriptor.findFieldByName("int32_to_enum_field"); 972 973 Map<Integer, Integer> data = 974 newMap( 975 0, 0, 976 1, 1, 977 2, 1000); // unknown value 978 979 TestMap.Builder builder = TestMap.newBuilder().putAllInt32ToEnumFieldValue(data); 980 981 // Try to read unknown enum values using reflection API. 982 for (int i = 0; i < builder.getRepeatedFieldCount(field); i++) { 983 Message mapEntry = (Message) builder.getRepeatedField(field, i); 984 int key = ((Integer) getFieldValue(mapEntry, "key")).intValue(); 985 int value = ((EnumValueDescriptor) getFieldValue(mapEntry, "value")).getNumber(); 986 assertEquals(data.get(key).intValue(), value); 987 Message.Builder mapEntryBuilder = mapEntry.toBuilder(); 988 // Increase the value by 1. 989 setFieldValue( 990 mapEntryBuilder, "value", enumDescriptor.findValueByNumberCreatingIfUnknown(value + 1)); 991 builder.setRepeatedField(field, i, mapEntryBuilder.build()); 992 } 993 994 // Verify that enum values have been successfully updated. 995 TestMap message = builder.build(); 996 for (Map.Entry<Integer, Integer> entry : message.getInt32ToEnumFieldValueMap().entrySet()) { 997 assertEquals(data.get(entry.getKey()) + 1, entry.getValue().intValue()); 998 } 999 } 1000 testIterationOrder()1001 public void testIterationOrder() throws Exception { 1002 TestMap.Builder builder = TestMap.newBuilder(); 1003 setMapValuesUsingAccessors(builder); 1004 TestMap message = builder.build(); 1005 1006 assertEquals( 1007 Arrays.asList("1", "2", "3"), new ArrayList<>(message.getStringToInt32FieldMap().keySet())); 1008 } 1009 testGetMap()1010 public void testGetMap() { 1011 TestMap.Builder builder = TestMap.newBuilder(); 1012 setMapValuesUsingAccessors(builder); 1013 TestMap message = builder.build(); 1014 assertEquals(message.getStringToInt32FieldMap(), message.getStringToInt32FieldMap()); 1015 assertEquals(message.getInt32ToBytesFieldMap(), message.getInt32ToBytesFieldMap()); 1016 assertEquals(message.getInt32ToEnumFieldMap(), message.getInt32ToEnumFieldMap()); 1017 assertEquals(message.getInt32ToEnumFieldValueMap(), message.getInt32ToEnumFieldValueMap()); 1018 assertEquals(message.getInt32ToMessageFieldMap(), message.getInt32ToMessageFieldMap()); 1019 } 1020 testContains()1021 public void testContains() { 1022 TestMap.Builder builder = TestMap.newBuilder(); 1023 setMapValuesUsingAccessors(builder); 1024 assertMapContainsSetValues(builder); 1025 assertMapContainsSetValues(builder.build()); 1026 } 1027 assertMapContainsSetValues(TestMapOrBuilder testMapOrBuilder)1028 private void assertMapContainsSetValues(TestMapOrBuilder testMapOrBuilder) { 1029 assertTrue(testMapOrBuilder.containsInt32ToInt32Field(1)); 1030 assertTrue(testMapOrBuilder.containsInt32ToInt32Field(2)); 1031 assertTrue(testMapOrBuilder.containsInt32ToInt32Field(3)); 1032 assertFalse(testMapOrBuilder.containsInt32ToInt32Field(-1)); 1033 1034 assertTrue(testMapOrBuilder.containsInt32ToStringField(1)); 1035 assertTrue(testMapOrBuilder.containsInt32ToStringField(2)); 1036 assertTrue(testMapOrBuilder.containsInt32ToStringField(3)); 1037 assertFalse(testMapOrBuilder.containsInt32ToStringField(-1)); 1038 1039 assertTrue(testMapOrBuilder.containsInt32ToBytesField(1)); 1040 assertTrue(testMapOrBuilder.containsInt32ToBytesField(2)); 1041 assertTrue(testMapOrBuilder.containsInt32ToBytesField(3)); 1042 assertFalse(testMapOrBuilder.containsInt32ToBytesField(-1)); 1043 1044 assertTrue(testMapOrBuilder.containsInt32ToEnumField(1)); 1045 assertTrue(testMapOrBuilder.containsInt32ToEnumField(2)); 1046 assertTrue(testMapOrBuilder.containsInt32ToEnumField(3)); 1047 assertFalse(testMapOrBuilder.containsInt32ToEnumField(-1)); 1048 1049 assertTrue(testMapOrBuilder.containsInt32ToMessageField(1)); 1050 assertTrue(testMapOrBuilder.containsInt32ToMessageField(2)); 1051 assertTrue(testMapOrBuilder.containsInt32ToMessageField(3)); 1052 assertFalse(testMapOrBuilder.containsInt32ToMessageField(-1)); 1053 1054 assertTrue(testMapOrBuilder.containsStringToInt32Field("1")); 1055 assertTrue(testMapOrBuilder.containsStringToInt32Field("2")); 1056 assertTrue(testMapOrBuilder.containsStringToInt32Field("3")); 1057 assertFalse(testMapOrBuilder.containsStringToInt32Field("-1")); 1058 } 1059 testCount()1060 public void testCount() { 1061 TestMap.Builder builder = TestMap.newBuilder(); 1062 assertMapCounts(0, builder); 1063 1064 setMapValuesUsingAccessors(builder); 1065 assertMapCounts(3, builder); 1066 1067 TestMap message = builder.build(); 1068 assertMapCounts(3, message); 1069 1070 builder = message.toBuilder().putInt32ToInt32Field(4, 44); 1071 assertEquals(4, builder.getInt32ToInt32FieldCount()); 1072 assertEquals(4, builder.build().getInt32ToInt32FieldCount()); 1073 1074 // already present - should be unchanged 1075 builder.putInt32ToInt32Field(4, 44); 1076 assertEquals(4, builder.getInt32ToInt32FieldCount()); 1077 } 1078 assertMapCounts(int expectedCount, TestMapOrBuilder testMapOrBuilder)1079 private void assertMapCounts(int expectedCount, TestMapOrBuilder testMapOrBuilder) { 1080 assertEquals(expectedCount, testMapOrBuilder.getInt32ToInt32FieldCount()); 1081 assertEquals(expectedCount, testMapOrBuilder.getInt32ToStringFieldCount()); 1082 assertEquals(expectedCount, testMapOrBuilder.getInt32ToBytesFieldCount()); 1083 assertEquals(expectedCount, testMapOrBuilder.getInt32ToEnumFieldCount()); 1084 assertEquals(expectedCount, testMapOrBuilder.getInt32ToMessageFieldCount()); 1085 assertEquals(expectedCount, testMapOrBuilder.getStringToInt32FieldCount()); 1086 } 1087 testGetOrDefault()1088 public void testGetOrDefault() { 1089 TestMap.Builder builder = TestMap.newBuilder(); 1090 assertMapCounts(0, builder); 1091 setMapValuesUsingAccessors(builder); 1092 doTestGetOrDefault(builder); 1093 doTestGetOrDefault(builder.build()); 1094 } 1095 doTestGetOrDefault(TestMapOrBuilder testMapOrBuilder)1096 public void doTestGetOrDefault(TestMapOrBuilder testMapOrBuilder) { 1097 assertEquals(11, testMapOrBuilder.getInt32ToInt32FieldOrDefault(1, -11)); 1098 assertEquals(-11, testMapOrBuilder.getInt32ToInt32FieldOrDefault(-1, -11)); 1099 1100 assertEquals("11", testMapOrBuilder.getInt32ToStringFieldOrDefault(1, "-11")); 1101 assertNull("-11", testMapOrBuilder.getInt32ToStringFieldOrDefault(-1, null)); 1102 1103 assertEquals(TestUtil.toBytes("11"), testMapOrBuilder.getInt32ToBytesFieldOrDefault(1, null)); 1104 assertNull(testMapOrBuilder.getInt32ToBytesFieldOrDefault(-1, null)); 1105 1106 assertEquals(TestMap.EnumValue.FOO, testMapOrBuilder.getInt32ToEnumFieldOrDefault(1, null)); 1107 assertNull(testMapOrBuilder.getInt32ToEnumFieldOrDefault(-1, null)); 1108 1109 assertEquals( 1110 TestMap.EnumValue.BAR.getNumber(), 1111 testMapOrBuilder.getInt32ToEnumFieldValueOrDefault(2, -1)); 1112 assertEquals(-1, testMapOrBuilder.getInt32ToEnumFieldValueOrDefault(-1000, -1)); 1113 1114 assertEquals( 1115 MessageValue.newBuilder().setValue(11).build(), 1116 testMapOrBuilder.getInt32ToMessageFieldOrDefault(1, null)); 1117 assertNull(testMapOrBuilder.getInt32ToMessageFieldOrDefault(-1, null)); 1118 1119 assertEquals(11, testMapOrBuilder.getStringToInt32FieldOrDefault("1", -11)); 1120 assertEquals(-11, testMapOrBuilder.getStringToInt32FieldOrDefault("-1", -11)); 1121 1122 try { 1123 testMapOrBuilder.getStringToInt32FieldOrDefault(null, -11); 1124 fail(); 1125 } catch (NullPointerException e) { 1126 // expected 1127 } 1128 } 1129 testGetOrThrow()1130 public void testGetOrThrow() { 1131 TestMap.Builder builder = TestMap.newBuilder(); 1132 assertMapCounts(0, builder); 1133 setMapValuesUsingAccessors(builder); 1134 doTestGetOrDefault(builder); 1135 doTestGetOrDefault(builder.build()); 1136 } 1137 doTestGetOrThrow(TestMapOrBuilder testMapOrBuilder)1138 public void doTestGetOrThrow(TestMapOrBuilder testMapOrBuilder) { 1139 assertEquals(11, testMapOrBuilder.getInt32ToInt32FieldOrThrow(1)); 1140 try { 1141 testMapOrBuilder.getInt32ToInt32FieldOrThrow(-1); 1142 fail(); 1143 } catch (IllegalArgumentException e) { 1144 // expected 1145 } 1146 1147 assertEquals("11", testMapOrBuilder.getInt32ToStringFieldOrThrow(1)); 1148 1149 try { 1150 testMapOrBuilder.getInt32ToStringFieldOrThrow(-1); 1151 fail(); 1152 } catch (IllegalArgumentException e) { 1153 // expected 1154 } 1155 1156 assertEquals(TestUtil.toBytes("11"), testMapOrBuilder.getInt32ToBytesFieldOrThrow(1)); 1157 1158 try { 1159 testMapOrBuilder.getInt32ToBytesFieldOrThrow(-1); 1160 fail(); 1161 } catch (IllegalArgumentException e) { 1162 // expected 1163 } 1164 1165 assertEquals(TestMap.EnumValue.FOO, testMapOrBuilder.getInt32ToEnumFieldOrThrow(1)); 1166 try { 1167 testMapOrBuilder.getInt32ToEnumFieldOrThrow(-1); 1168 fail(); 1169 } catch (IllegalArgumentException e) { 1170 // expected 1171 } 1172 1173 assertEquals( 1174 TestMap.EnumValue.BAR.getNumber(), testMapOrBuilder.getInt32ToEnumFieldValueOrThrow(2)); 1175 try { 1176 testMapOrBuilder.getInt32ToEnumFieldValueOrThrow(-1); 1177 fail(); 1178 } catch (IllegalArgumentException e) { 1179 // expected 1180 } 1181 1182 assertEquals( 1183 MessageValue.newBuilder().setValue(11).build(), 1184 testMapOrBuilder.getInt32ToMessageFieldOrThrow(1)); 1185 try { 1186 testMapOrBuilder.getInt32ToMessageFieldOrThrow(-1); 1187 fail(); 1188 } catch (IllegalArgumentException e) { 1189 // expected 1190 } 1191 1192 assertEquals(11, testMapOrBuilder.getStringToInt32FieldOrThrow("1")); 1193 try { 1194 testMapOrBuilder.getStringToInt32FieldOrThrow("-1"); 1195 fail(); 1196 } catch (IllegalArgumentException e) { 1197 // expected 1198 } 1199 1200 try { 1201 testMapOrBuilder.getStringToInt32FieldOrThrow(null); 1202 fail(); 1203 } catch (NullPointerException e) { 1204 // expected 1205 } 1206 } 1207 testPut()1208 public void testPut() { 1209 TestMap.Builder builder = TestMap.newBuilder(); 1210 builder.putInt32ToInt32Field(1, 11); 1211 assertEquals(11, builder.getInt32ToInt32FieldOrThrow(1)); 1212 1213 builder.putInt32ToStringField(1, "a"); 1214 assertEquals("a", builder.getInt32ToStringFieldOrThrow(1)); 1215 try { 1216 builder.putInt32ToStringField(1, null); 1217 fail(); 1218 } catch (NullPointerException e) { 1219 // expected 1220 } 1221 1222 builder.putInt32ToBytesField(1, TestUtil.toBytes("11")); 1223 assertEquals(TestUtil.toBytes("11"), builder.getInt32ToBytesFieldOrThrow(1)); 1224 try { 1225 builder.putInt32ToBytesField(1, null); 1226 fail(); 1227 } catch (NullPointerException e) { 1228 // expected 1229 } 1230 1231 builder.putInt32ToEnumField(1, TestMap.EnumValue.FOO); 1232 assertEquals(TestMap.EnumValue.FOO, builder.getInt32ToEnumFieldOrThrow(1)); 1233 try { 1234 builder.putInt32ToEnumField(1, null); 1235 fail(); 1236 } catch (NullPointerException e) { 1237 // expected 1238 } 1239 1240 builder.putInt32ToEnumFieldValue(1, TestMap.EnumValue.BAR.getNumber()); 1241 assertEquals(TestMap.EnumValue.BAR.getNumber(), builder.getInt32ToEnumFieldValueOrThrow(1)); 1242 builder.putInt32ToEnumFieldValue(1, -1); 1243 assertEquals(-1, builder.getInt32ToEnumFieldValueOrThrow(1)); 1244 assertEquals(TestMap.EnumValue.UNRECOGNIZED, builder.getInt32ToEnumFieldOrThrow(1)); 1245 1246 builder.putStringToInt32Field("a", 1); 1247 assertEquals(1, builder.getStringToInt32FieldOrThrow("a")); 1248 try { 1249 builder.putStringToInt32Field(null, -1); 1250 } catch (NullPointerException e) { 1251 // expected 1252 } 1253 } 1254 testRemove()1255 public void testRemove() { 1256 TestMap.Builder builder = TestMap.newBuilder(); 1257 setMapValuesUsingAccessors(builder); 1258 assertEquals(11, builder.getInt32ToInt32FieldOrThrow(1)); 1259 for (int times = 0; times < 2; times++) { 1260 builder.removeInt32ToInt32Field(1); 1261 assertEquals(-1, builder.getInt32ToInt32FieldOrDefault(1, -1)); 1262 } 1263 1264 assertEquals("11", builder.getInt32ToStringFieldOrThrow(1)); 1265 for (int times = 0; times < 2; times++) { 1266 builder.removeInt32ToStringField(1); 1267 assertNull(builder.getInt32ToStringFieldOrDefault(1, null)); 1268 } 1269 1270 assertEquals(TestUtil.toBytes("11"), builder.getInt32ToBytesFieldOrThrow(1)); 1271 for (int times = 0; times < 2; times++) { 1272 builder.removeInt32ToBytesField(1); 1273 assertNull(builder.getInt32ToBytesFieldOrDefault(1, null)); 1274 } 1275 1276 assertEquals(TestMap.EnumValue.FOO, builder.getInt32ToEnumFieldOrThrow(1)); 1277 for (int times = 0; times < 2; times++) { 1278 builder.removeInt32ToEnumField(1); 1279 assertNull(builder.getInt32ToEnumFieldOrDefault(1, null)); 1280 } 1281 1282 assertEquals(11, builder.getStringToInt32FieldOrThrow("1")); 1283 for (int times = 0; times < 2; times++) { 1284 builder.removeStringToInt32Field("1"); 1285 assertEquals(-1, builder.getStringToInt32FieldOrDefault("1", -1)); 1286 } 1287 1288 try { 1289 builder.removeStringToInt32Field(null); 1290 fail(); 1291 } catch (NullPointerException e) { 1292 // expected 1293 } 1294 } 1295 testReservedWordsFieldNames()1296 public void testReservedWordsFieldNames() { 1297 ReservedAsMapField.newBuilder().build(); 1298 ReservedAsMapFieldWithEnumValue.newBuilder().build(); 1299 } 1300 testDeterministicSerialziation()1301 public void testDeterministicSerialziation() throws Exception { 1302 TestMap.Builder builder = TestMap.newBuilder(); 1303 // int32->int32 1304 builder.putInt32ToInt32Field(5, 1); 1305 builder.putInt32ToInt32Field(1, 1); 1306 builder.putInt32ToInt32Field(4, 1); 1307 builder.putInt32ToInt32Field(-2, 1); 1308 builder.putInt32ToInt32Field(0, 1); 1309 1310 // uint32->int32 1311 builder.putUint32ToInt32Field(5, 1); 1312 builder.putUint32ToInt32Field(1, 1); 1313 builder.putUint32ToInt32Field(4, 1); 1314 builder.putUint32ToInt32Field(-2, 1); 1315 builder.putUint32ToInt32Field(0, 1); 1316 1317 // int64->int32 1318 builder.putInt64ToInt32Field(5L, 1); 1319 builder.putInt64ToInt32Field(1L, 1); 1320 builder.putInt64ToInt32Field(4L, 1); 1321 builder.putInt64ToInt32Field(-2L, 1); 1322 builder.putInt64ToInt32Field(0L, 1); 1323 1324 // string->int32 1325 builder.putStringToInt32Field("baz", 1); 1326 builder.putStringToInt32Field("foo", 1); 1327 builder.putStringToInt32Field("bar", 1); 1328 builder.putStringToInt32Field("", 1); 1329 builder.putStringToInt32Field("hello", 1); 1330 builder.putStringToInt32Field("world", 1); 1331 1332 TestMap message = builder.build(); 1333 byte[] serialized = new byte[message.getSerializedSize()]; 1334 CodedOutputStream output = CodedOutputStream.newInstance(serialized); 1335 output.useDeterministicSerialization(); 1336 message.writeTo(output); 1337 output.flush(); 1338 1339 CodedInputStream input = CodedInputStream.newInstance(serialized); 1340 List<Integer> int32Keys = new ArrayList<>(); 1341 List<Integer> uint32Keys = new ArrayList<>(); 1342 List<Long> int64Keys = new ArrayList<>(); 1343 List<String> stringKeys = new ArrayList<>(); 1344 int tag; 1345 while (true) { 1346 tag = input.readTag(); 1347 if (tag == 0) { 1348 break; 1349 } 1350 int length = input.readRawVarint32(); 1351 int oldLimit = input.pushLimit(length); 1352 switch (WireFormat.getTagFieldNumber(tag)) { 1353 case TestMap.STRING_TO_INT32_FIELD_FIELD_NUMBER: 1354 stringKeys.add(readMapStringKey(input)); 1355 break; 1356 case TestMap.INT32_TO_INT32_FIELD_FIELD_NUMBER: 1357 int32Keys.add(readMapIntegerKey(input)); 1358 break; 1359 case TestMap.UINT32_TO_INT32_FIELD_FIELD_NUMBER: 1360 uint32Keys.add(readMapIntegerKey(input)); 1361 break; 1362 case TestMap.INT64_TO_INT32_FIELD_FIELD_NUMBER: 1363 int64Keys.add(readMapLongKey(input)); 1364 break; 1365 default: 1366 fail("Unexpected fields."); 1367 } 1368 input.popLimit(oldLimit); 1369 } 1370 assertEquals(Arrays.asList(-2, 0, 1, 4, 5), int32Keys); 1371 assertEquals(Arrays.asList(-2, 0, 1, 4, 5), uint32Keys); 1372 assertEquals(Arrays.asList(-2L, 0L, 1L, 4L, 5L), int64Keys); 1373 assertEquals(Arrays.asList("", "bar", "baz", "foo", "hello", "world"), stringKeys); 1374 } 1375 testInitFromPartialDynamicMessage()1376 public void testInitFromPartialDynamicMessage() { 1377 FieldDescriptor fieldDescriptor = 1378 TestMap.getDescriptor().findFieldByNumber(TestMap.INT32_TO_MESSAGE_FIELD_FIELD_NUMBER); 1379 Descriptor mapEntryType = fieldDescriptor.getMessageType(); 1380 FieldDescriptor keyField = mapEntryType.findFieldByNumber(1); 1381 FieldDescriptor valueField = mapEntryType.findFieldByNumber(2); 1382 DynamicMessage dynamicMessage = 1383 DynamicMessage.newBuilder(TestMap.getDescriptor()) 1384 .addRepeatedField( 1385 fieldDescriptor, 1386 DynamicMessage.newBuilder(mapEntryType) 1387 .setField(keyField, 10) 1388 .setField(valueField, TestMap.MessageValue.newBuilder().setValue(10).build()) 1389 .build()) 1390 .build(); 1391 TestMap message = TestMap.newBuilder().mergeFrom(dynamicMessage).build(); 1392 assertEquals( 1393 TestMap.MessageValue.newBuilder().setValue(10).build(), 1394 message.getInt32ToMessageFieldMap().get(10)); 1395 } 1396 testInitFromFullyDynamicMessage()1397 public void testInitFromFullyDynamicMessage() { 1398 FieldDescriptor fieldDescriptor = 1399 TestMap.getDescriptor().findFieldByNumber(TestMap.INT32_TO_MESSAGE_FIELD_FIELD_NUMBER); 1400 Descriptor mapEntryType = fieldDescriptor.getMessageType(); 1401 FieldDescriptor keyField = mapEntryType.findFieldByNumber(1); 1402 FieldDescriptor valueField = mapEntryType.findFieldByNumber(2); 1403 DynamicMessage dynamicMessage = 1404 DynamicMessage.newBuilder(TestMap.getDescriptor()) 1405 .addRepeatedField( 1406 fieldDescriptor, 1407 DynamicMessage.newBuilder(mapEntryType) 1408 .setField(keyField, 10) 1409 .setField( 1410 valueField, 1411 DynamicMessage.newBuilder(TestMap.MessageValue.getDescriptor()) 1412 .setField( 1413 TestMap.MessageValue.getDescriptor().findFieldByName("value"), 10) 1414 .build()) 1415 .build()) 1416 .build(); 1417 TestMap message = TestMap.newBuilder().mergeFrom(dynamicMessage).build(); 1418 assertEquals( 1419 TestMap.MessageValue.newBuilder().setValue(10).build(), 1420 message.getInt32ToMessageFieldMap().get(10)); 1421 } 1422 readMapIntegerKey(CodedInputStream input)1423 private int readMapIntegerKey(CodedInputStream input) throws IOException { 1424 int tag = input.readTag(); 1425 assertEquals(WireFormat.makeTag(1, WireFormat.WIRETYPE_VARINT), tag); 1426 int ret = input.readInt32(); 1427 // skip the value field. 1428 input.skipField(input.readTag()); 1429 assertTrue(input.isAtEnd()); 1430 return ret; 1431 } 1432 readMapLongKey(CodedInputStream input)1433 private long readMapLongKey(CodedInputStream input) throws IOException { 1434 int tag = input.readTag(); 1435 assertEquals(WireFormat.makeTag(1, WireFormat.WIRETYPE_VARINT), tag); 1436 long ret = input.readInt64(); 1437 // skip the value field. 1438 input.skipField(input.readTag()); 1439 assertTrue(input.isAtEnd()); 1440 return ret; 1441 } 1442 readMapStringKey(CodedInputStream input)1443 private String readMapStringKey(CodedInputStream input) throws IOException { 1444 int tag = input.readTag(); 1445 assertEquals(WireFormat.makeTag(1, WireFormat.WIRETYPE_LENGTH_DELIMITED), tag); 1446 String ret = input.readString(); 1447 // skip the value field. 1448 input.skipField(input.readTag()); 1449 assertTrue(input.isAtEnd()); 1450 return ret; 1451 } 1452 newMap(K key1, V value1)1453 private static <K, V> Map<K, V> newMap(K key1, V value1) { 1454 Map<K, V> map = new HashMap<>(); 1455 map.put(key1, value1); 1456 return map; 1457 } 1458 newMap(K key1, V value1, K key2, V value2)1459 private static <K, V> Map<K, V> newMap(K key1, V value1, K key2, V value2) { 1460 Map<K, V> map = new HashMap<>(); 1461 map.put(key1, value1); 1462 map.put(key2, value2); 1463 return map; 1464 } 1465 newMap(K key1, V value1, K key2, V value2, K key3, V value3)1466 private static <K, V> Map<K, V> newMap(K key1, V value1, K key2, V value2, K key3, V value3) { 1467 Map<K, V> map = new HashMap<>(); 1468 map.put(key1, value1); 1469 map.put(key2, value2); 1470 map.put(key3, value3); 1471 return map; 1472 } 1473 testMap_withNulls()1474 public void testMap_withNulls() { 1475 TestMap.Builder builder = TestMap.newBuilder(); 1476 1477 try { 1478 builder.putStringToInt32Field(null, 3); 1479 fail(); 1480 } catch (NullPointerException expected) { 1481 } 1482 1483 try { 1484 builder.putAllStringToInt32Field(newMap(null, 3, "hi", 4)); 1485 fail(); 1486 } catch (NullPointerException expected) { 1487 } 1488 1489 try { 1490 builder.putInt32ToMessageField(3, null); 1491 fail(); 1492 } catch (NullPointerException expected) { 1493 } 1494 1495 try { 1496 builder.putAllInt32ToMessageField(MapTest.<Integer, MessageValue>newMap(4, null, 5, null)); 1497 fail(); 1498 } catch (NullPointerException expected) { 1499 } 1500 1501 try { 1502 builder.putAllInt32ToMessageField(null); 1503 fail(); 1504 } catch (NullPointerException expected) { 1505 } 1506 1507 assertArrayEquals(new byte[0], builder.build().toByteArray()); 1508 } 1509 } 1510