// skip-idempotent
import java.util.List;

public class CheckerFrameworkBuilder {

  /**
   * Most of this test was copied from
   * https://raw.githubusercontent.com/rzwitserloot/lombok/master/test/transform/resource/after-delombok/CheckerFrameworkBuilder.java
   * with the exception of the following lines until the next long comment. I have made one change
   * outside the scope of these comments: - I fixed the placement of the type annotations, which
   * were originally on scoping constructs. I think this is a bug in the delombok pretty-printer
   * used to generate this code, but I wasn't able to find the configuration options used to
   * reproduce it in the public release.
   *
   * <p>This test represents exactly the code that Lombok generates with the checkerframework = True
   * option in a lombok.config file, including the weird package names they use for the CF and the
   * {@code @NotCalledMethods} annotation that they use even though we don't (and never have)
   * supported such a thing.
   *
   * <p>The new code added in this block ensures that the Called Methods checker handles clients of
   * the copied code correctly.
   */
  public static void testOldCalledMethodsGood(
          @org.checkerframework.checker.calledmethods.qual.CalledMethods({"y", "z"}) CheckerFrameworkBuilderBuilder pb) {
    pb.build();
  }

  public static void testOldCalledMethodsBad(
          @org.checkerframework.checker.calledmethods.qual.CalledMethods({"y"}) CheckerFrameworkBuilderBuilder pb) {
    // :: error: finalizer.invocation
    pb.build(); // pb requires y, z
  }

  public static void testOldRRGood() {
    CheckerFrameworkBuilder b = CheckerFrameworkBuilder.builder().y(5).z(6).build();
  }

  public static void testOldRRBad() {
    CheckerFrameworkBuilder b =
        // :: error: finalizer.invocation
        CheckerFrameworkBuilder.builder().z(6).build(); // also needs to call y
  }

  /** End new, non-copied code. */
  int x;

  int y;
  int z;
  List<String> names;

  @java.lang.SuppressWarnings("all")
  private static int $default$x() {
    return 5;
  }

  @org.checkerframework.common.aliasing.qual.Unique @java.lang.SuppressWarnings("all")
  CheckerFrameworkBuilder(final int x, final int y, final int z, final List<String> names) {
    this.x = x;
    this.y = y;
    this.z = z;
    this.names = names;
  }

  @java.lang.SuppressWarnings("all")
  public static class CheckerFrameworkBuilderBuilder {
    @java.lang.SuppressWarnings("all")
    private boolean x$set;

    @java.lang.SuppressWarnings("all")
    private int x$value;

    @java.lang.SuppressWarnings("all")
    private int y;

    @java.lang.SuppressWarnings("all")
    private int z;

    @java.lang.SuppressWarnings("all")
    private java.util.ArrayList<String> names;

    @org.checkerframework.common.aliasing.qual.Unique @java.lang.SuppressWarnings("all")
    CheckerFrameworkBuilderBuilder() {}

    @org.checkerframework.checker.builder.qual.ReturnsReceiver
    @java.lang.SuppressWarnings("all")
    public CheckerFrameworkBuilder.CheckerFrameworkBuilderBuilder x(
        CheckerFrameworkBuilder.
            @org.checkerframework.checker.builder.qual.NotCalledMethods("x") CheckerFrameworkBuilderBuilder
            this,
        final int x) {
      this.x$value = x;
      x$set = true;
      return this;
    }

    @org.checkerframework.checker.builder.qual.ReturnsReceiver
    @java.lang.SuppressWarnings("all")
    public CheckerFrameworkBuilder.CheckerFrameworkBuilderBuilder y(
        CheckerFrameworkBuilder.
            @org.checkerframework.checker.builder.qual.NotCalledMethods("y") CheckerFrameworkBuilderBuilder
            this,
        final int y) {
      this.y = y;
      return this;
    }

    @org.checkerframework.checker.builder.qual.ReturnsReceiver
    @java.lang.SuppressWarnings("all")
    public CheckerFrameworkBuilder.CheckerFrameworkBuilderBuilder z(
        CheckerFrameworkBuilder.
            @org.checkerframework.checker.builder.qual.NotCalledMethods("z") CheckerFrameworkBuilderBuilder
            this,
        final int z) {
      this.z = z;
      return this;
    }

    @org.checkerframework.checker.builder.qual.ReturnsReceiver
    @java.lang.SuppressWarnings("all")
    public CheckerFrameworkBuilder.CheckerFrameworkBuilderBuilder name(final String name) {
      if (this.names == null) this.names = new java.util.ArrayList<String>();
      this.names.add(name);
      return this;
    }

    @org.checkerframework.checker.builder.qual.ReturnsReceiver
    @java.lang.SuppressWarnings("all")
    public CheckerFrameworkBuilder.CheckerFrameworkBuilderBuilder names(
        final java.util.Collection<? extends String> names) {
      if (names == null) {
        throw new java.lang.NullPointerException("names cannot be null");
      }
      if (this.names == null) this.names = new java.util.ArrayList<String>();
      this.names.addAll(names);
      return this;
    }

    @org.checkerframework.checker.builder.qual.ReturnsReceiver
    @java.lang.SuppressWarnings("all")
    public CheckerFrameworkBuilder.CheckerFrameworkBuilderBuilder clearNames() {
      if (this.names != null) this.names.clear();
      return this;
    }

    @org.checkerframework.dataflow.qual.SideEffectFree
    @java.lang.SuppressWarnings("all")
    public CheckerFrameworkBuilder build(
        CheckerFrameworkBuilder.
            @org.checkerframework.checker.builder.qual.CalledMethods({"y", "z"}) CheckerFrameworkBuilderBuilder
            this) {
      java.util.List<String> names;
      switch (this.names == null ? 0 : this.names.size()) {
        case 0:
          names = java.util.Collections.emptyList();
          break;
        case 1:
          names = java.util.Collections.singletonList(this.names.get(0));
          break;
        default:
          names =
              java.util.Collections.unmodifiableList(new java.util.ArrayList<String>(this.names));
      }
      int x$value = this.x$value;
      if (!this.x$set) x$value = CheckerFrameworkBuilder.$default$x();
      return new CheckerFrameworkBuilder(x$value, this.y, this.z, names);
    }

    @org.checkerframework.dataflow.qual.SideEffectFree
    @java.lang.Override
    @java.lang.SuppressWarnings("all")
    public java.lang.String toString() {
      return "CheckerFrameworkBuilder.CheckerFrameworkBuilderBuilder(x$value="
          + this.x$value
          + ", y="
          + this.y
          + ", z="
          + this.z
          + ", names="
          + this.names
          + ")";
    }
  }

  @org.checkerframework.dataflow.qual.SideEffectFree
  @java.lang.SuppressWarnings("all")
  public static CheckerFrameworkBuilder.
      @org.checkerframework.common.aliasing.qual.Unique CheckerFrameworkBuilderBuilder builder() {
    return new CheckerFrameworkBuilder.CheckerFrameworkBuilderBuilder();
  }
}
