Avoid re-initializing factories that are already initialized. This is necessary because we share the internal factory implementation, which leads to initialize(..) being called multiple times. There are other consequences/quirks of this, but re-initialization is the worst of it.

PiperOrigin-RevId: 530339379
This commit is contained in:
Sam Berlin
2023-05-08 10:23:36 -07:00
committed by Guice Team
parent 9ac476784e
commit 40a5bcfab5
2 changed files with 33 additions and 2 deletions
@@ -701,6 +701,7 @@ public final class RealMapBinder<K, V> implements Module {
extends RealMapBinderProviderWithDependencies<K, V, Map<K, Provider<V>>> {
private Map<K, Provider<V>> mapOfProviders;
private Set<Dependency<?>> dependencies = RealMapBinder.MODULE_DEPENDENCIES;
private boolean initialized;
private RealProviderMapProvider(BindingSelection<K, V> bindingSelection) {
super(bindingSelection);
@@ -713,6 +714,10 @@ public final class RealMapBinder<K, V> implements Module {
@Override
protected void doInitialize(InjectorImpl injector, Errors errors) {
if (initialized) {
return;
}
initialized = true;
ImmutableMap.Builder<K, Provider<V>> mapOfProvidersBuilder = ImmutableMap.builder();
ImmutableSet.Builder<Dependency<?>> dependenciesBuilder = ImmutableSet.builder();
for (Map.Entry<K, Binding<V>> entry : bindingSelection.getMapBindings().entrySet()) {
@@ -743,6 +748,8 @@ public final class RealMapBinder<K, V> implements Module {
K[] keys;
private boolean initialized = false;
RealMapProvider(BindingSelection<K, V> bindingSelection) {
super(bindingSelection);
}
@@ -753,6 +760,10 @@ public final class RealMapBinder<K, V> implements Module {
@Override
protected void doInitialize(InjectorImpl injector, Errors errors) throws ErrorsException {
if (initialized) {
return;
}
initialized = true;
@SuppressWarnings("unchecked")
K[] keysArray = (K[]) new Object[bindingSelection.getMapBindings().size()];
keys = keysArray;
@@ -1079,6 +1090,7 @@ public final class RealMapBinder<K, V> implements Module {
extends RealMultimapBinderProviderWithDependencies<K, V, Map<K, Set<Provider<V>>>> {
private Map<K, Set<Provider<V>>> multimapOfProviders;
private Set<Dependency<?>> dependencies = RealMapBinder.MODULE_DEPENDENCIES;
private boolean initialized;
private RealProviderMultimapProvider(Key<Map<K, V>> mapKey) {
super(mapKey);
@@ -1091,6 +1103,10 @@ public final class RealMapBinder<K, V> implements Module {
@Override
protected void doInitialize(InjectorImpl injector, Errors errors) {
if (initialized) {
return;
}
initialized = true;
ImmutableMap.Builder<K, Set<Provider<V>>> multimapOfProvidersBuilder =
ImmutableMap.builder();
ImmutableSet.Builder<Dependency<?>> dependenciesBuilder = ImmutableSet.builder();
@@ -1141,6 +1157,8 @@ public final class RealMapBinder<K, V> implements Module {
private PerKeyData<K, V>[] perKeyDatas;
private boolean initialized = false;
private RealMultimapProvider(Key<Map<K, V>> mapKey) {
super(mapKey);
}
@@ -1152,6 +1170,11 @@ public final class RealMapBinder<K, V> implements Module {
@Override
protected void doInitialize(InjectorImpl injector, Errors errors) throws ErrorsException {
if (initialized) {
return;
}
initialized = true;
@SuppressWarnings({"unchecked", "rawtypes"})
PerKeyData<K, V>[] typedPerKeyData =
new PerKeyData[bindingSelection.getMapBindings().size()];
@@ -706,6 +706,7 @@ public final class RealOptionalBinder<T> implements Module {
private abstract static class RealOptionalBinderProviderWithDependencies<T, P>
extends InternalProviderInstanceBindingImpl.Factory<P> {
protected final BindingSelection<T> bindingSelection;
private boolean initialized = false;
RealOptionalBinderProviderWithDependencies(BindingSelection<T> bindingSelection) {
// We need delayed initialization so we can detect jit bindings created by other bindings
@@ -717,8 +718,15 @@ public final class RealOptionalBinder<T> implements Module {
@Override
final void initialize(InjectorImpl injector, Errors errors) throws ErrorsException {
bindingSelection.initialize(injector, errors);
doInitialize();
if (!initialized) {
initialized = true;
// Note that bindingSelection.initialize has its own guard, because multiple Factory impls
// will delegate to the same bindingSelection (intentionally). The selection has some
// initialization, and each factory impl has other initialization that it may additionally
// do.
bindingSelection.initialize(injector, errors);
doInitialize();
}
}
/**