Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(303)

Side by Side Diff: third_party/protobuf/java/core/src/main/java/com/google/protobuf/MapField.java

Issue 2590803003: Revert "third_party/protobuf: Update to HEAD (83d681ee2c)" (Closed)
Patch Set: Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Protocol Buffers - Google's data interchange format 1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc. All rights reserved. 2 // Copyright 2008 Google Inc. All rights reserved.
3 // https://developers.google.com/protocol-buffers/ 3 // https://developers.google.com/protocol-buffers/
4 // 4 //
5 // Redistribution and use in source and binary forms, with or without 5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are 6 // modification, are permitted provided that the following conditions are
7 // met: 7 // met:
8 // 8 //
9 // * Redistributions of source code must retain the above copyright 9 // * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer. 10 // notice, this list of conditions and the following disclaimer.
(...skipping 12 matching lines...) Expand all
23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 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. 29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 30
31 package com.google.protobuf; 31 package com.google.protobuf;
32 32
33 import com.google.protobuf.MapFieldLite.MutatabilityAwareMap;
34
33 import java.util.ArrayList; 35 import java.util.ArrayList;
34 import java.util.Collection;
35 import java.util.Collections; 36 import java.util.Collections;
36 import java.util.Iterator;
37 import java.util.LinkedHashMap; 37 import java.util.LinkedHashMap;
38 import java.util.List; 38 import java.util.List;
39 import java.util.Map; 39 import java.util.Map;
40 import java.util.Set;
41 40
42 /** 41 /**
43 * Internal representation of map fields in generated messages. 42 * Internal representation of map fields in generated messages.
44 * 43 *
45 * This class supports accessing the map field as a {@link Map} to be used in 44 * This class supports accessing the map field as a {@link Map} to be used in
46 * generated API and also supports accessing the field as a {@link List} to be 45 * generated API and also supports accessing the field as a {@link List} to be
47 * used in reflection API. It keeps track of where the data is currently stored 46 * used in reflection API. It keeps track of where the data is currently stored
48 * and do necessary conversions between map and list. 47 * and do necessary conversions between map and list.
49 * 48 *
50 * This class is a protobuf implementation detail. Users shouldn't use this 49 * This class is a protobuf implementation detail. Users shouldn't use this
51 * class directly. 50 * class directly.
52 * 51 *
53 * THREAD-SAFETY NOTE: Read-only access is thread-safe. Users can call getMap() 52 * THREAD-SAFETY NOTE: Read-only access is thread-safe. Users can call getMap()
54 * and getList() concurrently in multiple threads. If write-access is needed, 53 * and getList() concurrently in multiple threads. If write-access is needed,
55 * all access must be synchronized. 54 * all access must be synchronized.
56 */ 55 */
57 public class MapField<K, V> implements MutabilityOracle { 56 public class MapField<K, V> implements MutabilityOracle {
58 /** 57 /**
59 * Indicates where the data of this map field is currently stored. 58 * Indicates where the data of this map field is currently stored.
60 * 59 *
61 * MAP: Data is stored in mapData. 60 * MAP: Data is stored in mapData.
62 * LIST: Data is stored in listData. 61 * LIST: Data is stored in listData.
63 * BOTH: mapData and listData have the same data. 62 * BOTH: mapData and listData have the same data.
64 * 63 *
65 * When the map field is accessed (through generated API or reflection API), 64 * When the map field is accessed (through generated API or reflection API),
66 * it will shift between these 3 modes: 65 * it will shift between these 3 modes:
67 * 66 *
68 * getMap() getList() getMutableMap() getMutableList() 67 * getMap() getList() getMutableMap() getMutableList()
69 * MAP MAP BOTH MAP LIST 68 * MAP MAP BOTH MAP LIST
70 * LIST BOTH LIST MAP LIST 69 * LIST BOTH LIST MAP LIST
71 * BOTH BOTH BOTH MAP LIST 70 * BOTH BOTH BOTH MAP LIST
72 * 71 *
73 * As the map field changes its mode, the list/map reference returned in a 72 * As the map field changes its mode, the list/map reference returned in a
74 * previous method call may be invalidated. 73 * previous method call may be invalidated.
75 */ 74 */
76 private enum StorageMode {MAP, LIST, BOTH} 75 private enum StorageMode {MAP, LIST, BOTH}
77 76
78 private volatile boolean isMutable; 77 private volatile boolean isMutable;
79 private volatile StorageMode mode; 78 private volatile StorageMode mode;
80 private MutatabilityAwareMap<K, V> mapData; 79 private MutatabilityAwareMap<K, V> mapData;
81 private List<Message> listData; 80 private List<Message> listData;
82 81
83 // Convert between a map entry Message and a key-value pair. 82 // Convert between a map entry Message and a key-value pair.
84 private static interface Converter<K, V> { 83 private static interface Converter<K, V> {
85 Message convertKeyAndValueToMessage(K key, V value); 84 Message convertKeyAndValueToMessage(K key, V value);
86 void convertMessageToKeyAndValue(Message message, Map<K, V> map); 85 void convertMessageToKeyAndValue(Message message, Map<K, V> map);
87 86
88 Message getMessageDefaultInstance(); 87 Message getMessageDefaultInstance();
89 } 88 }
90 89
91 private static class ImmutableMessageConverter<K, V> implements Converter<K, V > { 90 private static class ImmutableMessageConverter<K, V> implements Converter<K, V > {
92 private final MapEntry<K, V> defaultEntry; 91 private final MapEntry<K, V> defaultEntry;
93 public ImmutableMessageConverter(MapEntry<K, V> defaultEntry) { 92 public ImmutableMessageConverter(MapEntry<K, V> defaultEntry) {
94 this.defaultEntry = defaultEntry; 93 this.defaultEntry = defaultEntry;
95 } 94 }
96 95
97 @Override 96 @Override
98 public Message convertKeyAndValueToMessage(K key, V value) { 97 public Message convertKeyAndValueToMessage(K key, V value) {
99 return defaultEntry.newBuilderForType().setKey(key).setValue(value).buildP artial(); 98 return defaultEntry.newBuilderForType().setKey(key).setValue(value).buildP artial();
100 } 99 }
101 100
102 @Override 101 @Override
103 public void convertMessageToKeyAndValue(Message message, Map<K, V> map) { 102 public void convertMessageToKeyAndValue(Message message, Map<K, V> map) {
104 MapEntry<K, V> entry = (MapEntry<K, V>) message; 103 MapEntry<K, V> entry = (MapEntry<K, V>) message;
105 map.put(entry.getKey(), entry.getValue()); 104 map.put(entry.getKey(), entry.getValue());
106 } 105 }
107 106
108 @Override 107 @Override
109 public Message getMessageDefaultInstance() { 108 public Message getMessageDefaultInstance() {
110 return defaultEntry; 109 return defaultEntry;
111 } 110 }
112 } 111 }
113 112
114 113
115 private final Converter<K, V> converter; 114 private final Converter<K, V> converter;
116 115
117 private MapField( 116 private MapField(
118 Converter<K, V> converter, 117 Converter<K, V> converter,
119 StorageMode mode, 118 StorageMode mode,
120 Map<K, V> mapData) { 119 Map<K, V> mapData) {
121 this.converter = converter; 120 this.converter = converter;
122 this.isMutable = true; 121 this.isMutable = true;
123 this.mode = mode; 122 this.mode = mode;
124 this.mapData = new MutatabilityAwareMap<K, V>(this, mapData); 123 this.mapData = new MutatabilityAwareMap<K, V>(this, mapData);
125 this.listData = null; 124 this.listData = null;
126 } 125 }
127 126
128 private MapField( 127 private MapField(
129 MapEntry<K, V> defaultEntry, 128 MapEntry<K, V> defaultEntry,
130 StorageMode mode, 129 StorageMode mode,
131 Map<K, V> mapData) { 130 Map<K, V> mapData) {
132 this(new ImmutableMessageConverter<K, V>(defaultEntry), mode, mapData); 131 this(new ImmutableMessageConverter<K, V>(defaultEntry), mode, mapData);
133 } 132 }
134 133
135 134
136 /** Returns an immutable empty MapField. */ 135 /** Returns an immutable empty MapField. */
137 public static <K, V> MapField<K, V> emptyMapField( 136 public static <K, V> MapField<K, V> emptyMapField(
138 MapEntry<K, V> defaultEntry) { 137 MapEntry<K, V> defaultEntry) {
139 return new MapField<K, V>( 138 return new MapField<K, V>(
140 defaultEntry, StorageMode.MAP, Collections.<K, V>emptyMap()); 139 defaultEntry, StorageMode.MAP, Collections.<K, V>emptyMap());
141 } 140 }
142 141
143 142
144 /** Creates a new mutable empty MapField. */ 143 /** Creates a new mutable empty MapField. */
145 public static <K, V> MapField<K, V> newMapField(MapEntry<K, V> defaultEntry) { 144 public static <K, V> MapField<K, V> newMapField(MapEntry<K, V> defaultEntry) {
146 return new MapField<K, V>( 145 return new MapField<K, V>(
147 defaultEntry, StorageMode.MAP, new LinkedHashMap<K, V>()); 146 defaultEntry, StorageMode.MAP, new LinkedHashMap<K, V>());
148 } 147 }
149 148
150 149
151 private Message convertKeyAndValueToMessage(K key, V value) { 150 private Message convertKeyAndValueToMessage(K key, V value) {
152 return converter.convertKeyAndValueToMessage(key, value); 151 return converter.convertKeyAndValueToMessage(key, value);
153 } 152 }
154 153
155 @SuppressWarnings("unchecked") 154 @SuppressWarnings("unchecked")
156 private void convertMessageToKeyAndValue(Message message, Map<K, V> map) { 155 private void convertMessageToKeyAndValue(Message message, Map<K, V> map) {
157 converter.convertMessageToKeyAndValue(message, map); 156 converter.convertMessageToKeyAndValue(message, map);
158 } 157 }
159 158
160 private List<Message> convertMapToList(MutatabilityAwareMap<K, V> mapData) { 159 private List<Message> convertMapToList(MutatabilityAwareMap<K, V> mapData) {
161 List<Message> listData = new ArrayList<Message>(); 160 List<Message> listData = new ArrayList<Message>();
162 for (Map.Entry<K, V> entry : mapData.entrySet()) { 161 for (Map.Entry<K, V> entry : mapData.entrySet()) {
163 listData.add( 162 listData.add(
164 convertKeyAndValueToMessage( 163 convertKeyAndValueToMessage(
165 entry.getKey(), entry.getValue())); 164 entry.getKey(), entry.getValue()));
166 } 165 }
167 return listData; 166 return listData;
168 } 167 }
169 168
170 private MutatabilityAwareMap<K, V> convertListToMap(List<Message> listData) { 169 private MutatabilityAwareMap<K, V> convertListToMap(List<Message> listData) {
171 Map<K, V> mapData = new LinkedHashMap<K, V>(); 170 Map<K, V> mapData = new LinkedHashMap<K, V>();
172 for (Message item : listData) { 171 for (Message item : listData) {
173 convertMessageToKeyAndValue(item, mapData); 172 convertMessageToKeyAndValue(item, mapData);
174 } 173 }
175 return new MutatabilityAwareMap<K, V>(this, mapData); 174 return new MutatabilityAwareMap<K, V>(this, mapData);
176 } 175 }
177 176
178 /** Returns the content of this MapField as a read-only Map. */ 177 /** Returns the content of this MapField as a read-only Map. */
179 public Map<K, V> getMap() { 178 public Map<K, V> getMap() {
180 if (mode == StorageMode.LIST) { 179 if (mode == StorageMode.LIST) {
181 synchronized (this) { 180 synchronized (this) {
182 if (mode == StorageMode.LIST) { 181 if (mode == StorageMode.LIST) {
183 mapData = convertListToMap(listData); 182 mapData = convertListToMap(listData);
184 mode = StorageMode.BOTH; 183 mode = StorageMode.BOTH;
185 } 184 }
186 } 185 }
187 } 186 }
188 return Collections.unmodifiableMap(mapData); 187 return Collections.unmodifiableMap(mapData);
189 } 188 }
190 189
191 /** Gets a mutable Map view of this MapField. */ 190 /** Gets a mutable Map view of this MapField. */
192 public Map<K, V> getMutableMap() { 191 public Map<K, V> getMutableMap() {
193 if (mode != StorageMode.MAP) { 192 if (mode != StorageMode.MAP) {
194 if (mode == StorageMode.LIST) { 193 if (mode == StorageMode.LIST) {
195 mapData = convertListToMap(listData); 194 mapData = convertListToMap(listData);
196 } 195 }
197 listData = null; 196 listData = null;
198 mode = StorageMode.MAP; 197 mode = StorageMode.MAP;
199 } 198 }
200 return mapData; 199 return mapData;
201 } 200 }
202 201
203 public void mergeFrom(MapField<K, V> other) { 202 public void mergeFrom(MapField<K, V> other) {
204 getMutableMap().putAll(MapFieldLite.copy(other.getMap())); 203 getMutableMap().putAll(MapFieldLite.copy(other.getMap()));
205 } 204 }
206 205
207 public void clear() { 206 public void clear() {
208 mapData = new MutatabilityAwareMap<K, V>(this, new LinkedHashMap<K, V>()); 207 mapData = new MutatabilityAwareMap<K, V>(this, new LinkedHashMap<K, V>());
209 mode = StorageMode.MAP; 208 mode = StorageMode.MAP;
210 } 209 }
211 210
212 @SuppressWarnings("unchecked") 211 @SuppressWarnings("unchecked")
213 @Override 212 @Override
214 public boolean equals(Object object) { 213 public boolean equals(Object object) {
215 if (!(object instanceof MapField)) { 214 if (!(object instanceof MapField)) {
216 return false; 215 return false;
217 } 216 }
218 MapField<K, V> other = (MapField<K, V>) object; 217 MapField<K, V> other = (MapField<K, V>) object;
219 return MapFieldLite.<K, V>equals(getMap(), other.getMap()); 218 return MapFieldLite.<K, V>equals(getMap(), other.getMap());
220 } 219 }
221 220
222 @Override 221 @Override
223 public int hashCode() { 222 public int hashCode() {
224 return MapFieldLite.<K, V>calculateHashCodeForMap(getMap()); 223 return MapFieldLite.<K, V>calculateHashCodeForMap(getMap());
225 } 224 }
226 225
227 /** Returns a deep copy of this MapField. */ 226 /** Returns a deep copy of this MapField. */
228 public MapField<K, V> copy() { 227 public MapField<K, V> copy() {
229 return new MapField<K, V>( 228 return new MapField<K, V>(
230 converter, StorageMode.MAP, MapFieldLite.copy(getMap())); 229 converter, StorageMode.MAP, MapFieldLite.copy(getMap()));
231 } 230 }
232 231
233 /** Gets the content of this MapField as a read-only List. */ 232 /** Gets the content of this MapField as a read-only List. */
234 List<Message> getList() { 233 List<Message> getList() {
235 if (mode == StorageMode.MAP) { 234 if (mode == StorageMode.MAP) {
236 synchronized (this) { 235 synchronized (this) {
237 if (mode == StorageMode.MAP) { 236 if (mode == StorageMode.MAP) {
238 listData = convertMapToList(mapData); 237 listData = convertMapToList(mapData);
239 mode = StorageMode.BOTH; 238 mode = StorageMode.BOTH;
240 } 239 }
241 } 240 }
242 } 241 }
243 return Collections.unmodifiableList(listData); 242 return Collections.unmodifiableList(listData);
244 } 243 }
245 244
246 /** Gets a mutable List view of this MapField. */ 245 /** Gets a mutable List view of this MapField. */
247 List<Message> getMutableList() { 246 List<Message> getMutableList() {
248 if (mode != StorageMode.LIST) { 247 if (mode != StorageMode.LIST) {
249 if (mode == StorageMode.MAP) { 248 if (mode == StorageMode.MAP) {
250 listData = convertMapToList(mapData); 249 listData = convertMapToList(mapData);
251 } 250 }
252 mapData = null; 251 mapData = null;
253 mode = StorageMode.LIST; 252 mode = StorageMode.LIST;
254 } 253 }
255 return listData; 254 return listData;
256 } 255 }
257 256
258 /** 257 /**
259 * Gets the default instance of the message stored in the list view of this 258 * Gets the default instance of the message stored in the list view of this
260 * map field. 259 * map field.
261 */ 260 */
262 Message getMapEntryMessageDefaultInstance() { 261 Message getMapEntryMessageDefaultInstance() {
263 return converter.getMessageDefaultInstance(); 262 return converter.getMessageDefaultInstance();
264 } 263 }
265 264
266 /** 265 /**
267 * Makes this list immutable. All subsequent modifications will throw an 266 * Makes this list immutable. All subsequent modifications will throw an
268 * {@link UnsupportedOperationException}. 267 * {@link UnsupportedOperationException}.
269 */ 268 */
270 public void makeImmutable() { 269 public void makeImmutable() {
271 isMutable = false; 270 isMutable = false;
272 } 271 }
273 272
274 /** 273 /**
275 * Returns whether this field can be modified. 274 * Returns whether this field can be modified.
276 */ 275 */
277 public boolean isMutable() { 276 public boolean isMutable() {
278 return isMutable; 277 return isMutable;
279 } 278 }
280 279
281 /* (non-Javadoc) 280 /* (non-Javadoc)
282 * @see com.google.protobuf.MutabilityOracle#ensureMutable() 281 * @see com.google.protobuf.MutabilityOracle#ensureMutable()
283 */ 282 */
284 @Override 283 @Override
285 public void ensureMutable() { 284 public void ensureMutable() {
286 if (!isMutable()) { 285 if (!isMutable()) {
287 throw new UnsupportedOperationException(); 286 throw new UnsupportedOperationException();
288 } 287 }
289 } 288 }
290
291 /**
292 * An internal map that checks for mutability before delegating.
293 */
294 private static class MutatabilityAwareMap<K, V> implements Map<K, V> {
295 private final MutabilityOracle mutabilityOracle;
296 private final Map<K, V> delegate;
297
298 MutatabilityAwareMap(MutabilityOracle mutabilityOracle, Map<K, V> delegate) {
299 this.mutabilityOracle = mutabilityOracle;
300 this.delegate = delegate;
301 }
302
303 @Override
304 public int size() {
305 return delegate.size();
306 }
307
308 @Override
309 public boolean isEmpty() {
310 return delegate.isEmpty();
311 }
312
313 @Override
314 public boolean containsKey(Object key) {
315 return delegate.containsKey(key);
316 }
317
318 @Override
319 public boolean containsValue(Object value) {
320 return delegate.containsValue(value);
321 }
322
323 @Override
324 public V get(Object key) {
325 return delegate.get(key);
326 }
327
328 @Override
329 public V put(K key, V value) {
330 mutabilityOracle.ensureMutable();
331 return delegate.put(key, value);
332 }
333
334 @Override
335 public V remove(Object key) {
336 mutabilityOracle.ensureMutable();
337 return delegate.remove(key);
338 }
339
340 @Override
341 public void putAll(Map<? extends K, ? extends V> m) {
342 mutabilityOracle.ensureMutable();
343 delegate.putAll(m);
344 }
345
346 @Override
347 public void clear() {
348 mutabilityOracle.ensureMutable();
349 delegate.clear();
350 }
351
352 @Override
353 public Set<K> keySet() {
354 return new MutatabilityAwareSet<K>(mutabilityOracle, delegate.keySet());
355 }
356
357 @Override
358 public Collection<V> values() {
359 return new MutatabilityAwareCollection<V>(mutabilityOracle, delegate.value s());
360 }
361
362 @Override
363 public Set<java.util.Map.Entry<K, V>> entrySet() {
364 return new MutatabilityAwareSet<Entry<K, V>>(mutabilityOracle, delegate.en trySet());
365 }
366
367 @Override
368 public boolean equals(Object o) {
369 return delegate.equals(o);
370 }
371
372 @Override
373 public int hashCode() {
374 return delegate.hashCode();
375 }
376
377 @Override
378 public String toString() {
379 return delegate.toString();
380 }
381
382 /**
383 * An internal collection that checks for mutability before delegating.
384 */
385 private static class MutatabilityAwareCollection<E> implements Collection<E> {
386 private final MutabilityOracle mutabilityOracle;
387 private final Collection<E> delegate;
388
389 MutatabilityAwareCollection(MutabilityOracle mutabilityOracle, Collection< E> delegate) {
390 this.mutabilityOracle = mutabilityOracle;
391 this.delegate = delegate;
392 }
393
394 @Override
395 public int size() {
396 return delegate.size();
397 }
398
399 @Override
400 public boolean isEmpty() {
401 return delegate.isEmpty();
402 }
403
404 @Override
405 public boolean contains(Object o) {
406 return delegate.contains(o);
407 }
408
409 @Override
410 public Iterator<E> iterator() {
411 return new MutatabilityAwareIterator<E>(mutabilityOracle, delegate.itera tor());
412 }
413
414 @Override
415 public Object[] toArray() {
416 return delegate.toArray();
417 }
418
419 @Override
420 public <T> T[] toArray(T[] a) {
421 return delegate.toArray(a);
422 }
423
424 @Override
425 public boolean add(E e) {
426 // Unsupported operation in the delegate.
427 throw new UnsupportedOperationException();
428 }
429
430 @Override
431 public boolean remove(Object o) {
432 mutabilityOracle.ensureMutable();
433 return delegate.remove(o);
434 }
435
436 @Override
437 public boolean containsAll(Collection<?> c) {
438 return delegate.containsAll(c);
439 }
440
441 @Override
442 public boolean addAll(Collection<? extends E> c) {
443 // Unsupported operation in the delegate.
444 throw new UnsupportedOperationException();
445 }
446
447 @Override
448 public boolean removeAll(Collection<?> c) {
449 mutabilityOracle.ensureMutable();
450 return delegate.removeAll(c);
451 }
452
453 @Override
454 public boolean retainAll(Collection<?> c) {
455 mutabilityOracle.ensureMutable();
456 return delegate.retainAll(c);
457 }
458
459 @Override
460 public void clear() {
461 mutabilityOracle.ensureMutable();
462 delegate.clear();
463 }
464
465 @Override
466 public boolean equals(Object o) {
467 return delegate.equals(o);
468 }
469
470 @Override
471 public int hashCode() {
472 return delegate.hashCode();
473 }
474
475 @Override
476 public String toString() {
477 return delegate.toString();
478 }
479 }
480
481 /**
482 * An internal set that checks for mutability before delegating.
483 */
484 private static class MutatabilityAwareSet<E> implements Set<E> {
485 private final MutabilityOracle mutabilityOracle;
486 private final Set<E> delegate;
487
488 MutatabilityAwareSet(MutabilityOracle mutabilityOracle, Set<E> delegate) {
489 this.mutabilityOracle = mutabilityOracle;
490 this.delegate = delegate;
491 }
492
493 @Override
494 public int size() {
495 return delegate.size();
496 }
497
498 @Override
499 public boolean isEmpty() {
500 return delegate.isEmpty();
501 }
502
503 @Override
504 public boolean contains(Object o) {
505 return delegate.contains(o);
506 }
507
508 @Override
509 public Iterator<E> iterator() {
510 return new MutatabilityAwareIterator<E>(mutabilityOracle, delegate.itera tor());
511 }
512
513 @Override
514 public Object[] toArray() {
515 return delegate.toArray();
516 }
517
518 @Override
519 public <T> T[] toArray(T[] a) {
520 return delegate.toArray(a);
521 }
522
523 @Override
524 public boolean add(E e) {
525 mutabilityOracle.ensureMutable();
526 return delegate.add(e);
527 }
528
529 @Override
530 public boolean remove(Object o) {
531 mutabilityOracle.ensureMutable();
532 return delegate.remove(o);
533 }
534
535 @Override
536 public boolean containsAll(Collection<?> c) {
537 return delegate.containsAll(c);
538 }
539
540 @Override
541 public boolean addAll(Collection<? extends E> c) {
542 mutabilityOracle.ensureMutable();
543 return delegate.addAll(c);
544 }
545
546 @Override
547 public boolean retainAll(Collection<?> c) {
548 mutabilityOracle.ensureMutable();
549 return delegate.retainAll(c);
550 }
551
552 @Override
553 public boolean removeAll(Collection<?> c) {
554 mutabilityOracle.ensureMutable();
555 return delegate.removeAll(c);
556 }
557
558 @Override
559 public void clear() {
560 mutabilityOracle.ensureMutable();
561 delegate.clear();
562 }
563
564 @Override
565 public boolean equals(Object o) {
566 return delegate.equals(o);
567 }
568
569 @Override
570 public int hashCode() {
571 return delegate.hashCode();
572 }
573
574 @Override
575 public String toString() {
576 return delegate.toString();
577 }
578 }
579
580 /**
581 * An internal iterator that checks for mutability before delegating.
582 */
583 private static class MutatabilityAwareIterator<E> implements Iterator<E> {
584 private final MutabilityOracle mutabilityOracle;
585 private final Iterator<E> delegate;
586
587 MutatabilityAwareIterator(MutabilityOracle mutabilityOracle, Iterator<E> d elegate) {
588 this.mutabilityOracle = mutabilityOracle;
589 this.delegate = delegate;
590 }
591
592 @Override
593 public boolean hasNext() {
594 return delegate.hasNext();
595 }
596
597 @Override
598 public E next() {
599 return delegate.next();
600 }
601
602 @Override
603 public void remove() {
604 mutabilityOracle.ensureMutable();
605 delegate.remove();
606 }
607
608 @Override
609 public boolean equals(Object obj) {
610 return delegate.equals(obj);
611 }
612
613 @Override
614 public int hashCode() {
615 return delegate.hashCode();
616 }
617
618 @Override
619 public String toString() {
620 return delegate.toString();
621 }
622 }
623 }
624 } 289 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698