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