diff options
Diffstat (limited to 'third_party/protobuf/3.6.0/java/core/src/main/java/com/google/protobuf/MapFieldLite.java')
-rw-r--r-- | third_party/protobuf/3.6.0/java/core/src/main/java/com/google/protobuf/MapFieldLite.java | 236 |
1 files changed, 236 insertions, 0 deletions
diff --git a/third_party/protobuf/3.6.0/java/core/src/main/java/com/google/protobuf/MapFieldLite.java b/third_party/protobuf/3.6.0/java/core/src/main/java/com/google/protobuf/MapFieldLite.java new file mode 100644 index 0000000000..a8b3dd8849 --- /dev/null +++ b/third_party/protobuf/3.6.0/java/core/src/main/java/com/google/protobuf/MapFieldLite.java @@ -0,0 +1,236 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package com.google.protobuf; + +import static com.google.protobuf.Internal.checkNotNull; + +import com.google.protobuf.Internal.EnumLite; +import java.util.Arrays; +import java.util.Collections; +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> extends LinkedHashMap<K, V> { + + private boolean isMutable; + + private MapFieldLite() { + this.isMutable = true; + } + + private MapFieldLite(Map<K, V> mapData) { + super(mapData); + this.isMutable = true; + } + + @SuppressWarnings({"rawtypes", "unchecked"}) + private static final MapFieldLite EMPTY_MAP_FIELD = new MapFieldLite(); + 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; + } + + 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(); + super.clear(); + } + + @Override public V put(K key, V value) { + ensureMutable(); + checkNotNull(key); + + checkNotNull(value); + return super.put(key, value); + } + + public V put(Map.Entry<K, V> entry) { + return put(entry.getKey(), entry.getValue()); + } + + @Override public void putAll(Map<? extends K, ? extends V> m) { + ensureMutable(); + checkForNullKeysAndValues(m); + super.putAll(m); + } + + @Override public V remove(Object key) { + ensureMutable(); + return super.remove(key); + } + + private static void checkForNullKeysAndValues(Map<?, ?> m) { + for (Object key : m.keySet()) { + checkNotNull(key); + checkNotNull(m.get(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 + * byte arrays. + */ + static <K, V> boolean equals(Map<K, V> a, Map<K, V> b) { + if (a == b) { + return true; + } + if (a.size() != b.size()) { + return false; + } + for (Map.Entry<K, V> entry : a.entrySet()) { + if (!b.containsKey(entry.getKey())) { + return false; + } + if (!equals(entry.getValue(), b.get(entry.getKey()))) { + return false; + } + } + return true; + } + + /** + * Checks whether two map fields are equal. + */ + @SuppressWarnings("unchecked") + @Override + public boolean equals(Object object) { + 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); + } + // Enums should be stored as integers internally. + if (a instanceof EnumLite) { + throw new UnsupportedOperationException(); + } + return a.hashCode(); + } + + /** + * Calculates the hash code for a {@link Map}. We don't use the default hash + * code method of {@link Map} because for byte arrays and protobuf enums it + * use {@link Object#hashCode()}. + */ + static <K, V> int calculateHashCodeForMap(Map<K, V> a) { + int result = 0; + for (Map.Entry<K, V> entry : a.entrySet()) { + result += calculateHashCodeForObject(entry.getKey()) + ^ calculateHashCodeForObject(entry.getValue()); + } + return result; + } + + @Override + public int hashCode() { + return calculateHashCodeForMap(this); + } + + private static Object copy(Object object) { + if (object instanceof byte[]) { + byte[] data = (byte[]) object; + return Arrays.copyOf(data, data.length); + } + 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 + * have a copy (e.g., byte arrays, mutable messages). + */ + @SuppressWarnings("unchecked") + static <K, V> Map<K, V> copy(Map<K, V> map) { + Map<K, V> result = new LinkedHashMap<K, V>(); + for (Map.Entry<K, V> entry : map.entrySet()) { + result.put(entry.getKey(), (V) copy(entry.getValue())); + } + return result; + } + + /** Returns a deep copy of this map field. */ + 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}. + */ + public void makeImmutable() { + isMutable = false; + } + + /** + * Returns whether this field can be modified. + */ + public boolean isMutable() { + return isMutable; + } + + private void ensureMutable() { + if (!isMutable()) { + throw new UnsupportedOperationException(); + } + } +} |