private ImmutableSet<Property> annotationBuilderPropertySet(TypeElement annotationType) {
    // Annotation methods can't have their own annotations so there's nowhere for us to discover
    // a user @Nullable. We can only use our default @Nullable type annotation.
    Nullables nullables = Nullables.fromMethods(processingEnv, ImmutableList.of());
    // Translate the annotation elements into fake Property instances. We're really only interested
    // in the name and type, so we can use them to declare a parameter of the generated
    // @AutoAnnotation method. We'll generate a parameter for every element, even elements that
    // don't have setters in the builder. The generated builder implementation will pass the default
    // value from the annotation to those parameters.
    return methodsIn(annotationType.getEnclosedElements()).stream()
        .filter(m -> m.getParameters().isEmpty() && !m.getModifiers().contains(Modifier.STATIC))
        .map(method -> annotationBuilderProperty(method, nullables))
        .collect(toImmutableSet());
  }
Returns a map from property names to the corresponding getters in the built type. The built
type is the return type of the given {@code executable}, and the property names are the names
of its parameters. If the return type is a {@link DeclaredType} {@code Foo} and if every
property name {@code bar} matches a method {@code bar()} or {@code getBar()} in {@code Foo},
then the method returns a map where {@code bar} maps to {@code bar} or {@code getBar}. If these
conditions are not met then the method returns an empty map.

<p>The method name match is case-insensitive, so we will also accept {@code baR()} or {@code
getbar()}. For a property of type {@code boolean}, we also accept {@code isBar()} (or {@code
isbar()} etc).

<p>The return type of each getter method must match the type of the corresponding parameter
exactly. This will always be true for our principal use cases, Java records and Kotlin data
classes. For other use cases, we may in the future accept getters where we know how to convert,
for example if the getter has type {@code ImmutableList<Baz>} and the parameter has type {@code
Baz[]}. We already have similar logic for the parameter types of builder setters.
value/src/main/java/com/google/auto/value/processor/AutoBuilderProcessor.java