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 com.google.protobuf.Descriptors.FieldDescriptor; 34 import map_test.MapForProto2TestProto.BizarroTestMap; 35 import map_test.MapForProto2TestProto.ReservedAsMapField; 36 import map_test.MapForProto2TestProto.ReservedAsMapFieldWithEnumValue; 37 import map_test.MapForProto2TestProto.TestMap; 38 import map_test.MapForProto2TestProto.TestMap.MessageValue; 39 import map_test.MapForProto2TestProto.TestMap.MessageWithRequiredFields; 40 import map_test.MapForProto2TestProto.TestMapOrBuilder; 41 import map_test.MapForProto2TestProto.TestRecursiveMap; 42 import map_test.MapForProto2TestProto.TestUnknownEnumValue; 43 import java.io.ByteArrayOutputStream; 44 import java.io.IOException; 45 import java.util.ArrayList; 46 import java.util.Arrays; 47 import java.util.HashMap; 48 import java.util.List; 49 import java.util.Map; 50 import junit.framework.TestCase; 51 52 /** Unit tests for map fields in proto2 protos. */ 53 public class MapForProto2Test extends TestCase { 54 setMapValuesUsingMutableMap(TestMap.Builder builder)55 private void setMapValuesUsingMutableMap(TestMap.Builder builder) { 56 builder.getMutableInt32ToInt32Field().put(1, 11); 57 builder.getMutableInt32ToInt32Field().put(2, 22); 58 builder.getMutableInt32ToInt32Field().put(3, 33); 59 // 60 builder.getMutableInt32ToStringField().put(1, "11"); 61 builder.getMutableInt32ToStringField().put(2, "22"); 62 builder.getMutableInt32ToStringField().put(3, "33"); 63 // 64 builder.getMutableInt32ToBytesField().put(1, TestUtil.toBytes("11")); 65 builder.getMutableInt32ToBytesField().put(2, TestUtil.toBytes("22")); 66 builder.getMutableInt32ToBytesField().put(3, TestUtil.toBytes("33")); 67 // 68 builder.getMutableInt32ToEnumField().put(1, TestMap.EnumValue.FOO); 69 builder.getMutableInt32ToEnumField().put(2, TestMap.EnumValue.BAR); 70 builder.getMutableInt32ToEnumField().put(3, TestMap.EnumValue.BAZ); 71 // 72 builder.getMutableInt32ToMessageField().put( 73 1, MessageValue.newBuilder().setValue(11).build()); 74 builder.getMutableInt32ToMessageField().put( 75 2, MessageValue.newBuilder().setValue(22).build()); 76 builder.getMutableInt32ToMessageField().put( 77 3, MessageValue.newBuilder().setValue(33).build()); 78 // 79 builder.getMutableStringToInt32Field().put("1", 11); 80 builder.getMutableStringToInt32Field().put("2", 22); 81 builder.getMutableStringToInt32Field().put("3", 33); 82 } 83 setMapValuesUsingAccessors(TestMap.Builder builder)84 private void setMapValuesUsingAccessors(TestMap.Builder builder) { 85 builder 86 .putInt32ToInt32Field(1, 11) 87 .putInt32ToInt32Field(2, 22) 88 .putInt32ToInt32Field(3, 33) 89 .putInt32ToStringField(1, "11") 90 .putInt32ToStringField(2, "22") 91 .putInt32ToStringField(3, "33") 92 .putInt32ToBytesField(1, TestUtil.toBytes("11")) 93 .putInt32ToBytesField(2, TestUtil.toBytes("22")) 94 .putInt32ToBytesField(3, TestUtil.toBytes("33")) 95 .putInt32ToEnumField(1, TestMap.EnumValue.FOO) 96 .putInt32ToEnumField(2, TestMap.EnumValue.BAR) 97 .putInt32ToEnumField(3, TestMap.EnumValue.BAZ) 98 .putInt32ToMessageField(1, MessageValue.newBuilder().setValue(11).build()) 99 .putInt32ToMessageField(2, MessageValue.newBuilder().setValue(22).build()) 100 .putInt32ToMessageField(3, MessageValue.newBuilder().setValue(33).build()) 101 .putStringToInt32Field("1", 11) 102 .putStringToInt32Field("2", 22) 103 .putStringToInt32Field("3", 33); 104 } 105 testSetMapValues()106 public void testSetMapValues() { 107 TestMap.Builder usingMutableMapBuilder = TestMap.newBuilder(); 108 setMapValuesUsingMutableMap(usingMutableMapBuilder); 109 TestMap usingMutableMap = usingMutableMapBuilder.build(); 110 assertMapValuesSet(usingMutableMap); 111 112 TestMap.Builder usingAccessorsBuilder = TestMap.newBuilder(); 113 setMapValuesUsingAccessors(usingAccessorsBuilder); 114 TestMap usingAccessors = usingAccessorsBuilder.build(); 115 assertMapValuesSet(usingAccessors); 116 117 assertEquals(usingAccessors, usingMutableMap); 118 } 119 copyMapValues(TestMap source, TestMap.Builder destination)120 private void copyMapValues(TestMap source, TestMap.Builder destination) { 121 destination 122 .putAllInt32ToInt32Field(source.getInt32ToInt32Field()) 123 .putAllInt32ToStringField(source.getInt32ToStringField()) 124 .putAllInt32ToBytesField(source.getInt32ToBytesField()) 125 .putAllInt32ToEnumField(source.getInt32ToEnumField()) 126 .putAllInt32ToMessageField(source.getInt32ToMessageField()) 127 .putAllStringToInt32Field(source.getStringToInt32Field()); 128 } 129 assertMapValuesSet(TestMapOrBuilder message)130 private void assertMapValuesSet(TestMapOrBuilder message) { 131 assertEquals(3, message.getInt32ToInt32Field().size()); 132 assertEquals(11, message.getInt32ToInt32Field().get(1).intValue()); 133 assertEquals(22, message.getInt32ToInt32Field().get(2).intValue()); 134 assertEquals(33, message.getInt32ToInt32Field().get(3).intValue()); 135 136 assertEquals(3, message.getInt32ToStringField().size()); 137 assertEquals("11", message.getInt32ToStringField().get(1)); 138 assertEquals("22", message.getInt32ToStringField().get(2)); 139 assertEquals("33", message.getInt32ToStringField().get(3)); 140 141 assertEquals(3, message.getInt32ToBytesField().size()); 142 assertEquals(TestUtil.toBytes("11"), message.getInt32ToBytesField().get(1)); 143 assertEquals(TestUtil.toBytes("22"), message.getInt32ToBytesField().get(2)); 144 assertEquals(TestUtil.toBytes("33"), message.getInt32ToBytesField().get(3)); 145 146 assertEquals(3, message.getInt32ToEnumField().size()); 147 assertEquals(TestMap.EnumValue.FOO, message.getInt32ToEnumField().get(1)); 148 assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumField().get(2)); 149 assertEquals(TestMap.EnumValue.BAZ, message.getInt32ToEnumField().get(3)); 150 151 assertEquals(3, message.getInt32ToMessageField().size()); 152 assertEquals(11, message.getInt32ToMessageField().get(1).getValue()); 153 assertEquals(22, message.getInt32ToMessageField().get(2).getValue()); 154 assertEquals(33, message.getInt32ToMessageField().get(3).getValue()); 155 156 assertEquals(3, message.getStringToInt32Field().size()); 157 assertEquals(11, message.getStringToInt32Field().get("1").intValue()); 158 assertEquals(22, message.getStringToInt32Field().get("2").intValue()); 159 assertEquals(33, message.getStringToInt32Field().get("3").intValue()); 160 } 161 updateMapValuesUsingMutableMap(TestMap.Builder builder)162 private void updateMapValuesUsingMutableMap(TestMap.Builder builder) { 163 builder.getMutableInt32ToInt32Field().put(1, 111); 164 builder.getMutableInt32ToInt32Field().remove(2); 165 builder.getMutableInt32ToInt32Field().put(4, 44); 166 // 167 builder.getMutableInt32ToStringField().put(1, "111"); 168 builder.getMutableInt32ToStringField().remove(2); 169 builder.getMutableInt32ToStringField().put(4, "44"); 170 // 171 builder.getMutableInt32ToBytesField().put(1, TestUtil.toBytes("111")); 172 builder.getMutableInt32ToBytesField().remove(2); 173 builder.getMutableInt32ToBytesField().put(4, TestUtil.toBytes("44")); 174 // 175 builder.getMutableInt32ToEnumField().put(1, TestMap.EnumValue.BAR); 176 builder.getMutableInt32ToEnumField().remove(2); 177 builder.getMutableInt32ToEnumField().put(4, TestMap.EnumValue.QUX); 178 // 179 builder.getMutableInt32ToMessageField().put( 180 1, MessageValue.newBuilder().setValue(111).build()); 181 builder.getMutableInt32ToMessageField().remove(2); 182 builder.getMutableInt32ToMessageField().put( 183 4, MessageValue.newBuilder().setValue(44).build()); 184 // 185 builder.getMutableStringToInt32Field().put("1", 111); 186 builder.getMutableStringToInt32Field().remove("2"); 187 builder.getMutableStringToInt32Field().put("4", 44); 188 } 189 updateMapValuesUsingAccessors(TestMap.Builder builder)190 private void updateMapValuesUsingAccessors(TestMap.Builder builder) { 191 builder 192 .putInt32ToInt32Field(1, 111) 193 .removeInt32ToInt32Field(2) 194 .putInt32ToInt32Field(4, 44) 195 .putInt32ToStringField(1, "111") 196 .removeInt32ToStringField(2) 197 .putInt32ToStringField(4, "44") 198 .putInt32ToBytesField(1, TestUtil.toBytes("111")) 199 .removeInt32ToBytesField(2) 200 .putInt32ToBytesField(4, TestUtil.toBytes("44")) 201 .putInt32ToEnumField(1, TestMap.EnumValue.BAR) 202 .removeInt32ToEnumField(2) 203 .putInt32ToEnumField(4, TestMap.EnumValue.QUX) 204 .putInt32ToMessageField(1, MessageValue.newBuilder().setValue(111).build()) 205 .removeInt32ToMessageField(2) 206 .putInt32ToMessageField(4, MessageValue.newBuilder().setValue(44).build()) 207 .putStringToInt32Field("1", 111) 208 .removeStringToInt32Field("2") 209 .putStringToInt32Field("4", 44); 210 } 211 testUpdateMapValues()212 public void testUpdateMapValues() { 213 TestMap.Builder usingMutableMapBuilder = TestMap.newBuilder(); 214 setMapValuesUsingMutableMap(usingMutableMapBuilder); 215 TestMap usingMutableMap = usingMutableMapBuilder.build(); 216 assertMapValuesSet(usingMutableMap); 217 218 TestMap.Builder usingAccessorsBuilder = TestMap.newBuilder(); 219 setMapValuesUsingAccessors(usingAccessorsBuilder); 220 TestMap usingAccessors = usingAccessorsBuilder.build(); 221 assertMapValuesSet(usingAccessors); 222 223 assertEquals(usingAccessors, usingMutableMap); 224 // 225 usingMutableMapBuilder = usingMutableMap.toBuilder(); 226 updateMapValuesUsingMutableMap(usingMutableMapBuilder); 227 usingMutableMap = usingMutableMapBuilder.build(); 228 assertMapValuesUpdated(usingMutableMap); 229 230 usingAccessorsBuilder = usingAccessors.toBuilder(); 231 updateMapValuesUsingAccessors(usingAccessorsBuilder); 232 usingAccessors = usingAccessorsBuilder.build(); 233 assertMapValuesUpdated(usingAccessors); 234 235 assertEquals(usingAccessors, usingMutableMap); 236 } 237 assertMapValuesUpdated(TestMap message)238 private void assertMapValuesUpdated(TestMap message) { 239 assertEquals(3, message.getInt32ToInt32Field().size()); 240 assertEquals(111, message.getInt32ToInt32Field().get(1).intValue()); 241 assertEquals(33, message.getInt32ToInt32Field().get(3).intValue()); 242 assertEquals(44, message.getInt32ToInt32Field().get(4).intValue()); 243 244 assertEquals(3, message.getInt32ToStringField().size()); 245 assertEquals("111", message.getInt32ToStringField().get(1)); 246 assertEquals("33", message.getInt32ToStringField().get(3)); 247 assertEquals("44", message.getInt32ToStringField().get(4)); 248 249 assertEquals(3, message.getInt32ToBytesField().size()); 250 assertEquals(TestUtil.toBytes("111"), message.getInt32ToBytesField().get(1)); 251 assertEquals(TestUtil.toBytes("33"), message.getInt32ToBytesField().get(3)); 252 assertEquals(TestUtil.toBytes("44"), message.getInt32ToBytesField().get(4)); 253 254 assertEquals(3, message.getInt32ToEnumField().size()); 255 assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumField().get(1)); 256 assertEquals(TestMap.EnumValue.BAZ, message.getInt32ToEnumField().get(3)); 257 assertEquals(TestMap.EnumValue.QUX, message.getInt32ToEnumField().get(4)); 258 259 assertEquals(3, message.getInt32ToMessageField().size()); 260 assertEquals(111, message.getInt32ToMessageField().get(1).getValue()); 261 assertEquals(33, message.getInt32ToMessageField().get(3).getValue()); 262 assertEquals(44, message.getInt32ToMessageField().get(4).getValue()); 263 264 assertEquals(3, message.getStringToInt32Field().size()); 265 assertEquals(111, message.getStringToInt32Field().get("1").intValue()); 266 assertEquals(33, message.getStringToInt32Field().get("3").intValue()); 267 assertEquals(44, message.getStringToInt32Field().get("4").intValue()); 268 } 269 assertMapValuesCleared(TestMapOrBuilder testMapOrBuilder)270 private void assertMapValuesCleared(TestMapOrBuilder testMapOrBuilder) { 271 assertEquals(0, testMapOrBuilder.getInt32ToInt32Field().size()); 272 assertEquals(0, testMapOrBuilder.getInt32ToInt32FieldCount()); 273 assertEquals(0, testMapOrBuilder.getInt32ToStringField().size()); 274 assertEquals(0, testMapOrBuilder.getInt32ToStringFieldCount()); 275 assertEquals(0, testMapOrBuilder.getInt32ToBytesField().size()); 276 assertEquals(0, testMapOrBuilder.getInt32ToBytesFieldCount()); 277 assertEquals(0, testMapOrBuilder.getInt32ToEnumField().size()); 278 assertEquals(0, testMapOrBuilder.getInt32ToEnumFieldCount()); 279 assertEquals(0, testMapOrBuilder.getInt32ToMessageField().size()); 280 assertEquals(0, testMapOrBuilder.getInt32ToMessageFieldCount()); 281 assertEquals(0, testMapOrBuilder.getStringToInt32Field().size()); 282 assertEquals(0, testMapOrBuilder.getStringToInt32FieldCount()); 283 } 284 testGetMapIsImmutable()285 public void testGetMapIsImmutable() { 286 TestMap.Builder builder = TestMap.newBuilder(); 287 assertMapsAreImmutable(builder); 288 assertMapsAreImmutable(builder.build()); 289 290 setMapValuesUsingAccessors(builder); 291 assertMapsAreImmutable(builder); 292 assertMapsAreImmutable(builder.build()); 293 } 294 assertMapsAreImmutable(TestMapOrBuilder testMapOrBuilder)295 private void assertMapsAreImmutable(TestMapOrBuilder testMapOrBuilder) { 296 assertImmutable(testMapOrBuilder.getInt32ToInt32Field(), 1, 2); 297 assertImmutable(testMapOrBuilder.getInt32ToStringField(), 1, "2"); 298 assertImmutable(testMapOrBuilder.getInt32ToBytesField(), 1, TestUtil.toBytes("2")); 299 assertImmutable(testMapOrBuilder.getInt32ToEnumField(), 1, TestMap.EnumValue.FOO); 300 assertImmutable( 301 testMapOrBuilder.getInt32ToMessageField(), 1, MessageValue.getDefaultInstance()); 302 assertImmutable(testMapOrBuilder.getStringToInt32Field(), "1", 2); 303 } 304 assertImmutable(Map<K, V> map, K key, V value)305 private <K, V> void assertImmutable(Map<K, V> map, K key, V value) { 306 try { 307 map.put(key, value); 308 fail(); 309 } catch (UnsupportedOperationException e) { 310 // expected 311 } 312 } 313 testMutableMapLifecycle()314 public void testMutableMapLifecycle() { 315 TestMap.Builder builder = TestMap.newBuilder(); 316 Map<Integer, Integer> intMap = builder.getMutableInt32ToInt32Field(); 317 intMap.put(1, 2); 318 assertEquals(newMap(1, 2), builder.build().getInt32ToInt32Field()); 319 try { 320 intMap.put(2, 3); 321 fail(); 322 } catch (UnsupportedOperationException e) { 323 // expected 324 } 325 assertEquals(newMap(1, 2), builder.getInt32ToInt32Field()); 326 builder.getMutableInt32ToInt32Field().put(2, 3); 327 assertEquals(newMap(1, 2, 2, 3), builder.getInt32ToInt32Field()); 328 // 329 Map<Integer, TestMap.EnumValue> enumMap = builder.getMutableInt32ToEnumField(); 330 enumMap.put(1, TestMap.EnumValue.BAR); 331 assertEquals(newMap(1, TestMap.EnumValue.BAR), builder.build().getInt32ToEnumField()); 332 try { 333 enumMap.put(2, TestMap.EnumValue.FOO); 334 fail(); 335 } catch (UnsupportedOperationException e) { 336 // expected 337 } 338 assertEquals(newMap(1, TestMap.EnumValue.BAR), builder.getInt32ToEnumField()); 339 builder.getMutableInt32ToEnumField().put(2, TestMap.EnumValue.FOO); 340 assertEquals( 341 newMap(1, TestMap.EnumValue.BAR, 2, TestMap.EnumValue.FOO), 342 builder.getInt32ToEnumField()); 343 // 344 Map<Integer, String> stringMap = builder.getMutableInt32ToStringField(); 345 stringMap.put(1, "1"); 346 assertEquals(newMap(1, "1"), builder.build().getInt32ToStringField()); 347 try { 348 stringMap.put(2, "2"); 349 fail(); 350 } catch (UnsupportedOperationException e) { 351 // expected 352 } 353 assertEquals(newMap(1, "1"), builder.getInt32ToStringField()); 354 builder.getMutableInt32ToStringField().put(2, "2"); 355 assertEquals( 356 newMap(1, "1", 2, "2"), 357 builder.getInt32ToStringField()); 358 // 359 Map<Integer, TestMap.MessageValue> messageMap = builder.getMutableInt32ToMessageField(); 360 messageMap.put(1, TestMap.MessageValue.getDefaultInstance()); 361 assertEquals(newMap(1, TestMap.MessageValue.getDefaultInstance()), 362 builder.build().getInt32ToMessageField()); 363 try { 364 messageMap.put(2, TestMap.MessageValue.getDefaultInstance()); 365 fail(); 366 } catch (UnsupportedOperationException e) { 367 // expected 368 } 369 assertEquals(newMap(1, TestMap.MessageValue.getDefaultInstance()), 370 builder.getInt32ToMessageField()); 371 builder.getMutableInt32ToMessageField().put(2, TestMap.MessageValue.getDefaultInstance()); 372 assertEquals( 373 newMap(1, TestMap.MessageValue.getDefaultInstance(), 374 2, TestMap.MessageValue.getDefaultInstance()), 375 builder.getInt32ToMessageField()); 376 } 377 // testMutableMapLifecycle_collections()378 public void testMutableMapLifecycle_collections() { 379 TestMap.Builder builder = TestMap.newBuilder(); 380 Map<Integer, Integer> intMap = builder.getMutableInt32ToInt32Field(); 381 intMap.put(1, 2); 382 assertEquals(newMap(1, 2), builder.build().getInt32ToInt32Field()); 383 try { 384 intMap.remove(2); 385 fail(); 386 } catch (UnsupportedOperationException e) { 387 // expected 388 } 389 try { 390 intMap.entrySet().remove(new Object()); 391 fail(); 392 } catch (UnsupportedOperationException e) { 393 // expected 394 } 395 try { 396 intMap.entrySet().iterator().remove(); 397 fail(); 398 } catch (UnsupportedOperationException e) { 399 // expected 400 } 401 try { 402 intMap.keySet().remove(new Object()); 403 fail(); 404 } catch (UnsupportedOperationException e) { 405 // expected 406 } 407 try { 408 intMap.values().remove(new Object()); 409 fail(); 410 } catch (UnsupportedOperationException e) { 411 // expected 412 } 413 try { 414 intMap.values().iterator().remove(); 415 fail(); 416 } catch (UnsupportedOperationException e) { 417 // expected 418 } 419 assertEquals(newMap(1, 2), intMap); 420 assertEquals(newMap(1, 2), builder.getInt32ToInt32Field()); 421 assertEquals(newMap(1, 2), builder.build().getInt32ToInt32Field()); 422 } 423 // newMap(K key1, V value1)424 private static <K, V> Map<K, V> newMap(K key1, V value1) { 425 Map<K, V> map = new HashMap<K, V>(); 426 map.put(key1, value1); 427 return map; 428 } 429 // newMap(K key1, V value1, K key2, V value2)430 private static <K, V> Map<K, V> newMap(K key1, V value1, K key2, V value2) { 431 Map<K, V> map = new HashMap<K, V>(); 432 map.put(key1, value1); 433 map.put(key2, value2); 434 return map; 435 } 436 testGettersAndSetters()437 public void testGettersAndSetters() throws Exception { 438 TestMap.Builder builder = TestMap.newBuilder(); 439 TestMap message = builder.build(); 440 assertMapValuesCleared(message); 441 442 builder = message.toBuilder(); 443 setMapValuesUsingAccessors(builder); 444 message = builder.build(); 445 assertMapValuesSet(message); 446 447 builder = message.toBuilder(); 448 updateMapValuesUsingAccessors(builder); 449 message = builder.build(); 450 assertMapValuesUpdated(message); 451 452 builder = message.toBuilder(); 453 builder.clear(); 454 assertMapValuesCleared(builder); 455 message = builder.build(); 456 assertMapValuesCleared(message); 457 } 458 testPutAll()459 public void testPutAll() throws Exception { 460 TestMap.Builder sourceBuilder = TestMap.newBuilder(); 461 setMapValuesUsingAccessors(sourceBuilder); 462 TestMap source = sourceBuilder.build(); 463 assertMapValuesSet(source); 464 465 TestMap.Builder destination = TestMap.newBuilder(); 466 copyMapValues(source, destination); 467 assertMapValuesSet(destination.build()); 468 469 assertEquals(3, destination.getInt32ToEnumFieldCount()); 470 } 471 testPutChecksNullKeysAndValues()472 public void testPutChecksNullKeysAndValues() throws Exception { 473 TestMap.Builder builder = TestMap.newBuilder(); 474 475 try { 476 builder.putInt32ToStringField(1, null); 477 fail(); 478 } catch (NullPointerException e) { 479 // expected. 480 } 481 482 try { 483 builder.putInt32ToBytesField(1, null); 484 fail(); 485 } catch (NullPointerException e) { 486 // expected. 487 } 488 489 try { 490 builder.putInt32ToEnumField(1, null); 491 fail(); 492 } catch (NullPointerException e) { 493 // expected. 494 } 495 496 try { 497 builder.putInt32ToMessageField(1, null); 498 fail(); 499 } catch (NullPointerException e) { 500 // expected. 501 } 502 503 try { 504 builder.putStringToInt32Field(null, 1); 505 fail(); 506 } catch (NullPointerException e) { 507 // expected. 508 } 509 } 510 testSerializeAndParse()511 public void testSerializeAndParse() throws Exception { 512 TestMap.Builder builder = TestMap.newBuilder(); 513 setMapValuesUsingAccessors(builder); 514 TestMap message = builder.build(); 515 assertEquals(message.getSerializedSize(), message.toByteString().size()); 516 message = TestMap.parser().parseFrom(message.toByteString()); 517 assertMapValuesSet(message); 518 519 builder = message.toBuilder(); 520 updateMapValuesUsingAccessors(builder); 521 message = builder.build(); 522 assertEquals(message.getSerializedSize(), message.toByteString().size()); 523 message = TestMap.parser().parseFrom(message.toByteString()); 524 assertMapValuesUpdated(message); 525 526 builder = message.toBuilder(); 527 builder.clear(); 528 message = builder.build(); 529 assertEquals(message.getSerializedSize(), message.toByteString().size()); 530 message = TestMap.parser().parseFrom(message.toByteString()); 531 assertMapValuesCleared(message); 532 } 533 tryParseTestMap(BizarroTestMap bizarroMap)534 private TestMap tryParseTestMap(BizarroTestMap bizarroMap) throws IOException { 535 ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); 536 CodedOutputStream output = CodedOutputStream.newInstance(byteArrayOutputStream); 537 bizarroMap.writeTo(output); 538 output.flush(); 539 return TestMap.parser().parseFrom(ByteString.copyFrom(byteArrayOutputStream.toByteArray())); 540 } 541 testParseError()542 public void testParseError() throws Exception { 543 ByteString bytes = TestUtil.toBytes("SOME BYTES"); 544 String stringKey = "a string key"; 545 546 TestMap map = 547 tryParseTestMap(BizarroTestMap.newBuilder().putInt32ToInt32Field(5, bytes).build()); 548 assertEquals(0, map.getInt32ToInt32FieldOrDefault(5, -1)); 549 550 map = tryParseTestMap(BizarroTestMap.newBuilder().putInt32ToStringField(stringKey, 5).build()); 551 assertEquals("", map.getInt32ToStringFieldOrDefault(0, null)); 552 553 map = tryParseTestMap(BizarroTestMap.newBuilder().putInt32ToBytesField(stringKey, 5).build()); 554 assertEquals(map.getInt32ToBytesFieldOrDefault(0, null), ByteString.EMPTY); 555 556 map = 557 tryParseTestMap(BizarroTestMap.newBuilder().putInt32ToEnumField(stringKey, bytes).build()); 558 assertEquals(TestMap.EnumValue.FOO, map.getInt32ToEnumFieldOrDefault(0, null)); 559 560 try { 561 tryParseTestMap(BizarroTestMap.newBuilder().putInt32ToMessageField(stringKey, bytes).build()); 562 fail(); 563 } catch (InvalidProtocolBufferException expected) { 564 assertTrue(expected.getUnfinishedMessage() instanceof TestMap); 565 map = (TestMap) expected.getUnfinishedMessage(); 566 assertTrue(map.getInt32ToMessageField().isEmpty()); 567 } 568 569 map = 570 tryParseTestMap( 571 BizarroTestMap.newBuilder().putStringToInt32Field(stringKey, bytes).build()); 572 assertEquals(0, map.getStringToInt32FieldOrDefault(stringKey, -1)); 573 } 574 testMergeFrom()575 public void testMergeFrom() throws Exception { 576 TestMap.Builder builder = TestMap.newBuilder(); 577 setMapValuesUsingAccessors(builder); 578 TestMap message = builder.build(); 579 580 TestMap.Builder other = TestMap.newBuilder(); 581 other.mergeFrom(message); 582 assertMapValuesSet(other.build()); 583 } 584 testEqualsAndHashCode()585 public void testEqualsAndHashCode() throws Exception { 586 // Test that generated equals() and hashCode() will disregard the order 587 // of map entries when comparing/hashing map fields. 588 589 // We can't control the order of elements in a HashMap. The best we can do 590 // here is to add elements in different order. 591 TestMap.Builder b1 = TestMap.newBuilder(); 592 b1.putInt32ToInt32Field(1, 2); 593 b1.putInt32ToInt32Field(3, 4); 594 b1.putInt32ToInt32Field(5, 6); 595 TestMap m1 = b1.build(); 596 597 TestMap.Builder b2 = TestMap.newBuilder(); 598 b2.putInt32ToInt32Field(5, 6); 599 b2.putInt32ToInt32Field(1, 2); 600 b2.putInt32ToInt32Field(3, 4); 601 TestMap m2 = b2.build(); 602 603 assertEquals(m1, m2); 604 assertEquals(m1.hashCode(), m2.hashCode()); 605 606 // Make sure we did compare map fields. 607 b2.putInt32ToInt32Field(1, 0); 608 m2 = b2.build(); 609 assertFalse(m1.equals(m2)); 610 // Don't check m1.hashCode() != m2.hashCode() because it's not guaranteed 611 // to be different. 612 } 613 614 615 // The following methods are used to test reflection API. 616 f(String name)617 private static FieldDescriptor f(String name) { 618 return TestMap.getDescriptor().findFieldByName(name); 619 } 620 getFieldValue(Message mapEntry, String name)621 private static Object getFieldValue(Message mapEntry, String name) { 622 FieldDescriptor field = mapEntry.getDescriptorForType().findFieldByName(name); 623 return mapEntry.getField(field); 624 } 625 setFieldValue( Message.Builder mapEntry, String name, Object value)626 private static Message.Builder setFieldValue( 627 Message.Builder mapEntry, String name, Object value) { 628 FieldDescriptor field = mapEntry.getDescriptorForType().findFieldByName(name); 629 mapEntry.setField(field, value); 630 return mapEntry; 631 } 632 assertHasMapValues(Message message, String name, Map<?, ?> values)633 private static void assertHasMapValues(Message message, String name, Map<?, ?> values) { 634 FieldDescriptor field = f(name); 635 for (Object entry : (List<?>) message.getField(field)) { 636 Message mapEntry = (Message) entry; 637 Object key = getFieldValue(mapEntry, "key"); 638 Object value = getFieldValue(mapEntry, "value"); 639 assertTrue(values.containsKey(key)); 640 assertEquals(value, values.get(key)); 641 } 642 assertEquals(values.size(), message.getRepeatedFieldCount(field)); 643 for (int i = 0; i < message.getRepeatedFieldCount(field); i++) { 644 Message mapEntry = (Message) message.getRepeatedField(field, i); 645 Object key = getFieldValue(mapEntry, "key"); 646 Object value = getFieldValue(mapEntry, "value"); 647 assertTrue(values.containsKey(key)); 648 assertEquals(value, values.get(key)); 649 } 650 } 651 newMapEntry(Message.Builder builder, String name, K key, V value)652 private static <K, V> Message newMapEntry(Message.Builder builder, String name, K key, V value) { 653 FieldDescriptor field = builder.getDescriptorForType().findFieldByName(name); 654 Message.Builder entryBuilder = builder.newBuilderForField(field); 655 FieldDescriptor keyField = entryBuilder.getDescriptorForType().findFieldByName("key"); 656 FieldDescriptor valueField = entryBuilder.getDescriptorForType().findFieldByName("value"); 657 entryBuilder.setField(keyField, key); 658 entryBuilder.setField(valueField, value); 659 return entryBuilder.build(); 660 } 661 setMapValues(Message.Builder builder, String name, Map<?, ?> values)662 private static void setMapValues(Message.Builder builder, String name, Map<?, ?> values) { 663 List<Message> entryList = new ArrayList<Message>(); 664 for (Map.Entry<?, ?> entry : values.entrySet()) { 665 entryList.add(newMapEntry(builder, name, entry.getKey(), entry.getValue())); 666 } 667 FieldDescriptor field = builder.getDescriptorForType().findFieldByName(name); 668 builder.setField(field, entryList); 669 } 670 mapForValues(K key1, V value1, K key2, V value2)671 private static <K, V> Map<K, V> mapForValues(K key1, V value1, K key2, V value2) { 672 Map<K, V> map = new HashMap<K, V>(); 673 map.put(key1, value1); 674 map.put(key2, value2); 675 return map; 676 } 677 testReflectionApi()678 public void testReflectionApi() throws Exception { 679 // In reflection API, map fields are just repeated message fields. 680 TestMap.Builder builder = 681 TestMap.newBuilder() 682 .putInt32ToInt32Field(1, 2) 683 .putInt32ToInt32Field(3, 4) 684 .putInt32ToMessageField(11, MessageValue.newBuilder().setValue(22).build()) 685 .putInt32ToMessageField(33, MessageValue.newBuilder().setValue(44).build()); 686 TestMap message = builder.build(); 687 688 // Test getField(), getRepeatedFieldCount(), getRepeatedField(). 689 assertHasMapValues(message, "int32_to_int32_field", mapForValues(1, 2, 3, 4)); 690 assertHasMapValues( 691 message, 692 "int32_to_message_field", 693 mapForValues( 694 11, MessageValue.newBuilder().setValue(22).build(), 695 33, MessageValue.newBuilder().setValue(44).build())); 696 697 // Test clearField() 698 builder.clearField(f("int32_to_int32_field")); 699 builder.clearField(f("int32_to_message_field")); 700 message = builder.build(); 701 assertEquals(0, message.getInt32ToInt32Field().size()); 702 assertEquals(0, message.getInt32ToMessageField().size()); 703 704 // Test setField() 705 setMapValues(builder, "int32_to_int32_field", mapForValues(11, 22, 33, 44)); 706 setMapValues( 707 builder, 708 "int32_to_message_field", 709 mapForValues( 710 111, MessageValue.newBuilder().setValue(222).build(), 711 333, MessageValue.newBuilder().setValue(444).build())); 712 message = builder.build(); 713 assertEquals(22, message.getInt32ToInt32Field().get(11).intValue()); 714 assertEquals(44, message.getInt32ToInt32Field().get(33).intValue()); 715 assertEquals(222, message.getInt32ToMessageField().get(111).getValue()); 716 assertEquals(444, message.getInt32ToMessageField().get(333).getValue()); 717 718 // Test addRepeatedField 719 builder.addRepeatedField( 720 f("int32_to_int32_field"), newMapEntry(builder, "int32_to_int32_field", 55, 66)); 721 builder.addRepeatedField( 722 f("int32_to_message_field"), 723 newMapEntry( 724 builder, 725 "int32_to_message_field", 726 555, 727 MessageValue.newBuilder().setValue(666).build())); 728 message = builder.build(); 729 assertEquals(66, message.getInt32ToInt32Field().get(55).intValue()); 730 assertEquals(666, message.getInt32ToMessageField().get(555).getValue()); 731 732 // Test addRepeatedField (overriding existing values) 733 builder.addRepeatedField( 734 f("int32_to_int32_field"), newMapEntry(builder, "int32_to_int32_field", 55, 55)); 735 builder.addRepeatedField( 736 f("int32_to_message_field"), 737 newMapEntry( 738 builder, 739 "int32_to_message_field", 740 555, 741 MessageValue.newBuilder().setValue(555).build())); 742 message = builder.build(); 743 assertEquals(55, message.getInt32ToInt32Field().get(55).intValue()); 744 assertEquals(555, message.getInt32ToMessageField().get(555).getValue()); 745 746 // Test setRepeatedField 747 for (int i = 0; i < builder.getRepeatedFieldCount(f("int32_to_int32_field")); i++) { 748 Message mapEntry = (Message) builder.getRepeatedField(f("int32_to_int32_field"), i); 749 int oldKey = ((Integer) getFieldValue(mapEntry, "key")).intValue(); 750 int oldValue = ((Integer) getFieldValue(mapEntry, "value")).intValue(); 751 // Swap key with value for each entry. 752 Message.Builder mapEntryBuilder = mapEntry.toBuilder(); 753 setFieldValue(mapEntryBuilder, "key", oldValue); 754 setFieldValue(mapEntryBuilder, "value", oldKey); 755 builder.setRepeatedField(f("int32_to_int32_field"), i, mapEntryBuilder.build()); 756 } 757 message = builder.build(); 758 assertEquals(11, message.getInt32ToInt32Field().get(22).intValue()); 759 assertEquals(33, message.getInt32ToInt32Field().get(44).intValue()); 760 assertEquals(55, message.getInt32ToInt32Field().get(55).intValue()); 761 } 762 763 // See additional coverage in TextFormatTest.java. testTextFormat()764 public void testTextFormat() throws Exception { 765 TestMap.Builder builder = TestMap.newBuilder(); 766 setMapValuesUsingAccessors(builder); 767 TestMap message = builder.build(); 768 769 String textData = TextFormat.printer().printToString(message); 770 771 builder = TestMap.newBuilder(); 772 TextFormat.merge(textData, builder); 773 message = builder.build(); 774 775 assertMapValuesSet(message); 776 } 777 testDynamicMessage()778 public void testDynamicMessage() throws Exception { 779 TestMap.Builder builder = TestMap.newBuilder(); 780 setMapValuesUsingAccessors(builder); 781 TestMap message = builder.build(); 782 783 Message dynamicDefaultInstance = DynamicMessage.getDefaultInstance(TestMap.getDescriptor()); 784 Message dynamicMessage = 785 dynamicDefaultInstance.newBuilderForType().mergeFrom(message.toByteString()).build(); 786 787 assertEquals(message, dynamicMessage); 788 assertEquals(message.hashCode(), dynamicMessage.hashCode()); 789 } 790 791 // Check that DynamicMessage handles map field serialization the same way as generated code 792 // regarding unset key and value field in a map entry. testDynamicMessageUnsetKeyAndValue()793 public void testDynamicMessageUnsetKeyAndValue() throws Exception { 794 FieldDescriptor field = f("int32_to_int32_field"); 795 796 Message dynamicDefaultInstance = DynamicMessage.getDefaultInstance(TestMap.getDescriptor()); 797 Message.Builder builder = dynamicDefaultInstance.newBuilderForType(); 798 // Add an entry without key and value. 799 builder.addRepeatedField(field, builder.newBuilderForField(field).build()); 800 Message message = builder.build(); 801 ByteString bytes = message.toByteString(); 802 // Parse it back to the same generated type. 803 Message generatedMessage = TestMap.parseFrom(bytes); 804 // Assert the serialized bytes are equivalent. 805 assertEquals(generatedMessage.toByteString(), bytes); 806 } 807 testReflectionEqualsAndHashCode()808 public void testReflectionEqualsAndHashCode() throws Exception { 809 // Test that generated equals() and hashCode() will disregard the order 810 // of map entries when comparing/hashing map fields. 811 812 // We use DynamicMessage to test reflection based equals()/hashCode(). 813 Message dynamicDefaultInstance = DynamicMessage.getDefaultInstance(TestMap.getDescriptor()); 814 FieldDescriptor field = f("int32_to_int32_field"); 815 816 Message.Builder b1 = dynamicDefaultInstance.newBuilderForType(); 817 b1.addRepeatedField(field, newMapEntry(b1, "int32_to_int32_field", 1, 2)); 818 b1.addRepeatedField(field, newMapEntry(b1, "int32_to_int32_field", 3, 4)); 819 b1.addRepeatedField(field, newMapEntry(b1, "int32_to_int32_field", 5, 6)); 820 Message m1 = b1.build(); 821 822 Message.Builder b2 = dynamicDefaultInstance.newBuilderForType(); 823 b2.addRepeatedField(field, newMapEntry(b2, "int32_to_int32_field", 5, 6)); 824 b2.addRepeatedField(field, newMapEntry(b2, "int32_to_int32_field", 1, 2)); 825 b2.addRepeatedField(field, newMapEntry(b2, "int32_to_int32_field", 3, 4)); 826 Message m2 = b2.build(); 827 828 assertEquals(m1, m2); 829 assertEquals(m1.hashCode(), m2.hashCode()); 830 831 // Make sure we did compare map fields. 832 b2.setRepeatedField(field, 0, newMapEntry(b1, "int32_to_int32_field", 0, 0)); 833 m2 = b2.build(); 834 assertFalse(m1.equals(m2)); 835 // Don't check m1.hashCode() != m2.hashCode() because it's not guaranteed 836 // to be different. 837 } 838 testUnknownEnumValues()839 public void testUnknownEnumValues() throws Exception { 840 TestUnknownEnumValue.Builder builder = 841 TestUnknownEnumValue.newBuilder().putInt32ToInt32Field(1, 1).putInt32ToInt32Field(2, 54321); 842 ByteString data = builder.build().toByteString(); 843 844 TestMap message = TestMap.parseFrom(data); 845 // Entries with unknown enum values will be stored into UnknownFieldSet so 846 // there is only one entry in the map. 847 assertEquals(1, message.getInt32ToEnumField().size()); 848 assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumField().get(1)); 849 // UnknownFieldSet should not be empty. 850 assertFalse(message.getUnknownFields().asMap().isEmpty()); 851 // Serializing and parsing should preserve the unknown entry. 852 data = message.toByteString(); 853 TestUnknownEnumValue messageWithUnknownEnums = TestUnknownEnumValue.parseFrom(data); 854 assertEquals(2, messageWithUnknownEnums.getInt32ToInt32Field().size()); 855 assertEquals(1, messageWithUnknownEnums.getInt32ToInt32Field().get(1).intValue()); 856 assertEquals(54321, messageWithUnknownEnums.getInt32ToInt32Field().get(2).intValue()); 857 } 858 testRequiredMessage()859 public void testRequiredMessage() throws Exception { 860 TestMap.Builder builder = TestMap.newBuilder(); 861 builder.putRequiredMessageMap(0, MessageWithRequiredFields.newBuilder().buildPartial()); 862 TestMap message = builder.buildPartial(); 863 assertFalse(message.isInitialized()); 864 865 builder.putRequiredMessageMap(0, MessageWithRequiredFields.newBuilder().setValue(1).build()); 866 message = builder.build(); 867 assertTrue(message.isInitialized()); 868 } 869 testRecursiveMap()870 public void testRecursiveMap() throws Exception { 871 TestRecursiveMap.Builder builder = TestRecursiveMap.newBuilder(); 872 builder.putRecursiveMapField(1, TestRecursiveMap.newBuilder().setValue(2).build()); 873 builder.putRecursiveMapField(3, TestRecursiveMap.newBuilder().setValue(4).build()); 874 ByteString data = builder.build().toByteString(); 875 876 TestRecursiveMap message = TestRecursiveMap.parseFrom(data); 877 assertEquals(2, message.getRecursiveMapField().get(1).getValue()); 878 assertEquals(4, message.getRecursiveMapField().get(3).getValue()); 879 } 880 testIterationOrder()881 public void testIterationOrder() throws Exception { 882 TestMap.Builder builder = TestMap.newBuilder(); 883 setMapValuesUsingAccessors(builder); 884 TestMap message = builder.build(); 885 886 assertEquals( 887 Arrays.asList("1", "2", "3"), 888 new ArrayList<String>(message.getStringToInt32Field().keySet())); 889 } 890 testContains()891 public void testContains() { 892 TestMap.Builder builder = TestMap.newBuilder(); 893 setMapValuesUsingAccessors(builder); 894 assertMapContainsSetValues(builder); 895 assertMapContainsSetValues(builder.build()); 896 } 897 assertMapContainsSetValues(TestMapOrBuilder testMapOrBuilder)898 private void assertMapContainsSetValues(TestMapOrBuilder testMapOrBuilder) { 899 assertTrue(testMapOrBuilder.containsInt32ToInt32Field(1)); 900 assertTrue(testMapOrBuilder.containsInt32ToInt32Field(2)); 901 assertTrue(testMapOrBuilder.containsInt32ToInt32Field(3)); 902 assertFalse(testMapOrBuilder.containsInt32ToInt32Field(-1)); 903 904 assertTrue(testMapOrBuilder.containsInt32ToStringField(1)); 905 assertTrue(testMapOrBuilder.containsInt32ToStringField(2)); 906 assertTrue(testMapOrBuilder.containsInt32ToStringField(3)); 907 assertFalse(testMapOrBuilder.containsInt32ToStringField(-1)); 908 909 assertTrue(testMapOrBuilder.containsInt32ToBytesField(1)); 910 assertTrue(testMapOrBuilder.containsInt32ToBytesField(2)); 911 assertTrue(testMapOrBuilder.containsInt32ToBytesField(3)); 912 assertFalse(testMapOrBuilder.containsInt32ToBytesField(-1)); 913 914 assertTrue(testMapOrBuilder.containsInt32ToEnumField(1)); 915 assertTrue(testMapOrBuilder.containsInt32ToEnumField(2)); 916 assertTrue(testMapOrBuilder.containsInt32ToEnumField(3)); 917 assertFalse(testMapOrBuilder.containsInt32ToEnumField(-1)); 918 919 assertTrue(testMapOrBuilder.containsInt32ToMessageField(1)); 920 assertTrue(testMapOrBuilder.containsInt32ToMessageField(2)); 921 assertTrue(testMapOrBuilder.containsInt32ToMessageField(3)); 922 assertFalse(testMapOrBuilder.containsInt32ToMessageField(-1)); 923 924 assertTrue(testMapOrBuilder.containsStringToInt32Field("1")); 925 assertTrue(testMapOrBuilder.containsStringToInt32Field("2")); 926 assertTrue(testMapOrBuilder.containsStringToInt32Field("3")); 927 assertFalse(testMapOrBuilder.containsStringToInt32Field("-1")); 928 } 929 testCount()930 public void testCount() { 931 TestMap.Builder builder = TestMap.newBuilder(); 932 assertMapCounts(0, builder); 933 934 setMapValuesUsingAccessors(builder); 935 assertMapCounts(3, builder); 936 937 TestMap message = builder.build(); 938 assertMapCounts(3, message); 939 940 builder = message.toBuilder().putInt32ToInt32Field(4, 44); 941 assertEquals(4, builder.getInt32ToInt32FieldCount()); 942 assertEquals(4, builder.build().getInt32ToInt32FieldCount()); 943 944 // already present - should be unchanged 945 builder.putInt32ToInt32Field(4, 44); 946 assertEquals(4, builder.getInt32ToInt32FieldCount()); 947 } 948 assertMapCounts(int expectedCount, TestMapOrBuilder testMapOrBuilder)949 private void assertMapCounts(int expectedCount, TestMapOrBuilder testMapOrBuilder) { 950 assertEquals(expectedCount, testMapOrBuilder.getInt32ToInt32FieldCount()); 951 assertEquals(expectedCount, testMapOrBuilder.getInt32ToStringFieldCount()); 952 assertEquals(expectedCount, testMapOrBuilder.getInt32ToBytesFieldCount()); 953 assertEquals(expectedCount, testMapOrBuilder.getInt32ToEnumFieldCount()); 954 assertEquals(expectedCount, testMapOrBuilder.getInt32ToMessageFieldCount()); 955 assertEquals(expectedCount, testMapOrBuilder.getStringToInt32FieldCount()); 956 } 957 testGetOrDefault()958 public void testGetOrDefault() { 959 TestMap.Builder builder = TestMap.newBuilder(); 960 assertMapCounts(0, builder); 961 setMapValuesUsingAccessors(builder); 962 doTestGetOrDefault(builder); 963 doTestGetOrDefault(builder.build()); 964 } 965 doTestGetOrDefault(TestMapOrBuilder testMapOrBuilder)966 public void doTestGetOrDefault(TestMapOrBuilder testMapOrBuilder) { 967 assertEquals(11, testMapOrBuilder.getInt32ToInt32FieldOrDefault(1, -11)); 968 assertEquals(-11, testMapOrBuilder.getInt32ToInt32FieldOrDefault(-1, -11)); 969 970 assertEquals("11", testMapOrBuilder.getInt32ToStringFieldOrDefault(1, "-11")); 971 assertNull("-11", testMapOrBuilder.getInt32ToStringFieldOrDefault(-1, null)); 972 973 assertEquals(TestUtil.toBytes("11"), testMapOrBuilder.getInt32ToBytesFieldOrDefault(1, null)); 974 assertNull(testMapOrBuilder.getInt32ToBytesFieldOrDefault(-1, null)); 975 976 assertEquals(TestMap.EnumValue.FOO, testMapOrBuilder.getInt32ToEnumFieldOrDefault(1, null)); 977 assertNull(testMapOrBuilder.getInt32ToEnumFieldOrDefault(-1, null)); 978 979 assertEquals( 980 MessageValue.newBuilder().setValue(11).build(), 981 testMapOrBuilder.getInt32ToMessageFieldOrDefault(1, null)); 982 assertNull(testMapOrBuilder.getInt32ToMessageFieldOrDefault(-1, null)); 983 984 assertEquals(11, testMapOrBuilder.getStringToInt32FieldOrDefault("1", -11)); 985 assertEquals(-11, testMapOrBuilder.getStringToInt32FieldOrDefault("-1", -11)); 986 987 try { 988 testMapOrBuilder.getStringToInt32FieldOrDefault(null, -11); 989 fail(); 990 } catch (NullPointerException e) { 991 // expected 992 } 993 } 994 testGetOrThrow()995 public void testGetOrThrow() { 996 TestMap.Builder builder = TestMap.newBuilder(); 997 assertMapCounts(0, builder); 998 setMapValuesUsingAccessors(builder); 999 doTestGetOrDefault(builder); 1000 doTestGetOrDefault(builder.build()); 1001 } 1002 doTestGetOrThrow(TestMapOrBuilder testMapOrBuilder)1003 public void doTestGetOrThrow(TestMapOrBuilder testMapOrBuilder) { 1004 assertEquals(11, testMapOrBuilder.getInt32ToInt32FieldOrThrow(1)); 1005 try { 1006 testMapOrBuilder.getInt32ToInt32FieldOrThrow(-1); 1007 fail(); 1008 } catch (IllegalArgumentException e) { 1009 // expected 1010 } 1011 1012 assertEquals("11", testMapOrBuilder.getInt32ToStringFieldOrThrow(1)); 1013 1014 try { 1015 testMapOrBuilder.getInt32ToStringFieldOrThrow(-1); 1016 fail(); 1017 } catch (IllegalArgumentException e) { 1018 // expected 1019 } 1020 1021 assertEquals(TestUtil.toBytes("11"), testMapOrBuilder.getInt32ToBytesFieldOrThrow(1)); 1022 1023 try { 1024 testMapOrBuilder.getInt32ToBytesFieldOrThrow(-1); 1025 fail(); 1026 } catch (IllegalArgumentException e) { 1027 // expected 1028 } 1029 1030 assertEquals(TestMap.EnumValue.FOO, testMapOrBuilder.getInt32ToEnumFieldOrThrow(1)); 1031 try { 1032 testMapOrBuilder.getInt32ToEnumFieldOrThrow(-1); 1033 fail(); 1034 } catch (IllegalArgumentException e) { 1035 // expected 1036 } 1037 1038 assertEquals( 1039 MessageValue.newBuilder().setValue(11).build(), 1040 testMapOrBuilder.getInt32ToMessageFieldOrThrow(1)); 1041 try { 1042 testMapOrBuilder.getInt32ToMessageFieldOrThrow(-1); 1043 fail(); 1044 } catch (IllegalArgumentException e) { 1045 // expected 1046 } 1047 1048 assertEquals(11, testMapOrBuilder.getStringToInt32FieldOrThrow("1")); 1049 try { 1050 testMapOrBuilder.getStringToInt32FieldOrThrow("-1"); 1051 fail(); 1052 } catch (IllegalArgumentException e) { 1053 // expected 1054 } 1055 1056 try { 1057 testMapOrBuilder.getStringToInt32FieldOrThrow(null); 1058 fail(); 1059 } catch (NullPointerException e) { 1060 // expected 1061 } 1062 } 1063 testPut()1064 public void testPut() { 1065 TestMap.Builder builder = TestMap.newBuilder(); 1066 builder.putInt32ToInt32Field(1, 11); 1067 assertEquals(11, builder.getInt32ToInt32FieldOrThrow(1)); 1068 1069 builder.putInt32ToStringField(1, "a"); 1070 assertEquals("a", builder.getInt32ToStringFieldOrThrow(1)); 1071 try { 1072 builder.putInt32ToStringField(1, null); 1073 fail(); 1074 } catch (NullPointerException e) { 1075 // expected 1076 } 1077 1078 builder.putInt32ToBytesField(1, TestUtil.toBytes("11")); 1079 assertEquals(TestUtil.toBytes("11"), builder.getInt32ToBytesFieldOrThrow(1)); 1080 try { 1081 builder.putInt32ToBytesField(1, null); 1082 fail(); 1083 } catch (NullPointerException e) { 1084 // expected 1085 } 1086 1087 builder.putInt32ToEnumField(1, TestMap.EnumValue.FOO); 1088 assertEquals(TestMap.EnumValue.FOO, builder.getInt32ToEnumFieldOrThrow(1)); 1089 try { 1090 builder.putInt32ToEnumField(1, null); 1091 fail(); 1092 } catch (NullPointerException e) { 1093 // expected 1094 } 1095 1096 builder.putStringToInt32Field("a", 1); 1097 assertEquals(1, builder.getStringToInt32FieldOrThrow("a")); 1098 try { 1099 builder.putStringToInt32Field(null, -1); 1100 } catch (NullPointerException e) { 1101 // expected 1102 } 1103 } 1104 testRemove()1105 public void testRemove() { 1106 TestMap.Builder builder = TestMap.newBuilder(); 1107 setMapValuesUsingAccessors(builder); 1108 assertEquals(11, builder.getInt32ToInt32FieldOrThrow(1)); 1109 for (int times = 0; times < 2; times++) { 1110 builder.removeInt32ToInt32Field(1); 1111 assertEquals(-1, builder.getInt32ToInt32FieldOrDefault(1, -1)); 1112 } 1113 1114 assertEquals("11", builder.getInt32ToStringFieldOrThrow(1)); 1115 for (int times = 0; times < 2; times++) { 1116 builder.removeInt32ToStringField(1); 1117 assertNull(builder.getInt32ToStringFieldOrDefault(1, null)); 1118 } 1119 1120 assertEquals(TestUtil.toBytes("11"), builder.getInt32ToBytesFieldOrThrow(1)); 1121 for (int times = 0; times < 2; times++) { 1122 builder.removeInt32ToBytesField(1); 1123 assertNull(builder.getInt32ToBytesFieldOrDefault(1, null)); 1124 } 1125 1126 assertEquals(TestMap.EnumValue.FOO, builder.getInt32ToEnumFieldOrThrow(1)); 1127 for (int times = 0; times < 2; times++) { 1128 builder.removeInt32ToEnumField(1); 1129 assertNull(builder.getInt32ToEnumFieldOrDefault(1, null)); 1130 } 1131 1132 assertEquals(11, builder.getStringToInt32FieldOrThrow("1")); 1133 for (int times = 0; times < 2; times++) { 1134 builder.removeStringToInt32Field("1"); 1135 assertEquals(-1, builder.getStringToInt32FieldOrDefault("1", -1)); 1136 } 1137 1138 try { 1139 builder.removeStringToInt32Field(null); 1140 fail(); 1141 } catch (NullPointerException e) { 1142 // expected 1143 } 1144 } 1145 1146 // Regression test for b/20494788 testMapInitializationOrder()1147 public void testMapInitializationOrder() throws Exception { 1148 assertEquals( 1149 "RedactAllTypes", 1150 map_test.RedactAllTypes.getDefaultInstance() 1151 .getDescriptorForType() 1152 .getName()); 1153 1154 map_test.Message1.Builder builder = 1155 map_test.Message1.newBuilder(); 1156 builder.putMapField("key", true); 1157 map_test.Message1 message = builder.build(); 1158 Message mapEntry = 1159 (Message) 1160 message.getRepeatedField( 1161 message.getDescriptorForType().findFieldByName("map_field"), 0); 1162 assertEquals(2, mapEntry.getAllFields().size()); 1163 } 1164 testReservedWordsFieldNames()1165 public void testReservedWordsFieldNames() { 1166 ReservedAsMapField.newBuilder().build(); 1167 ReservedAsMapFieldWithEnumValue.newBuilder().build(); 1168 } 1169 testGetMap()1170 public void testGetMap() { 1171 TestMap.Builder builder = TestMap.newBuilder(); 1172 setMapValuesUsingAccessors(builder); 1173 assertMapValuesSet(builder); 1174 TestMap message = builder.build(); 1175 assertEquals(message.getStringToInt32Field(), message.getStringToInt32FieldMap()); 1176 assertEquals(message.getInt32ToBytesField(), message.getInt32ToBytesFieldMap()); 1177 assertEquals(message.getInt32ToEnumField(), message.getInt32ToEnumFieldMap()); 1178 assertEquals(message.getInt32ToMessageField(), message.getInt32ToMessageFieldMap()); 1179 } 1180 } 1181