@Test
  public void builderContext() {
    JavaFileObject parent =
        JavaFileObjects.forSourceLines(
            "foo.bar.Parent",
            "package foo.bar;",
            "",
            "import com.google.common.collect.ImmutableList;",
            "",
            "interface Parent<T> {",
            "  T thing();",
            "  ImmutableList<T> list();",
            "}");
    JavaFileObject autoValueClass =
        JavaFileObjects.forSourceLines(
            "foo.bar.Baz",
            "package foo.bar;",
            "",
            "import com.google.auto.value.AutoValue;",
            "import com.google.common.collect.ImmutableList;",
            "",
            "@AutoValue",
            "abstract class Baz implements Parent<String> {",
            "  static Builder builder() {",
            "    return new AutoValue_Baz.Builder();",
            "  }",
            "",
            "  abstract Builder toBuilder();",
            "",
            "  @AutoValue.Builder",
            "  abstract static class Builder {",
            "    abstract Builder setThing(String x);",
            "    abstract Builder setList(Iterable<String> x);",
            "    abstract Builder setList(ImmutableList<String> x);",
            "    abstract ImmutableList.Builder<String> listBuilder();",
            "    abstract Baz autoBuild();",
            "    Baz build() {",
            "      return autoBuild();",
            "    }",
            "  }",
            "}");
    ContextChecker checker =
        context -> {
          assertThat(context.builder()).isPresent();
          BuilderContext builderContext = context.builder().get();

          assertThat(builderContext.builderType().getQualifiedName().toString())
              .isEqualTo("foo.bar.Baz.Builder");

          Set<ExecutableElement> builderMethods = builderContext.builderMethods();
          assertThat(builderMethods).hasSize(1);
          ExecutableElement builderMethod = Iterables.getOnlyElement(builderMethods);
          assertThat(builderMethod.getSimpleName().toString()).isEqualTo("builder");

          Set<ExecutableElement> toBuilderMethods = builderContext.toBuilderMethods();
          assertThat(toBuilderMethods).hasSize(1);
          ExecutableElement toBuilderMethod = Iterables.getOnlyElement(toBuilderMethods);
          assertThat(toBuilderMethod.getSimpleName().toString()).isEqualTo("toBuilder");

          Optional<ExecutableElement> buildMethod = builderContext.buildMethod();
          assertThat(buildMethod).isPresent();
          assertThat(buildMethod.get().getSimpleName().toString()).isEqualTo("build");
          assertThat(buildMethod.get().getParameters()).isEmpty();
          assertThat(buildMethod.get().getReturnType().toString()).isEqualTo("foo.bar.Baz");

          ExecutableElement autoBuildMethod = builderContext.autoBuildMethod();
          assertThat(autoBuildMethod.getSimpleName().toString()).isEqualTo("autoBuild");
          assertThat(autoBuildMethod.getModifiers()).contains(Modifier.ABSTRACT);
          assertThat(autoBuildMethod.getParameters()).isEmpty();
          assertThat(autoBuildMethod.getReturnType().toString()).isEqualTo("foo.bar.Baz");

          Map<String, Set<ExecutableElement>> setters = builderContext.setters();
          assertThat(setters.keySet()).containsExactly("thing", "list");
          Set<ExecutableElement> thingSetters = setters.get("thing");
          assertThat(thingSetters).hasSize(1);
          ExecutableElement thingSetter = Iterables.getOnlyElement(thingSetters);
          assertThat(thingSetter.getSimpleName().toString()).isEqualTo("setThing");
          Set<ExecutableElement> listSetters = setters.get("list");
          assertThat(listSetters).hasSize(2);
          for (ExecutableElement listSetter : listSetters) {
            assertThat(listSetter.getSimpleName().toString()).isEqualTo("setList");
          }

          Map<String, ExecutableElement> propertyBuilders = builderContext.propertyBuilders();
          assertThat(propertyBuilders.keySet()).containsExactly("list");
          assertThat(propertyBuilders.get("list").getSimpleName().toString())
              .isEqualTo("listBuilder");
        };
    ContextCheckingExtension extension = new ContextCheckingExtension(checker);
    Compilation compilation =
        javac()
            .withProcessors(new AutoValueProcessor(ImmutableList.of(extension)))
            .compile(autoValueClass, parent);
    assertThat(compilation).succeededWithoutWarnings();
  }
Tests that extensions providing their own implemented annotation types or options get picked
up.
value/src/test/java/com/google/auto/value/processor/ExtensionTest.java