@Override
  public synchronized void init(ProcessingEnvironment processingEnv) {
    super.init(processingEnv);
    elements = processingEnv.getElementUtils();
    types = processingEnv.getTypeUtils();
    messager = processingEnv.getMessager();
    String api = processingEnv.getOptions().get(INJECT_API_OPTION);
    if (api != null && !INJECT_APIS.contains(api)) {
      messager.printMessage(
          Kind.ERROR,
          "Usage: -A"
              + INJECT_API_OPTION
              + "=<api>, where <api> is "
              + String.join(" or ", INJECT_APIS));
      errorFunction = unused -> {};
      return;
    }
    try {
      injectApi = InjectApi.from(elements, api);
    } catch (IllegalStateException e) {
      errorFunction =
          element -> {
            messager.printMessage(Kind.ERROR, e.getMessage(), element);
            errorFunction = unused -> {}; // Only print the error once.
          };
      return;
    }
    providedChecker = new ProvidedChecker(messager);
    declarationFactory = new AutoFactoryDeclaration.Factory(elements, messager);
    factoryDescriptorGenerator =
        new FactoryDescriptorGenerator(messager, types, declarationFactory, injectApi);
  }
If non-null, we will call this whenever the {@link #process} method is called, giving it one of
the {@code @AutoFactory} elements, and do nothing else.
factory/src/main/java/com/google/auto/factory/processor/AutoFactoryProcessor.java