private static ElementKind elementKindRecord() {
    try {
      Field record = ElementKind.class.getField("RECORD");
      return (ElementKind) record.get(null);
    } catch (ReflectiveOperationException e) {
      // OK: we must be on a JDK version that predates this.
      return null;
    }
  }
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