ImmutableSet<FactoryMethodDescriptor> generateDescriptor(Element element) {
    final AnnotationMirror mirror = Mirrors.getAnnotationMirror(element, AutoFactory.class).get();
    final Optional<AutoFactoryDeclaration> declaration = declarationFactory.createIfValid(element);
    if (!declaration.isPresent()) {
      return ImmutableSet.of();
    }
    return element.accept(
        new ElementKindVisitor6<ImmutableSet<FactoryMethodDescriptor>, Void>() {
          @Override
          protected ImmutableSet<FactoryMethodDescriptor> defaultAction(Element e, Void p) {
            throw new AssertionError("@AutoFactory applied to an impossible element");
          }

          @Override
          public ImmutableSet<FactoryMethodDescriptor> visitTypeAsClass(TypeElement type, Void p) {
            if (type.getModifiers().contains(ABSTRACT)) {
              // applied to an abstract factory
              messager.printMessage(
                  ERROR,
                  "Auto-factory doesn't support being applied to abstract classes.",
                  type,
                  mirror);
              return ImmutableSet.of();
            } else {
              // applied to the type to be created
              ImmutableSet<ExecutableElement> constructors = Elements2.getConstructors(type);
              if (constructors.isEmpty()) {
                return generateDescriptorForDefaultConstructor(declaration.get(), type);
              } else {
                return FluentIterable.from(constructors)
                    .transform(
                        new Function<ExecutableElement, FactoryMethodDescriptor>() {
                          @Override
                          public FactoryMethodDescriptor apply(ExecutableElement constructor) {
                            return generateDescriptorForConstructor(declaration.get(), constructor);
                          }
                        })
                    .toSet();
              }
            }
          }

          @Override
          public ImmutableSet<FactoryMethodDescriptor> visitTypeAsInterface(
              TypeElement type, Void p) {
            // applied to the factory interface
            messager.printMessage(
                ERROR, "Auto-factory doesn't support being applied to interfaces.", type, mirror);
            return ImmutableSet.of();
          }

          @Override
          public ImmutableSet<FactoryMethodDescriptor> visitExecutableAsConstructor(
              ExecutableElement e, Void p) {
            // applied to a constructor of a type to be created
            return ImmutableSet.of(generateDescriptorForConstructor(declaration.get(), e));
          }
        },
        null);
  }
A service that traverses an element and returns the set of factory methods defined therein.

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