/* * Decompiled with CFR 0.152. */ package com.google.common.collect; import com.google.common.annotations.GwtCompatible; import com.google.common.annotations.GwtIncompatible; import com.google.common.base.Objects; import com.google.common.base.Preconditions; import com.google.common.collect.BiMap; import com.google.common.collect.CollectPreconditions; import com.google.common.collect.ForwardingMap; import com.google.common.collect.ForwardingMapEntry; import com.google.common.collect.ForwardingSet; import com.google.common.collect.Maps; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; import java.util.Collection; import java.util.Iterator; import java.util.Map; import java.util.Set; import javax.annotation.Nullable; @GwtCompatible(emulated=true) abstract class AbstractBiMap extends ForwardingMap implements BiMap, Serializable { private transient Map delegate; transient AbstractBiMap inverse; private transient Set keySet; private transient Set valueSet; private transient Set> entrySet; @GwtIncompatible(value="Not needed in emulated source.") private static final long serialVersionUID = 0L; AbstractBiMap(Map forward, Map backward) { this.setDelegates(forward, backward); } private AbstractBiMap(Map backward, AbstractBiMap forward) { this.delegate = backward; this.inverse = forward; } @Override protected Map delegate() { return this.delegate; } K checkKey(@Nullable K key) { return key; } V checkValue(@Nullable V value) { return value; } void setDelegates(Map forward, Map backward) { Preconditions.checkState(this.delegate == null); Preconditions.checkState(this.inverse == null); Preconditions.checkArgument(forward.isEmpty()); Preconditions.checkArgument(backward.isEmpty()); Preconditions.checkArgument(forward != backward); this.delegate = forward; this.inverse = new Inverse(backward, this); } void setInverse(AbstractBiMap inverse) { this.inverse = inverse; } @Override public boolean containsValue(@Nullable Object value) { return this.inverse.containsKey(value); } @Override public V put(@Nullable K key, @Nullable V value) { return this.putInBothMaps(key, value, false); } @Override public V forcePut(@Nullable K key, @Nullable V value) { return this.putInBothMaps(key, value, true); } private V putInBothMaps(@Nullable K key, @Nullable V value, boolean force) { this.checkKey(key); this.checkValue(value); boolean containedKey = this.containsKey(key); if (containedKey && Objects.equal(value, this.get(key))) { return value; } if (force) { this.inverse().remove(value); } else { Preconditions.checkArgument(!this.containsValue(value), "value already present: %s", value); } V oldValue = this.delegate.put(key, value); this.updateInverseMap(key, containedKey, oldValue, value); return oldValue; } private void updateInverseMap(K key, boolean containedKey, V oldValue, V newValue) { if (containedKey) { this.removeFromInverseMap(oldValue); } this.inverse.delegate.put(newValue, key); } @Override public V remove(@Nullable Object key) { return this.containsKey(key) ? (V)this.removeFromBothMaps(key) : null; } private V removeFromBothMaps(Object key) { V oldValue = this.delegate.remove(key); this.removeFromInverseMap(oldValue); return oldValue; } private void removeFromInverseMap(V oldValue) { this.inverse.delegate.remove(oldValue); } @Override public void putAll(Map map) { for (Map.Entry entry : map.entrySet()) { this.put(entry.getKey(), entry.getValue()); } } @Override public void clear() { this.delegate.clear(); this.inverse.delegate.clear(); } @Override public BiMap inverse() { return this.inverse; } @Override public Set keySet() { KeySet result = this.keySet; return result == null ? (this.keySet = new KeySet()) : result; } @Override public Set values() { ValueSet result = this.valueSet; return result == null ? (this.valueSet = new ValueSet()) : result; } @Override public Set> entrySet() { EntrySet result = this.entrySet; return result == null ? (this.entrySet = new EntrySet()) : result; } private static class Inverse extends AbstractBiMap { @GwtIncompatible(value="Not needed in emulated source.") private static final long serialVersionUID = 0L; private Inverse(Map backward, AbstractBiMap forward) { super(backward, forward); } @Override K checkKey(K key) { return this.inverse.checkValue(key); } @Override V checkValue(V value) { return this.inverse.checkKey(value); } @GwtIncompatible(value="java.io.ObjectOuputStream") private void writeObject(ObjectOutputStream stream) throws IOException { stream.defaultWriteObject(); stream.writeObject(this.inverse()); } @GwtIncompatible(value="java.io.ObjectInputStream") private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException { stream.defaultReadObject(); this.setInverse((AbstractBiMap)stream.readObject()); } @GwtIncompatible(value="Not needed in the emulated source.") Object readResolve() { return this.inverse().inverse(); } } private class EntrySet extends ForwardingSet> { final Set> esDelegate; private EntrySet() { this.esDelegate = AbstractBiMap.this.delegate.entrySet(); } @Override protected Set> delegate() { return this.esDelegate; } @Override public void clear() { AbstractBiMap.this.clear(); } @Override public boolean remove(Object object) { if (!this.esDelegate.contains(object)) { return false; } Map.Entry entry = (Map.Entry)object; AbstractBiMap.this.inverse.delegate.remove(entry.getValue()); this.esDelegate.remove(entry); return true; } @Override public Iterator> iterator() { final Iterator iterator = this.esDelegate.iterator(); return new Iterator>(){ Map.Entry entry; @Override public boolean hasNext() { return iterator.hasNext(); } @Override public Map.Entry next() { this.entry = (Map.Entry)iterator.next(); final Map.Entry finalEntry = this.entry; return new ForwardingMapEntry(){ @Override protected Map.Entry delegate() { return finalEntry; } @Override public V setValue(V value) { Preconditions.checkState(EntrySet.this.contains(this), "entry no longer in map"); if (Objects.equal(value, this.getValue())) { return value; } Preconditions.checkArgument(!AbstractBiMap.this.containsValue(value), "value already present: %s", value); Object oldValue = finalEntry.setValue(value); Preconditions.checkState(Objects.equal(value, AbstractBiMap.this.get(this.getKey())), "entry no longer in map"); AbstractBiMap.this.updateInverseMap(this.getKey(), true, oldValue, value); return oldValue; } }; } @Override public void remove() { CollectPreconditions.checkRemove(this.entry != null); Object value = this.entry.getValue(); iterator.remove(); AbstractBiMap.this.removeFromInverseMap(value); } }; } @Override public Object[] toArray() { return this.standardToArray(); } @Override public T[] toArray(T[] array) { return this.standardToArray(array); } @Override public boolean contains(Object o) { return Maps.containsEntryImpl(this.delegate(), o); } @Override public boolean containsAll(Collection c) { return this.standardContainsAll(c); } @Override public boolean removeAll(Collection c) { return this.standardRemoveAll(c); } @Override public boolean retainAll(Collection c) { return this.standardRetainAll(c); } } private class ValueSet extends ForwardingSet { final Set valuesDelegate; private ValueSet() { this.valuesDelegate = AbstractBiMap.this.inverse.keySet(); } @Override protected Set delegate() { return this.valuesDelegate; } @Override public Iterator iterator() { return Maps.valueIterator(AbstractBiMap.this.entrySet().iterator()); } @Override public Object[] toArray() { return this.standardToArray(); } @Override public T[] toArray(T[] array) { return this.standardToArray(array); } @Override public String toString() { return this.standardToString(); } } private class KeySet extends ForwardingSet { private KeySet() { } @Override protected Set delegate() { return AbstractBiMap.this.delegate.keySet(); } @Override public void clear() { AbstractBiMap.this.clear(); } @Override public boolean remove(Object key) { if (!this.contains(key)) { return false; } AbstractBiMap.this.removeFromBothMaps(key); return true; } @Override public boolean removeAll(Collection keysToRemove) { return this.standardRemoveAll(keysToRemove); } @Override public boolean retainAll(Collection keysToRetain) { return this.standardRetainAll(keysToRetain); } @Override public Iterator iterator() { return Maps.keyIterator(AbstractBiMap.this.entrySet().iterator()); } } }