core/src/com/google/inject/internal/InjectorImpl.java
private <T> BindingImpl<T> createJustInTimeBindingRecursive(
      Key<T> key, Errors errors, boolean jitDisabled, JitLimitation jitType)
      throws ErrorsException {
    // ask the parent to create the JIT binding
    if (parent != null) {
      if (jitType == JitLimitation.NEW_OR_EXISTING_JIT
          && jitDisabled
          && !parent.options.jitDisabled) {
        // If the binding would be forbidden here but allowed in a parent, report an error instead
        throw errors.jitDisabledInParent(key).toException();
      }

      try {
        return parent.createJustInTimeBindingRecursive(
            key,
            new Errors(),
            jitDisabled,
            parent.options.jitDisabled ? JitLimitation.NO_JIT : jitType);
      } catch (ErrorsException ignored) {
      }
    }

    // Retrieve the sources before checking for blacklisting to guard against sources becoming null
    // due to a full GC happening after calling state.isBlacklisted and
    // state.getSourcesForBlacklistedKey.
    // TODO(user): Consolidate these two APIs.
    Set<Object> sources = state.getSourcesForBlacklistedKey(key);
    if (state.isBlacklisted(key)) {
      throw errors.childBindingAlreadySet(key, sources).toException();
    }

    key = MoreTypes.canonicalizeKey(key); // before storing the key long-term, canonicalize it.
    BindingImpl<T> binding = createJustInTimeBinding(key, errors, jitDisabled, jitType);
    state.parent().blacklist(key, state, binding.getSource());
    jitBindings.put(key, binding);
    return binding;
  }
private <T> BindingImpl<T> createJustInTimeBindingRecursive(
      Key<T> key, Errors errors, boolean jitDisabled, JitLimitation jitType)
      throws ErrorsException {
    // ask the parent to create the JIT binding
    if (parent != null) {
      if (jitType == JitLimitation.NEW_OR_EXISTING_JIT
          && jitDisabled
          && !parent.options.jitDisabled) {
        // If the binding would be forbidden here but allowed in a parent, report an error instead
        throw errors.jitDisabledInParent(key).toException();
      }

      try {
        return parent.createJustInTimeBindingRecursive(
            key,
            new Errors(),
            jitDisabled,
            parent.options.jitDisabled ? JitLimitation.NO_JIT : jitType);
      } catch (ErrorsException ignored) {
      }
    }

    // Retrieve the sources before checking for blacklisting to guard against sources becoming null
    // due to a full GC happening after calling state.isBlacklisted and
    // state.getSourcesForBlacklistedKey.
    // TODO(user): Consolidate these two APIs.
    Set<Object> sources = state.getSourcesForBlacklistedKey(key);
    if (state.isBlacklisted(key)) {
      throw errors.childBindingAlreadySet(key, sources).toException();
    }

    key = MoreTypes.canonicalizeKey(key); // before storing the key long-term, canonicalize it.
    BindingImpl<T> binding = createJustInTimeBinding(key, errors, jitDisabled, jitType);
    state.parent().blacklist(key, state, binding.getSource());
    jitBindings.put(key, binding);
    return binding;
  }
Attempts to create a just-in-time binding for {@code key} in the root injector, falling back to
other ancestor injectors until this injector is tried.