BakeOptions_Builder.java

// Autogenerated code. Do not modify.
package com.varmateo.yawg.api;

import java.nio.file.Path;
import java.util.Collection;
import java.util.Collections;
import java.util.EnumSet;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Objects;
import java.util.function.Consumer;
import java.util.function.UnaryOperator;
import javax.annotation.Generated;

/**
 * Auto-generated superclass of {@link BakeOptions.Builder}, derived from the API of {@link
 * BakeOptions}.
 */
@Generated("org.inferred.freebuilder.processor.Processor")
abstract class BakeOptions_Builder {

  /**
   * Creates a new builder using {@code value} as a template.
   *
   * <p>If {@code value} is a partial, the builder will return more partials.
   */
  public static BakeOptions.Builder from(BakeOptions value) {
    if (value instanceof Rebuildable) {
      return ((Rebuildable) value).toBuilder();
    } else {
      return BakeOptions.builder().mergeFrom(value);
    }
  }

  private enum Property {
    SOURCE_DIR("sourceDir"),
    TARGET_DIR("targetDir"),
    ;

    private final String name;

    private Property(String name) {
      this.name = name;
    }

    @Override
    public String toString() {
      return name;
    }
  }

  private Path sourceDir;
  private Path targetDir;
  private final LinkedHashMap<String, Object> externalPageVars = new LinkedHashMap<>();
  private final EnumSet<Property> _unsetProperties = EnumSet.allOf(Property.class);

  /**
   * Sets the value to be returned by {@link BakeOptions#sourceDir()}.
   *
   * @return this {@code Builder} object
   * @throws NullPointerException if {@code sourceDir} is null
   */
  public BakeOptions.Builder sourceDir(Path sourceDir) {
    this.sourceDir = Objects.requireNonNull(sourceDir);
    _unsetProperties.remove(Property.SOURCE_DIR);
    return (BakeOptions.Builder) this;
  }

  /**
   * Replaces the value to be returned by {@link BakeOptions#sourceDir()} by applying {@code mapper}
   * to it and using the result.
   *
   * @return this {@code Builder} object
   * @throws NullPointerException if {@code mapper} is null or returns null
   * @throws IllegalStateException if the field has not been set
   */
  public BakeOptions.Builder mapSourceDir(UnaryOperator<Path> mapper) {
    Objects.requireNonNull(mapper);
    return sourceDir(mapper.apply(sourceDir()));
  }

  /**
   * Returns the value that will be returned by {@link BakeOptions#sourceDir()}.
   *
   * @throws IllegalStateException if the field has not been set
   */
  public Path sourceDir() {
    if (_unsetProperties.contains(Property.SOURCE_DIR)) {
      throw new IllegalStateException("sourceDir not set");
    }
    return sourceDir;
  }

  /**
   * Sets the value to be returned by {@link BakeOptions#targetDir()}.
   *
   * @return this {@code Builder} object
   * @throws NullPointerException if {@code targetDir} is null
   */
  public BakeOptions.Builder targetDir(Path targetDir) {
    this.targetDir = Objects.requireNonNull(targetDir);
    _unsetProperties.remove(Property.TARGET_DIR);
    return (BakeOptions.Builder) this;
  }

  /**
   * Replaces the value to be returned by {@link BakeOptions#targetDir()} by applying {@code mapper}
   * to it and using the result.
   *
   * @return this {@code Builder} object
   * @throws NullPointerException if {@code mapper} is null or returns null
   * @throws IllegalStateException if the field has not been set
   */
  public BakeOptions.Builder mapTargetDir(UnaryOperator<Path> mapper) {
    Objects.requireNonNull(mapper);
    return targetDir(mapper.apply(targetDir()));
  }

  /**
   * Returns the value that will be returned by {@link BakeOptions#targetDir()}.
   *
   * @throws IllegalStateException if the field has not been set
   */
  public Path targetDir() {
    if (_unsetProperties.contains(Property.TARGET_DIR)) {
      throw new IllegalStateException("targetDir not set");
    }
    return targetDir;
  }

  /**
   * Associates {@code key} with {@code value} in the map to be returned from {@link
   * BakeOptions#externalPageVars()}. If the map previously contained a mapping for the key, the old
   * value is replaced by the specified value.
   *
   * @return this {@code Builder} object
   * @throws NullPointerException if either {@code key} or {@code value} are null
   */
  public BakeOptions.Builder putExternalPageVars(String key, Object value) {
    Objects.requireNonNull(key);
    Objects.requireNonNull(value);
    externalPageVars.put(key, value);
    return (BakeOptions.Builder) this;
  }

  /**
   * Copies all of the mappings from {@code map} to the map to be returned from {@link
   * BakeOptions#externalPageVars()}.
   *
   * @return this {@code Builder} object
   * @throws NullPointerException if {@code map} is null or contains a null key or value
   */
  public BakeOptions.Builder putAllExternalPageVars(Map<? extends String, ? extends Object> map) {
    for (Map.Entry<? extends String, ? extends Object> entry : map.entrySet()) {
      putExternalPageVars(entry.getKey(), entry.getValue());
    }
    return (BakeOptions.Builder) this;
  }

  /**
   * Removes the mapping for {@code key} from the map to be returned from {@link
   * BakeOptions#externalPageVars()}, if one is present.
   *
   * @return this {@code Builder} object
   * @throws NullPointerException if {@code key} is null
   */
  public BakeOptions.Builder removeExternalPageVars(String key) {
    Objects.requireNonNull(key);
    externalPageVars.remove(key);
    return (BakeOptions.Builder) this;
  }

  /**
   * Invokes {@code mutator} with the map to be returned from {@link
   * BakeOptions#externalPageVars()}.
   *
   * <p>This method mutates the map in-place. {@code mutator} is a void consumer, so any value
   * returned from a lambda will be ignored. Take care not to call pure functions, like {@link
   * Collection#stream()}.
   *
   * @return this {@code Builder} object
   * @throws NullPointerException if {@code mutator} is null
   */
  public BakeOptions.Builder mutateExternalPageVars(Consumer<? super Map<String, Object>> mutator) {
    // If putExternalPageVars is overridden, this method will be updated to delegate to it
    mutator.accept(externalPageVars);
    return (BakeOptions.Builder) this;
  }

  /**
   * Removes all of the mappings from the map to be returned from {@link
   * BakeOptions#externalPageVars()}.
   *
   * @return this {@code Builder} object
   */
  public BakeOptions.Builder clearExternalPageVars() {
    externalPageVars.clear();
    return (BakeOptions.Builder) this;
  }

  /**
   * Returns an unmodifiable view of the map that will be returned by {@link
   * BakeOptions#externalPageVars()}. Changes to this builder will be reflected in the view.
   */
  public Map<String, Object> externalPageVars() {
    return Collections.unmodifiableMap(externalPageVars);
  }

  /**
   * Copies values from {@code value}, appending to collections.
   *
   * @return this {@code Builder} object
   */
  public BakeOptions.Builder mergeFrom(BakeOptions value) {
    BakeOptions_Builder defaults = BakeOptions.builder();
    if (defaults._unsetProperties.contains(Property.SOURCE_DIR)
        || !Objects.equals(value.sourceDir(), defaults.sourceDir())) {
      sourceDir(value.sourceDir());
    }
    if (defaults._unsetProperties.contains(Property.TARGET_DIR)
        || !Objects.equals(value.targetDir(), defaults.targetDir())) {
      targetDir(value.targetDir());
    }
    putAllExternalPageVars(value.externalPageVars());
    return (BakeOptions.Builder) this;
  }

  /**
   * Copies values from {@code template}, appending to collections, and skipping unset properties.
   *
   * @return this {@code Builder} object
   */
  public BakeOptions.Builder mergeFrom(BakeOptions.Builder template) {
    // Upcast to access private fields; otherwise, oddly, we get an access violation.
    BakeOptions_Builder base = template;
    BakeOptions_Builder defaults = BakeOptions.builder();
    if (!base._unsetProperties.contains(Property.SOURCE_DIR)
        && (defaults._unsetProperties.contains(Property.SOURCE_DIR)
            || !Objects.equals(template.sourceDir(), defaults.sourceDir()))) {
      sourceDir(template.sourceDir());
    }
    if (!base._unsetProperties.contains(Property.TARGET_DIR)
        && (defaults._unsetProperties.contains(Property.TARGET_DIR)
            || !Objects.equals(template.targetDir(), defaults.targetDir()))) {
      targetDir(template.targetDir());
    }
    putAllExternalPageVars(base.externalPageVars);
    return (BakeOptions.Builder) this;
  }

  /**
   * Resets the state of this builder.
   *
   * @return this {@code Builder} object
   */
  public BakeOptions.Builder clear() {
    BakeOptions_Builder defaults = BakeOptions.builder();
    sourceDir = defaults.sourceDir;
    targetDir = defaults.targetDir;
    externalPageVars.clear();
    _unsetProperties.clear();
    _unsetProperties.addAll(defaults._unsetProperties);
    return (BakeOptions.Builder) this;
  }

  /**
   * Returns a newly-created {@link BakeOptions} based on the contents of this {@code Builder}.
   *
   * @throws IllegalStateException if any field has not been set
   */
  public BakeOptions build() {
    if (!_unsetProperties.isEmpty()) {
      throw new IllegalStateException("Not set: " + _unsetProperties);
    }
    return new Value(this);
  }

  /**
   * Returns a newly-created partial {@link BakeOptions} for use in unit tests. State checking will
   * not be performed. Unset properties will throw an {@link UnsupportedOperationException} when
   * accessed via the partial object.
   *
   * <p>The builder returned by {@link BakeOptions.Builder#from(BakeOptions)} will propagate the
   * partial status of its input, overriding {@link BakeOptions.Builder#build() build()} to return
   * another partial. This allows for robust tests of modify-rebuild code.
   *
   * <p>Partials should only ever be used in tests. They permit writing robust test cases that won't
   * fail if this type gains more application-level constraints (e.g. new required fields) in
   * future. If you require partially complete values in production code, consider using a Builder.
   */
  public BakeOptions buildPartial() {
    return new Partial(this);
  }

  private abstract static class Rebuildable implements BakeOptions {
    public abstract Builder toBuilder();
  }

  private static final class Value extends Rebuildable {
    private final Path sourceDir;
    private final Path targetDir;
    private final Map<String, Object> externalPageVars;

    private Value(BakeOptions_Builder builder) {
      this.sourceDir = builder.sourceDir;
      this.targetDir = builder.targetDir;
      this.externalPageVars = immutableMap(builder.externalPageVars);
    }

    @Override
    public Path sourceDir() {
      return sourceDir;
    }

    @Override
    public Path targetDir() {
      return targetDir;
    }

    @Override
    public Map<String, Object> externalPageVars() {
      return externalPageVars;
    }

    @Override
    public Builder toBuilder() {
      BakeOptions_Builder builder = BakeOptions.builder();
      builder.sourceDir = sourceDir;
      builder.targetDir = targetDir;
      builder.externalPageVars.putAll(externalPageVars);
      builder._unsetProperties.clear();
      return (Builder) builder;
    }

    @Override
    public boolean equals(Object obj) {
      if (!(obj instanceof Value)) {
        return false;
      }
      Value other = (Value) obj;
      return Objects.equals(sourceDir, other.sourceDir)
          && Objects.equals(targetDir, other.targetDir)
          && Objects.equals(externalPageVars, other.externalPageVars);
    }

    @Override
    public int hashCode() {
      return Objects.hash(sourceDir, targetDir, externalPageVars);
    }

    @Override
    public String toString() {
      return "BakeOptions{sourceDir="
          + sourceDir
          + ", targetDir="
          + targetDir
          + ", externalPageVars="
          + externalPageVars
          + "}";
    }
  }

  private static final class Partial extends Rebuildable {
    private final Path sourceDir;
    private final Path targetDir;
    private final Map<String, Object> externalPageVars;
    private final EnumSet<Property> _unsetProperties;

    Partial(BakeOptions_Builder builder) {
      this.sourceDir = builder.sourceDir;
      this.targetDir = builder.targetDir;
      this.externalPageVars = immutableMap(builder.externalPageVars);
      this._unsetProperties = builder._unsetProperties.clone();
    }

    @Override
    public Path sourceDir() {
      if (_unsetProperties.contains(Property.SOURCE_DIR)) {
        throw new UnsupportedOperationException("sourceDir not set");
      }
      return sourceDir;
    }

    @Override
    public Path targetDir() {
      if (_unsetProperties.contains(Property.TARGET_DIR)) {
        throw new UnsupportedOperationException("targetDir not set");
      }
      return targetDir;
    }

    @Override
    public Map<String, Object> externalPageVars() {
      return externalPageVars;
    }

    private static class PartialBuilder extends Builder {
      @Override
      public BakeOptions build() {
        return buildPartial();
      }
    }

    @Override
    public Builder toBuilder() {
      BakeOptions_Builder builder = new PartialBuilder();
      builder.sourceDir = sourceDir;
      builder.targetDir = targetDir;
      builder.externalPageVars.putAll(externalPageVars);
      builder._unsetProperties.clear();
      builder._unsetProperties.addAll(_unsetProperties);
      return (Builder) builder;
    }

    @Override
    public boolean equals(Object obj) {
      if (!(obj instanceof Partial)) {
        return false;
      }
      Partial other = (Partial) obj;
      return Objects.equals(sourceDir, other.sourceDir)
          && Objects.equals(targetDir, other.targetDir)
          && Objects.equals(externalPageVars, other.externalPageVars)
          && Objects.equals(_unsetProperties, other._unsetProperties);
    }

    @Override
    public int hashCode() {
      return Objects.hash(sourceDir, targetDir, externalPageVars, _unsetProperties);
    }

    @Override
    public String toString() {
      StringBuilder result = new StringBuilder("partial BakeOptions{");
      if (!_unsetProperties.contains(Property.SOURCE_DIR)) {
        result.append("sourceDir=").append(sourceDir).append(", ");
      }
      if (!_unsetProperties.contains(Property.TARGET_DIR)) {
        result.append("targetDir=").append(targetDir).append(", ");
      }
      return result.append("externalPageVars=").append(externalPageVars).append("}").toString();
    }
  }

  private static <K, V> Map<K, V> immutableMap(Map<K, V> entries) {
    switch (entries.size()) {
      case 0:
        return Collections.emptyMap();
      case 1:
        Map.Entry<K, V> entry = entries.entrySet().iterator().next();
        return Collections.singletonMap(entry.getKey(), entry.getValue());
      default:
        return Collections.unmodifiableMap(new LinkedHashMap<>(entries));
    }
  }
}