| Index: third_party/protobuf/java/core/src/main/java/com/google/protobuf/MapField.java
|
| diff --git a/third_party/protobuf/java/core/src/main/java/com/google/protobuf/MapField.java b/third_party/protobuf/java/core/src/main/java/com/google/protobuf/MapField.java
|
| index 907f0f71120d6b0b29399c0e930ea602231b1aaf..a6109f988f99e0d8c7060cac39c82fd267d58db9 100644
|
| --- a/third_party/protobuf/java/core/src/main/java/com/google/protobuf/MapField.java
|
| +++ b/third_party/protobuf/java/core/src/main/java/com/google/protobuf/MapField.java
|
| @@ -30,25 +30,26 @@
|
|
|
| package com.google.protobuf;
|
|
|
| -import com.google.protobuf.MapFieldLite.MutatabilityAwareMap;
|
| -
|
| import java.util.ArrayList;
|
| +import java.util.Collection;
|
| import java.util.Collections;
|
| +import java.util.Iterator;
|
| import java.util.LinkedHashMap;
|
| import java.util.List;
|
| import java.util.Map;
|
| +import java.util.Set;
|
|
|
| /**
|
| * Internal representation of map fields in generated messages.
|
| - *
|
| + *
|
| * This class supports accessing the map field as a {@link Map} to be used in
|
| * generated API and also supports accessing the field as a {@link List} to be
|
| * used in reflection API. It keeps track of where the data is currently stored
|
| - * and do necessary conversions between map and list.
|
| - *
|
| + * and do necessary conversions between map and list.
|
| + *
|
| * This class is a protobuf implementation detail. Users shouldn't use this
|
| * class directly.
|
| - *
|
| + *
|
| * THREAD-SAFETY NOTE: Read-only access is thread-safe. Users can call getMap()
|
| * and getList() concurrently in multiple threads. If write-access is needed,
|
| * all access must be synchronized.
|
| @@ -56,21 +57,21 @@ import java.util.Map;
|
| public class MapField<K, V> implements MutabilityOracle {
|
| /**
|
| * Indicates where the data of this map field is currently stored.
|
| - *
|
| + *
|
| * MAP: Data is stored in mapData.
|
| * LIST: Data is stored in listData.
|
| * BOTH: mapData and listData have the same data.
|
| *
|
| * When the map field is accessed (through generated API or reflection API),
|
| * it will shift between these 3 modes:
|
| - *
|
| + *
|
| * getMap() getList() getMutableMap() getMutableList()
|
| * MAP MAP BOTH MAP LIST
|
| * LIST BOTH LIST MAP LIST
|
| * BOTH BOTH BOTH MAP LIST
|
| - *
|
| + *
|
| * As the map field changes its mode, the list/map reference returned in a
|
| - * previous method call may be invalidated.
|
| + * previous method call may be invalidated.
|
| */
|
| private enum StorageMode {MAP, LIST, BOTH}
|
|
|
| @@ -78,26 +79,26 @@ public class MapField<K, V> implements MutabilityOracle {
|
| private volatile StorageMode mode;
|
| private MutatabilityAwareMap<K, V> mapData;
|
| private List<Message> listData;
|
| -
|
| +
|
| // Convert between a map entry Message and a key-value pair.
|
| private static interface Converter<K, V> {
|
| Message convertKeyAndValueToMessage(K key, V value);
|
| void convertMessageToKeyAndValue(Message message, Map<K, V> map);
|
| -
|
| +
|
| Message getMessageDefaultInstance();
|
| }
|
| -
|
| +
|
| private static class ImmutableMessageConverter<K, V> implements Converter<K, V> {
|
| private final MapEntry<K, V> defaultEntry;
|
| public ImmutableMessageConverter(MapEntry<K, V> defaultEntry) {
|
| this.defaultEntry = defaultEntry;
|
| }
|
| -
|
| +
|
| @Override
|
| public Message convertKeyAndValueToMessage(K key, V value) {
|
| return defaultEntry.newBuilderForType().setKey(key).setValue(value).buildPartial();
|
| }
|
| -
|
| +
|
| @Override
|
| public void convertMessageToKeyAndValue(Message message, Map<K, V> map) {
|
| MapEntry<K, V> entry = (MapEntry<K, V>) message;
|
| @@ -109,10 +110,10 @@ public class MapField<K, V> implements MutabilityOracle {
|
| return defaultEntry;
|
| }
|
| }
|
| -
|
| +
|
|
|
| private final Converter<K, V> converter;
|
| -
|
| +
|
| private MapField(
|
| Converter<K, V> converter,
|
| StorageMode mode,
|
| @@ -123,34 +124,34 @@ public class MapField<K, V> implements MutabilityOracle {
|
| this.mapData = new MutatabilityAwareMap<K, V>(this, mapData);
|
| this.listData = null;
|
| }
|
| -
|
| +
|
| private MapField(
|
| MapEntry<K, V> defaultEntry,
|
| StorageMode mode,
|
| Map<K, V> mapData) {
|
| this(new ImmutableMessageConverter<K, V>(defaultEntry), mode, mapData);
|
| }
|
| -
|
| -
|
| +
|
| +
|
| /** Returns an immutable empty MapField. */
|
| public static <K, V> MapField<K, V> emptyMapField(
|
| MapEntry<K, V> defaultEntry) {
|
| return new MapField<K, V>(
|
| defaultEntry, StorageMode.MAP, Collections.<K, V>emptyMap());
|
| }
|
| -
|
| -
|
| +
|
| +
|
| /** Creates a new mutable empty MapField. */
|
| public static <K, V> MapField<K, V> newMapField(MapEntry<K, V> defaultEntry) {
|
| return new MapField<K, V>(
|
| defaultEntry, StorageMode.MAP, new LinkedHashMap<K, V>());
|
| }
|
| -
|
| -
|
| +
|
| +
|
| private Message convertKeyAndValueToMessage(K key, V value) {
|
| return converter.convertKeyAndValueToMessage(key, value);
|
| }
|
| -
|
| +
|
| @SuppressWarnings("unchecked")
|
| private void convertMessageToKeyAndValue(Message message, Map<K, V> map) {
|
| converter.convertMessageToKeyAndValue(message, map);
|
| @@ -173,7 +174,7 @@ public class MapField<K, V> implements MutabilityOracle {
|
| }
|
| return new MutatabilityAwareMap<K, V>(this, mapData);
|
| }
|
| -
|
| +
|
| /** Returns the content of this MapField as a read-only Map. */
|
| public Map<K, V> getMap() {
|
| if (mode == StorageMode.LIST) {
|
| @@ -186,7 +187,7 @@ public class MapField<K, V> implements MutabilityOracle {
|
| }
|
| return Collections.unmodifiableMap(mapData);
|
| }
|
| -
|
| +
|
| /** Gets a mutable Map view of this MapField. */
|
| public Map<K, V> getMutableMap() {
|
| if (mode != StorageMode.MAP) {
|
| @@ -194,20 +195,20 @@ public class MapField<K, V> implements MutabilityOracle {
|
| mapData = convertListToMap(listData);
|
| }
|
| listData = null;
|
| - mode = StorageMode.MAP;
|
| + mode = StorageMode.MAP;
|
| }
|
| return mapData;
|
| }
|
| -
|
| +
|
| public void mergeFrom(MapField<K, V> other) {
|
| getMutableMap().putAll(MapFieldLite.copy(other.getMap()));
|
| }
|
| -
|
| +
|
| public void clear() {
|
| mapData = new MutatabilityAwareMap<K, V>(this, new LinkedHashMap<K, V>());
|
| mode = StorageMode.MAP;
|
| }
|
| -
|
| +
|
| @SuppressWarnings("unchecked")
|
| @Override
|
| public boolean equals(Object object) {
|
| @@ -217,18 +218,18 @@ public class MapField<K, V> implements MutabilityOracle {
|
| MapField<K, V> other = (MapField<K, V>) object;
|
| return MapFieldLite.<K, V>equals(getMap(), other.getMap());
|
| }
|
| -
|
| +
|
| @Override
|
| public int hashCode() {
|
| return MapFieldLite.<K, V>calculateHashCodeForMap(getMap());
|
| }
|
| -
|
| +
|
| /** Returns a deep copy of this MapField. */
|
| public MapField<K, V> copy() {
|
| return new MapField<K, V>(
|
| converter, StorageMode.MAP, MapFieldLite.copy(getMap()));
|
| }
|
| -
|
| +
|
| /** Gets the content of this MapField as a read-only List. */
|
| List<Message> getList() {
|
| if (mode == StorageMode.MAP) {
|
| @@ -241,7 +242,7 @@ public class MapField<K, V> implements MutabilityOracle {
|
| }
|
| return Collections.unmodifiableList(listData);
|
| }
|
| -
|
| +
|
| /** Gets a mutable List view of this MapField. */
|
| List<Message> getMutableList() {
|
| if (mode != StorageMode.LIST) {
|
| @@ -253,7 +254,7 @@ public class MapField<K, V> implements MutabilityOracle {
|
| }
|
| return listData;
|
| }
|
| -
|
| +
|
| /**
|
| * Gets the default instance of the message stored in the list view of this
|
| * map field.
|
| @@ -261,7 +262,7 @@ public class MapField<K, V> implements MutabilityOracle {
|
| Message getMapEntryMessageDefaultInstance() {
|
| return converter.getMessageDefaultInstance();
|
| }
|
| -
|
| +
|
| /**
|
| * Makes this list immutable. All subsequent modifications will throw an
|
| * {@link UnsupportedOperationException}.
|
| @@ -269,14 +270,14 @@ public class MapField<K, V> implements MutabilityOracle {
|
| public void makeImmutable() {
|
| isMutable = false;
|
| }
|
| -
|
| +
|
| /**
|
| * Returns whether this field can be modified.
|
| */
|
| public boolean isMutable() {
|
| return isMutable;
|
| }
|
| -
|
| +
|
| /* (non-Javadoc)
|
| * @see com.google.protobuf.MutabilityOracle#ensureMutable()
|
| */
|
| @@ -286,4 +287,338 @@ public class MapField<K, V> implements MutabilityOracle {
|
| throw new UnsupportedOperationException();
|
| }
|
| }
|
| +
|
| + /**
|
| + * An internal map that checks for mutability before delegating.
|
| + */
|
| + private 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.
|
| + 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();
|
| + }
|
| + }
|
| + }
|
| }
|
|
|