void defineVars(AutoValueOrBuilderTemplateVars vars, BuilderMethodClassifier<?> classifier) {
      this.classifier = classifier;
      Set<ExecutableElement> buildMethods = classifier.buildMethods();
      if (buildMethods.size() != 1) {
        Set<? extends Element> errorElements =
            buildMethods.isEmpty() ? ImmutableSet.of(builderTypeElement) : buildMethods;
        for (Element buildMethod : errorElements) {
          errorReporter.reportError(
              buildMethod,
              "[AutoValueBuilderBuild] Builder must have a single no-argument method, typically"
                  + " called build(), that returns %s%s",
              autoValueClass,
              typeParamsString());
        }
        errorReporter.abortIfAnyError();
        return;
      }
      this.buildMethod = Iterables.getOnlyElement(buildMethods);
      vars.builderIsInterface = builderTypeElement.getKind() == ElementKind.INTERFACE;
      vars.builderTypeName = TypeSimplifier.classNameOf(builderTypeElement);
      vars.builderFormalTypes =
          TypeEncoder.typeParametersString(builderTypeElement.getTypeParameters());
      vars.builderActualTypes = TypeSimplifier.actualTypeParametersString(builderTypeElement);
      vars.buildMethod = Optional.of(new SimpleMethod(buildMethod));
      vars.builderGetters = classifier.builderGetters();
      vars.builderSetters = classifier.propertyNameToSetters();

      vars.builderPropertyBuilders =
          ImmutableMap.copyOf(classifier.propertyNameToPropertyBuilder());

      ImmutableSet<Property> requiredProperties =
          vars.props.stream()
              .filter(p -> !p.isNullable())
              .filter(p -> p.getBuilderInitializer().isEmpty())
              .filter(p -> !p.hasDefault())
              .filter(p -> !vars.builderPropertyBuilders.containsKey(p.getName()))
              .collect(toImmutableSet());
      vars.builderRequiredProperties = BuilderRequiredProperties.of(vars.props, requiredProperties);
    }
Finds any methods in the set that return the builder type. If the builder has type parameters
{@code <A, B>}, then the return type of the method must be {@code Builder<A, B>} with the
same parameter names. We enforce elsewhere that the names and bounds of the builder
parameters must be the same as those of the {@code @AutoValue} class. Here's a correct
example:

<pre>{@code
@AutoValue abstract class Foo<A extends Number, B> {
  abstract int someProperty();

  abstract Builder<A, B> toBuilder();

  interface Builder<A extends Number, B> {...}
}
}</pre>

<p>We currently impose that there cannot be more than one such method.
value/src/main/java/com/google/auto/value/processor/BuilderSpec.java