diff options
Diffstat (limited to 'java/core/src/main/java/com/google/protobuf/MapFieldLite.java')
-rw-r--r-- | java/core/src/main/java/com/google/protobuf/MapFieldLite.java | 445 |
1 files changed, 60 insertions, 385 deletions
diff --git a/java/core/src/main/java/com/google/protobuf/MapFieldLite.java b/java/core/src/main/java/com/google/protobuf/MapFieldLite.java index 960b6339..3c0ad89a 100644 --- a/java/core/src/main/java/com/google/protobuf/MapFieldLite.java +++ b/java/core/src/main/java/com/google/protobuf/MapFieldLite.java @@ -33,71 +33,85 @@ package com.google.protobuf; import com.google.protobuf.Internal.EnumLite; import java.util.Arrays; -import java.util.Collection; import java.util.Collections; -import java.util.Iterator; import java.util.LinkedHashMap; import java.util.Map; import java.util.Set; /** * Internal representation of map fields in generated lite-runtime messages. - * + * * This class is a protobuf implementation detail. Users shouldn't use this * class directly. */ -public final class MapFieldLite<K, V> implements MutabilityOracle { - private MutatabilityAwareMap<K, V> mapData; +public final class MapFieldLite<K, V> extends LinkedHashMap<K, V> { + private boolean isMutable; - + + private MapFieldLite() { + this.isMutable = true; + } + private MapFieldLite(Map<K, V> mapData) { - this.mapData = new MutatabilityAwareMap<K, V>(this, mapData); + super(mapData); this.isMutable = true; } - + @SuppressWarnings({"rawtypes", "unchecked"}) - private static final MapFieldLite EMPTY_MAP_FIELD = - new MapFieldLite(Collections.emptyMap()); + private static final MapFieldLite EMPTY_MAP_FIELD = new MapFieldLite(Collections.emptyMap()); static { EMPTY_MAP_FIELD.makeImmutable(); } - + /** Returns an singleton immutable empty MapFieldLite instance. */ @SuppressWarnings({"unchecked", "cast"}) public static <K, V> MapFieldLite<K, V> emptyMapField() { return (MapFieldLite<K, V>) EMPTY_MAP_FIELD; } - - /** Creates a new MapFieldLite instance. */ - public static <K, V> MapFieldLite<K, V> newMapField() { - return new MapFieldLite<K, V>(new LinkedHashMap<K, V>()); + + public void mergeFrom(MapFieldLite<K, V> other) { + ensureMutable(); + if (!other.isEmpty()) { + putAll(other); + } + } + + @SuppressWarnings({"unchecked", "cast"}) + @Override public Set<Map.Entry<K, V>> entrySet() { + return isEmpty() ? Collections.<Map.Entry<K, V>>emptySet() : super.entrySet(); + } + + @Override public void clear() { + ensureMutable(); + clear(); } - - /** Gets the content of this MapField as a read-only Map. */ - public Map<K, V> getMap() { - return Collections.unmodifiableMap(mapData); + + @Override public V put(K key, V value) { + ensureMutable(); + return super.put(key, value); } - - /** Gets a mutable Map view of this MapField. */ - public Map<K, V> getMutableMap() { - return mapData; + + public V put(Map.Entry<K, V> entry) { + return put(entry.getKey(), entry.getValue()); } - - public void mergeFrom(MapFieldLite<K, V> other) { - mapData.putAll(copy(other.mapData)); + + @Override public void putAll(Map<? extends K, ? extends V> m) { + ensureMutable(); + super.putAll(m); } - - public void clear() { - mapData.clear(); + + @Override public V remove(Object key) { + ensureMutable(); + return super.remove(key); } - + private static boolean equals(Object a, Object b) { if (a instanceof byte[] && b instanceof byte[]) { return Arrays.equals((byte[]) a, (byte[]) b); } return a.equals(b); } - + /** * Checks whether two {@link Map}s are equal. We don't use the default equals * method of {@link Map} because it compares by identity not by content for @@ -120,20 +134,16 @@ public final class MapFieldLite<K, V> implements MutabilityOracle { } return true; } - + /** * Checks whether two map fields are equal. */ @SuppressWarnings("unchecked") @Override public boolean equals(Object object) { - if (!(object instanceof MapFieldLite)) { - return false; - } - MapFieldLite<K, V> other = (MapFieldLite<K, V>) object; - return equals(mapData, other.mapData); + return (object instanceof Map) && equals(this, (Map<K, V>) object); } - + private static int calculateHashCodeForObject(Object a) { if (a instanceof byte[]) { return Internal.hashCode((byte[]) a); @@ -156,14 +166,14 @@ public final class MapFieldLite<K, V> implements MutabilityOracle { result += calculateHashCodeForObject(entry.getKey()) ^ calculateHashCodeForObject(entry.getValue()); } - return result; + return result; } - + @Override public int hashCode() { - return calculateHashCodeForMap(mapData); + return calculateHashCodeForMap(this); } - + private static Object copy(Object object) { if (object instanceof byte[]) { byte[] data = (byte[]) object; @@ -171,7 +181,7 @@ public final class MapFieldLite<K, V> implements MutabilityOracle { } return object; } - + /** * Makes a deep copy of a {@link Map}. Immutable objects in the map will be * shared (e.g., integers, strings, immutable messages) and mutable ones will @@ -185,12 +195,12 @@ public final class MapFieldLite<K, V> implements MutabilityOracle { } return result; } - + /** Returns a deep copy of this map field. */ - public MapFieldLite<K, V> copy() { - return new MapFieldLite<K, V>(copy(mapData)); + public MapFieldLite<K, V> mutableCopy() { + return isEmpty() ? new MapFieldLite<K, V>() : new MapFieldLite<K, V>(this); } - + /** * Makes this field immutable. All subsequent modifications will throw an * {@link UnsupportedOperationException}. @@ -198,352 +208,17 @@ public final class MapFieldLite<K, V> implements MutabilityOracle { public void makeImmutable() { isMutable = false; } - + /** * Returns whether this field can be modified. */ public boolean isMutable() { return isMutable; } - - @Override - public void ensureMutable() { - if (!isMutable()) { - throw new UnsupportedOperationException(); - } - } - - /** - * An internal map that checks for mutability before delegating. - */ - static class MutatabilityAwareMap<K, V> implements Map<K, V> { - private final MutabilityOracle mutabilityOracle; - private final Map<K, V> delegate; - - MutatabilityAwareMap(MutabilityOracle mutabilityOracle, Map<K, V> delegate) { - this.mutabilityOracle = mutabilityOracle; - this.delegate = delegate; - } - - @Override - public int size() { - return delegate.size(); - } - - @Override - public boolean isEmpty() { - return delegate.isEmpty(); - } - - @Override - public boolean containsKey(Object key) { - return delegate.containsKey(key); - } - - @Override - public boolean containsValue(Object value) { - return delegate.containsValue(value); - } - - @Override - public V get(Object key) { - return delegate.get(key); - } - - @Override - public V put(K key, V value) { - mutabilityOracle.ensureMutable(); - return delegate.put(key, value); - } - - @Override - public V remove(Object key) { - mutabilityOracle.ensureMutable(); - return delegate.remove(key); - } - - @Override - public void putAll(Map<? extends K, ? extends V> m) { - mutabilityOracle.ensureMutable(); - delegate.putAll(m); - } - - @Override - public void clear() { - mutabilityOracle.ensureMutable(); - delegate.clear(); - } - - @Override - public Set<K> keySet() { - return new MutatabilityAwareSet<K>(mutabilityOracle, delegate.keySet()); - } - - @Override - public Collection<V> values() { - return new MutatabilityAwareCollection<V>(mutabilityOracle, delegate.values()); - } - - @Override - public Set<java.util.Map.Entry<K, V>> entrySet() { - return new MutatabilityAwareSet<Entry<K, V>>(mutabilityOracle, delegate.entrySet()); - } - - @Override - public boolean equals(Object o) { - return delegate.equals(o); - } - - @Override - public int hashCode() { - return delegate.hashCode(); - } - - @Override - public String toString() { - return delegate.toString(); - } - } - - /** - * An internal collection that checks for mutability before delegating. - */ - private static class MutatabilityAwareCollection<E> implements Collection<E> { - private final MutabilityOracle mutabilityOracle; - private final Collection<E> delegate; - - MutatabilityAwareCollection(MutabilityOracle mutabilityOracle, Collection<E> delegate) { - this.mutabilityOracle = mutabilityOracle; - this.delegate = delegate; - } - @Override - public int size() { - return delegate.size(); - } - - @Override - public boolean isEmpty() { - return delegate.isEmpty(); - } - - @Override - public boolean contains(Object o) { - return delegate.contains(o); - } - - @Override - public Iterator<E> iterator() { - return new MutatabilityAwareIterator<E>(mutabilityOracle, delegate.iterator()); - } - - @Override - public Object[] toArray() { - return delegate.toArray(); - } - - @Override - public <T> T[] toArray(T[] a) { - return delegate.toArray(a); - } - - @Override - public boolean add(E e) { - // Unsupported operation in the delegate. - throw new UnsupportedOperationException(); - } - - @Override - public boolean remove(Object o) { - mutabilityOracle.ensureMutable(); - return delegate.remove(o); - } - - @Override - public boolean containsAll(Collection<?> c) { - return delegate.containsAll(c); - } - - @Override - public boolean addAll(Collection<? extends E> c) { - // Unsupported operation in the delegate. + private void ensureMutable() { + if (!isMutable()) { throw new UnsupportedOperationException(); } - - @Override - public boolean removeAll(Collection<?> c) { - mutabilityOracle.ensureMutable(); - return delegate.removeAll(c); - } - - @Override - public boolean retainAll(Collection<?> c) { - mutabilityOracle.ensureMutable(); - return delegate.retainAll(c); - } - - @Override - public void clear() { - mutabilityOracle.ensureMutable(); - delegate.clear(); - } - - @Override - public boolean equals(Object o) { - return delegate.equals(o); - } - - @Override - public int hashCode() { - return delegate.hashCode(); - } - - @Override - public String toString() { - return delegate.toString(); - } - } - - /** - * An internal set that checks for mutability before delegating. - */ - private static class MutatabilityAwareSet<E> implements Set<E> { - private final MutabilityOracle mutabilityOracle; - private final Set<E> delegate; - - MutatabilityAwareSet(MutabilityOracle mutabilityOracle, Set<E> delegate) { - this.mutabilityOracle = mutabilityOracle; - this.delegate = delegate; - } - - @Override - public int size() { - return delegate.size(); - } - - @Override - public boolean isEmpty() { - return delegate.isEmpty(); - } - - @Override - public boolean contains(Object o) { - return delegate.contains(o); - } - - @Override - public Iterator<E> iterator() { - return new MutatabilityAwareIterator<E>(mutabilityOracle, delegate.iterator()); - } - - @Override - public Object[] toArray() { - return delegate.toArray(); - } - - @Override - public <T> T[] toArray(T[] a) { - return delegate.toArray(a); - } - - @Override - public boolean add(E e) { - mutabilityOracle.ensureMutable(); - return delegate.add(e); - } - - @Override - public boolean remove(Object o) { - mutabilityOracle.ensureMutable(); - return delegate.remove(o); - } - - @Override - public boolean containsAll(Collection<?> c) { - return delegate.containsAll(c); - } - - @Override - public boolean addAll(Collection<? extends E> c) { - mutabilityOracle.ensureMutable(); - return delegate.addAll(c); - } - - @Override - public boolean retainAll(Collection<?> c) { - mutabilityOracle.ensureMutable(); - return delegate.retainAll(c); - } - - @Override - public boolean removeAll(Collection<?> c) { - mutabilityOracle.ensureMutable(); - return delegate.removeAll(c); - } - - @Override - public void clear() { - mutabilityOracle.ensureMutable(); - delegate.clear(); - } - - @Override - public boolean equals(Object o) { - return delegate.equals(o); - } - - @Override - public int hashCode() { - return delegate.hashCode(); - } - - @Override - public String toString() { - return delegate.toString(); - } - } - - /** - * An internal iterator that checks for mutability before delegating. - */ - private static class MutatabilityAwareIterator<E> implements Iterator<E> { - private final MutabilityOracle mutabilityOracle; - private final Iterator<E> delegate; - - MutatabilityAwareIterator(MutabilityOracle mutabilityOracle, Iterator<E> delegate) { - this.mutabilityOracle = mutabilityOracle; - this.delegate = delegate; - } - - @Override - public boolean hasNext() { - return delegate.hasNext(); - } - - @Override - public E next() { - return delegate.next(); - } - - @Override - public void remove() { - mutabilityOracle.ensureMutable(); - delegate.remove(); - } - - @Override - public boolean equals(Object obj) { - return delegate.equals(obj); - } - - @Override - public int hashCode() { - return delegate.hashCode(); - } - - @Override - public String toString() { - return delegate.toString(); - } } } |