Optional<AutoFactoryDeclaration> createIfValid(Element element) {
      checkNotNull(element);
      AnnotationMirror mirror = Mirrors.getAnnotationMirror(element, AutoFactory.class).get();
      checkArgument(
          Mirrors.getQualifiedName(mirror.getAnnotationType())
              .contentEquals(AutoFactory.class.getName()));
      Map<String, AnnotationValue> values =
          Mirrors.simplifyAnnotationValueMap(elements.getElementValuesWithDefaults(mirror));

      // className value is a string, so we can just call toString. We know values.get("className")
      // is non-null because @AutoFactory has an annotation element of that name.
      AnnotationValue classNameValue = requireNonNull(values.get("className"));
      String className = classNameValue.getValue().toString();
      if (!className.isEmpty() && !isValidIdentifier(className)) {
        messager.printMessage(
            ERROR,
            String.format("\"%s\" is not a valid Java identifier", className),
            element,
            mirror,
            classNameValue);
        return Optional.empty();
      }

      ImmutableSet<AnnotationMirror> annotations = annotationsToAdd(element);
      AnnotationValue extendingValue = checkNotNull(values.get("extending"));
      TypeElement extendingType = AnnotationValues.asType(extendingValue);
      if (extendingType == null) {
        messager.printMessage(
            ERROR,
            "Unable to find the type: " + extendingValue.getValue(),
            element,
            mirror,
            extendingValue);
        return Optional.empty();
      } else if (!isValidSupertypeForClass(extendingType)) {
        messager.printMessage(
            ERROR,
            String.format(
                "%s is not a valid supertype for a factory. "
                    + "Supertypes must be non-final classes.",
                extendingType.getQualifiedName()),
            element,
            mirror,
            extendingValue);
        return Optional.empty();
      }
      ImmutableList<ExecutableElement> noParameterConstructors =
          FluentIterable.from(ElementFilter.constructorsIn(extendingType.getEnclosedElements()))
              .filter(
                  new Predicate<ExecutableElement>() {
                    @Override
                    public boolean apply(ExecutableElement constructor) {
                      return constructor.getParameters().isEmpty();
                    }
                  })
              .toList();
      if (noParameterConstructors.isEmpty()) {
        messager.printMessage(
            ERROR,
            String.format(
                "%s is not a valid supertype for a factory. "
                    + "Factory supertypes must have a no-arg constructor.",
                extendingType.getQualifiedName()),
            element,
            mirror,
            extendingValue);
        return Optional.empty();
      } else if (noParameterConstructors.size() > 1) {
        throw new IllegalStateException("Multiple constructors with no parameters??");
      }

      AnnotationValue implementingValue = checkNotNull(values.get("implementing"));
      ImmutableSet.Builder<TypeElement> builder = ImmutableSet.builder();
      for (AnnotationValue implementingTypeValue : AnnotationValues.asList(implementingValue)) {
        builder.add(AnnotationValues.asType(implementingTypeValue));
      }
      ImmutableSet<TypeElement> implementingTypes = builder.build();

      AnnotationValue allowSubclassesValue = checkNotNull(values.get("allowSubclasses"));
      boolean allowSubclasses = AnnotationValues.asBoolean(allowSubclassesValue);

      return Optional.<AutoFactoryDeclaration>of(
          new AutoValue_AutoFactoryDeclaration(
              getAnnotatedType(element),
              element,
              className.isEmpty() ? Optional.empty() : Optional.of(className),
              annotations,
              extendingType,
              implementingTypes,
              allowSubclasses,
              mirror,
              ImmutableMap.copyOf(values)));
    }
This is a value object that mirrors the static declaration of an {@link AutoFactory} annotation.

@author Gregory Kick
factory/src/main/java/com/google/auto/factory/processor/AutoFactoryDeclaration.java