aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcpovirk <cpovirk@google.com>2023-06-26 13:53:57 -0700
committerGoogle Java Core Libraries <java-core-libraries-team+copybara@google.com>2023-06-26 14:02:13 -0700
commit1df87a86cb7f327e5d80e478f7bcda1061c2e861 (patch)
tree9f0e944afce16cc9683c33a3ffc49f2a8599c358
parent80c8d9ce4a8ba63f9704113399a001e456e83e73 (diff)
downloadguava-1df87a86cb7f327e5d80e478f7bcda1061c2e861.tar.gz
Improve racy single-check init code:
- Use `@LazyInit` (to help J2ObjC and TSAN) on various `@CheckForNull transient` fields (and also on `UnmodifiableBiMap.inverse` and on the `LocalCache` fields, all of which are `@RetainedWith @CheckForNull`). I skipped some other such fields, including: - `Synchronized` (which already uses, well, `synchronized`, making the check not racy) - `TreeBasedTable.TreeRow` and some `common.graph` classes (e.g., `DirectedMultiNetworkConnections`), which are doing something more sophisticated. - Update the TODO in `ImmutableSortedMap` about actually caching a view computed on the fly. It's likely that I didn't get _every_ field that deserves an annotation. It's also likely that some of the fields should additionally use `@RetainedWith` or similar for J2ObjC purposes. And probably some fields would be better off with either eagerly computing the views or with not caching them at all (b/280079296). But this CL should be strictly an improvement over the status quo. RELNOTES=n/a PiperOrigin-RevId: 543532432
-rw-r--r--android/guava/src/com/google/common/cache/LocalCache.java7
-rw-r--r--android/guava/src/com/google/common/collect/AbstractBiMap.java7
-rw-r--r--android/guava/src/com/google/common/collect/AbstractSortedMultiset.java3
-rw-r--r--android/guava/src/com/google/common/collect/ArrayTable.java5
-rw-r--r--android/guava/src/com/google/common/collect/CompactHashMap.java7
-rw-r--r--android/guava/src/com/google/common/collect/DescendingMultiset.java7
-rw-r--r--android/guava/src/com/google/common/collect/GeneralRange.java3
-rw-r--r--android/guava/src/com/google/common/collect/ImmutableRangeSet.java2
-rw-r--r--android/guava/src/com/google/common/collect/ImmutableSortedMap.java14
-rw-r--r--android/guava/src/com/google/common/collect/MapMakerInternalMap.java7
-rw-r--r--android/guava/src/com/google/common/collect/Maps.java19
-rw-r--r--android/guava/src/com/google/common/collect/Multisets.java5
-rw-r--r--android/guava/src/com/google/common/collect/NaturalOrdering.java6
-rw-r--r--android/guava/src/com/google/common/collect/Sets.java3
-rw-r--r--android/guava/src/com/google/common/collect/StandardTable.java7
-rw-r--r--android/guava/src/com/google/common/collect/TreeRangeSet.java7
-rw-r--r--android/guava/src/com/google/common/collect/UnmodifiableSortedMultiset.java3
-rw-r--r--android/guava/src/com/google/common/reflect/TypeToken.java5
-rw-r--r--android/guava/src/com/google/common/util/concurrent/AtomicLongMap.java3
-rw-r--r--guava/src/com/google/common/cache/LocalCache.java7
-rw-r--r--guava/src/com/google/common/collect/AbstractBiMap.java7
-rw-r--r--guava/src/com/google/common/collect/AbstractSortedMultiset.java3
-rw-r--r--guava/src/com/google/common/collect/ArrayTable.java5
-rw-r--r--guava/src/com/google/common/collect/CompactHashMap.java7
-rw-r--r--guava/src/com/google/common/collect/DescendingMultiset.java7
-rw-r--r--guava/src/com/google/common/collect/GeneralRange.java3
-rw-r--r--guava/src/com/google/common/collect/ImmutableRangeSet.java2
-rw-r--r--guava/src/com/google/common/collect/ImmutableSortedMap.java14
-rw-r--r--guava/src/com/google/common/collect/JdkBackedImmutableMultiset.java3
-rw-r--r--guava/src/com/google/common/collect/MapMakerInternalMap.java7
-rw-r--r--guava/src/com/google/common/collect/Maps.java19
-rw-r--r--guava/src/com/google/common/collect/Multisets.java5
-rw-r--r--guava/src/com/google/common/collect/NaturalOrdering.java6
-rw-r--r--guava/src/com/google/common/collect/Sets.java3
-rw-r--r--guava/src/com/google/common/collect/StandardTable.java7
-rw-r--r--guava/src/com/google/common/collect/TreeRangeSet.java7
-rw-r--r--guava/src/com/google/common/collect/UnmodifiableSortedMultiset.java3
-rw-r--r--guava/src/com/google/common/reflect/TypeToken.java5
-rw-r--r--guava/src/com/google/common/util/concurrent/AtomicLongMap.java3
39 files changed, 142 insertions, 101 deletions
diff --git a/android/guava/src/com/google/common/cache/LocalCache.java b/android/guava/src/com/google/common/cache/LocalCache.java
index 74df5a234..239afe204 100644
--- a/android/guava/src/com/google/common/cache/LocalCache.java
+++ b/android/guava/src/com/google/common/cache/LocalCache.java
@@ -52,6 +52,7 @@ import com.google.common.util.concurrent.UncheckedExecutionException;
import com.google.common.util.concurrent.Uninterruptibles;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import com.google.errorprone.annotations.concurrent.GuardedBy;
+import com.google.errorprone.annotations.concurrent.LazyInit;
import com.google.j2objc.annotations.RetainedWith;
import com.google.j2objc.annotations.Weak;
import java.io.IOException;
@@ -4201,7 +4202,7 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V>
}
}
- @RetainedWith @CheckForNull Set<K> keySet;
+ @LazyInit @RetainedWith @CheckForNull Set<K> keySet;
@Override
public Set<K> keySet() {
@@ -4210,7 +4211,7 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V>
return (ks != null) ? ks : (keySet = new KeySet());
}
- @RetainedWith @CheckForNull Collection<V> values;
+ @LazyInit @RetainedWith @CheckForNull Collection<V> values;
@Override
public Collection<V> values() {
@@ -4219,7 +4220,7 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V>
return (vs != null) ? vs : (values = new Values());
}
- @RetainedWith @CheckForNull Set<Entry<K, V>> entrySet;
+ @LazyInit @RetainedWith @CheckForNull Set<Entry<K, V>> entrySet;
@Override
@GwtIncompatible // Not supported.
diff --git a/android/guava/src/com/google/common/collect/AbstractBiMap.java b/android/guava/src/com/google/common/collect/AbstractBiMap.java
index 56cf0a00a..10edc5c4c 100644
--- a/android/guava/src/com/google/common/collect/AbstractBiMap.java
+++ b/android/guava/src/com/google/common/collect/AbstractBiMap.java
@@ -25,6 +25,7 @@ import com.google.common.annotations.GwtIncompatible;
import com.google.common.annotations.J2ktIncompatible;
import com.google.common.base.Objects;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
+import com.google.errorprone.annotations.concurrent.LazyInit;
import com.google.j2objc.annotations.RetainedWith;
import com.google.j2objc.annotations.WeakOuter;
import java.io.IOException;
@@ -206,7 +207,7 @@ abstract class AbstractBiMap<K extends @Nullable Object, V extends @Nullable Obj
return inverse;
}
- @CheckForNull private transient Set<K> keySet;
+ @LazyInit @CheckForNull private transient Set<K> keySet;
@Override
public Set<K> keySet() {
@@ -251,7 +252,7 @@ abstract class AbstractBiMap<K extends @Nullable Object, V extends @Nullable Obj
}
}
- @CheckForNull private transient Set<V> valueSet;
+ @LazyInit @CheckForNull private transient Set<V> valueSet;
@Override
public Set<V> values() {
@@ -294,7 +295,7 @@ abstract class AbstractBiMap<K extends @Nullable Object, V extends @Nullable Obj
}
}
- @CheckForNull private transient Set<Entry<K, V>> entrySet;
+ @LazyInit @CheckForNull private transient Set<Entry<K, V>> entrySet;
@Override
public Set<Entry<K, V>> entrySet() {
diff --git a/android/guava/src/com/google/common/collect/AbstractSortedMultiset.java b/android/guava/src/com/google/common/collect/AbstractSortedMultiset.java
index 621e8f98a..98b6211a7 100644
--- a/android/guava/src/com/google/common/collect/AbstractSortedMultiset.java
+++ b/android/guava/src/com/google/common/collect/AbstractSortedMultiset.java
@@ -17,6 +17,7 @@ package com.google.common.collect;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.annotations.GwtCompatible;
+import com.google.errorprone.annotations.concurrent.LazyInit;
import com.google.j2objc.annotations.WeakOuter;
import java.util.Comparator;
import java.util.Iterator;
@@ -122,7 +123,7 @@ abstract class AbstractSortedMultiset<E extends @Nullable Object> extends Abstra
return Multisets.iteratorImpl(descendingMultiset());
}
- @CheckForNull private transient SortedMultiset<E> descendingMultiset;
+ @LazyInit @CheckForNull private transient SortedMultiset<E> descendingMultiset;
@Override
public SortedMultiset<E> descendingMultiset() {
diff --git a/android/guava/src/com/google/common/collect/ArrayTable.java b/android/guava/src/com/google/common/collect/ArrayTable.java
index d63853a82..97a784bac 100644
--- a/android/guava/src/com/google/common/collect/ArrayTable.java
+++ b/android/guava/src/com/google/common/collect/ArrayTable.java
@@ -27,6 +27,7 @@ import com.google.common.base.Objects;
import com.google.common.collect.Maps.IteratorBasedAbstractMap;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import com.google.errorprone.annotations.DoNotCall;
+import com.google.errorprone.annotations.concurrent.LazyInit;
import com.google.j2objc.annotations.WeakOuter;
import java.io.Serializable;
import java.lang.reflect.Array;
@@ -648,7 +649,7 @@ public final class ArrayTable<R, C, V> extends AbstractTable<R, C, @Nullable V>
return columnKeyToIndex.keySet();
}
- @CheckForNull private transient ColumnMap columnMap;
+ @LazyInit @CheckForNull private transient ColumnMap columnMap;
@Override
public Map<C, Map<R, @Nullable V>> columnMap() {
@@ -743,7 +744,7 @@ public final class ArrayTable<R, C, V> extends AbstractTable<R, C, @Nullable V>
return rowKeyToIndex.keySet();
}
- @CheckForNull private transient RowMap rowMap;
+ @LazyInit @CheckForNull private transient RowMap rowMap;
@Override
public Map<R, Map<C, @Nullable V>> rowMap() {
diff --git a/android/guava/src/com/google/common/collect/CompactHashMap.java b/android/guava/src/com/google/common/collect/CompactHashMap.java
index 1e5da07ac..d664c46ac 100644
--- a/android/guava/src/com/google/common/collect/CompactHashMap.java
+++ b/android/guava/src/com/google/common/collect/CompactHashMap.java
@@ -30,6 +30,7 @@ import com.google.common.base.Objects;
import com.google.common.base.Preconditions;
import com.google.common.primitives.Ints;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
+import com.google.errorprone.annotations.concurrent.LazyInit;
import com.google.j2objc.annotations.WeakOuter;
import java.io.IOException;
import java.io.InvalidObjectException;
@@ -671,7 +672,7 @@ class CompactHashMap<K extends @Nullable Object, V extends @Nullable Object>
}
}
- @CheckForNull private transient Set<K> keySetView;
+ @LazyInit @CheckForNull private transient Set<K> keySetView;
@Override
public Set<K> keySet() {
@@ -727,7 +728,7 @@ class CompactHashMap<K extends @Nullable Object, V extends @Nullable Object>
};
}
- @CheckForNull private transient Set<Entry<K, V>> entrySetView;
+ @LazyInit @CheckForNull private transient Set<Entry<K, V>> entrySetView;
@Override
public Set<Entry<K, V>> entrySet() {
@@ -907,7 +908,7 @@ class CompactHashMap<K extends @Nullable Object, V extends @Nullable Object>
return false;
}
- @CheckForNull private transient Collection<V> valuesView;
+ @LazyInit @CheckForNull private transient Collection<V> valuesView;
@Override
public Collection<V> values() {
diff --git a/android/guava/src/com/google/common/collect/DescendingMultiset.java b/android/guava/src/com/google/common/collect/DescendingMultiset.java
index 7db0fbbd4..23ff8319c 100644
--- a/android/guava/src/com/google/common/collect/DescendingMultiset.java
+++ b/android/guava/src/com/google/common/collect/DescendingMultiset.java
@@ -17,6 +17,7 @@
package com.google.common.collect;
import com.google.common.annotations.GwtCompatible;
+import com.google.errorprone.annotations.concurrent.LazyInit;
import com.google.j2objc.annotations.WeakOuter;
import java.util.Comparator;
import java.util.Iterator;
@@ -37,7 +38,7 @@ abstract class DescendingMultiset<E extends @Nullable Object> extends Forwarding
implements SortedMultiset<E> {
abstract SortedMultiset<E> forwardMultiset();
- @CheckForNull private transient Comparator<? super E> comparator;
+ @LazyInit @CheckForNull private transient Comparator<? super E> comparator;
@Override
public Comparator<? super E> comparator() {
@@ -48,7 +49,7 @@ abstract class DescendingMultiset<E extends @Nullable Object> extends Forwarding
return result;
}
- @CheckForNull private transient NavigableSet<E> elementSet;
+ @LazyInit @CheckForNull private transient NavigableSet<E> elementSet;
@Override
public NavigableSet<E> elementSet() {
@@ -116,7 +117,7 @@ abstract class DescendingMultiset<E extends @Nullable Object> extends Forwarding
abstract Iterator<Entry<E>> entryIterator();
- @CheckForNull private transient Set<Entry<E>> entrySet;
+ @LazyInit @CheckForNull private transient Set<Entry<E>> entrySet;
@Override
public Set<Entry<E>> entrySet() {
diff --git a/android/guava/src/com/google/common/collect/GeneralRange.java b/android/guava/src/com/google/common/collect/GeneralRange.java
index c5e1ba3c4..e462b7a01 100644
--- a/android/guava/src/com/google/common/collect/GeneralRange.java
+++ b/android/guava/src/com/google/common/collect/GeneralRange.java
@@ -22,6 +22,7 @@ import static com.google.common.collect.NullnessCasts.uncheckedCastNullableTToT;
import com.google.common.annotations.GwtCompatible;
import com.google.common.base.Objects;
+import com.google.errorprone.annotations.concurrent.LazyInit;
import java.io.Serializable;
import java.util.Comparator;
import javax.annotation.CheckForNull;
@@ -263,7 +264,7 @@ final class GeneralRange<T extends @Nullable Object> implements Serializable {
getUpperBoundType());
}
- @CheckForNull private transient GeneralRange<T> reverse;
+ @LazyInit @CheckForNull private transient GeneralRange<T> reverse;
/** Returns the same range relative to the reversed comparator. */
GeneralRange<T> reverse() {
diff --git a/android/guava/src/com/google/common/collect/ImmutableRangeSet.java b/android/guava/src/com/google/common/collect/ImmutableRangeSet.java
index e09bc4a84..844c1c1dc 100644
--- a/android/guava/src/com/google/common/collect/ImmutableRangeSet.java
+++ b/android/guava/src/com/google/common/collect/ImmutableRangeSet.java
@@ -542,7 +542,7 @@ public final class ImmutableRangeSet<C extends Comparable> extends AbstractRange
this.domain = domain;
}
- @CheckForNull private transient Integer size;
+ @LazyInit @CheckForNull private transient Integer size;
@Override
public int size() {
diff --git a/android/guava/src/com/google/common/collect/ImmutableSortedMap.java b/android/guava/src/com/google/common/collect/ImmutableSortedMap.java
index 6ee63c680..15c384eb7 100644
--- a/android/guava/src/com/google/common/collect/ImmutableSortedMap.java
+++ b/android/guava/src/com/google/common/collect/ImmutableSortedMap.java
@@ -1083,16 +1083,18 @@ public final class ImmutableSortedMap<K, V> extends ImmutableSortedMapFauxveride
@Override
public ImmutableSortedMap<K, V> descendingMap() {
- // TODO(kevinb): the descendingMap is never actually cached at all. Either it should be or the
- // code below simplified.
+ // TODO(kevinb): The descendingMap is never actually cached at all. Either:
+ //
+ // - Cache it, and annotate the field with @LazyInit.
+ // - Simplify the code below, and consider eliminating the field (b/287198172), which is also
+ // set by one of the constructors.
ImmutableSortedMap<K, V> result = descendingMap;
if (result == null) {
if (isEmpty()) {
- return result = emptyMap(Ordering.from(comparator()).reverse());
+ return emptyMap(Ordering.from(comparator()).reverse());
} else {
- return result =
- new ImmutableSortedMap<>(
- (RegularImmutableSortedSet<K>) keySet.descendingSet(), valueList.reverse(), this);
+ return new ImmutableSortedMap<>(
+ (RegularImmutableSortedSet<K>) keySet.descendingSet(), valueList.reverse(), this);
}
}
return result;
diff --git a/android/guava/src/com/google/common/collect/MapMakerInternalMap.java b/android/guava/src/com/google/common/collect/MapMakerInternalMap.java
index e80ec27a5..c64d81eb3 100644
--- a/android/guava/src/com/google/common/collect/MapMakerInternalMap.java
+++ b/android/guava/src/com/google/common/collect/MapMakerInternalMap.java
@@ -25,6 +25,7 @@ import com.google.common.collect.MapMaker.Dummy;
import com.google.common.primitives.Ints;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import com.google.errorprone.annotations.concurrent.GuardedBy;
+import com.google.errorprone.annotations.concurrent.LazyInit;
import com.google.j2objc.annotations.Weak;
import com.google.j2objc.annotations.WeakOuter;
import java.io.IOException;
@@ -2522,7 +2523,7 @@ class MapMakerInternalMap<
}
}
- @CheckForNull transient Set<K> keySet;
+ @LazyInit @CheckForNull transient Set<K> keySet;
@Override
public Set<K> keySet() {
@@ -2530,7 +2531,7 @@ class MapMakerInternalMap<
return (ks != null) ? ks : (keySet = new KeySet());
}
- @CheckForNull transient Collection<V> values;
+ @LazyInit @CheckForNull transient Collection<V> values;
@Override
public Collection<V> values() {
@@ -2538,7 +2539,7 @@ class MapMakerInternalMap<
return (vs != null) ? vs : (values = new Values());
}
- @CheckForNull transient Set<Entry<K, V>> entrySet;
+ @LazyInit @CheckForNull transient Set<Entry<K, V>> entrySet;
@Override
public Set<Entry<K, V>> entrySet() {
diff --git a/android/guava/src/com/google/common/collect/Maps.java b/android/guava/src/com/google/common/collect/Maps.java
index 4e9792057..9a3852047 100644
--- a/android/guava/src/com/google/common/collect/Maps.java
+++ b/android/guava/src/com/google/common/collect/Maps.java
@@ -38,6 +38,7 @@ import com.google.common.base.Predicates;
import com.google.common.collect.MapDifference.ValueDifference;
import com.google.common.primitives.Ints;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
+import com.google.errorprone.annotations.concurrent.LazyInit;
import com.google.j2objc.annotations.RetainedWith;
import com.google.j2objc.annotations.Weak;
import com.google.j2objc.annotations.WeakOuter;
@@ -1605,8 +1606,8 @@ public final class Maps {
extends ForwardingMap<K, V> implements BiMap<K, V>, Serializable {
final Map<K, V> unmodifiableMap;
final BiMap<? extends K, ? extends V> delegate;
- @RetainedWith @CheckForNull BiMap<V, K> inverse;
- @CheckForNull transient Set<V> values;
+ @LazyInit @RetainedWith @CheckForNull BiMap<V, K> inverse;
+ @LazyInit @CheckForNull transient Set<V> values;
UnmodifiableBiMap(BiMap<? extends K, ? extends V> delegate, @CheckForNull BiMap<V, K> inverse) {
unmodifiableMap = Collections.unmodifiableMap(delegate);
@@ -3450,7 +3451,7 @@ public final class Maps {
throw new UnsupportedOperationException();
}
- @CheckForNull private transient UnmodifiableNavigableMap<K, V> descendingMap;
+ @LazyInit @CheckForNull private transient UnmodifiableNavigableMap<K, V> descendingMap;
@Override
public NavigableMap<K, V> descendingMap() {
@@ -3580,7 +3581,7 @@ public final class Maps {
*/
abstract Set<Entry<K, V>> createEntrySet();
- @CheckForNull private transient Set<Entry<K, V>> entrySet;
+ @LazyInit @CheckForNull private transient Set<Entry<K, V>> entrySet;
@Override
public Set<Entry<K, V>> entrySet() {
@@ -3588,7 +3589,7 @@ public final class Maps {
return (result == null) ? entrySet = createEntrySet() : result;
}
- @CheckForNull private transient Set<K> keySet;
+ @LazyInit @CheckForNull private transient Set<K> keySet;
@Override
public Set<K> keySet() {
@@ -3600,7 +3601,7 @@ public final class Maps {
return new KeySet<>(this);
}
- @CheckForNull private transient Collection<V> values;
+ @LazyInit @CheckForNull private transient Collection<V> values;
@Override
public Collection<V> values() {
@@ -4129,7 +4130,7 @@ public final class Maps {
return forward();
}
- @CheckForNull private transient Comparator<? super K> comparator;
+ @LazyInit @CheckForNull private transient Comparator<? super K> comparator;
@SuppressWarnings("unchecked")
@Override
@@ -4239,7 +4240,7 @@ public final class Maps {
return forward();
}
- @CheckForNull private transient Set<Entry<K, V>> entrySet;
+ @LazyInit @CheckForNull private transient Set<Entry<K, V>> entrySet;
@Override
public Set<Entry<K, V>> entrySet() {
@@ -4270,7 +4271,7 @@ public final class Maps {
return navigableKeySet();
}
- @CheckForNull private transient NavigableSet<K> navigableKeySet;
+ @LazyInit @CheckForNull private transient NavigableSet<K> navigableKeySet;
@Override
public NavigableSet<K> navigableKeySet() {
diff --git a/android/guava/src/com/google/common/collect/Multisets.java b/android/guava/src/com/google/common/collect/Multisets.java
index 0483de559..8bcc639ab 100644
--- a/android/guava/src/com/google/common/collect/Multisets.java
+++ b/android/guava/src/com/google/common/collect/Multisets.java
@@ -30,6 +30,7 @@ import com.google.common.collect.Multiset.Entry;
import com.google.common.math.IntMath;
import com.google.common.primitives.Ints;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
+import com.google.errorprone.annotations.concurrent.LazyInit;
import java.io.Serializable;
import java.util.Arrays;
import java.util.Collection;
@@ -104,7 +105,7 @@ public final class Multisets {
return (Multiset<E>) delegate;
}
- @CheckForNull transient Set<E> elementSet;
+ @LazyInit @CheckForNull transient Set<E> elementSet;
Set<E> createElementSet() {
return Collections.<E>unmodifiableSet(delegate.elementSet());
@@ -116,7 +117,7 @@ public final class Multisets {
return (es == null) ? elementSet = createElementSet() : es;
}
- @CheckForNull transient Set<Multiset.Entry<E>> entrySet;
+ @LazyInit @CheckForNull transient Set<Multiset.Entry<E>> entrySet;
@SuppressWarnings("unchecked")
@Override
diff --git a/android/guava/src/com/google/common/collect/NaturalOrdering.java b/android/guava/src/com/google/common/collect/NaturalOrdering.java
index 8cb8aef9a..dae531270 100644
--- a/android/guava/src/com/google/common/collect/NaturalOrdering.java
+++ b/android/guava/src/com/google/common/collect/NaturalOrdering.java
@@ -19,6 +19,7 @@ package com.google.common.collect;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.annotations.GwtCompatible;
+import com.google.errorprone.annotations.concurrent.LazyInit;
import java.io.Serializable;
import javax.annotation.CheckForNull;
import org.checkerframework.checker.nullness.qual.Nullable;
@@ -30,8 +31,9 @@ import org.checkerframework.checker.nullness.qual.Nullable;
final class NaturalOrdering extends Ordering<Comparable<?>> implements Serializable {
static final NaturalOrdering INSTANCE = new NaturalOrdering();
- @CheckForNull private transient Ordering<@Nullable Comparable<?>> nullsFirst;
- @CheckForNull private transient Ordering<@Nullable Comparable<?>> nullsLast;
+ // TODO: b/287198172 - Consider eagerly initializing these (but think about serialization).
+ @LazyInit @CheckForNull private transient Ordering<@Nullable Comparable<?>> nullsFirst;
+ @LazyInit @CheckForNull private transient Ordering<@Nullable Comparable<?>> nullsLast;
@Override
public int compare(Comparable<?> left, Comparable<?> right) {
diff --git a/android/guava/src/com/google/common/collect/Sets.java b/android/guava/src/com/google/common/collect/Sets.java
index 4a62001f1..1f433f4b6 100644
--- a/android/guava/src/com/google/common/collect/Sets.java
+++ b/android/guava/src/com/google/common/collect/Sets.java
@@ -29,6 +29,7 @@ import com.google.common.collect.Collections2.FilteredCollection;
import com.google.common.math.IntMath;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import com.google.errorprone.annotations.DoNotCall;
+import com.google.errorprone.annotations.concurrent.LazyInit;
import java.io.Serializable;
import java.util.AbstractSet;
import java.util.Arrays;
@@ -1802,7 +1803,7 @@ public final class Sets {
throw new UnsupportedOperationException();
}
- @CheckForNull private transient UnmodifiableNavigableSet<E> descendingSet;
+ @LazyInit @CheckForNull private transient UnmodifiableNavigableSet<E> descendingSet;
@Override
public NavigableSet<E> descendingSet() {
diff --git a/android/guava/src/com/google/common/collect/StandardTable.java b/android/guava/src/com/google/common/collect/StandardTable.java
index b2dacf181..e039877a9 100644
--- a/android/guava/src/com/google/common/collect/StandardTable.java
+++ b/android/guava/src/com/google/common/collect/StandardTable.java
@@ -34,6 +34,7 @@ import com.google.common.collect.Maps.IteratorBasedAbstractMap;
import com.google.common.collect.Maps.ViewCachingAbstractMap;
import com.google.common.collect.Sets.ImprovedAbstractSet;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
+import com.google.errorprone.annotations.concurrent.LazyInit;
import com.google.j2objc.annotations.WeakOuter;
import java.io.Serializable;
import java.util.Collection;
@@ -649,7 +650,7 @@ class StandardTable<R, C, V> extends AbstractTable<R, C, V> implements Serializa
return rowMap().keySet();
}
- @CheckForNull private transient Set<C> columnKeySet;
+ @LazyInit @CheckForNull private transient Set<C> columnKeySet;
/**
* {@inheritDoc}
@@ -780,7 +781,7 @@ class StandardTable<R, C, V> extends AbstractTable<R, C, V> implements Serializa
return super.values();
}
- @CheckForNull private transient Map<R, Map<C, V>> rowMap;
+ @LazyInit @CheckForNull private transient Map<R, Map<C, V>> rowMap;
@Override
public Map<R, Map<C, V>> rowMap() {
@@ -862,7 +863,7 @@ class StandardTable<R, C, V> extends AbstractTable<R, C, V> implements Serializa
}
}
- @CheckForNull private transient ColumnMap columnMap;
+ @LazyInit @CheckForNull private transient ColumnMap columnMap;
@Override
public Map<C, Map<R, V>> columnMap() {
diff --git a/android/guava/src/com/google/common/collect/TreeRangeSet.java b/android/guava/src/com/google/common/collect/TreeRangeSet.java
index 967981ff6..415e80ffb 100644
--- a/android/guava/src/com/google/common/collect/TreeRangeSet.java
+++ b/android/guava/src/com/google/common/collect/TreeRangeSet.java
@@ -20,6 +20,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.annotations.GwtIncompatible;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.MoreObjects;
+import com.google.errorprone.annotations.concurrent.LazyInit;
import java.io.Serializable;
import java.util.Collection;
import java.util.Comparator;
@@ -75,8 +76,8 @@ public class TreeRangeSet<C extends Comparable<?>> extends AbstractRangeSet<C>
this.rangesByLowerBound = rangesByLowerCut;
}
- @CheckForNull private transient Set<Range<C>> asRanges;
- @CheckForNull private transient Set<Range<C>> asDescendingSetOfRanges;
+ @LazyInit @CheckForNull private transient Set<Range<C>> asRanges;
+ @LazyInit @CheckForNull private transient Set<Range<C>> asDescendingSetOfRanges;
@Override
public Set<Range<C>> asRanges() {
@@ -272,7 +273,7 @@ public class TreeRangeSet<C extends Comparable<?>> extends AbstractRangeSet<C>
}
}
- @CheckForNull private transient RangeSet<C> complement;
+ @LazyInit @CheckForNull private transient RangeSet<C> complement;
@Override
public RangeSet<C> complement() {
diff --git a/android/guava/src/com/google/common/collect/UnmodifiableSortedMultiset.java b/android/guava/src/com/google/common/collect/UnmodifiableSortedMultiset.java
index 31f3c7197..c7e1d4c33 100644
--- a/android/guava/src/com/google/common/collect/UnmodifiableSortedMultiset.java
+++ b/android/guava/src/com/google/common/collect/UnmodifiableSortedMultiset.java
@@ -18,6 +18,7 @@ package com.google.common.collect;
import com.google.common.annotations.GwtCompatible;
import com.google.common.collect.Multisets.UnmodifiableMultiset;
+import com.google.errorprone.annotations.concurrent.LazyInit;
import java.util.Comparator;
import java.util.NavigableSet;
import javax.annotation.CheckForNull;
@@ -58,7 +59,7 @@ final class UnmodifiableSortedMultiset<E extends @Nullable Object> extends Unmod
return (NavigableSet<E>) super.elementSet();
}
- @CheckForNull private transient UnmodifiableSortedMultiset<E> descendingMultiset;
+ @LazyInit @CheckForNull private transient UnmodifiableSortedMultiset<E> descendingMultiset;
@Override
public SortedMultiset<E> descendingMultiset() {
diff --git a/android/guava/src/com/google/common/reflect/TypeToken.java b/android/guava/src/com/google/common/reflect/TypeToken.java
index 8abec1a57..6ac3385e8 100644
--- a/android/guava/src/com/google/common/reflect/TypeToken.java
+++ b/android/guava/src/com/google/common/reflect/TypeToken.java
@@ -31,6 +31,7 @@ import com.google.common.collect.Maps;
import com.google.common.collect.Ordering;
import com.google.common.primitives.Primitives;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
+import com.google.errorprone.annotations.concurrent.LazyInit;
import java.io.Serializable;
import java.lang.reflect.Constructor;
import java.lang.reflect.GenericArrayType;
@@ -103,10 +104,10 @@ public abstract class TypeToken<T> extends TypeCapture<T> implements Serializabl
private final Type runtimeType;
/** Resolver for resolving parameter and field types with {@link #runtimeType} as context. */
- @CheckForNull private transient TypeResolver invariantTypeResolver;
+ @LazyInit @CheckForNull private transient TypeResolver invariantTypeResolver;
/** Resolver for resolving covariant types with {@link #runtimeType} as context. */
- @CheckForNull private transient TypeResolver covariantTypeResolver;
+ @LazyInit @CheckForNull private transient TypeResolver covariantTypeResolver;
/**
* Constructs a new type token of {@code T}.
diff --git a/android/guava/src/com/google/common/util/concurrent/AtomicLongMap.java b/android/guava/src/com/google/common/util/concurrent/AtomicLongMap.java
index ace5e3c53..33f08298c 100644
--- a/android/guava/src/com/google/common/util/concurrent/AtomicLongMap.java
+++ b/android/guava/src/com/google/common/util/concurrent/AtomicLongMap.java
@@ -21,6 +21,7 @@ import com.google.common.annotations.J2ktIncompatible;
import com.google.common.base.Function;
import com.google.common.collect.Maps;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
+import com.google.errorprone.annotations.concurrent.LazyInit;
import java.io.Serializable;
import java.util.Collections;
import java.util.Iterator;
@@ -328,7 +329,7 @@ public final class AtomicLongMap<K> implements Serializable {
return sum;
}
- @CheckForNull private transient Map<K, Long> asMap;
+ @LazyInit @CheckForNull private transient Map<K, Long> asMap;
/** Returns a live, read-only view of the map backing this {@code AtomicLongMap}. */
public Map<K, Long> asMap() {
diff --git a/guava/src/com/google/common/cache/LocalCache.java b/guava/src/com/google/common/cache/LocalCache.java
index a0d58280d..8206c8c8a 100644
--- a/guava/src/com/google/common/cache/LocalCache.java
+++ b/guava/src/com/google/common/cache/LocalCache.java
@@ -51,6 +51,7 @@ import com.google.common.util.concurrent.UncheckedExecutionException;
import com.google.common.util.concurrent.Uninterruptibles;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import com.google.errorprone.annotations.concurrent.GuardedBy;
+import com.google.errorprone.annotations.concurrent.LazyInit;
import com.google.j2objc.annotations.RetainedWith;
import com.google.j2objc.annotations.Weak;
import java.io.IOException;
@@ -4348,7 +4349,7 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V>
}
}
- @RetainedWith @CheckForNull Set<K> keySet;
+ @LazyInit @RetainedWith @CheckForNull Set<K> keySet;
@Override
public Set<K> keySet() {
@@ -4357,7 +4358,7 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V>
return (ks != null) ? ks : (keySet = new KeySet());
}
- @RetainedWith @CheckForNull Collection<V> values;
+ @LazyInit @RetainedWith @CheckForNull Collection<V> values;
@Override
public Collection<V> values() {
@@ -4366,7 +4367,7 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V>
return (vs != null) ? vs : (values = new Values());
}
- @RetainedWith @CheckForNull Set<Entry<K, V>> entrySet;
+ @LazyInit @RetainedWith @CheckForNull Set<Entry<K, V>> entrySet;
@Override
@GwtIncompatible // Not supported.
diff --git a/guava/src/com/google/common/collect/AbstractBiMap.java b/guava/src/com/google/common/collect/AbstractBiMap.java
index e72462975..0563ea0e8 100644
--- a/guava/src/com/google/common/collect/AbstractBiMap.java
+++ b/guava/src/com/google/common/collect/AbstractBiMap.java
@@ -25,6 +25,7 @@ import com.google.common.annotations.GwtIncompatible;
import com.google.common.annotations.J2ktIncompatible;
import com.google.common.base.Objects;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
+import com.google.errorprone.annotations.concurrent.LazyInit;
import com.google.j2objc.annotations.RetainedWith;
import com.google.j2objc.annotations.WeakOuter;
import java.io.IOException;
@@ -230,7 +231,7 @@ abstract class AbstractBiMap<K extends @Nullable Object, V extends @Nullable Obj
return inverse;
}
- @CheckForNull private transient Set<K> keySet;
+ @LazyInit @CheckForNull private transient Set<K> keySet;
@Override
public Set<K> keySet() {
@@ -275,7 +276,7 @@ abstract class AbstractBiMap<K extends @Nullable Object, V extends @Nullable Obj
}
}
- @CheckForNull private transient Set<V> valueSet;
+ @LazyInit @CheckForNull private transient Set<V> valueSet;
@Override
public Set<V> values() {
@@ -318,7 +319,7 @@ abstract class AbstractBiMap<K extends @Nullable Object, V extends @Nullable Obj
}
}
- @CheckForNull private transient Set<Entry<K, V>> entrySet;
+ @LazyInit @CheckForNull private transient Set<Entry<K, V>> entrySet;
@Override
public Set<Entry<K, V>> entrySet() {
diff --git a/guava/src/com/google/common/collect/AbstractSortedMultiset.java b/guava/src/com/google/common/collect/AbstractSortedMultiset.java
index 621e8f98a..98b6211a7 100644
--- a/guava/src/com/google/common/collect/AbstractSortedMultiset.java
+++ b/guava/src/com/google/common/collect/AbstractSortedMultiset.java
@@ -17,6 +17,7 @@ package com.google.common.collect;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.annotations.GwtCompatible;
+import com.google.errorprone.annotations.concurrent.LazyInit;
import com.google.j2objc.annotations.WeakOuter;
import java.util.Comparator;
import java.util.Iterator;
@@ -122,7 +123,7 @@ abstract class AbstractSortedMultiset<E extends @Nullable Object> extends Abstra
return Multisets.iteratorImpl(descendingMultiset());
}
- @CheckForNull private transient SortedMultiset<E> descendingMultiset;
+ @LazyInit @CheckForNull private transient SortedMultiset<E> descendingMultiset;
@Override
public SortedMultiset<E> descendingMultiset() {
diff --git a/guava/src/com/google/common/collect/ArrayTable.java b/guava/src/com/google/common/collect/ArrayTable.java
index 38902e3c9..411ee6335 100644
--- a/guava/src/com/google/common/collect/ArrayTable.java
+++ b/guava/src/com/google/common/collect/ArrayTable.java
@@ -27,6 +27,7 @@ import com.google.common.base.Objects;
import com.google.common.collect.Maps.IteratorBasedAbstractMap;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import com.google.errorprone.annotations.DoNotCall;
+import com.google.errorprone.annotations.concurrent.LazyInit;
import com.google.j2objc.annotations.WeakOuter;
import java.io.Serializable;
import java.lang.reflect.Array;
@@ -660,7 +661,7 @@ public final class ArrayTable<R, C, V> extends AbstractTable<R, C, @Nullable V>
return columnKeyToIndex.keySet();
}
- @CheckForNull private transient ColumnMap columnMap;
+ @LazyInit @CheckForNull private transient ColumnMap columnMap;
@Override
public Map<C, Map<R, @Nullable V>> columnMap() {
@@ -755,7 +756,7 @@ public final class ArrayTable<R, C, V> extends AbstractTable<R, C, @Nullable V>
return rowKeyToIndex.keySet();
}
- @CheckForNull private transient RowMap rowMap;
+ @LazyInit @CheckForNull private transient RowMap rowMap;
@Override
public Map<R, Map<C, @Nullable V>> rowMap() {
diff --git a/guava/src/com/google/common/collect/CompactHashMap.java b/guava/src/com/google/common/collect/CompactHashMap.java
index 83f27f8e6..c5cac7ca5 100644
--- a/guava/src/com/google/common/collect/CompactHashMap.java
+++ b/guava/src/com/google/common/collect/CompactHashMap.java
@@ -31,6 +31,7 @@ import com.google.common.base.Objects;
import com.google.common.base.Preconditions;
import com.google.common.primitives.Ints;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
+import com.google.errorprone.annotations.concurrent.LazyInit;
import com.google.j2objc.annotations.WeakOuter;
import java.io.IOException;
import java.io.InvalidObjectException;
@@ -688,7 +689,7 @@ class CompactHashMap<K extends @Nullable Object, V extends @Nullable Object>
}
}
- @CheckForNull private transient Set<K> keySetView;
+ @LazyInit @CheckForNull private transient Set<K> keySetView;
@Override
public Set<K> keySet() {
@@ -798,7 +799,7 @@ class CompactHashMap<K extends @Nullable Object, V extends @Nullable Object>
}
}
- @CheckForNull private transient Set<Entry<K, V>> entrySetView;
+ @LazyInit @CheckForNull private transient Set<Entry<K, V>> entrySetView;
@Override
public Set<Entry<K, V>> entrySet() {
@@ -981,7 +982,7 @@ class CompactHashMap<K extends @Nullable Object, V extends @Nullable Object>
return false;
}
- @CheckForNull private transient Collection<V> valuesView;
+ @LazyInit @CheckForNull private transient Collection<V> valuesView;
@Override
public Collection<V> values() {
diff --git a/guava/src/com/google/common/collect/DescendingMultiset.java b/guava/src/com/google/common/collect/DescendingMultiset.java
index 7db0fbbd4..23ff8319c 100644
--- a/guava/src/com/google/common/collect/DescendingMultiset.java
+++ b/guava/src/com/google/common/collect/DescendingMultiset.java
@@ -17,6 +17,7 @@
package com.google.common.collect;
import com.google.common.annotations.GwtCompatible;
+import com.google.errorprone.annotations.concurrent.LazyInit;
import com.google.j2objc.annotations.WeakOuter;
import java.util.Comparator;
import java.util.Iterator;
@@ -37,7 +38,7 @@ abstract class DescendingMultiset<E extends @Nullable Object> extends Forwarding
implements SortedMultiset<E> {
abstract SortedMultiset<E> forwardMultiset();
- @CheckForNull private transient Comparator<? super E> comparator;
+ @LazyInit @CheckForNull private transient Comparator<? super E> comparator;
@Override
public Comparator<? super E> comparator() {
@@ -48,7 +49,7 @@ abstract class DescendingMultiset<E extends @Nullable Object> extends Forwarding
return result;
}
- @CheckForNull private transient NavigableSet<E> elementSet;
+ @LazyInit @CheckForNull private transient NavigableSet<E> elementSet;
@Override
public NavigableSet<E> elementSet() {
@@ -116,7 +117,7 @@ abstract class DescendingMultiset<E extends @Nullable Object> extends Forwarding
abstract Iterator<Entry<E>> entryIterator();
- @CheckForNull private transient Set<Entry<E>> entrySet;
+ @LazyInit @CheckForNull private transient Set<Entry<E>> entrySet;
@Override
public Set<Entry<E>> entrySet() {
diff --git a/guava/src/com/google/common/collect/GeneralRange.java b/guava/src/com/google/common/collect/GeneralRange.java
index c5e1ba3c4..e462b7a01 100644
--- a/guava/src/com/google/common/collect/GeneralRange.java
+++ b/guava/src/com/google/common/collect/GeneralRange.java
@@ -22,6 +22,7 @@ import static com.google.common.collect.NullnessCasts.uncheckedCastNullableTToT;
import com.google.common.annotations.GwtCompatible;
import com.google.common.base.Objects;
+import com.google.errorprone.annotations.concurrent.LazyInit;
import java.io.Serializable;
import java.util.Comparator;
import javax.annotation.CheckForNull;
@@ -263,7 +264,7 @@ final class GeneralRange<T extends @Nullable Object> implements Serializable {
getUpperBoundType());
}
- @CheckForNull private transient GeneralRange<T> reverse;
+ @LazyInit @CheckForNull private transient GeneralRange<T> reverse;
/** Returns the same range relative to the reversed comparator. */
GeneralRange<T> reverse() {
diff --git a/guava/src/com/google/common/collect/ImmutableRangeSet.java b/guava/src/com/google/common/collect/ImmutableRangeSet.java
index 608456496..afd421cd7 100644
--- a/guava/src/com/google/common/collect/ImmutableRangeSet.java
+++ b/guava/src/com/google/common/collect/ImmutableRangeSet.java
@@ -555,7 +555,7 @@ public final class ImmutableRangeSet<C extends Comparable> extends AbstractRange
this.domain = domain;
}
- @CheckForNull private transient Integer size;
+ @LazyInit @CheckForNull private transient Integer size;
@Override
public int size() {
diff --git a/guava/src/com/google/common/collect/ImmutableSortedMap.java b/guava/src/com/google/common/collect/ImmutableSortedMap.java
index 7479a6023..f38922e43 100644
--- a/guava/src/com/google/common/collect/ImmutableSortedMap.java
+++ b/guava/src/com/google/common/collect/ImmutableSortedMap.java
@@ -1104,16 +1104,18 @@ public final class ImmutableSortedMap<K, V> extends ImmutableSortedMapFauxveride
@Override
public ImmutableSortedMap<K, V> descendingMap() {
- // TODO(kevinb): the descendingMap is never actually cached at all. Either it should be or the
- // code below simplified.
+ // TODO(kevinb): The descendingMap is never actually cached at all. Either:
+ //
+ // - Cache it, and annotate the field with @LazyInit.
+ // - Simplify the code below, and consider eliminating the field (b/287198172), which is also
+ // set by one of the constructors.
ImmutableSortedMap<K, V> result = descendingMap;
if (result == null) {
if (isEmpty()) {
- return result = emptyMap(Ordering.from(comparator()).reverse());
+ return emptyMap(Ordering.from(comparator()).reverse());
} else {
- return result =
- new ImmutableSortedMap<>(
- (RegularImmutableSortedSet<K>) keySet.descendingSet(), valueList.reverse(), this);
+ return new ImmutableSortedMap<>(
+ (RegularImmutableSortedSet<K>) keySet.descendingSet(), valueList.reverse(), this);
}
}
return result;
diff --git a/guava/src/com/google/common/collect/JdkBackedImmutableMultiset.java b/guava/src/com/google/common/collect/JdkBackedImmutableMultiset.java
index faf22b343..41d95f045 100644
--- a/guava/src/com/google/common/collect/JdkBackedImmutableMultiset.java
+++ b/guava/src/com/google/common/collect/JdkBackedImmutableMultiset.java
@@ -18,6 +18,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.annotations.GwtCompatible;
import com.google.common.primitives.Ints;
+import com.google.errorprone.annotations.concurrent.LazyInit;
import java.util.Collection;
import java.util.Map;
import javax.annotation.CheckForNull;
@@ -66,7 +67,7 @@ final class JdkBackedImmutableMultiset<E> extends ImmutableMultiset<E> {
return delegateMap.getOrDefault(element, 0);
}
- @CheckForNull private transient ImmutableSet<E> elementSet;
+ @LazyInit @CheckForNull private transient ImmutableSet<E> elementSet;
@Override
public ImmutableSet<E> elementSet() {
diff --git a/guava/src/com/google/common/collect/MapMakerInternalMap.java b/guava/src/com/google/common/collect/MapMakerInternalMap.java
index e80ec27a5..c64d81eb3 100644
--- a/guava/src/com/google/common/collect/MapMakerInternalMap.java
+++ b/guava/src/com/google/common/collect/MapMakerInternalMap.java
@@ -25,6 +25,7 @@ import com.google.common.collect.MapMaker.Dummy;
import com.google.common.primitives.Ints;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import com.google.errorprone.annotations.concurrent.GuardedBy;
+import com.google.errorprone.annotations.concurrent.LazyInit;
import com.google.j2objc.annotations.Weak;
import com.google.j2objc.annotations.WeakOuter;
import java.io.IOException;
@@ -2522,7 +2523,7 @@ class MapMakerInternalMap<
}
}
- @CheckForNull transient Set<K> keySet;
+ @LazyInit @CheckForNull transient Set<K> keySet;
@Override
public Set<K> keySet() {
@@ -2530,7 +2531,7 @@ class MapMakerInternalMap<
return (ks != null) ? ks : (keySet = new KeySet());
}
- @CheckForNull transient Collection<V> values;
+ @LazyInit @CheckForNull transient Collection<V> values;
@Override
public Collection<V> values() {
@@ -2538,7 +2539,7 @@ class MapMakerInternalMap<
return (vs != null) ? vs : (values = new Values());
}
- @CheckForNull transient Set<Entry<K, V>> entrySet;
+ @LazyInit @CheckForNull transient Set<Entry<K, V>> entrySet;
@Override
public Set<Entry<K, V>> entrySet() {
diff --git a/guava/src/com/google/common/collect/Maps.java b/guava/src/com/google/common/collect/Maps.java
index 942e21cc8..3c1e9c03f 100644
--- a/guava/src/com/google/common/collect/Maps.java
+++ b/guava/src/com/google/common/collect/Maps.java
@@ -38,6 +38,7 @@ import com.google.common.base.Predicates;
import com.google.common.collect.MapDifference.ValueDifference;
import com.google.common.primitives.Ints;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
+import com.google.errorprone.annotations.concurrent.LazyInit;
import com.google.j2objc.annotations.RetainedWith;
import com.google.j2objc.annotations.Weak;
import com.google.j2objc.annotations.WeakOuter;
@@ -1683,8 +1684,8 @@ public final class Maps {
extends ForwardingMap<K, V> implements BiMap<K, V>, Serializable {
final Map<K, V> unmodifiableMap;
final BiMap<? extends K, ? extends V> delegate;
- @RetainedWith @CheckForNull BiMap<V, K> inverse;
- @CheckForNull transient Set<V> values;
+ @LazyInit @RetainedWith @CheckForNull BiMap<V, K> inverse;
+ @LazyInit @CheckForNull transient Set<V> values;
UnmodifiableBiMap(BiMap<? extends K, ? extends V> delegate, @CheckForNull BiMap<V, K> inverse) {
unmodifiableMap = Collections.unmodifiableMap(delegate);
@@ -3660,7 +3661,7 @@ public final class Maps {
throw new UnsupportedOperationException();
}
- @CheckForNull private transient UnmodifiableNavigableMap<K, V> descendingMap;
+ @LazyInit @CheckForNull private transient UnmodifiableNavigableMap<K, V> descendingMap;
@Override
public NavigableMap<K, V> descendingMap() {
@@ -3790,7 +3791,7 @@ public final class Maps {
*/
abstract Set<Entry<K, V>> createEntrySet();
- @CheckForNull private transient Set<Entry<K, V>> entrySet;
+ @LazyInit @CheckForNull private transient Set<Entry<K, V>> entrySet;
@Override
public Set<Entry<K, V>> entrySet() {
@@ -3798,7 +3799,7 @@ public final class Maps {
return (result == null) ? entrySet = createEntrySet() : result;
}
- @CheckForNull private transient Set<K> keySet;
+ @LazyInit @CheckForNull private transient Set<K> keySet;
@Override
public Set<K> keySet() {
@@ -3810,7 +3811,7 @@ public final class Maps {
return new KeySet<>(this);
}
- @CheckForNull private transient Collection<V> values;
+ @LazyInit @CheckForNull private transient Collection<V> values;
@Override
public Collection<V> values() {
@@ -4372,7 +4373,7 @@ public final class Maps {
return forward();
}
- @CheckForNull private transient Comparator<? super K> comparator;
+ @LazyInit @CheckForNull private transient Comparator<? super K> comparator;
@SuppressWarnings("unchecked")
@Override
@@ -4482,7 +4483,7 @@ public final class Maps {
return forward();
}
- @CheckForNull private transient Set<Entry<K, V>> entrySet;
+ @LazyInit @CheckForNull private transient Set<Entry<K, V>> entrySet;
@Override
public Set<Entry<K, V>> entrySet() {
@@ -4513,7 +4514,7 @@ public final class Maps {
return navigableKeySet();
}
- @CheckForNull private transient NavigableSet<K> navigableKeySet;
+ @LazyInit @CheckForNull private transient NavigableSet<K> navigableKeySet;
@Override
public NavigableSet<K> navigableKeySet() {
diff --git a/guava/src/com/google/common/collect/Multisets.java b/guava/src/com/google/common/collect/Multisets.java
index 88e458315..fcc674472 100644
--- a/guava/src/com/google/common/collect/Multisets.java
+++ b/guava/src/com/google/common/collect/Multisets.java
@@ -30,6 +30,7 @@ import com.google.common.collect.Multiset.Entry;
import com.google.common.math.IntMath;
import com.google.common.primitives.Ints;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
+import com.google.errorprone.annotations.concurrent.LazyInit;
import java.io.Serializable;
import java.util.Arrays;
import java.util.Collection;
@@ -134,7 +135,7 @@ public final class Multisets {
return (Multiset<E>) delegate;
}
- @CheckForNull transient Set<E> elementSet;
+ @LazyInit @CheckForNull transient Set<E> elementSet;
Set<E> createElementSet() {
return Collections.<E>unmodifiableSet(delegate.elementSet());
@@ -146,7 +147,7 @@ public final class Multisets {
return (es == null) ? elementSet = createElementSet() : es;
}
- @CheckForNull transient Set<Multiset.Entry<E>> entrySet;
+ @LazyInit @CheckForNull transient Set<Multiset.Entry<E>> entrySet;
@SuppressWarnings("unchecked")
@Override
diff --git a/guava/src/com/google/common/collect/NaturalOrdering.java b/guava/src/com/google/common/collect/NaturalOrdering.java
index 8cb8aef9a..dae531270 100644
--- a/guava/src/com/google/common/collect/NaturalOrdering.java
+++ b/guava/src/com/google/common/collect/NaturalOrdering.java
@@ -19,6 +19,7 @@ package com.google.common.collect;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.annotations.GwtCompatible;
+import com.google.errorprone.annotations.concurrent.LazyInit;
import java.io.Serializable;
import javax.annotation.CheckForNull;
import org.checkerframework.checker.nullness.qual.Nullable;
@@ -30,8 +31,9 @@ import org.checkerframework.checker.nullness.qual.Nullable;
final class NaturalOrdering extends Ordering<Comparable<?>> implements Serializable {
static final NaturalOrdering INSTANCE = new NaturalOrdering();
- @CheckForNull private transient Ordering<@Nullable Comparable<?>> nullsFirst;
- @CheckForNull private transient Ordering<@Nullable Comparable<?>> nullsLast;
+ // TODO: b/287198172 - Consider eagerly initializing these (but think about serialization).
+ @LazyInit @CheckForNull private transient Ordering<@Nullable Comparable<?>> nullsFirst;
+ @LazyInit @CheckForNull private transient Ordering<@Nullable Comparable<?>> nullsLast;
@Override
public int compare(Comparable<?> left, Comparable<?> right) {
diff --git a/guava/src/com/google/common/collect/Sets.java b/guava/src/com/google/common/collect/Sets.java
index 057888f3e..da3814881 100644
--- a/guava/src/com/google/common/collect/Sets.java
+++ b/guava/src/com/google/common/collect/Sets.java
@@ -29,6 +29,7 @@ import com.google.common.collect.Collections2.FilteredCollection;
import com.google.common.math.IntMath;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import com.google.errorprone.annotations.DoNotCall;
+import com.google.errorprone.annotations.concurrent.LazyInit;
import java.io.Serializable;
import java.util.AbstractSet;
import java.util.Arrays;
@@ -1883,7 +1884,7 @@ public final class Sets {
throw new UnsupportedOperationException();
}
- @CheckForNull private transient UnmodifiableNavigableSet<E> descendingSet;
+ @LazyInit @CheckForNull private transient UnmodifiableNavigableSet<E> descendingSet;
@Override
public NavigableSet<E> descendingSet() {
diff --git a/guava/src/com/google/common/collect/StandardTable.java b/guava/src/com/google/common/collect/StandardTable.java
index 9f5898d4a..6ec3c6b23 100644
--- a/guava/src/com/google/common/collect/StandardTable.java
+++ b/guava/src/com/google/common/collect/StandardTable.java
@@ -34,6 +34,7 @@ import com.google.common.collect.Maps.IteratorBasedAbstractMap;
import com.google.common.collect.Maps.ViewCachingAbstractMap;
import com.google.common.collect.Sets.ImprovedAbstractSet;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
+import com.google.errorprone.annotations.concurrent.LazyInit;
import com.google.j2objc.annotations.WeakOuter;
import java.io.Serializable;
import java.util.Collection;
@@ -674,7 +675,7 @@ class StandardTable<R, C, V> extends AbstractTable<R, C, V> implements Serializa
return rowMap().keySet();
}
- @CheckForNull private transient Set<C> columnKeySet;
+ @LazyInit @CheckForNull private transient Set<C> columnKeySet;
/**
* {@inheritDoc}
@@ -805,7 +806,7 @@ class StandardTable<R, C, V> extends AbstractTable<R, C, V> implements Serializa
return super.values();
}
- @CheckForNull private transient Map<R, Map<C, V>> rowMap;
+ @LazyInit @CheckForNull private transient Map<R, Map<C, V>> rowMap;
@Override
public Map<R, Map<C, V>> rowMap() {
@@ -887,7 +888,7 @@ class StandardTable<R, C, V> extends AbstractTable<R, C, V> implements Serializa
}
}
- @CheckForNull private transient ColumnMap columnMap;
+ @LazyInit @CheckForNull private transient ColumnMap columnMap;
@Override
public Map<C, Map<R, V>> columnMap() {
diff --git a/guava/src/com/google/common/collect/TreeRangeSet.java b/guava/src/com/google/common/collect/TreeRangeSet.java
index 967981ff6..415e80ffb 100644
--- a/guava/src/com/google/common/collect/TreeRangeSet.java
+++ b/guava/src/com/google/common/collect/TreeRangeSet.java
@@ -20,6 +20,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.annotations.GwtIncompatible;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.MoreObjects;
+import com.google.errorprone.annotations.concurrent.LazyInit;
import java.io.Serializable;
import java.util.Collection;
import java.util.Comparator;
@@ -75,8 +76,8 @@ public class TreeRangeSet<C extends Comparable<?>> extends AbstractRangeSet<C>
this.rangesByLowerBound = rangesByLowerCut;
}
- @CheckForNull private transient Set<Range<C>> asRanges;
- @CheckForNull private transient Set<Range<C>> asDescendingSetOfRanges;
+ @LazyInit @CheckForNull private transient Set<Range<C>> asRanges;
+ @LazyInit @CheckForNull private transient Set<Range<C>> asDescendingSetOfRanges;
@Override
public Set<Range<C>> asRanges() {
@@ -272,7 +273,7 @@ public class TreeRangeSet<C extends Comparable<?>> extends AbstractRangeSet<C>
}
}
- @CheckForNull private transient RangeSet<C> complement;
+ @LazyInit @CheckForNull private transient RangeSet<C> complement;
@Override
public RangeSet<C> complement() {
diff --git a/guava/src/com/google/common/collect/UnmodifiableSortedMultiset.java b/guava/src/com/google/common/collect/UnmodifiableSortedMultiset.java
index 31f3c7197..c7e1d4c33 100644
--- a/guava/src/com/google/common/collect/UnmodifiableSortedMultiset.java
+++ b/guava/src/com/google/common/collect/UnmodifiableSortedMultiset.java
@@ -18,6 +18,7 @@ package com.google.common.collect;
import com.google.common.annotations.GwtCompatible;
import com.google.common.collect.Multisets.UnmodifiableMultiset;
+import com.google.errorprone.annotations.concurrent.LazyInit;
import java.util.Comparator;
import java.util.NavigableSet;
import javax.annotation.CheckForNull;
@@ -58,7 +59,7 @@ final class UnmodifiableSortedMultiset<E extends @Nullable Object> extends Unmod
return (NavigableSet<E>) super.elementSet();
}
- @CheckForNull private transient UnmodifiableSortedMultiset<E> descendingMultiset;
+ @LazyInit @CheckForNull private transient UnmodifiableSortedMultiset<E> descendingMultiset;
@Override
public SortedMultiset<E> descendingMultiset() {
diff --git a/guava/src/com/google/common/reflect/TypeToken.java b/guava/src/com/google/common/reflect/TypeToken.java
index 8abec1a57..6ac3385e8 100644
--- a/guava/src/com/google/common/reflect/TypeToken.java
+++ b/guava/src/com/google/common/reflect/TypeToken.java
@@ -31,6 +31,7 @@ import com.google.common.collect.Maps;
import com.google.common.collect.Ordering;
import com.google.common.primitives.Primitives;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
+import com.google.errorprone.annotations.concurrent.LazyInit;
import java.io.Serializable;
import java.lang.reflect.Constructor;
import java.lang.reflect.GenericArrayType;
@@ -103,10 +104,10 @@ public abstract class TypeToken<T> extends TypeCapture<T> implements Serializabl
private final Type runtimeType;
/** Resolver for resolving parameter and field types with {@link #runtimeType} as context. */
- @CheckForNull private transient TypeResolver invariantTypeResolver;
+ @LazyInit @CheckForNull private transient TypeResolver invariantTypeResolver;
/** Resolver for resolving covariant types with {@link #runtimeType} as context. */
- @CheckForNull private transient TypeResolver covariantTypeResolver;
+ @LazyInit @CheckForNull private transient TypeResolver covariantTypeResolver;
/**
* Constructs a new type token of {@code T}.
diff --git a/guava/src/com/google/common/util/concurrent/AtomicLongMap.java b/guava/src/com/google/common/util/concurrent/AtomicLongMap.java
index 571e1b1d3..28481cca5 100644
--- a/guava/src/com/google/common/util/concurrent/AtomicLongMap.java
+++ b/guava/src/com/google/common/util/concurrent/AtomicLongMap.java
@@ -21,6 +21,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.J2ktIncompatible;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
+import com.google.errorprone.annotations.concurrent.LazyInit;
import java.io.Serializable;
import java.util.Collections;
import java.util.Map;
@@ -265,7 +266,7 @@ public final class AtomicLongMap<K> implements Serializable {
return map.values().stream().mapToLong(Long::longValue).sum();
}
- @CheckForNull private transient Map<K, Long> asMap;
+ @LazyInit @CheckForNull private transient Map<K, Long> asMap;
/** Returns a live, read-only view of the map backing this {@code AtomicLongMap}. */
public Map<K, Long> asMap() {