/*
 * Copyright 2018 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.google.auto.value.processor;

import static com.google.common.truth.Truth.assertThat;
import static com.google.testing.compile.CompilationSubject.assertThat;
import static com.google.testing.compile.CompilationSubject.compilations;
import static com.google.testing.compile.Compiler.javac;
import static java.util.stream.Collectors.joining;

import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.truth.Expect;
import com.google.testing.compile.Compilation;
import com.google.testing.compile.JavaFileObjects;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.UncheckedIOException;
import java.io.Writer;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Arrays;
import java.util.Set;
import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.TypeParameterElement;
import javax.lang.model.util.ElementFilter;
import javax.tools.JavaFileObject;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/** @author emcmanus@google.com (Éamonn McManus) */
@RunWith(JUnit4.class)
public class AutoValueCompilationTest {
  @Rule public final Expect expect = Expect.create();

  @Test
  public void simpleSuccess() {
    // Positive test case that ensures we generate the expected code for at least one case.
    // Most AutoValue code-generation tests are functional, meaning that we check that the generated
    // code does the right thing rather than checking what it looks like, but this test is a sanity
    // check that we are not generating correct but weird code.
    JavaFileObject javaFileObject =
        JavaFileObjects.forSourceLines(
            "foo.bar.Baz",
            "package foo.bar;",
            "",
            "import com.google.auto.value.AutoValue;",
            "",
            "@AutoValue",
            "public abstract class Baz {",
            "  public abstract long buh();",
            "",
            "  public static Baz create(long buh) {",
            "    return new AutoValue_Baz(buh);",
            "  }",
            "}");
    JavaFileObject expectedOutput =
        JavaFileObjects.forSourceLines(
            "foo.bar.AutoValue_Baz",
            "package foo.bar;",
            "",
            GeneratedImport.importGeneratedAnnotationType(),
            "",
            "@Generated(\"" + AutoValueProcessor.class.getName() + "\")",
            "final class AutoValue_Baz extends Baz {",
            "  private final long buh;",
            "",
            "  AutoValue_Baz(long buh) {",
            "    this.buh = buh;",
            "  }",
            "",
            "  @Override public long buh() {",
            "    return buh;",
            "  }",
            "",
            "  @Override public String toString() {",
            "    return \"Baz{\"",
            "        + \"buh=\" + buh",
            "        + \"}\";",
            "  }",
            "",
            "  @Override public boolean equals(Object o) {",
            "    if (o == this) {",
            "      return true;",
            "    }",
            "    if (o instanceof Baz) {",
            "      Baz that = (Baz) o;",
            "      return this.buh == that.buh();",
            "    }",
            "    return false;",
            "  }",
            "",
            "  @Override public int hashCode() {",
            "    int h$ = 1;",
            "    h$ *= 1000003;",
            "    h$ ^= (int) ((buh >>> 32) ^ buh);",
            "    return h$;",
            "  }",
            "}");
    Compilation compilation =
        javac().withProcessors(new AutoValueProcessor()).compile(javaFileObject);
    assertThat(compilation)
        .generatedSourceFile("foo.bar.AutoValue_Baz")
        .hasSourceEquivalentTo(expectedOutput);
  }

  @Test
  public void importTwoWays() {
    // Test that referring to the same class in two different ways does not confuse the import logic
    // into thinking it is two different classes and that therefore it can't import. The code here
    // is nonsensical but successfully reproduces a real problem, which is that a TypeMirror that is
    // extracted using Elements.getTypeElement(name).asType() does not compare equal to one that is
    // extracted from ExecutableElement.getReturnType(), even though Types.isSameType considers them
    // equal. So unless we are careful, the java.util.Arrays that we import explicitly to use its
    // methods will appear different from the java.util.Arrays that is the return type of the
    // arrays() method here.
    JavaFileObject javaFileObject =
        JavaFileObjects.forSourceLines(
            "foo.bar.Baz",
            "package foo.bar;",
            "",
            "import com.google.auto.value.AutoValue;",
            "",
            "import java.util.Arrays;",
            "",
            "@AutoValue",
            "public abstract class Baz {",
            "  @SuppressWarnings(\"mutable\")",
            "  public abstract int[] ints();",
            "  public abstract Arrays arrays();",
            "",
            "  public static Baz create(int[] ints, Arrays arrays) {",
            "    return new AutoValue_Baz(ints, arrays);",
            "  }",
            "}");
    JavaFileObject expectedOutput =
        JavaFileObjects.forSourceLines(
            "foo.bar.AutoValue_Baz",
            "package foo.bar;",
            "",
            "import java.util.Arrays;",
            GeneratedImport.importGeneratedAnnotationType(),
            "",
            "@Generated(\"" + AutoValueProcessor.class.getName() + "\")",
            "final class AutoValue_Baz extends Baz {",
            "  private final int[] ints;",
            "  private final Arrays arrays;",
            "",
            "  AutoValue_Baz(int[] ints, Arrays arrays) {",
            "    if (ints == null) {",
            "      throw new NullPointerException(\"Null ints\");",
            "    }",
            "    this.ints = ints;",
            "    if (arrays == null) {",
            "      throw new NullPointerException(\"Null arrays\");",
            "    }",
            "    this.arrays = arrays;",
            "  }",
            "",
            "  @SuppressWarnings(\"mutable\")",
            "  @Override public int[] ints() {",
            "    return ints;",
            "  }",
            "",
            "  @Override public Arrays arrays() {",
            "    return arrays;",
            "  }",
            "",
            "  @Override public String toString() {",
            "    return \"Baz{\"",
            "        + \"ints=\" + Arrays.toString(ints) + \", \"",
            "        + \"arrays=\" + arrays",
            "        + \"}\";",
            "  }",
            "",
            "  @Override public boolean equals(Object o) {",
            "    if (o == this) {",
            "      return true;",
            "    }",
            "    if (o instanceof Baz) {",
            "      Baz that = (Baz) o;",
            "      return Arrays.equals(this.ints, (that instanceof AutoValue_Baz) "
                + "? ((AutoValue_Baz) that).ints : that.ints())",
            "          && this.arrays.equals(that.arrays());",
            "    }",
            "    return false;",
            "  }",
            "",
            "  @Override public int hashCode() {",
            "    int h$ = 1;",
            "    h$ *= 1000003;",
            "    h$ ^= Arrays.hashCode(ints);",
            "    h$ *= 1000003;",
            "    h$ ^= arrays.hashCode();",
            "    return h$;",
            "  }",
            "}");
    Compilation compilation =
        javac().withProcessors(new AutoValueProcessor()).compile(javaFileObject);
    assertThat(compilation)
        .generatedSourceFile("foo.bar.AutoValue_Baz")
        .hasSourceEquivalentTo(expectedOutput);
  }

  @Test
  public void testNoWarningsFromGenerics() {
    JavaFileObject javaFileObject =
        JavaFileObjects.forSourceLines(
            "foo.bar.Baz",
            "package foo.bar;",
            "import com.google.auto.value.AutoValue;",
            "@AutoValue",
            "public abstract class Baz<T extends Number, U extends T> {",
            "  public abstract T t();",
            "  public abstract U u();",
            "  public static <T extends Number, U extends T> Baz<T, U> create(T t, U u) {",
            "    return new AutoValue_Baz<T, U>(t, u);",
            "  }",
            "}");
    Compilation compilation =
        javac()
            .withProcessors(new AutoValueProcessor())
            .withOptions("-Xlint:-processing", "-implicit:none")
            .compile(javaFileObject);
    assertThat(compilation).succeededWithoutWarnings();
  }

  @Test
  public void testNestedParameterizedTypesWithTypeAnnotations() {
    JavaFileObject annotFileObject =
        JavaFileObjects.forSourceLines(
            "foo.bar.Annot",
            "package foo.bar;",
            "",
            "import java.lang.annotation.ElementType;",
            "import java.lang.annotation.Target;",
            "",
            "@Target(ElementType.TYPE_USE)",
            "public @interface Annot {",
            "  int value();",
            "}");
    JavaFileObject outerFileObject =
        JavaFileObjects.forSourceLines(
            "foo.baz.OuterWithTypeParam",
            "package foo.baz;",
            "",
            "public class OuterWithTypeParam<T extends Number> {",
            "  public class InnerWithTypeParam<U> {}",
            "}");
    JavaFileObject nestyFileObject =
        JavaFileObjects.forSourceLines(
            "com.example.Nesty",
            "package com.example;",
            "",
            "import com.google.auto.value.AutoValue;",
            "import foo.bar.Annot;",
            "import foo.baz.OuterWithTypeParam;",
            "",
            "@AutoValue",
            "abstract class Nesty {",
            "  abstract @Annot(1) OuterWithTypeParam<@Annot(2) Double>",
            "      .@Annot(3) InnerWithTypeParam<@Annot(4) String> inner();",
            "",
            "  static Nesty of(",
            "      @Annot(1) OuterWithTypeParam<@Annot(2) Double>",
            "          .@Annot(3) InnerWithTypeParam<@Annot(4) String> inner) {",
            "    return new AutoValue_Nesty(inner);",
            "  }",
            "}");
    JavaFileObject expectedOutput =
        JavaFileObjects.forSourceLines(
            "com.example.AutoValue_Nesty",
            "package com.example;",
            "",
            "import foo.bar.Annot;",
            "import foo.baz.OuterWithTypeParam;",
            GeneratedImport.importGeneratedAnnotationType(),
            "",
            "@Generated(\"com.google.auto.value.processor.AutoValueProcessor\")",
            "final class AutoValue_Nesty extends Nesty {",
            "  private final @Annot(1) OuterWithTypeParam<@Annot(2) Double>"
                + ".@Annot(3) InnerWithTypeParam<@Annot(4) String> inner;",
            "",
            "  AutoValue_Nesty(",
            "      @Annot(1) OuterWithTypeParam<@Annot(2) Double>"
                + ".@Annot(3) InnerWithTypeParam<@Annot(4) String> inner) {",
            "    if (inner == null) {",
            "      throw new NullPointerException(\"Null inner\");",
            "    }",
            "    this.inner = inner;",
            "  }",
            "",
            "  @Override",
            "  @Annot(1) OuterWithTypeParam<@Annot(2) Double>"
                + ".@Annot(3) InnerWithTypeParam<@Annot(4) String> inner() {",
            "    return inner;",
            "  }",
            "",
            "  @Override",
            "  public String toString() {",
            "    return \"Nesty{\"",
            "        + \"inner=\" + inner",
            "        + \"}\";",
            "  }",
            "",
            "  @Override",
            "  public boolean equals(Object o) {",
            "    if (o == this) {",
            "      return true;",
            "    }",
            "    if (o instanceof Nesty) {",
            "      Nesty that = (Nesty) o;",
            "      return this.inner.equals(that.inner());",
            "    }",
            "    return false;",
            "  }",
            "",

            "  @Override",
            "  public int hashCode() {",
            "    int h$ = 1;",
            "    h$ *= 1000003;",
            "    h$ ^= inner.hashCode();",
            "    return h$;",
            "  }",
            "}");

    Compilation compilation =
        javac()
            .withProcessors(new AutoValueProcessor())
            .withOptions("-Xlint:-processing", "-implicit:none")
            .compile(annotFileObject, outerFileObject, nestyFileObject);
    assertThat(compilation).succeededWithoutWarnings();
    assertThat(compilation)
        .generatedSourceFile("com.example.AutoValue_Nesty")
        .hasSourceEquivalentTo(expectedOutput);
  }

  // Tests that type annotations are correctly copied from the bounds of type parameters in the
  // @AutoValue class to the bounds of the corresponding parameters in the generated class. For
  // example, if we have `@AutoValue abstract class Foo<T extends @NullableType Object>`, then the
  // generated class should be `class AutoValue_Foo<T extends @NullableType Object> extends Foo<T>`.
  // Some buggy versions of javac do not report type annotations correctly in this context.
  // AutoValue can't copy them if it can't see them, so we make a special annotation processor to
  // detect if we are in the presence of this bug and if so we don't fail.
  @Test
  public void testTypeParametersWithAnnotationsOnBounds() {
    @SupportedAnnotationTypes("*")
    class CompilerBugProcessor extends AbstractProcessor {
      boolean checkedAnnotationsOnTypeBounds;
      boolean reportsAnnotationsOnTypeBounds;

      @Override
      public SourceVersion getSupportedSourceVersion() {
        return SourceVersion.latestSupported();
      }

      @Override
      public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
        if (roundEnv.processingOver()) {
          TypeElement test = processingEnv.getElementUtils().getTypeElement("com.example.Test");
          TypeParameterElement t = test.getTypeParameters().get(0);
          this.checkedAnnotationsOnTypeBounds = true;
          this.reportsAnnotationsOnTypeBounds =
              !t.getBounds().get(0).getAnnotationMirrors().isEmpty();
        }
        return false;
      }
    }
    CompilerBugProcessor compilerBugProcessor = new CompilerBugProcessor();
    JavaFileObject nullableTypeFileObject =
        JavaFileObjects.forSourceLines(
            "foo.bar.NullableType",
            "package foo.bar;",
            "",
            "import java.lang.annotation.ElementType;",
            "import java.lang.annotation.Target;",
            "",
            "@Target(ElementType.TYPE_USE)",
            "public @interface NullableType {}");
    JavaFileObject autoValueFileObject =
        JavaFileObjects.forSourceLines(
            "com.example.Test",
            "package com.example;",
            "",
            "import com.google.auto.value.AutoValue;",
            "import foo.bar.NullableType;",
            "",
            "@AutoValue",
            "abstract class Test<T extends @NullableType Object & @NullableType Cloneable> {}");
    Compilation compilation =
        javac()
            .withProcessors(new AutoValueProcessor(), compilerBugProcessor)
            .withOptions("-Xlint:-processing", "-implicit:none")
            .compile(nullableTypeFileObject, autoValueFileObject);
    assertThat(compilation).succeededWithoutWarnings();
    assertThat(compilerBugProcessor.checkedAnnotationsOnTypeBounds).isTrue();
    if (compilerBugProcessor.reportsAnnotationsOnTypeBounds) {
      assertThat(compilation)
          .generatedSourceFile("com.example.AutoValue_Test")
          .contentsAsUtf8String()
          .contains(
              "class AutoValue_Test<T extends @NullableType Object & @NullableType Cloneable>"
                  + " extends Test<T> {");
    }
  }

  // In the following few tests, see AutoValueProcessor.validateMethods for why unrecognized
  // abstract methods provoke only a warning rather than an error. Compilation will fail anyway
  // because the generated class is not abstract and does not implement the unrecognized methods.

  @Test
  public void testAbstractVoid() {
    JavaFileObject javaFileObject =
        JavaFileObjects.forSourceLines(
            "foo.bar.Baz",
            "package foo.bar;",
            "import com.google.auto.value.AutoValue;",
            "@AutoValue",
            "public abstract class Baz {",
            "  public abstract void foo();",
            "}");
    Compilation compilation =
        javac().withProcessors(new AutoValueProcessor()).compile(javaFileObject);
    assertThat(compilation).failed();
    assertThat(compilation)
        .hadWarningContaining(
            "Abstract method is neither a property getter nor a Builder converter")
        .inFile(javaFileObject)
        .onLineContaining("void foo()");
  }

  @Test
  public void testAbstractWithParams() {
    JavaFileObject javaFileObject =
        JavaFileObjects.forSourceLines(
            "foo.bar.Baz",
            "package foo.bar;",
            "import com.google.auto.value.AutoValue;",
            "@AutoValue",
            "public abstract class Baz {",
            "  public abstract int foo(int bar);",
            "}");
    Compilation compilation =
        javac().withProcessors(new AutoValueProcessor()).compile(javaFileObject);
    assertThat(compilation).failed();
    assertThat(compilation)
        .hadWarningContaining(
            "Abstract method is neither a property getter nor a Builder converter")
        .inFile(javaFileObject)
        .onLineContaining("int foo(int bar)");
  }

  @Test
  public void testPrimitiveArrayWarning() {
    JavaFileObject javaFileObject =
        JavaFileObjects.forSourceLines(
            "foo.bar.Baz",
            "package foo.bar;",
            "import com.google.auto.value.AutoValue;",
            "@AutoValue",
            "public abstract class Baz {",
            "  public abstract byte[] bytes();",
            "  public static Baz create(byte[] bytes) {",
            "    return new AutoValue_Baz(bytes);",
            "  }",
            "}");
    Compilation compilation =
        javac().withProcessors(new AutoValueProcessor()).compile(javaFileObject);
    assertThat(compilation).succeeded();
    assertThat(compilation)
        .hadWarningContaining(
            "An @AutoValue property that is a primitive array returns the original array")
        .inFile(javaFileObject)
        .onLineContaining("byte[] bytes()");
  }

  @Test
  public void testPrimitiveArrayWarningFromParent() {
    // If the array-valued property is defined by an ancestor then we shouldn't try to attach
    // the warning to the method that defined it, but rather to the @AutoValue class itself.
    JavaFileObject javaFileObject =
        JavaFileObjects.forSourceLines(
            "foo.bar.Baz",
            "package foo.bar;",
            "import com.google.auto.value.AutoValue;",
            "public abstract class Baz {",
            "  public abstract byte[] bytes();",
            "",
            "  @AutoValue",
            "  public abstract static class BazChild extends Baz {",
            "    public static BazChild create(byte[] bytes) {",
            "      return new AutoValue_Baz_BazChild(bytes);",
            "    }",
            "  }",
            "}");
    Compilation compilation =
        javac().withProcessors(new AutoValueProcessor()).compile(javaFileObject);
    assertThat(compilation).succeeded();
    assertThat(compilation)
        .hadWarningContainingMatch(
            "An @AutoValue property that is a primitive array returns the original array"
                + ".*foo\\.bar\\.Baz\\.bytes")
        .inFile(javaFileObject)
        .onLineContaining("BazChild extends Baz");
  }

  @Test
  public void testPrimitiveArrayWarningSuppressed() {
    JavaFileObject javaFileObject =
        JavaFileObjects.forSourceLines(
            "foo.bar.Baz",
            "package foo.bar;",
            "import com.google.auto.value.AutoValue;",
            "@AutoValue",
            "public abstract class Baz {",
            "  @SuppressWarnings(\"mutable\")",
            "  public abstract byte[] bytes();",
            "  public static Baz create(byte[] bytes) {",
            "    return new AutoValue_Baz(bytes);",
            "  }",
            "}");
    Compilation compilation =
        javac()
            .withProcessors(new AutoValueProcessor())
            .withOptions("-Xlint:-processing", "-implicit:none")
            .compile(javaFileObject);
    assertThat(compilation).succeededWithoutWarnings();
  }

  @Test
  public void autoValueMustBeStatic() {
    JavaFileObject javaFileObject =
        JavaFileObjects.forSourceLines(
            "foo.bar.Baz",
            "package foo.bar;",
            "",
            "import com.google.auto.value.AutoValue;",
            "",
            "public class Baz {",
            "  @AutoValue",
            "  public abstract class NotStatic {",
            "    public abstract String buh();",
            "    public NotStatic create(String buh) {",
            "      return new AutoValue_Baz_NotStatic(buh);",
            "    }",
            "  }",
            "}");
    Compilation compilation =
        javac().withProcessors(new AutoValueProcessor()).compile(javaFileObject);
    assertThat(compilation)
        .hadErrorContaining("Nested @AutoValue class must be static")
        .inFile(javaFileObject)
        .onLineContaining("abstract class NotStatic");
  }

  @Test
  public void autoValueMustBeNotBePrivate() {
    JavaFileObject javaFileObject =
        JavaFileObjects.forSourceLines(
            "foo.bar.Baz",
            "package foo.bar;",
            "",
            "import com.google.auto.value.AutoValue;",
            "",
            "public class Baz {",
            "  @AutoValue",
            "  private abstract static class Private {",
            "    public abstract String buh();",
            "    public Private create(String buh) {",
            "      return new AutoValue_Baz_Private(buh);",
            "    }",
            "  }",
            "}");
    Compilation compilation =
        javac().withProcessors(new AutoValueProcessor()).compile(javaFileObject);
    assertThat(compilation)
        .hadErrorContaining("@AutoValue class must not be private")
        .inFile(javaFileObject)
        .onLineContaining("class Private");
  }

  @Test
  public void autoValueMustBeNotBeNestedInPrivate() {
    JavaFileObject javaFileObject =
        JavaFileObjects.forSourceLines(
            "foo.bar.Baz",
            "package foo.bar;",
            "",
            "import com.google.auto.value.AutoValue;",
            "",
            "public class Baz {",
            "  private static class Private {",
            "    @AutoValue",
            "    abstract static class Nested {",
            "      public abstract String buh();",
            "      public Nested create(String buh) {",
            "        return new AutoValue_Baz_Private_Nested(buh);",
            "      }",
            "    }",
            "  }",
            "}");
    Compilation compilation =
        javac().withProcessors(new AutoValueProcessor()).compile(javaFileObject);
    assertThat(compilation)
        .hadErrorContaining("@AutoValue class must not be nested in a private class")
        .inFile(javaFileObject)
        .onLineContaining("class Nested");
  }

  @Test
  public void noMultidimensionalPrimitiveArrays() {
    JavaFileObject javaFileObject =
        JavaFileObjects.forSourceLines(
            "foo.bar.Baz",
            "package foo.bar;",
            "",
            "import com.google.auto.value.AutoValue;",
            "",
            "@AutoValue",
            "public abstract class Baz {",
            "  public abstract int[][] ints();",
            "",
            "  public static Baz create(int[][] ints) {",
            "    return new AutoValue_Baz(ints);",
            "  }",
            "}");
    Compilation compilation =
        javac().withProcessors(new AutoValueProcessor()).compile(javaFileObject);
    assertThat(compilation)
        .hadErrorContaining(
            "@AutoValue class cannot define an array-valued property "
                + "unless it is a primitive array")
        .inFile(javaFileObject)
        .onLineContaining("int[][] ints()");
  }

  @Test
  public void noObjectArrays() {
    JavaFileObject javaFileObject =
        JavaFileObjects.forSourceLines(
            "foo.bar.Baz",
            "package foo.bar;",
            "",
            "import com.google.auto.value.AutoValue;",
            "",
            "@AutoValue",
            "public abstract class Baz {",
            "  public abstract String[] strings();",
            "",
            "  public static Baz create(String[] strings) {",
            "    return new AutoValue_Baz(strings);",
            "  }",
            "}");
    Compilation compilation =
        javac().withProcessors(new AutoValueProcessor()).compile(javaFileObject);
    assertThat(compilation)
        .hadErrorContaining(
            "@AutoValue class cannot define an array-valued property "
                + "unless it is a primitive array")
        .inFile(javaFileObject)
        .onLineContaining("String[] strings()");
  }

  @Test
  public void annotationOnInterface() {
    JavaFileObject javaFileObject =
        JavaFileObjects.forSourceLines(
            "foo.bar.Baz",
            "package foo.bar;",
            "",
            "import com.google.auto.value.AutoValue;",
            "",
            "@AutoValue",
            "public interface Baz {}");
    Compilation compilation =
        javac().withProcessors(new AutoValueProcessor()).compile(javaFileObject);
    assertThat(compilation)
        .hadErrorContaining("AutoValue only applies to classes")
        .inFile(javaFileObject)
        .onLineContaining("interface Baz");
  }

  @Test
  public void annotationOnEnum() {
    JavaFileObject javaFileObject =
        JavaFileObjects.forSourceLines(
            "foo.bar.Baz",
            "package foo.bar;",
            "",
            "import com.google.auto.value.AutoValue;",
            "",
            "@AutoValue",
            "public enum Baz {}");
    Compilation compilation =
        javac().withProcessors(new AutoValueProcessor()).compile(javaFileObject);
    assertThat(compilation)
        .hadErrorContaining("AutoValue only applies to classes")
        .inFile(javaFileObject)
        .onLineContaining("enum Baz");
  }

  @Test
  public void extendAutoValue() {
    JavaFileObject javaFileObject =
        JavaFileObjects.forSourceLines(
            "foo.bar.Outer",
            "package foo.bar;",
            "",
            "import com.google.auto.value.AutoValue;",
            "",
            "public class Outer {",
            "  @AutoValue",
            "  static abstract class Parent {",
            "    static Parent create(int randomProperty) {",
            "      return new AutoValue_Outer_Parent(randomProperty);",
            "    }",
            "",
            "    abstract int randomProperty();",
            "  }",
            "",
            "  @AutoValue",
            "  static abstract class Child extends Parent {",
            "    static Child create(int randomProperty) {",
            "      return new AutoValue_Outer_Child(randomProperty);",
            "    }",
            "",
            "    abstract int randomProperty();",
            "  }",
            "}");
    Compilation compilation =
        javac().withProcessors(new AutoValueProcessor()).compile(javaFileObject);
    assertThat(compilation)
        .hadErrorContaining("may not extend")
        .inFile(javaFileObject)
        .onLineContaining("Child extends Parent");
  }

  @Test
  public void bogusSerialVersionUID() {
    String[] mistakes = {
      "final long serialVersionUID = 1234L", // not static
      "static long serialVersionUID = 1234L", // not final
      "static final Long serialVersionUID = 1234L", // not long
      "static final long serialVersionUID = (Long) 1234L", // not a compile-time constant
    };
    for (String mistake : mistakes) {
      JavaFileObject javaFileObject =
          JavaFileObjects.forSourceLines(
              "foo.bar.Baz",
              "package foo.bar;",
              "",
              "import com.google.auto.value.AutoValue;",
              "",
              "@AutoValue",
              "public abstract class Baz implements java.io.Serializable {",
              "  " + mistake + ";",
              "",
              "  public abstract int foo();",
              "}");
      Compilation compilation =
          javac().withProcessors(new AutoValueProcessor()).compile(javaFileObject);
      expect
          .about(compilations())
          .that(compilation)
          .hadErrorContaining("serialVersionUID must be a static final long compile-time constant")
          .inFile(javaFileObject)
          .onLineContaining(mistake);
    }
  }

  @Test
  public void nonExistentSuperclass() {
    // The main purpose of this test is to check that AutoValueProcessor doesn't crash the
    // compiler in this case.
    JavaFileObject javaFileObject =
        JavaFileObjects.forSourceLines(
            "foo.bar.Baz",
            "package foo.bar;",
            "",
            "import com.google.auto.value.AutoValue;",
            "",
            "@AutoValue",
            "public abstract class Existent extends NonExistent {",
            "}");
    Compilation compilation =
        javac().withProcessors(new AutoValueProcessor()).compile(javaFileObject);
    assertThat(compilation)
        .hadErrorContaining("NonExistent")
        .inFile(javaFileObject)
        .onLineContaining("NonExistent");
  }

  @Test
  public void cannotImplementAnnotation() {
    JavaFileObject javaFileObject =
        JavaFileObjects.forSourceLines(
            "foo.bar.RetentionImpl",
            "package foo.bar;",
            "",
            "import com.google.auto.value.AutoValue;",
            "import java.lang.annotation.Retention;",
            "import java.lang.annotation.RetentionPolicy;",
            "",
            "@AutoValue",
            "public abstract class RetentionImpl implements Retention {",
            "  public static Retention create(RetentionPolicy policy) {",
            "    return new AutoValue_RetentionImpl(policy);",
            "  }",
            "",
            "  @Override public Class<? extends Retention> annotationType() {",
            "    return Retention.class;",
            "  }",
            "",
            "  @Override public boolean equals(Object o) {",
            "    return (o instanceof Retention && value().equals((Retention) o).value());",
            "  }",
            "",
            "  @Override public int hashCode() {",
            "    return (\"value\".hashCode() * 127) ^ value().hashCode();",
            "  }",
            "}");
    Compilation compilation =
        javac().withProcessors(new AutoValueProcessor()).compile(javaFileObject);
    assertThat(compilation)
        .hadErrorContaining("may not be used to implement an annotation interface")
        .inFile(javaFileObject)
        .onLineContaining("RetentionImpl implements Retention");
  }

  @Test
  public void missingPropertyType() {
    JavaFileObject javaFileObject =
        JavaFileObjects.forSourceLines(
            "foo.bar.Baz",
            "package foo.bar;",
            "",
            "import com.google.auto.value.AutoValue;",
            "",
            "@AutoValue",
            "public abstract class Baz {",
            "  public abstract MissingType missingType();",
            "}");
    Compilation compilation =
        javac().withProcessors(new AutoValueProcessor()).compile(javaFileObject);
    assertThat(compilation)
        .hadErrorContaining("MissingType")
        .inFile(javaFileObject)
        .onLineContaining("MissingType");
  }

  @Test
  public void missingGenericPropertyType() {
    JavaFileObject javaFileObject =
        JavaFileObjects.forSourceLines(
            "foo.bar.Baz",
            "package foo.bar;",
            "",
            "import com.google.auto.value.AutoValue;",
            "",
            "@AutoValue",
            "public abstract class Baz {",
            "  public abstract MissingType<?> missingType();",
            "}");
    Compilation compilation =
        javac().withProcessors(new AutoValueProcessor()).compile(javaFileObject);
    assertThat(compilation)
        .hadErrorContaining("MissingType")
        .inFile(javaFileObject)
        .onLineContaining("MissingType");
  }

  @Test
  public void missingComplexGenericPropertyType() {
    JavaFileObject javaFileObject =
        JavaFileObjects.forSourceLines(
            "foo.bar.Baz",
            "package foo.bar;",
            "",
            "import com.google.auto.value.AutoValue;",
            "",
            "import java.util.Map;",
            "import java.util.Set;",
            "",
            "@AutoValue",
            "public abstract class Baz {",
            "  public abstract Map<Set<?>, MissingType<?>> missingType();",
            "}");
    Compilation compilation =
        javac().withProcessors(new AutoValueProcessor()).compile(javaFileObject);
    assertThat(compilation)
        .hadErrorContaining("MissingType")
        .inFile(javaFileObject)
        .onLineContaining("MissingType");
  }

  @Test
  public void missingSuperclassGenericParameter() {
    JavaFileObject javaFileObject =
        JavaFileObjects.forSourceLines(
            "foo.bar.Baz",
            "package foo.bar;",
            "",
            "import com.google.auto.value.AutoValue;",
            "",
            "@AutoValue",
            "public abstract class Baz<T extends MissingType<?>> {",
            "  public abstract int foo();",
            "}");
    Compilation compilation =
        javac().withProcessors(new AutoValueProcessor()).compile(javaFileObject);
    assertThat(compilation)
        .hadErrorContaining("MissingType")
        .inFile(javaFileObject)
        .onLineContaining("MissingType");
  }

  @Test
  public void nullablePrimitive() {
    JavaFileObject javaFileObject =
        JavaFileObjects.forSourceLines(
            "foo.bar.Baz",
            "package foo.bar;",
            "",
            "import com.google.auto.value.AutoValue;",
            "",
            "@AutoValue",
            "public abstract class Baz {",
            "  @interface Nullable {}",
            "  public abstract @Nullable int foo();",
            "}");
    Compilation compilation =
        javac().withProcessors(new AutoValueProcessor()).compile(javaFileObject);
    assertThat(compilation)
        .hadErrorContaining("Primitive types cannot be @Nullable")
        .inFile(javaFileObject)
        .onLineContaining("@Nullable int");
  }

  @Test
  public void correctBuilder() {
    JavaFileObject javaFileObject =
        JavaFileObjects.forSourceLines(
            "foo.bar.Baz",
            "package foo.bar;",
            "",
            "import com.google.auto.value.AutoValue;",
            "import com.google.common.base.Optional;",
            "import com.google.common.collect.ImmutableList;",
            "",
            "import java.util.ArrayList;",
            "import java.util.List;",
            "import javax.annotation.Nullable;",
            "",
            "@AutoValue",
            "public abstract class Baz<T extends Number> {",
            "  public abstract int anInt();",
            "  @SuppressWarnings(\"mutable\")",
            "  public abstract byte[] aByteArray();",
            "  @SuppressWarnings(\"mutable\")",
            "  @Nullable public abstract int[] aNullableIntArray();",
            "  public abstract List<T> aList();",
            "  public abstract ImmutableList<T> anImmutableList();",
            "  public abstract Optional<String> anOptionalString();",
            "  public abstract NestedAutoValue<T> aNestedAutoValue();",
            "",
            "  public abstract Builder<T> toBuilder();",
            "",
            "  @AutoValue.Builder",
            "  public abstract static class Builder<T extends Number> {",
            "    public abstract Builder<T> anInt(int x);",
            "    public abstract Builder<T> aByteArray(byte[] x);",
            "    public abstract Builder<T> aNullableIntArray(@Nullable int[] x);",
            "    public abstract Builder<T> aList(List<T> x);",
            "    public abstract Builder<T> anImmutableList(List<T> x);",
            "    public abstract ImmutableList.Builder<T> anImmutableListBuilder();",
            "    public abstract Builder<T> anOptionalString(Optional<String> s);",
            "    public abstract Builder<T> anOptionalString(String s);",
            "    public abstract NestedAutoValue.Builder<T> aNestedAutoValueBuilder();",
            "",
            "    public Builder<T> aList(ArrayList<T> x) {",
            // ArrayList should not be imported in the generated class.
            "      return aList((List<T>) x);",
            "    }",
            "",
            "    public abstract Optional<Integer> anInt();",
            "    public abstract List<T> aList();",
            "    public abstract ImmutableList<T> anImmutableList();",
            "",
            "    public abstract Baz<T> build();",
            "  }",
            "",
            "  public static <T extends Number> Builder<T> builder() {",
            "    return AutoValue_Baz.builder();",
            "  }",
            "}");
    JavaFileObject nestedJavaFileObject =
        JavaFileObjects.forSourceLines(
            "foo.bar.NestedAutoValue",
            "package foo.bar;",
            "",
            "import com.google.auto.value.AutoValue;",
            "",
            "@AutoValue",
            "public abstract class NestedAutoValue<T extends Number> {",
            "  public abstract T t();",
            "",
            "  public abstract Builder<T> toBuilder();",
            "",
            "  @AutoValue.Builder",
            "  public abstract static class Builder<T extends Number> {",
            "    public abstract Builder<T> t(T t);",
            "    public abstract NestedAutoValue<T> build();",
            "  }",
            "",
            "  public static <T extends Number> Builder<T> builder() {",
            "    return AutoValue_NestedAutoValue.builder();",
            "  }",
            "}");
    JavaFileObject expectedOutput =
        JavaFileObjects.forSourceLines(
            "foo.bar.AutoValue_Baz",
            "package foo.bar;",
            "",
            "import com.google.common.base.Optional;",
            "import com.google.common.collect.ImmutableList;",
            "import java.util.Arrays;",
            "import java.util.List;",
            sorted(
                GeneratedImport.importGeneratedAnnotationType(),
                "import javax.annotation.Nullable;"),
            "",
            "@Generated(\"" + AutoValueProcessor.class.getName() + "\")",
            "final class AutoValue_Baz<T extends Number> extends Baz<T> {",
            "  private final int anInt;",
            "  private final byte[] aByteArray;",
            "  private final int[] aNullableIntArray;",
            "  private final List<T> aList;",
            "  private final ImmutableList<T> anImmutableList;",
            "  private final Optional<String> anOptionalString;",
            "  private final NestedAutoValue<T> aNestedAutoValue;",
            "",
            "  private AutoValue_Baz(",
            "      int anInt,",
            "      byte[] aByteArray,",
            "      @Nullable int[] aNullableIntArray,",
            "      List<T> aList,",
            "      ImmutableList<T> anImmutableList,",
            "      Optional<String> anOptionalString,",
            "      NestedAutoValue<T> aNestedAutoValue) {",
            "    this.anInt = anInt;",
            "    this.aByteArray = aByteArray;",
            "    this.aNullableIntArray = aNullableIntArray;",
            "    this.aList = aList;",
            "    this.anImmutableList = anImmutableList;",
            "    this.anOptionalString = anOptionalString;",
            "    this.aNestedAutoValue = aNestedAutoValue;",
            "  }",
            "",
            "  @Override public int anInt() {",
            "    return anInt;",
            "  }",
            "",
            "  @SuppressWarnings(\"mutable\")",
            "  @Override public byte[] aByteArray() {",
            "    return aByteArray;",
            "  }",
            "",
            "  @SuppressWarnings(\"mutable\")",
            "  @Nullable",
            "  @Override public int[] aNullableIntArray() {",
            "    return aNullableIntArray;",
            "  }",
            "",
            "  @Override public List<T> aList() {",
            "    return aList;",
            "  }",
            "",
            "  @Override public ImmutableList<T> anImmutableList() {",
            "    return anImmutableList;",
            "  }",
            "",
            "  @Override public Optional<String> anOptionalString() {",
            "    return anOptionalString;",
            "  }",
            "",
            "  @Override public NestedAutoValue<T> aNestedAutoValue() {",
            "    return aNestedAutoValue;",
            "  }",
            "",
            "  @Override public String toString() {",
            "    return \"Baz{\"",
            "        + \"anInt=\" + anInt + \", \"",
            "        + \"aByteArray=\" + Arrays.toString(aByteArray) + \", \"",
            "        + \"aNullableIntArray=\" + Arrays.toString(aNullableIntArray) + \", \"",
            "        + \"aList=\" + aList + \", \"",
            "        + \"anImmutableList=\" + anImmutableList + \", \"",
            "        + \"anOptionalString=\" + anOptionalString + \", \"",
            "        + \"aNestedAutoValue=\" + aNestedAutoValue",
            "        + \"}\";",
            "  }",
            "",
            "  @Override public boolean equals(Object o) {",
            "    if (o == this) {",
            "      return true;",
            "    }",
            "    if (o instanceof Baz) {",
            "      Baz<?> that = (Baz<?>) o;",
            "      return this.anInt == that.anInt()",
            "          && Arrays.equals(this.aByteArray, "
                + "(that instanceof AutoValue_Baz) "
                + "? ((AutoValue_Baz) that).aByteArray : that.aByteArray())",
            "          && Arrays.equals(this.aNullableIntArray, "
                + "(that instanceof AutoValue_Baz) "
                + "? ((AutoValue_Baz) that).aNullableIntArray : that.aNullableIntArray())",
            "          && this.aList.equals(that.aList())",
            "          && this.anImmutableList.equals(that.anImmutableList())",
            "          && this.anOptionalString.equals(that.anOptionalString())",
            "          && this.aNestedAutoValue.equals(that.aNestedAutoValue());",
            "    }",
            "    return false;",
            "  }",
            "",
            "  @Override public int hashCode() {",
            "    int h$ = 1;",
            "    h$ *= 1000003;",
            "    h$ ^= anInt;",
            "    h$ *= 1000003;",
            "    h$ ^= Arrays.hashCode(aByteArray);",
            "    h$ *= 1000003;",
            "    h$ ^= Arrays.hashCode(aNullableIntArray);",
            "    h$ *= 1000003;",
            "    h$ ^= aList.hashCode();",
            "    h$ *= 1000003;",
            "    h$ ^= anImmutableList.hashCode();",
            "    h$ *= 1000003;",
            "    h$ ^= anOptionalString.hashCode();",
            "    h$ *= 1000003;",
            "    h$ ^= aNestedAutoValue.hashCode();",
            "    return h$;",
            "  }",
            "",
            "  @Override public Baz.Builder<T> toBuilder() {",
            "    return new Builder<T>(this);",
            "  }",
            "",
            "  static final class Builder<T extends Number> extends Baz.Builder<T> {",
            "    private Integer anInt;",
            "    private byte[] aByteArray;",
            "    private int[] aNullableIntArray;",
            "    private List<T> aList;",
            "    private ImmutableList.Builder<T> anImmutableListBuilder$;",
            "    private ImmutableList<T> anImmutableList;",
            "    private Optional<String> anOptionalString = Optional.absent();",
            "    private NestedAutoValue.Builder<T> aNestedAutoValueBuilder$;",
            "    private NestedAutoValue<T> aNestedAutoValue;",
            "",
            "    Builder() {",
            "    }",
            "",
            "    private Builder(Baz<T> source) {",
            "      this.anInt = source.anInt();",
            "      this.aByteArray = source.aByteArray();",
            "      this.aNullableIntArray = source.aNullableIntArray();",
            "      this.aList = source.aList();",
            "      this.anImmutableList = source.anImmutableList();",
            "      this.anOptionalString = source.anOptionalString();",
            "      this.aNestedAutoValue = source.aNestedAutoValue();",
            "    }",
            "",
            "    @Override",
            "    public Baz.Builder<T> anInt(int anInt) {",
            "      this.anInt = anInt;",
            "      return this;",
            "    }",
            "",
            "    @Override",
            "    public Optional<Integer> anInt() {",
            "      if (anInt == null) {",
            "        return Optional.absent();",
            "      } else {",
            "        return Optional.of(anInt);",
            "      }",
            "    }",
            "",
            "    @Override",
            "    public Baz.Builder<T> aByteArray(byte[] aByteArray) {",
            "      if (aByteArray == null) {",
            "        throw new NullPointerException(\"Null aByteArray\");",
            "      }",
            "      this.aByteArray = aByteArray;",
            "      return this;",
            "    }",
            "",
            "    @Override",
            "    public Baz.Builder<T> aNullableIntArray(@Nullable int[] aNullableIntArray) {",
            "      this.aNullableIntArray = aNullableIntArray;",
            "      return this;",
            "    }",
            "",
            "    @Override",
            "    public Baz.Builder<T> aList(List<T> aList) {",
            "      if (aList == null) {",
            "        throw new NullPointerException(\"Null aList\");",
            "      }",
            "      this.aList = aList;",
            "      return this;",
            "    }",
            "",
            "    @Override",
            "    public List<T> aList() {",
            "      if (aList == null) {",
            "        throw new IllegalStateException(\"Property \\\"aList\\\" has not been set\");",
            "      }",
            "      return aList;",
            "    }",
            "",
            "    @Override",
            "    public Baz.Builder<T> anImmutableList(List<T> anImmutableList) {",
            "      if (anImmutableListBuilder$ != null) {",
            "        throw new IllegalStateException("
                + "\"Cannot set anImmutableList after calling anImmutableListBuilder()\");",
            "      }",
            "      this.anImmutableList = ImmutableList.copyOf(anImmutableList);",
            "      return this;",
            "    }",
            "",
            "    @Override",
            "    public ImmutableList.Builder<T> anImmutableListBuilder() {",
            "      if (anImmutableListBuilder$ == null) {",
            "        if (anImmutableList == null) {",
            "          anImmutableListBuilder$ = ImmutableList.builder();",
            "        } else {",
            "          anImmutableListBuilder$ = ImmutableList.builder();",
            "          anImmutableListBuilder$.addAll(anImmutableList);",
            "          anImmutableList = null;",
            "        }",
            "      }",
            "      return anImmutableListBuilder$;",
            "    }",
            "",
            "    @Override",
            "    public ImmutableList<T> anImmutableList() {",
            "      if (anImmutableListBuilder$ != null) {",
            "        return anImmutableListBuilder$.build();",
            "      }",
            "      if (anImmutableList == null) {",
            "        anImmutableList = ImmutableList.of();",
            "      }",
            "      return anImmutableList;",
            "    }",
            "",
            "    @Override",
            "    public Baz.Builder<T> anOptionalString(Optional<String> anOptionalString) {",
            "      if (anOptionalString == null) {",
            "        throw new NullPointerException(\"Null anOptionalString\");",
            "      }",
            "      this.anOptionalString = anOptionalString;",
            "      return this;",
            "    }",
            "",
            "    @Override",
            "    public Baz.Builder<T> anOptionalString(String anOptionalString) {",
            "      this.anOptionalString = Optional.of(anOptionalString);",
            "      return this;",
            "    }",
            "",
            "    @Override",
            "    public NestedAutoValue.Builder<T> aNestedAutoValueBuilder() {",
            "      if (aNestedAutoValueBuilder$ == null) {",
            "        if (aNestedAutoValue == null) {",
            "          aNestedAutoValueBuilder$ = NestedAutoValue.builder();",
            "        } else {",
            "          aNestedAutoValueBuilder$ = aNestedAutoValue.toBuilder();",
            "          aNestedAutoValue = null;",
            "        }",
            "      }",
            "      return aNestedAutoValueBuilder$;",
            "    }",
            "",
            "    @Override",
            "    public Baz<T> build() {",
            "      if (anImmutableListBuilder$ != null) {",
            "        this.anImmutableList = anImmutableListBuilder$.build();",
            "      } else if (this.anImmutableList == null) {",
            "        this.anImmutableList = ImmutableList.of();",
            "      }",
            "      if (aNestedAutoValueBuilder$ != null) {",
            "        this.aNestedAutoValue = aNestedAutoValueBuilder$.build();",
            "      } else if (this.aNestedAutoValue == null) {",
            "        NestedAutoValue.Builder<T> aNestedAutoValue$builder = "
                + "NestedAutoValue.builder();",
            "        this.aNestedAutoValue = aNestedAutoValue$builder.build();",
            "      }",
            "      String missing = \"\";",
            "      if (this.anInt == null) {",
            "        missing += \" anInt\";",
            "      }",
            "      if (this.aByteArray == null) {",
            "        missing += \" aByteArray\";",
            "      }",
            "      if (this.aList == null) {",
            "        missing += \" aList\";",
            "      }",
            "      if (!missing.isEmpty()) {",
            "        throw new IllegalStateException(\"Missing required properties:\" + missing);",
            "      }",
            "      return new AutoValue_Baz<T>(",
            "          this.anInt,",
            "          this.aByteArray,",
            "          this.aNullableIntArray,",
            "          this.aList,",
            "          this.anImmutableList,",
            "          this.anOptionalString,",
            "          this.aNestedAutoValue);",
            "    }",
            "  }",
            "}");
    Compilation compilation =
        javac()
            .withProcessors(new AutoValueProcessor())
            .withOptions("-Xlint:-processing", "-implicit:none")
            .compile(javaFileObject, nestedJavaFileObject);
    assertThat(compilation).succeededWithoutWarnings();
    assertThat(compilation)
        .generatedSourceFile("foo.bar.AutoValue_Baz")
        .hasSourceEquivalentTo(expectedOutput);
  }

  @Test
  public void autoValueBuilderOnTopLevelClass() {
    JavaFileObject javaFileObject =
        JavaFileObjects.forSourceLines(
            "foo.bar.Builder",
            "package foo.bar;",
            "",
            "import com.google.auto.value.AutoValue;",
            "",
            "@AutoValue.Builder",
            "public interface Builder {",
            "  Builder foo(int x);",
            "  Object build();",
            "}");
    Compilation compilation =
        javac()
            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())
            .compile(javaFileObject);
    assertThat(compilation)
        .hadErrorContaining("can only be applied to a class or interface inside")
        .inFile(javaFileObject)
        .onLineContaining("public interface Builder");
  }

  @Test
  public void autoValueBuilderNotInsideAutoValue() {
    JavaFileObject javaFileObject =
        JavaFileObjects.forSourceLines(
            "foo.bar.Baz",
            "package foo.bar;",
            "",
            "import com.google.auto.value.AutoValue;",
            "",
            "public abstract class Baz {",
            "  abstract int foo();",
            "",
            "  static Builder builder() {",
            "    return new AutoValue_Baz.Builder();",
            "  }",
            "",
            "  @AutoValue.Builder",
            "  public interface Builder {",
            "    Builder foo(int x);",
            "    Baz build();",
            "  }",
            "}");
    Compilation compilation =
        javac()
            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())
            .compile(javaFileObject);
    assertThat(compilation)
        .hadErrorContaining("can only be applied to a class or interface inside")
        .inFile(javaFileObject)
        .onLineContaining("public interface Builder");
  }

  @Test
  public void autoValueBuilderNotStatic() {
    JavaFileObject javaFileObject =
        JavaFileObjects.forSourceLines(
            "foo.bar.Example",
            "package foo.bar;",
            "",
            "import com.google.auto.value.AutoValue;",
            "",
            "class Example {",
            "  @AutoValue",
            "  abstract static class Baz {",
            "    abstract int foo();",
            "",
            "    static Builder builder() {",
            "      return new AutoValue_Example_Baz.Builder();",
            "    }",
            "",
            "    @AutoValue.Builder",
            "    abstract class Builder {",
            "      abstract Builder foo(int x);",
            "      abstract Baz build();",
            "    }",
            "  }",
            "}");
    Compilation compilation =
        javac()
            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())
            .compile(javaFileObject);
    assertThat(compilation)
        .hadErrorContaining("@AutoValue.Builder cannot be applied to a non-static class")
        .inFile(javaFileObject)
        .onLineContaining("abstract class Builder");
  }

  @Test
  public void autoValueBuilderOnEnum() {
    JavaFileObject javaFileObject =
        JavaFileObjects.forSourceLines(
            "foo.bar.Baz",
            "package foo.bar;",
            "",
            "import com.google.auto.value.AutoValue;",
            "",
            "@AutoValue",
            "public abstract class Baz {",
            "  abstract int foo();",
            "",
            "  static Builder builder() {",
            "    return null;",
            "  }",
            "",
            "  @AutoValue.Builder",
            "  public enum Builder {}",
            "}");
    Compilation compilation =
        javac()
            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())
            .compile(javaFileObject);
    assertThat(compilation)
        .hadErrorContaining("can only apply to a class or an interface")
        .inFile(javaFileObject)
        .onLineContaining("public enum Builder");
  }

  @Test
  public void autoValueBuilderDuplicate() {
    JavaFileObject javaFileObject =
        JavaFileObjects.forSourceLines(
            "foo.bar.Baz",
            "package foo.bar;",
            "",
            "import com.google.auto.value.AutoValue;",
            "",
            "@AutoValue",
            "public abstract class Baz {",
            "  @AutoValue.Builder",
            "  public interface Builder1 {",
            "    Baz build();",
            "  }",
            "",
            "  @AutoValue.Builder",
            "  public interface Builder2 {",
            "    Baz build();",
            "  }",
            "}");
    Compilation compilation =
        javac()
            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())
            .compile(javaFileObject);
    assertThat(compilation)
        .hadErrorContaining("already has a Builder: foo.bar.Baz.Builder1")
        .inFile(javaFileObject)
        .onLineContaining("public interface Builder2");
  }

  @Test
  public void autoValueBuilderMissingSetter() {
    JavaFileObject javaFileObject =
        JavaFileObjects.forSourceLines(
            "foo.bar.Baz",
            "package foo.bar;",
            "",
            "import com.google.auto.value.AutoValue;",
            "",
            "@AutoValue",
            "public abstract class Baz {",
            "  abstract int blim();",
            "  abstract String blam();",
            "",
            "  @AutoValue.Builder",
            "  public interface Builder {",
            "    Builder blam(String x);",
            "    Baz build();",
            "  }",
            "}");
    Compilation compilation =
        javac()
            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())
            .compile(javaFileObject);
    assertThat(compilation)
        .hadErrorContaining("with this signature: foo.bar.Baz.Builder blim(int)")
        .inFile(javaFileObject)
        .onLineContaining("public interface Builder");
  }

  @Test
  public void autoValueBuilderMissingSetterUsingSetPrefix() {
    JavaFileObject javaFileObject =
        JavaFileObjects.forSourceLines(
            "foo.bar.Baz",
            "package foo.bar;",
            "",
            "import com.google.auto.value.AutoValue;",
            "",
            "@AutoValue",
            "public abstract class Baz {",
            "  abstract int blim();",
            "  abstract String blam();",
            "",
            "  @AutoValue.Builder",
            "  public interface Builder {",
            "    Builder setBlam(String x);",
            "    Baz build();",
            "  }",
            "}");
    Compilation compilation =
        javac()
            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())
            .compile(javaFileObject);
    assertThat(compilation)
        .hadErrorContaining("with this signature: foo.bar.Baz.Builder setBlim(int)")
        .inFile(javaFileObject)
        .onLineContaining("public interface Builder");
  }

  @Test
  public void autoValueBuilderWrongTypeSetter() {
    JavaFileObject javaFileObject =
        JavaFileObjects.forSourceLines(
            "foo.bar.Baz",
            "package foo.bar;",
            "",
            "import com.google.auto.value.AutoValue;",
            "",
            "@AutoValue",
            "public abstract class Baz {",
            "  abstract int blim();",
            "  abstract String blam();",
            "",
            "  @AutoValue.Builder",
            "  public interface Builder {",
            "    Builder blim(String x);",
            "    Builder blam(String x);",
            "    Baz build();",
            "  }",
            "}");
    Compilation compilation =
        javac()
            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())
            .compile(javaFileObject);
    assertThat(compilation)
        .hadErrorContaining(
            "Parameter type java.lang.String of setter method should be int "
                + "to match getter foo.bar.Baz.blim")
        .inFile(javaFileObject)
        .onLineContaining("Builder blim(String x)");
  }

  @Test
  public void autoValueBuilderWrongTypeSetterWithCopyOf() {
    JavaFileObject javaFileObject =
        JavaFileObjects.forSourceLines(
            "foo.bar.Baz",
            "package foo.bar;",
            "",
            "import com.google.auto.value.AutoValue;",
            "import com.google.common.collect.ImmutableList;",
            "",
            "@AutoValue",
            "public abstract class Baz {",
            "  abstract String blim();",
            "  abstract ImmutableList<String> blam();",
            "",
            "  @AutoValue.Builder",
            "  public interface Builder {",
            "    Builder blim(String x);",
            "    Builder blam(String x);",
            "    Baz build();",
            "  }",
            "}");
    Compilation compilation =
        javac()
            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())
            .compile(javaFileObject);
    assertThat(compilation)
        .hadErrorContaining(
            "Parameter type java.lang.String of setter method should be "
                + "com.google.common.collect.ImmutableList<java.lang.String> to match getter "
                + "foo.bar.Baz.blam, or it should be a type that can be passed to "
                + "ImmutableList.copyOf")
        .inFile(javaFileObject)
        .onLineContaining("Builder blam(String x)");
  }

  @Test
  public void autoValueBuilderWrongTypeSetterWithCopyOfGenericallyWrong() {
    JavaFileObject javaFileObject =
        JavaFileObjects.forSourceLines(
            "foo.bar.Baz",
            "package foo.bar;",
            "",
            "import com.google.auto.value.AutoValue;",
            "import com.google.common.collect.ImmutableList;",
            "import java.util.Collection;",
            "",
            "@AutoValue",
            "public abstract class Baz {",
            "  abstract String blim();",
            "  abstract ImmutableList<String> blam();",
            "",
            "  @AutoValue.Builder",
            "  public interface Builder {",
            "    Builder blim(String x);",
            "    Builder blam(Collection<Integer> x);",
            "    Baz build();",
            "  }",
            "}");
    Compilation compilation =
        javac()
            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())
            .compile(javaFileObject);
    assertThat(compilation)
        .hadErrorContaining(
            "Parameter type java.util.Collection<java.lang.Integer> of setter method should be "
                + "com.google.common.collect.ImmutableList<java.lang.String> to match getter "
                + "foo.bar.Baz.blam, or it should be a type that can be passed to "
                + "ImmutableList.copyOf to produce "
                + "com.google.common.collect.ImmutableList<java.lang.String>")
        .inFile(javaFileObject)
        .onLineContaining("Builder blam(Collection<Integer> x)");
  }

  @Test
  public void autoValueBuilderWrongTypeSetterWithGetPrefix() {
    JavaFileObject javaFileObject =
        JavaFileObjects.forSourceLines(
            "foo.bar.Baz",
            "package foo.bar;",
            "",
            "import com.google.auto.value.AutoValue;",
            "",
            "@AutoValue",
            "public abstract class Baz {",
            "  abstract int getBlim();",
            "  abstract String getBlam();",
            "",
            "  @AutoValue.Builder",
            "  public interface Builder {",
            "    Builder blim(String x);",
            "    Builder blam(String x);",
            "    Baz build();",
            "  }",
            "}");
    Compilation compilation =
        javac()
            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())
            .compile(javaFileObject);
    assertThat(compilation)
        .hadErrorContaining(
            "Parameter type java.lang.String of setter method should be int "
                + "to match getter foo.bar.Baz.getBlim")
        .inFile(javaFileObject)
        .onLineContaining("Builder blim(String x)");
  }

  @Test
  public void autoValueBuilderNullableSetterForNonNullable() {
    JavaFileObject nullableFileObject =
        JavaFileObjects.forSourceLines(
            "foo.bar.Nullable",
            "package foo.bar;",
            "",
            "import java.lang.annotation.ElementType;",
            "import java.lang.annotation.Target;",
            "",
            "@Target(ElementType.TYPE_USE)",
            "public @interface Nullable {}");
    JavaFileObject javaFileObject =
        JavaFileObjects.forSourceLines(
            "foo.bar.Baz",
            "package foo.bar;",
            "",
            "import com.google.auto.value.AutoValue;",
            "",
            "@AutoValue",
            "public abstract class Baz {",
            "  abstract String notNull();",
            "",
            "  @AutoValue.Builder",
            "  public interface Builder {",
            "    Builder setNotNull(@Nullable String x);",
            "    Baz build();",
            "  }",
            "}");
    Compilation compilation =
        javac()
            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())
            .compile(javaFileObject, nullableFileObject);
    assertThat(compilation)
        .hadErrorContaining(
            "Parameter of setter method is @Nullable but property method"
                + " foo.bar.Baz.notNull() is not")
        .inFile(javaFileObject)
        .onLineContaining("setNotNull");
  }

  // Check that we get a helpful error message if some of your properties look like getters but
  // others don't.
  @Test
  public void autoValueBuilderBeansConfusion() {
    JavaFileObject javaFileObject =
        JavaFileObjects.forSourceLines(
            "foo.bar.Item",
            "package foo.bar;",
            "",
            "import com.google.auto.value.AutoValue;",
            "",
            "@AutoValue",
            "public abstract class Item {",
            "  abstract String getTitle();",
            "  abstract boolean hasThumbnail();",
            "",
            "  @AutoValue.Builder",
            "  public interface Builder {",
            "    Builder setTitle(String title);",
            "    Builder setHasThumbnail(boolean t);",
            "    Item build();",
            "  }",
            "}");
    Compilation compilation =
        javac()
            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())
            .compile(javaFileObject);
    assertThat(compilation)
        .hadErrorContaining("Method does not correspond to a property of foo.bar.Item")
        .inFile(javaFileObject)
        .onLineContaining("Builder setTitle(String title)");
    assertThat(compilation)
        .hadNoteContaining("hasThumbnail")
        .inFile(javaFileObject)
        .onLineContaining("Builder setTitle(String title)");
  }

  @Test
  public void autoValueBuilderExtraSetter() {
    JavaFileObject javaFileObject =
        JavaFileObjects.forSourceLines(
            "foo.bar.Baz",
            "package foo.bar;",
            "",
            "import com.google.auto.value.AutoValue;",
            "",
            "@AutoValue",
            "public abstract class Baz {",
            "  abstract String blam();",
            "",
            "  @AutoValue.Builder",
            "  public interface Builder {",
            "    Builder blim(int x);",
            "    Builder blam(String x);",
            "    Baz build();",
            "  }",
            "}");
    Compilation compilation =
        javac()
            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())
            .compile(javaFileObject);
    assertThat(compilation)
        .hadErrorContaining("Method does not correspond to a property of foo.bar.Baz")
        .inFile(javaFileObject)
        .onLineContaining("Builder blim(int x)");
  }

  @Test
  public void autoValueBuilderSetPrefixAndNoSetPrefix() {
    JavaFileObject javaFileObject =
        JavaFileObjects.forSourceLines(
            "foo.bar.Baz",
            "package foo.bar;",
            "",
            "import com.google.auto.value.AutoValue;",
            "",
            "@AutoValue",
            "public abstract class Baz {",
            "  abstract int blim();",
            "  abstract String blam();",
            "",
            "  @AutoValue.Builder",
            "  public interface Builder {",
            "    Builder blim(int x);",
            "    Builder setBlam(String x);",
            "    Baz build();",
            "  }",
            "}");
    Compilation compilation =
        javac()
            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())
            .compile(javaFileObject);
    assertThat(compilation)
        .hadErrorContaining("If any setter methods use the setFoo convention then all must")
        .inFile(javaFileObject)
        .onLineContaining("Builder blim(int x)");
  }

  @Test
  public void autoValueBuilderWrongTypeGetter() {
    JavaFileObject javaFileObject =
        JavaFileObjects.forSourceLines(
            "foo.bar.Baz",
            "package foo.bar;",
            "",
            "import com.google.auto.value.AutoValue;",
            "",
            "@AutoValue",
            "public abstract class Baz<T, U> {",
            "  abstract T blim();",
            "  abstract U blam();",
            "",
            "  @AutoValue.Builder",
            "  public interface Builder<T, U> {",
            "    Builder<T, U> blim(T x);",
            "    Builder<T, U> blam(U x);",
            "    T blim();",
            "    T blam();",
            "    Baz<T, U> build();",
            "  }",
            "}");
    Compilation compilation =
        javac()
            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())
            .compile(javaFileObject);
    assertThat(compilation)
        .hadErrorContaining(
            "Method matches a property of foo.bar.Baz but has return type T instead of U")
        .inFile(javaFileObject)
        .onLineContaining("T blam()");
  }

  @Test
  public void autoValueBuilderPropertyBuilderInvalidType() {
    JavaFileObject javaFileObject =
        JavaFileObjects.forSourceLines(
            "foo.bar.Baz",
            "package foo.bar;",
            "",
            "import com.google.auto.value.AutoValue;",
            "",
            "@AutoValue",
            "public abstract class Baz<T, U> {",
            "  abstract String blim();",
            "",
            "  @AutoValue.Builder",
            "  public interface Builder<T, U> {",
            "    StringBuilder blimBuilder();",
            "    Baz<T, U> build();",
            "  }",
            "}");
    Compilation compilation =
        javac()
            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())
            .compile(javaFileObject);
    assertThat(compilation)
        .hadErrorContaining(
            "Method looks like a property builder, but it returns java.lang.StringBuilder which "
                + "does not have a non-static build() method")
        .inFile(javaFileObject)
        .onLineContaining("StringBuilder blimBuilder()");
  }

  @Test
  public void autoValueBuilderPropertyBuilderNullable() {
    JavaFileObject javaFileObject =
        JavaFileObjects.forSourceLines(
            "foo.bar.Baz",
            "package foo.bar;",
            "",
            "import com.google.auto.value.AutoValue;",
            "import com.google.common.collect.ImmutableList;",
            "",
            "@AutoValue",
            "public abstract class Baz<T, U> {",
            "  @interface Nullable {}",
            "  abstract @Nullable ImmutableList<String> strings();",
            "",
            "  @AutoValue.Builder",
            "  public interface Builder<T, U> {",
            "    ImmutableList.Builder<String> stringsBuilder();",
            "    Baz<T, U> build();",
            "  }",
            "}");
    Compilation compilation =
        javac()
            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())
            .compile(javaFileObject);
    assertThat(compilation)
        .hadErrorContaining("Property strings has a property builder so it cannot be @Nullable")
        .inFile(javaFileObject)
        .onLineContaining("@Nullable ImmutableList<String> strings()");
  }

  @Test
  public void autoValueBuilderPropertyBuilderNullableType() {
    JavaFileObject javaFileObject =
        JavaFileObjects.forSourceLines(
            "foo.bar.Baz",
            "package foo.bar;",
            "",
            "import com.google.auto.value.AutoValue;",
            "import com.google.common.collect.ImmutableList;",
            "import java.lang.annotation.ElementType;",
            "import java.lang.annotation.Target;",
            "",
            "@AutoValue",
            "public abstract class Baz<T, U> {",
            "  @Target(ElementType.TYPE_USE)",
            "  @interface Nullable {}",
            "  abstract @Nullable ImmutableList<String> strings();",
            "",
            "  @AutoValue.Builder",
            "  public interface Builder<T, U> {",
            "    ImmutableList.Builder<String> stringsBuilder();",
            "    Baz<T, U> build();",
            "  }",
            "}");
    Compilation compilation =
        javac()
            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())
            .compile(javaFileObject);
    assertThat(compilation)
        .hadErrorContaining("Property strings has a property builder so it cannot be @Nullable")
        .inFile(javaFileObject)
        .onLineContaining("@Nullable ImmutableList<String> strings()");
  }

  @Test
  public void autoValueBuilderPropertyBuilderWrongCollectionType() {
    JavaFileObject javaFileObject =
        JavaFileObjects.forSourceLines(
            "foo.bar.Baz",
            "package foo.bar;",
            "",
            "import com.google.auto.value.AutoValue;",
            "import com.google.common.collect.ImmutableList;",
            "import com.google.common.collect.ImmutableSet;",
            "",
            "@AutoValue",
            "public abstract class Baz<T, U> {",
            "  abstract ImmutableList<T> blim();",
            "",
            "  @AutoValue.Builder",
            "  public interface Builder<T, U> {",
            "    ImmutableSet.Builder<T> blimBuilder();",
            "    Baz<T, U> build();",
            "  }",
            "}");
    Compilation compilation =
        javac()
            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())
            .compile(javaFileObject);
    assertThat(compilation)
        .hadErrorContaining(
            "Property builder for blim has type com.google.common.collect.ImmutableSet.Builder "
                + "whose build() method returns com.google.common.collect.ImmutableSet<T> "
                + "instead of com.google.common.collect.ImmutableList<T>")
        .inFile(javaFileObject)
        .onLineContaining("ImmutableSet.Builder<T> blimBuilder()");
  }

  @Test
  public void autoValueBuilderPropertyBuilderWeirdBuilderType() {
    JavaFileObject javaFileObject =
        JavaFileObjects.forSourceLines(
            "foo.bar.Baz",
            "package foo.bar;",
            "",
            "import com.google.auto.value.AutoValue;",
            "import com.google.common.collect.ImmutableSet;",
            "",
            "@AutoValue",
            "public abstract class Baz<T, U> {",
            "  abstract Integer blim();",
            "",
            "  @AutoValue.Builder",
            "  public interface Builder<T, U> {",
            "    int blimBuilder();",
            "    Baz<T, U> build();",
            "  }",
            "}");
    Compilation compilation =
        javac()
            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())
            .compile(javaFileObject);
    assertThat(compilation)
        .hadErrorContaining(
            "Method looks like a property builder, but its return type is not a class or interface")
        .inFile(javaFileObject)
        .onLineContaining("int blimBuilder()");
  }

  @Test
  public void autoValueBuilderPropertyBuilderWeirdBuiltType() {
    JavaFileObject javaFileObject =
        JavaFileObjects.forSourceLines(
            "foo.bar.Baz",
            "package foo.bar;",
            "",
            "import com.google.auto.value.AutoValue;",
            "import com.google.common.collect.ImmutableSet;",
            "",
            "@AutoValue",
            "public abstract class Baz<T, U> {",
            "  abstract int blim();",
            "",
            "  @AutoValue.Builder",
            "  public interface Builder<T, U> {",
            "    Integer blimBuilder();",
            "    Baz<T, U> build();",
            "  }",
            "}");
    Compilation compilation =
        javac()
            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())
            .compile(javaFileObject);
    assertThat(compilation)
        .hadErrorContaining(
            "Method looks like a property builder, but the type of property blim is not a class "
                + "or interface")
        .inFile(javaFileObject)
        .onLineContaining("Integer blimBuilder()");
  }

  @Test
  public void autoValueBuilderPropertyBuilderHasNoBuild() {
    JavaFileObject javaFileObject =
        JavaFileObjects.forSourceLines(
            "foo.bar.Baz",
            "package foo.bar;",
            "",
            "import com.google.auto.value.AutoValue;",
            "import com.google.common.collect.ImmutableSet;",
            "",
            "@AutoValue",
            "public abstract class Baz<T, U> {",
            "  abstract String blim();",
            "",
            "  @AutoValue.Builder",
            "  public interface Builder<T, U> {",
            "    StringBuilder blimBuilder();",
            "    Baz<T, U> build();",
            "  }",
            "}");
    Compilation compilation =
        javac()
            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())
            .compile(javaFileObject);
    assertThat(compilation)
        .hadErrorContaining(
            "Method looks like a property builder, but it returns java.lang.StringBuilder which "
                + "does not have a non-static build() method")
        .inFile(javaFileObject)
        .onLineContaining("StringBuilder blimBuilder()");
  }

  @Test
  public void autoValueBuilderPropertyBuilderHasStaticBuild() {
    JavaFileObject javaFileObject =
        JavaFileObjects.forSourceLines(
            "foo.bar.Baz",
            "package foo.bar;",
            "",
            "import com.google.auto.value.AutoValue;",
            "import com.google.common.collect.ImmutableSet;",
            "",
            "@AutoValue",
            "public abstract class Baz<T, U> {",
            "  abstract String blim();",
            "",
            "  public static class StringFactory {",
            "    public static String build() {",
            "      return null;",
            "    }",
            "  }",
            "",
            "  @AutoValue.Builder",
            "  public interface Builder<T, U> {",
            "    StringFactory blimBuilder();",
            "    Baz<T, U> build();",
            "  }",
            "}");
    Compilation compilation =
        javac()
            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())
            .compile(javaFileObject);
    assertThat(compilation)
        .hadErrorContaining(
            "Method looks like a property builder, but it returns foo.bar.Baz.StringFactory which "
                + "does not have a non-static build() method")
        .inFile(javaFileObject)
        .onLineContaining("StringFactory blimBuilder()");
  }

  @Test
  public void autoValueBuilderPropertyBuilderReturnsWrongType() {
    JavaFileObject javaFileObject =
        JavaFileObjects.forSourceLines(
            "foo.bar.Baz",
            "package foo.bar;",
            "",
            "import com.google.auto.value.AutoValue;",
            "import com.google.common.collect.ImmutableSet;",
            "import java.util.List;",
            "",
            "@AutoValue",
            "public abstract class Baz<E> {",
            "  abstract List<E> blim();",
            "",
            "  public static class ListFactory<E> {",
            "    public List<? extends E> build() {",
            "      return null;",
            "    }",
            "  }",
            "",
            "  @AutoValue.Builder",
            "  public interface Builder<E> {",
            "    ListFactory<E> blimBuilder();",
            "    Baz<E> build();",
            "  }",
            "}");
    Compilation compilation =
        javac()
            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())
            .compile(javaFileObject);
    assertThat(compilation)
        .hadErrorContaining(
            "Property builder for blim has type foo.bar.Baz.ListFactory whose build() method "
                + "returns java.util.List<? extends E> instead of java.util.List<E>")
        .inFile(javaFileObject)
        .onLineContaining("ListFactory<E> blimBuilder()");
  }

  @Test
  public void autoValueBuilderPropertyBuilderCantConstruct() {
    JavaFileObject javaFileObject =
        JavaFileObjects.forSourceLines(
            "foo.bar.Baz",
            "package foo.bar;",
            "",
            "import com.google.auto.value.AutoValue;",
            "import com.google.common.collect.ImmutableSet;",
            "",
            "@AutoValue",
            "public abstract class Baz<E> {",
            "  abstract String blim();",
            "",
            "  public static class StringFactory {",
            "    private StringFactory() {}",
            "",
            "    public String build() {",
            "      return null;",
            "    }",
            "  }",
            "",
            "  @AutoValue.Builder",
            "  public interface Builder<E> {",
            "    StringFactory blimBuilder();",
            "    Baz<E> build();",
            "  }",
            "}");
    Compilation compilation =
        javac()
            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())
            .compile(javaFileObject);
    assertThat(compilation)
        .hadErrorContaining(
            "Method looks like a property builder, but its type foo.bar.Baz.StringFactory "
                + "does not have a public constructor and java.lang.String does not have a static "
                + "builder() or newBuilder() method that returns foo.bar.Baz.StringFactory")
        .inFile(javaFileObject)
        .onLineContaining("StringFactory blimBuilder()");
  }

  @Test
  public void autoValueBuilderPropertyBuilderCantReconstruct() {
    JavaFileObject javaFileObject =
        JavaFileObjects.forSourceLines(
            "foo.bar.Baz",
            "package foo.bar;",
            "",
            "import com.google.auto.value.AutoValue;",
            "",
            "@AutoValue",
            "public abstract class Baz<E> {",
            "  abstract String blim();",
            "  abstract Builder<E> toBuilder();",
            "",
            "  public static class StringFactory {",
            "    public String build() {",
            "      return null;",
            "    }",
            "  }",
            "",
            "  @AutoValue.Builder",
            "  public interface Builder<E> {",
            "    StringFactory blimBuilder();",
            "    Baz<E> build();",
            "  }",
            "}");
    Compilation compilation =
        javac()
            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())
            .compile(javaFileObject);
    assertThat(compilation)
        .hadErrorContaining(
            "Property builder method returns foo.bar.Baz.StringFactory but there is no way to make"
                + " that type from java.lang.String: java.lang.String does not have a non-static"
                + " toBuilder() method that returns foo.bar.Baz.StringFactory, and"
                + " foo.bar.Baz.StringFactory does not have a method addAll or putAll that accepts"
                + " an argument of type java.lang.String")
        .inFile(javaFileObject)
        .onLineContaining("StringFactory blimBuilder()");
  }

  @Test
  public void autoValueBuilderPropertyBuilderWrongTypeAddAll() {
    JavaFileObject javaFileObject =
        JavaFileObjects.forSourceLines(
            "foo.bar.Baz",
            "package foo.bar;",
            "",
            "import com.google.auto.value.AutoValue;",
            "import com.google.common.collect.ImmutableSet;",
            "import java.util.Iterator;",
            "",
            "@AutoValue",
            "public abstract class Baz<T> {",
            "  abstract ImmutableSet<String> strings();",
            "  abstract Builder<T> toBuilder();",
            "",
            "  public static class ImmutableSetBuilder<E> {",
            "    public void addAll(Iterator<? extends E> elements) {}",
            "",
            "    public ImmutableSet<E> build() {",
            "      return null;",
            "    }",
            "  }",
            "",
            "  @AutoValue.Builder",
            "  public interface Builder<T> {",
            "    ImmutableSetBuilder<String> stringsBuilder();",
            "    Baz<T> build();",
            "  }",
            "}");
    Compilation compilation =
        javac()
            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())
            .compile(javaFileObject);
    assertThat(compilation)
        .hadErrorContaining(
            "Property builder method returns foo.bar.Baz.ImmutableSetBuilder<java.lang.String> but"
                + " there is no way to make that type from"
                + " com.google.common.collect.ImmutableSet<java.lang.String>:"
                + " com.google.common.collect.ImmutableSet<java.lang.String> does not have a"
                + " non-static toBuilder() method that returns"
                + " foo.bar.Baz.ImmutableSetBuilder<java.lang.String>, and"
                + " foo.bar.Baz.ImmutableSetBuilder<java.lang.String> does not have a method"
                + " addAll or putAll that accepts an argument of type"
                + " com.google.common.collect.ImmutableSet<java.lang.String>")
        .inFile(javaFileObject)
        .onLineContaining("ImmutableSetBuilder<String> stringsBuilder();");
  }

  @Test
  public void autoValueBuilderPropertyBuilderCantSet() {
    JavaFileObject javaFileObject =
        JavaFileObjects.forSourceLines(
            "foo.bar.Baz",
            "package foo.bar;",
            "",
            "import com.google.auto.value.AutoValue;",
            "import com.google.common.collect.ImmutableSet;",
            "",
            "@AutoValue",
            "public abstract class Baz<E> {",
            "  abstract String blim();",
            "",
            "  public static class StringFactory {",
            "    public String build() {",
            "      return null;",
            "    }",
            "  }",
            "",
            "  @AutoValue.Builder",
            "  public interface Builder<E> {",
            "    Builder<E> setBlim(String s);",
            "    StringFactory blimBuilder();",
            "    Baz<E> build();",
            "  }",
            "}");
    Compilation compilation =
        javac()
            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())
            .compile(javaFileObject);
    assertThat(compilation)
        .hadErrorContaining(
            "Property builder method returns foo.bar.Baz.StringFactory but there is no way to make "
                + "that type from java.lang.String: java.lang.String does not have a non-static "
                + "toBuilder() method that returns foo.bar.Baz.StringFactory")
        .inFile(javaFileObject)
        .onLineContaining("StringFactory blimBuilder()");
  }

  @Test
  public void autoValueBuilderPropertyBuilderWrongTypeToBuilder() {
    JavaFileObject javaFileObject =
        JavaFileObjects.forSourceLines(
            "foo.bar.Baz",
            "package foo.bar;",
            "",
            "import com.google.auto.value.AutoValue;",
            "import com.google.common.collect.ImmutableSet;",
            "",
            "@AutoValue",
            "public abstract class Baz<E> {",
            "  abstract Buh blim();",
            "  abstract Builder<E> toBuilder();",
            "",
            "  public static class Buh {",
            "    StringBuilder toBuilder() {",
            "      return null;",
            "    }",
            "  }",
            "",
            "  public static class BuhBuilder {",
            "    public Buh build() {",
            "      return null;",
            "    }",
            "  }",
            "",
            "  @AutoValue.Builder",
            "  public interface Builder<E> {",
            "    BuhBuilder blimBuilder();",
            "    Baz<E> build();",
            "  }",
            "}");
    Compilation compilation =
        javac()
            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())
            .compile(javaFileObject);
    assertThat(compilation)
        .hadErrorContaining(
            "Property builder method returns foo.bar.Baz.BuhBuilder but there is no way to make "
                + "that type from foo.bar.Baz.Buh: foo.bar.Baz.Buh does not have a non-static "
                + "toBuilder() method that returns foo.bar.Baz.BuhBuilder")
        .inFile(javaFileObject)
        .onLineContaining("BuhBuilder blimBuilder()");
  }

  @Test
  public void autoValueBuilderPropertyBuilderWrongElementType() {
    JavaFileObject javaFileObject =
        JavaFileObjects.forSourceLines(
            "foo.bar.Baz",
            "package foo.bar;",
            "",
            "import com.google.auto.value.AutoValue;",
            "import com.google.common.collect.ImmutableSet;",
            "",
            "@AutoValue",
            "public abstract class Baz<T, U> {",
            "  abstract ImmutableSet<T> blim();",
            "",
            "  @AutoValue.Builder",
            "  public interface Builder<T, U> {",
            "    ImmutableSet.Builder<U> blimBuilder();",
            "    Baz<T, U> build();",
            "  }",
            "}");
    Compilation compilation =
        javac()
            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())
            .compile(javaFileObject);
    assertThat(compilation)
        .hadErrorContaining(
            "Property builder for blim has type com.google.common.collect.ImmutableSet.Builder "
                + "whose build() method returns com.google.common.collect.ImmutableSet<U> "
                + "instead of com.google.common.collect.ImmutableSet<T>")
        .inFile(javaFileObject)
        .onLineContaining("ImmutableSet.Builder<U> blimBuilder()");
  }

  @Test
  public void autoValueBuilderAlienMethod0() {
    JavaFileObject javaFileObject =
        JavaFileObjects.forSourceLines(
            "foo.bar.Baz",
            "package foo.bar;",
            "",
            "import com.google.auto.value.AutoValue;",
            "",
            "@AutoValue",
            "public abstract class Baz {",
            "  abstract String blam();",
            "",
            "  @AutoValue.Builder",
            "  public interface Builder {",
            "    Builder blam(String x);",
            "    Builder whut();",
            "    Baz build();",
            "  }",
            "}");
    Compilation compilation =
        javac()
            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())
            .compile(javaFileObject);
    assertThat(compilation)
        .hadErrorContaining(
            "Method without arguments should be a build method returning foo.bar.Baz, or a getter"
                + " method with the same name and type as a getter method of foo.bar.Baz, or"
                + " fooBuilder() where foo() or getFoo() is a getter method of foo.bar.Baz")
        .inFile(javaFileObject)
        .onLineContaining("Builder whut()");
  }

  @Test
  public void autoValueBuilderAlienMethod1() {
    JavaFileObject javaFileObject =
        JavaFileObjects.forSourceLines(
            "foo.bar.Baz",
            "package foo.bar;",
            "",
            "import com.google.auto.value.AutoValue;",
            "",
            "@AutoValue",
            "public abstract class Baz {",
            "  abstract String blam();",
            "",
            "  @AutoValue.Builder",
            "  public interface Builder {",
            "    void whut(String x);",
            "    Baz build();",
            "  }",
            "}");
    Compilation compilation =
        javac()
            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())
            .compile(javaFileObject);
    assertThat(compilation)
        .hadErrorContaining("Method does not correspond to a property of foo.bar.Baz")
        .inFile(javaFileObject)
        .onLineContaining("void whut(String x)");
  }

  @Test
  public void autoValueBuilderAlienMethod2() {
    JavaFileObject javaFileObject =
        JavaFileObjects.forSourceLines(
            "foo.bar.Baz",
            "package foo.bar;",
            "",
            "import com.google.auto.value.AutoValue;",
            "",
            "@AutoValue",
            "public abstract class Baz {",
            "  abstract String blam();",
            "",
            "  @AutoValue.Builder",
            "  public interface Builder {",
            "    Builder blam(String x, String y);",
            "    Baz build();",
            "  }",
            "}");
    Compilation compilation =
        javac()
            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())
            .compile(javaFileObject);
    assertThat(compilation)
        .hadErrorContaining("Builder methods must have 0 or 1 parameters")
        .inFile(javaFileObject)
        .onLineContaining("Builder blam(String x, String y)");
  }

  @Test
  public void autoValueBuilderMissingBuildMethod() {
    JavaFileObject javaFileObject =
        JavaFileObjects.forSourceLines(
            "foo.bar.Baz",
            "package foo.bar;",
            "",
            "import com.google.auto.value.AutoValue;",
            "",
            "@AutoValue",
            "public abstract class Baz<T> {",
            "  abstract T blam();",
            "",
            "  @AutoValue.Builder",
            "  public interface Builder<T> {",
            "    Builder<T> blam(T x);",
            "  }",
            "}");
    Compilation compilation =
        javac()
            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())
            .compile(javaFileObject);
    assertThat(compilation)
        .hadErrorContaining(
            "Builder must have a single no-argument method returning foo.bar.Baz<T>")
        .inFile(javaFileObject)
        .onLineContaining("public interface Builder<T>");
  }

  @Test
  public void autoValueBuilderDuplicateBuildMethods() {
    JavaFileObject javaFileObject =
        JavaFileObjects.forSourceLines(
            "foo.bar.Baz",
            "package foo.bar;",
            "",
            "import com.google.auto.value.AutoValue;",
            "",
            "@AutoValue",
            "public abstract class Baz {",
            "  abstract String blam();",
            "",
            "  @AutoValue.Builder",
            "  public interface Builder {",
            "    Builder blam(String x);",
            "    Baz build();",
            "    Baz create();",
            "  }",
            "}");
    Compilation compilation =
        javac()
            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())
            .compile(javaFileObject);
    assertThat(compilation)
        .hadErrorContaining("Builder must have a single no-argument method returning foo.bar.Baz")
        .inFile(javaFileObject)
        .onLineContaining("Baz build()");
    assertThat(compilation)
        .hadErrorContaining("Builder must have a single no-argument method returning foo.bar.Baz")
        .inFile(javaFileObject)
        .onLineContaining("Baz create()");
  }

  @Test
  public void autoValueBuilderWrongTypeBuildMethod() {
    JavaFileObject javaFileObject =
        JavaFileObjects.forSourceLines(
            "foo.bar.Baz",
            "package foo.bar;",
            "",
            "import com.google.auto.value.AutoValue;",
            "",
            "@AutoValue",
            "public abstract class Baz {",
            "  abstract String blam();",
            "",
            "  @AutoValue.Builder",
            "  public interface Builder {",
            "    Builder blam(String x);",
            "    String build();",
            "  }",
            "}");
    Compilation compilation =
        javac()
            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())
            .compile(javaFileObject);
    assertThat(compilation)
        .hadErrorContaining(
            "Method without arguments should be a build method returning foo.bar.Baz")
        .inFile(javaFileObject)
        .onLineContaining("String build()");
  }

  @Test
  public void autoValueBuilderTypeParametersDontMatch1() {
    JavaFileObject javaFileObject =
        JavaFileObjects.forSourceLines(
            "foo.bar.Baz",
            "package foo.bar;",
            "",
            "import com.google.auto.value.AutoValue;",
            "",
            "@AutoValue",
            "public abstract class Baz<T> {",
            "  abstract String blam();",
            "",
            "  @AutoValue.Builder",
            "  public interface Builder {",
            "    Builder blam(String x);",
            "    Baz build();",
            "  }",
            "}");
    Compilation compilation =
        javac()
            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())
            .compile(javaFileObject);
    assertThat(compilation)
        .hadErrorContaining(
            "Type parameters of foo.bar.Baz.Builder must have same names and "
                + "bounds as type parameters of foo.bar.Baz")
        .inFile(javaFileObject)
        .onLineContaining("public interface Builder");
  }

  @Test
  public void autoValueBuilderTypeParametersDontMatch2() {
    JavaFileObject javaFileObject =
        JavaFileObjects.forSourceLines(
            "foo.bar.Baz",
            "package foo.bar;",
            "",
            "import com.google.auto.value.AutoValue;",
            "",
            "@AutoValue",
            "public abstract class Baz<T> {",
            "  abstract T blam();",
            "",
            "  @AutoValue.Builder",
            "  public interface Builder<E> {",
            "    Builder<E> blam(E x);",
            "    Baz build();",
            "  }",
            "}");
    Compilation compilation =
        javac()
            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())
            .compile(javaFileObject);
    assertThat(compilation)
        .hadErrorContaining(
            "Type parameters of foo.bar.Baz.Builder must have same names and "
                + "bounds as type parameters of foo.bar.Baz")
        .inFile(javaFileObject)
        .onLineContaining("public interface Builder<E>");
  }

  @Test
  public void autoValueBuilderTypeParametersDontMatch3() {
    JavaFileObject javaFileObject =
        JavaFileObjects.forSourceLines(
            "foo.bar.Baz",
            "package foo.bar;",
            "",
            "import com.google.auto.value.AutoValue;",
            "",
            "@AutoValue",
            "public abstract class Baz<T extends Number & Comparable<T>> {",
            "  abstract T blam();",
            "",
            "  @AutoValue.Builder",
            "  public interface Builder<T extends Number> {",
            "    Builder<T> blam(T x);",
            "    Baz build();",
            "  }",
            "}");
    Compilation compilation =
        javac()
            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())
            .compile(javaFileObject);
    assertThat(compilation)
        .hadErrorContaining(
            "Type parameters of foo.bar.Baz.Builder must have same names and "
                + "bounds as type parameters of foo.bar.Baz")
        .inFile(javaFileObject)
        .onLineContaining("public interface Builder<T extends Number>");
  }

  @Test
  public void autoValueBuilderToBuilderWrongTypeParameters() {
    JavaFileObject javaFileObject =
        JavaFileObjects.forSourceLines(
            "foo.bar.Baz",
            "package foo.bar;",
            "",
            "import com.google.auto.value.AutoValue;",
            "",
            "@AutoValue",
            "abstract class Baz<K extends Comparable<K>, V> {",
            "  abstract K key();",
            "  abstract V value();",
            "  abstract Builder<V, K> toBuilder1();",
            "",
            "  @AutoValue.Builder",
            "  interface Builder<K extends Comparable<K>, V> {",
            "    Builder<K, V> key(K key);",
            "    Builder<K, V> value(V value);",
            "    Baz<K, V> build();",
            "  }",
            "}");
    Compilation compilation =
        javac()
            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())
            .compile(javaFileObject);
    assertThat(compilation)
        .hadErrorContaining("Builder converter method should return foo.bar.Baz.Builder<K, V>")
        .inFile(javaFileObject)
        .onLineContaining("abstract Builder<V, K> toBuilder1()");
  }

  @Test
  public void autoValueBuilderToBuilderDuplicate() {
    JavaFileObject javaFileObject =
        JavaFileObjects.forSourceLines(
            "foo.bar.Baz",
            "package foo.bar;",
            "",
            "import com.google.auto.value.AutoValue;",
            "",
            "@AutoValue",
            "abstract class Baz<K extends Comparable<K>, V> {",
            "  abstract K key();",
            "  abstract V value();",
            "  abstract Builder<K, V> toBuilder1();",
            "  abstract Builder<K, V> toBuilder2();",
            "",
            "  @AutoValue.Builder",
            "  interface Builder<K extends Comparable<K>, V> {",
            "    Builder<K, V> key(K key);",
            "    Builder<K, V> value(V value);",
            "    Baz<K, V> build();",
            "  }",
            "}");
    Compilation compilation =
        javac()
            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())
            .compile(javaFileObject);
    assertThat(compilation)
        .hadErrorContaining("There can be at most one builder converter method")
        .inFile(javaFileObject)
        .onLineContaining("abstract Builder<K, V> toBuilder1()");
  }

  @Test
  public void getFooIsFoo() {
    JavaFileObject javaFileObject =
        JavaFileObjects.forSourceLines(
            "foo.bar.Baz",
            "package foo.bar;",
            "",
            "import com.google.auto.value.AutoValue;",
            "",
            "@AutoValue",
            "public abstract class Baz {",
            "  abstract int getFoo();",
            "  abstract boolean isFoo();",
            "}");
    Compilation compilation =
        javac()
            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())
            .compile(javaFileObject);
    assertThat(compilation)
        .hadErrorContaining("More than one @AutoValue property called foo")
        .inFile(javaFileObject)
        .onLineContaining("getFoo");
    assertThat(compilation)
        .hadErrorContaining("More than one @AutoValue property called foo")
        .inFile(javaFileObject)
        .onLineContaining("isFoo");
  }

  @Retention(RetentionPolicy.SOURCE)
  public @interface Foo {}

  /* Processor that generates an empty class BarFoo every time it sees a class Bar annotated with
   * @Foo.
   */
  public static class FooProcessor extends AbstractProcessor {
    @Override
    public Set<String> getSupportedAnnotationTypes() {
      return ImmutableSet.of(Foo.class.getCanonicalName());
    }

    @Override
    public SourceVersion getSupportedSourceVersion() {
      return SourceVersion.latestSupported();
    }

    @Override
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
      Set<? extends Element> elements = roundEnv.getElementsAnnotatedWith(Foo.class);
      for (TypeElement type : ElementFilter.typesIn(elements)) {
        try {
          generateFoo(type);
        } catch (IOException e) {
          throw new AssertionError(e);
        }
      }
      return false;
    }

    private void generateFoo(TypeElement type) throws IOException {
      String pkg = TypeSimplifier.packageNameOf(type);
      String className = type.getSimpleName().toString();
      String generatedClassName = className + "Foo";
      JavaFileObject source =
          processingEnv.getFiler().createSourceFile(pkg + "." + generatedClassName, type);
      PrintWriter writer = new PrintWriter(source.openWriter());
      writer.println("package " + pkg + ";");
      writer.println("public class " + generatedClassName + " {}");
      writer.close();
    }
  }

  @Test
  public void referencingGeneratedClass() {
    // Test that ensures that a type that does not exist can be the type of an @AutoValue property
    // as long as it later does come into existence. The BarFoo type referenced here does not exist
    // when the AutoValueProcessor runs on the first round, but the FooProcessor then generates it.
    // That generation provokes a further round of annotation processing and AutoValueProcessor
    // should succeed then.
    JavaFileObject bazFileObject =
        JavaFileObjects.forSourceLines(
            "foo.bar.Baz",
            "package foo.bar;",
            "",
            "import com.google.auto.value.AutoValue;",
            "",
            "@AutoValue",
            "public abstract class Baz {",
            "  public abstract BarFoo barFoo();",
            "",
            "  public static Baz create(BarFoo barFoo) {",
            "    return new AutoValue_Baz(barFoo);",
            "  }",
            "}");
    JavaFileObject barFileObject =
        JavaFileObjects.forSourceLines(
            "foo.bar.Bar",
            "package foo.bar;",
            "",
            "import com.google.auto.value.AutoValue;",
            "",
            "@" + Foo.class.getCanonicalName(),
            "public abstract class Bar {",
            "  public abstract BarFoo barFoo();",
            "}");
    Compilation compilation =
        javac()
            .withProcessors(new AutoValueProcessor(), new FooProcessor())
            .withOptions("-Xlint:-processing", "-implicit:none")
            .compile(bazFileObject, barFileObject);
    assertThat(compilation).succeededWithoutWarnings();
  }

  @Test
  public void annotationReferencesUndefined() {
    // Test that we don't throw an exception if asked to compile @SuppressWarnings(UNDEFINED)
    // where UNDEFINED is an undefined symbol.
    JavaFileObject bazFileObject =
        JavaFileObjects.forSourceLines(
            "foo.bar.Baz",
            "package foo.bar;",
            "",
            "import com.google.auto.value.AutoValue;",
            "",
            "@AutoValue",
            "public abstract class Baz {",
            "  @SuppressWarnings(UNDEFINED)",
            "  public abstract int[] buh();",
            "}");
    Compilation compilation1 =
        javac()
            .withOptions("-Xlint:-processing")
            .withProcessors(new AutoValueProcessor())
            .compile(bazFileObject);
    assertThat(compilation1).hadErrorCount(1);
    assertThat(compilation1)
        .hadErrorContaining("UNDEFINED")
        .inFile(bazFileObject)
        .onLineContaining("UNDEFINED");
    assertThat(compilation1).hadWarningCount(1);
    assertThat(compilation1)
        .hadWarningContaining("mutable")
        .inFile(bazFileObject)
        .onLineContaining("public abstract int[] buh()");

    // Same test, except we do successfully suppress the warning despite the UNDEFINED.
    bazFileObject =
        JavaFileObjects.forSourceLines(
            "foo.bar.Baz",
            "package foo.bar;",
            "",
            "import com.google.auto.value.AutoValue;",
            "",
            "@AutoValue",
            "public abstract class Baz {",
            "  @SuppressWarnings({UNDEFINED, \"mutable\"})",
            "  public abstract int[] buh();",
            "}");
    Compilation compilation2 =
        javac()
            .withOptions("-Xlint:-processing")
            .withProcessors(new AutoValueProcessor())
            .compile(bazFileObject);
    assertThat(compilation2).hadErrorCount(1);
    assertThat(compilation2)
        .hadErrorContaining("UNDEFINED")
        .inFile(bazFileObject)
        .onLineContaining("UNDEFINED");
    assertThat(compilation2).hadWarningCount(0);
  }

  @Test
  public void packagePrivateAnnotationFromOtherPackage() {
    JavaFileObject bazFileObject =
        JavaFileObjects.forSourceLines(
            "foo.bar.Baz",
            "package foo.bar;",
            "",
            "import com.google.auto.value.AutoValue;",
            "",
            "@AutoValue",
            "public abstract class Baz extends otherpackage.Parent {",
            "}");
    JavaFileObject parentFileObject =
        JavaFileObjects.forSourceLines(
            "otherpackage.Parent",
            "package otherpackage;",
            "",
            "public abstract class Parent {",
            "  @PackageAnnotation",
            "  public abstract String foo();",
            "",
            "  @interface PackageAnnotation {}",
            "}");
    Compilation compilation =
        javac()
            .withProcessors(new AutoValueProcessor())
            .withOptions("-Xlint:-processing", "-implicit:none")
            .compile(bazFileObject, parentFileObject);
    assertThat(compilation).succeededWithoutWarnings();
    assertThat(compilation).generatedSourceFile("foo.bar.AutoValue_Baz");
  }

  @Test
  public void visibleProtectedAnnotationFromOtherPackage() {
    JavaFileObject bazFileObject =
        JavaFileObjects.forSourceLines(
            "foo.bar.Baz",
            "package foo.bar;",
            "",
            "import com.google.auto.value.AutoValue;",
            "",
            "@AutoValue",
            "public abstract class Baz extends otherpackage.Parent {}");
    JavaFileObject parentFileObject =
        JavaFileObjects.forSourceLines(
            "otherpackage.Parent",
            "package otherpackage;",
            "",
            "public abstract class Parent {",
            "  @ProtectedAnnotation",
            "  public abstract String foo();",
            "",
            "  protected @interface ProtectedAnnotation {}",
            "}");
    Compilation compilation =
        javac()
            .withProcessors(new AutoValueProcessor())
            .withOptions("-Xlint:-processing", "-implicit:none")
            .compile(bazFileObject, parentFileObject);
    assertThat(compilation).succeededWithoutWarnings();
    assertThat(compilation)
        .generatedSourceFile("foo.bar.AutoValue_Baz")
        .contentsAsUtf8String()
        .containsMatch("(?s:@Parent.ProtectedAnnotation\\s*@Override\\s*public String foo\\(\\))");
  }

  @Test
  public void nonVisibleProtectedAnnotationFromOtherPackage() {
    JavaFileObject bazFileObject =
        JavaFileObjects.forSourceLines(
            "foo.bar.Baz",
            "package foo.bar;",
            "",
            "import com.google.auto.value.AutoValue;",
            "",
            "@AutoValue",
            "public abstract class Baz extends otherpackage.Parent {",
            "}");
    JavaFileObject parentFileObject =
        JavaFileObjects.forSourceLines(
            "otherpackage.Parent",
            "package otherpackage;",
            "",
            "import otherpackage.Annotations.ProtectedAnnotation;",
            "",
            "public abstract class Parent {",
            "  @ProtectedAnnotation",
            "  public abstract String foo();",
            "}");
    JavaFileObject annotationsFileObject =
        JavaFileObjects.forSourceLines(
            "otherpackage.Annotations",
            "package otherpackage;",
            "",
            "public class Annotations {",
            "  protected @interface ProtectedAnnotation {}",
            "}");
    Compilation compilation =
        javac()
            .withProcessors(new AutoValueProcessor())
            .withOptions("-Xlint:-processing", "-implicit:none")
            .compile(bazFileObject, parentFileObject, annotationsFileObject);
    assertThat(compilation).succeededWithoutWarnings();
    assertThat(compilation)
        .generatedSourceFile("foo.bar.AutoValue_Baz")
        .contentsAsUtf8String()
        .doesNotContain("ProtectedAnnotation");
  }

  @Test
  public void nonVisibleProtectedClassAnnotationFromOtherPackage() {
    JavaFileObject bazFileObject =
        JavaFileObjects.forSourceLines(
            "foo.bar.Outer",
            "package foo.bar;",
            "",
            "import com.google.auto.value.AutoValue;",
            "",
            "class Outer extends otherpackage.Parent {",
            "  @AutoValue",
            "  @AutoValue.CopyAnnotations",
            "  @ProtectedAnnotation",
            "  abstract static class Inner {",
            "    abstract String foo();",
            "  }",
            "}");
    JavaFileObject parentFileObject =
        JavaFileObjects.forSourceLines(
            "otherpackage.Parent",
            "package otherpackage;",
            "",
            "public abstract class Parent {",
            "  protected @interface ProtectedAnnotation {}",
            "}");
    Compilation compilation =
        javac()
            .withProcessors(new AutoValueProcessor())
            .withOptions("-Xlint:-processing", "-implicit:none")
            .compile(bazFileObject, parentFileObject);
    assertThat(compilation).succeededWithoutWarnings();
    assertThat(compilation)
        .generatedSourceFile("foo.bar.AutoValue_Outer_Inner")
        .contentsAsUtf8String()
        .doesNotContain("ProtectedAnnotation");
  }

  @Test
  public void builderWithVarArgsDoesNotImportJavaUtilArrays() {
    // Repro from https://github.com/google/auto/issues/373.
    JavaFileObject testFileObject =
        JavaFileObjects.forSourceLines(
            "foo.bar.Test",
            "package foo.bar;",
            "",
            "import com.google.auto.value.AutoValue;",
            "import com.google.common.collect.ImmutableList;",
            "",
            "@AutoValue",
            "public abstract class Test {",
            "  abstract ImmutableList<String> foo();",
            "",
            "  @AutoValue.Builder",
            "  abstract static class Builder {",
            "    abstract Builder foo(String... foos);",
            "    abstract Test build();",
            "  }",
            "}");
    Compilation compilation =
        javac()
            .withProcessors(new AutoValueProcessor())
            .withOptions("-Xlint:-processing", "-implicit:none")
            .compile(testFileObject);
    assertThat(compilation).succeededWithoutWarnings();
    assertThat(compilation)
        .generatedSourceFile("foo.bar.AutoValue_Test")
        .contentsAsUtf8String()
        .doesNotContain("java.util.Arrays");
  }

  @Test
  public void staticBuilderMethodInBuilderClass() {
    JavaFileObject javaFileObject =
        JavaFileObjects.forSourceLines(
            "com.example.Foo",
            "package com.example;",
            "",
            "import com.google.auto.value.AutoValue;",
            "",
            "@AutoValue",
            "public abstract class Foo {",
            "  public abstract String bar();",
            "",
            "  @AutoValue.Builder",
            "  public abstract static class Builder {",
            "    public static Builder builder() {",
            "      return new AutoValue_Foo.Builder();",
            "    }",
            "",
            "    public abstract Builder setBar(String s);",
            "    public abstract Foo build();",
            "  }",
            "}");
    Compilation compilation =
        javac()
            .withProcessors(new AutoValueProcessor())
            .withOptions("-Xlint:-processing", "-implicit:none")
            .compile(javaFileObject);
    assertThat(compilation).succeeded();
    assertThat(compilation)
        .hadWarningContaining("Static builder() method should be in the containing class")
        .inFile(javaFileObject)
        .onLineContaining("builder()");
  }

  /**
   * Tests behaviour when the package containing an {@code @AutoValue} class also has classes with
   * the same name as classes in {@code java.lang}. If you call a class {@code Object} you are
   * asking for trouble, but you could innocently call a class {@code Compiler} without realizing
   * there is a {@code java.lang.Compiler}.
   *
   * <p>The case where the class in question is mentioned in the {@code @AutoValue} class is the
   * easy one, because then our logic can easily see that there is a clash and will use
   * fully-qualified names. This is the case of the {@code Compiler} class below. The case where the
   * class is <i>not</i> mentioned is harder. We have to realize that we can't elide the package
   * name in {@code java.lang.Object} because there is also a {@code foo.bar.Object} in scope, and
   * in fact it takes precedence.
   */
  @Test
  public void javaLangClash() {
    JavaFileObject object =
        JavaFileObjects.forSourceLines(
            "foo.bar.Object", //
            "package foo.bar;",
            "",
            "public class Object {}");
    JavaFileObject string =
        JavaFileObjects.forSourceLines(
            "foo.bar.String", //
            "package foo.bar;",
            "",
            "public class String {}");
    JavaFileObject integer =
        JavaFileObjects.forSourceLines(
            "foo.bar.Integer", //
            "package foo.bar;",
            "",
            "public class Integer {}");
    JavaFileObject thread =
        JavaFileObjects.forSourceLines(
            "foo.bar.Thread", //
            "package foo.bar;",
            "",
            "public class Thread {}");
    JavaFileObject override =
        JavaFileObjects.forSourceLines(
            "foo.bar.Override", //
            "package foo.bar;",
            "",
            "public class Override {}");
    JavaFileObject test =
        JavaFileObjects.forSourceLines(
            "foo.bar.Test",
            "package foo.bar;",
            "",
            "import com.google.auto.value.AutoValue;",
            "",
            "@AutoValue",
            "public abstract class Test {",
            "  public abstract java.lang.Integer integer();",
            "  public abstract java.lang.Thread.State state();",
            "  public static Builder builder() {",
            "    return new AutoValue_Test.Builder();",
            "  }",
            "",
            "  @AutoValue.Builder",
            "  public abstract static class Builder {",
            "    public abstract Builder setInteger(java.lang.Integer x);",
            "    public abstract Builder setState(java.lang.Thread.State x);",
            "    public abstract Test build();",
            "  }",
            "}");
    Compilation compilation =
        javac()
            .withProcessors(new AutoValueProcessor())
            .withOptions("-Xlint:-processing", "-implicit:none")
            .compile(object, string, integer, thread, override, test);
    assertThat(compilation).succeededWithoutWarnings();
  }

  // This is a regression test for the problem described in
  // https://github.com/google/auto/issues/847#issuecomment-629857642.
  @Test
  public void generatedParentWithGeneratedGetterButSetterInBuilder() {
    JavaFileObject test =
        JavaFileObjects.forSourceLines(
            "foo.bar.Test",
            "package foo.bar;",
            "",
            "import com.google.auto.value.AutoValue;",
            "import foo.baz.GeneratedParent;",
            "import foo.baz.GeneratedPropertyType;",
            "import java.util.Optional;",
            "",
            "@AutoValue",
            "public abstract class Test extends GeneratedParent {",
            "  public abstract String string();",
            "",
            "  public static Builder builder() {",
            "    return new AutoValue_Test.Builder();",
            "  }",
            "",
            "  @AutoValue.Builder",
            "  public abstract static class Builder extends GeneratedParent.Builder<Builder> {",
            "    public abstract Builder setString(String x);",
            "    public abstract Builder setGenerated(GeneratedPropertyType x);",
            "    public abstract Test build();",
            "  }",
            "}");
    AutoValueProcessor autoValueProcessor = new AutoValueProcessor();
    GeneratedParentProcessor generatedParentProcessor =
        new GeneratedParentProcessor(autoValueProcessor, expect);
    Compilation compilation =
        javac()
            .withProcessors(autoValueProcessor, generatedParentProcessor)
            .withOptions("-Xlint:-processing", "-implicit:none")
            .compile(test);
    assertThat(compilation).succeededWithoutWarnings();
    assertThat(compilation)
        .generatedSourceFile("foo.bar.AutoValue_Test")
        .contentsAsUtf8String()
        .contains("  public int integer() {");
  }

  @SupportedAnnotationTypes("*")
  private static class GeneratedParentProcessor extends AbstractProcessor {
    private static final String GENERATED_PARENT =
        String.join(
            "\n",
            "package foo.baz;",
            "",
            "public abstract class GeneratedParent {",
            "  public abstract int integer();",
            "  public abstract GeneratedPropertyType generated();",
            "",
            "  public abstract static class Builder<B extends Builder<B>> {",
            "    public abstract B setInteger(int x);",
            "  }",
            "}");
    private static final String GENERATED_PROPERTY_TYPE =
        String.join(
            "\n",
            "package foo.baz;",
            "",
            "public class GeneratedPropertyType {}");
    private static final ImmutableMap<String, String> GENERATED_TYPES =
        ImmutableMap.of(
            "foo.baz.GeneratedParent", GENERATED_PARENT,
            "foo.baz.GeneratedPropertyType", GENERATED_PROPERTY_TYPE);

    private final AutoValueProcessor autoValueProcessor;
    private final Expect expect;

    GeneratedParentProcessor(AutoValueProcessor autoValueProcessor, Expect expect) {
      this.autoValueProcessor = autoValueProcessor;
      this.expect = expect;
    }

    private boolean generated;

    @Override
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
      if (!generated) {
        generated = true;
        // Check that AutoValueProcessor has already run and deferred the foo.bar.Test type because
        // we haven't generated its parent yet.
        expect.that(autoValueProcessor.deferredTypeNames()).contains("foo.bar.Test");
        GENERATED_TYPES.forEach(
            (typeName, source) -> {
              try {
                JavaFileObject generated =
                    processingEnv
                        .getFiler()
                        .createSourceFile(typeName);
                try (Writer writer = generated.openWriter()) {
                  writer.write(source);
                }
              } catch (IOException e) {
                throw new UncheckedIOException(e);
              }
            }
        );
      }
      return false;
    }

    @Override
    public SourceVersion getSupportedSourceVersion() {
      return SourceVersion.latestSupported();
    }
  }

  private String sorted(String... imports) {
     return Arrays.stream(imports).sorted().collect(joining("\n"));
 }
}
