package com.google.inject.internal;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.inject.ConfigurationException;
import com.google.inject.Stage;
import com.google.inject.TypeLiteral;
import com.google.inject.spi.InjectionPoint;
import com.google.inject.spi.InjectionRequest;
import com.google.inject.spi.StaticInjectionRequest;
import java.util.List;
import java.util.Set;
final class InjectionRequestProcessor extends AbstractProcessor {
private final List<StaticInjection> staticInjections = Lists.newArrayList();
private final Initializer initializer;
InjectionRequestProcessor(Errors errors, Initializer initializer) {
super(errors);
this.initializer = initializer;
}
@Override
public Boolean visit(StaticInjectionRequest request) {
staticInjections.add(new StaticInjection(injector, request));
injector.state.putStaticInjectionRequest(request);
return true;
}
@Override
public Boolean visit(InjectionRequest<?> request) {
Set<InjectionPoint> injectionPoints;
try {
injectionPoints = request.getInjectionPoints();
} catch (ConfigurationException e) {
errors.merge(e.getErrorMessages());
injectionPoints = e.getPartialValue();
}
initializer.requestInjection(
injector, request.getInstance(), null, request.getSource(), injectionPoints);
injector.state.putInjectionRequest(
new InjectionRequest<>(
request.getSource(),
TypeLiteral.get(request.getInstance().getClass()),
null));
return true;
}
void validate() {
for (StaticInjection staticInjection : staticInjections) {
staticInjection.validate();
}
}
void injectMembers() {
for (StaticInjection staticInjection : staticInjections) {
staticInjection.injectMembers();
}
}
private class StaticInjection {
final InjectorImpl injector;
final Object source;
final StaticInjectionRequest request;
ImmutableList<SingleMemberInjector> memberInjectors;
public StaticInjection(InjectorImpl injector, StaticInjectionRequest request) {
this.injector = injector;
this.source = request.getSource();
this.request = request;
}
void validate() {
Errors errorsForMember = errors.withSource(source);
Set<InjectionPoint> injectionPoints;
try {
injectionPoints = request.getInjectionPoints();
} catch (ConfigurationException e) {
errorsForMember.merge(e.getErrorMessages());
injectionPoints = e.getPartialValue();
}
if (injectionPoints != null) {
memberInjectors =
injector.membersInjectorStore.getInjectors(injectionPoints, errorsForMember);
} else {
memberInjectors = ImmutableList.of();
}
errors.merge(errorsForMember);
}
void injectMembers() {
InternalContext context = injector.enterContext();
try {
boolean isStageTool = injector.options.stage == Stage.TOOL;
for (SingleMemberInjector memberInjector : memberInjectors) {
if (!isStageTool || memberInjector.getInjectionPoint().isToolable()) {
try {
memberInjector.inject(context, null);
} catch (InternalProvisionException e) {
errors.merge(e);
}
}
}
} finally {
context.close();
}
}
}
}