All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.inferred.freebuilder.processor.excerpt.CheckedNavigableSet Maven / Gradle / Ivy

There is a newer version: 2.8.0
Show newest version
package org.inferred.freebuilder.processor.excerpt;

import org.inferred.freebuilder.processor.source.Excerpt;
import org.inferred.freebuilder.processor.source.LazyName;
import org.inferred.freebuilder.processor.source.PreconditionExcerpts;
import org.inferred.freebuilder.processor.source.SourceBuilder;
import org.inferred.freebuilder.processor.source.ValueType;

import java.util.AbstractSet;
import java.util.Comparator;
import java.util.Iterator;
import java.util.NavigableSet;
import java.util.Objects;
import java.util.function.Consumer;

/**
 * Excerpts defining a navigable set implementation that delegates to a provided add method to
 * perform element validation and insertion into a backing set.
 */
public class CheckedNavigableSet extends ValueType implements Excerpt {

  public static final LazyName TYPE =
      LazyName.of("CheckedNavigableSet", new CheckedNavigableSet());

  private CheckedNavigableSet() {}

  @Override
  public void addTo(SourceBuilder code) {
    code.addLine("")
        .addLine("/**")
        .addLine(" * A set implementation that delegates to a provided add method")
        .addLine(" * to perform element validation and insertion into a backing set.")
        .addLine(" */")
        .addLine("private static class %s extends %s implements %s {",
            TYPE, AbstractSet.class, NavigableSet.class)
        .addLine("")
        .addLine("  private final %s set;", NavigableSet.class)
        .addLine("  private final %s add;", Consumer.class)
        .addLine("  private final E fromElement;")
        .addLine("  private final boolean fromInclusive;")
        .addLine("  private final E toElement;")
        .addLine("  private final boolean toInclusive;")
        .addLine("")
        .addLine("  %s(%s set, %s add) {",
            TYPE, NavigableSet.class, Consumer.class)
        .addLine("    this.set = set;")
        .addLine("    this.add = add;")
        .addLine("    this.fromElement = null;")
        .addLine("    this.fromInclusive = false;")
        .addLine("    this.toElement = null;")
        .addLine("    this.toInclusive = false;")
        .addLine("  }")
        .addLine("")
        .addLine("  %s(", TYPE)
        .addLine("      %s set,", NavigableSet.class)
        .addLine("      %s add,", Consumer.class)
        .addLine("      E fromElement,")
        .addLine("      boolean fromInclusive,")
        .addLine("      E toElement,")
        .addLine("      boolean toInclusive) {")
        .addLine("    this.set = set;")
        .addLine("    this.add = add;")
        .addLine("    this.fromElement = fromElement;")
        .addLine("    this.fromInclusive = fromInclusive;")
        .addLine("    this.toElement = toElement;")
        .addLine("    this.toInclusive = toInclusive;")
        .addLine("  }")
        .addLine("")
        .addLine("")
        .addLine("  @Override public %s iterator() {", Iterator.class)
        .addLine("    return set.iterator();")
        .addLine("  }")
        .addLine("")
        .addLine("  @Override public int size() {")
        .addLine("    return set.size();")
        .addLine("  }")
        .addLine("")
        .addLine("  @Override public boolean contains(Object e) {")
        .addLine("    return set.contains(e);")
        .addLine("  }");
    addAddMethod(code);
    code.addLine("")
        .addLine("  @Override public boolean remove(Object e) {")
        .addLine("    return set.remove(e);")
        .addLine("  }")
        .addLine("")
        .addLine("  @Override public %s comparator() {", Comparator.class)
        .addLine("    return set.comparator();")
        .addLine("  }");
    addSubSetMethod(code);
    code.addLine("")
        .addLine("  @Override public E first() {")
        .addLine("    return set.first();")
        .addLine("  }")
        .addLine("")
        .addLine("  @Override public E last() {")
        .addLine("    return set.last();")
        .addLine("  }")
        .addLine("")
        .addLine("  @Override public E lower(E element) {")
        .addLine("    return set.lower(element);")
        .addLine("  }")
        .addLine("")
        .addLine("  @Override public E floor(E element) {")
        .addLine("    return set.floor(element);")
        .addLine("  }")
        .addLine("")
        .addLine("  @Override public E ceiling(E element) {")
        .addLine("    return set.ceiling(element);")
        .addLine("  }")
        .addLine("")
        .addLine("  @Override public E higher(E element) {")
        .addLine("    return set.higher(element);")
        .addLine("  }")
        .addLine("")
        .addLine("  @Override public E pollFirst() {")
        .addLine("    return set.pollFirst();")
        .addLine("  }")
        .addLine("")
        .addLine("  @Override public E pollLast() {")
        .addLine("    return set.pollLast();")
        .addLine("  }")
        .addLine("")
        .addLine("  @Override public %s descendingSet() {", NavigableSet.class)
        .addLine("    %s descendingSet = set.descendingSet();", NavigableSet.class)
        .addLine("    return new %s(", TYPE)
        .addLine("        descendingSet, add, toElement, toInclusive, fromElement, fromInclusive);")
        .addLine("  }")
        .addLine("")
        .addLine("  @Override public %s descendingIterator() {", Iterator.class)
        .addLine("    return set.descendingIterator();")
        .addLine("  }")
        .addLine("")
        .addLine("  @Override public %s subSet(", NavigableSet.class)
        .addLine("      E fromElement,")
        .addLine("      boolean fromInclusive,")
        .addLine("      E toElement,")
        .addLine("      boolean toInclusive) {")
        .addLine("    %s.requireNonNull(fromElement);", Objects.class)
        .addLine("    %s.requireNonNull(toElement);", Objects.class)
        .addLine("    %s subSet = set.subSet(", NavigableSet.class)
        .addLine("        fromElement, fromInclusive, toElement, toInclusive);")
        .addLine("    return new %s<>(", TYPE)
        .addLine("        subSet, add, fromElement, fromInclusive, toElement, toInclusive);")
        .addLine("  }")
        .addLine("")
        .addLine("  @Override public %s headSet(", NavigableSet.class)
        .addLine("      E toElement,")
        .addLine("      boolean inclusive) {")
        .addLine("    %s.requireNonNull(toElement);", Objects.class)
        .addLine("    %s headSet = set.headSet(toElement, inclusive);",
            NavigableSet.class)
        .addLine("    return new %s<>(", TYPE)
        .addLine("        headSet, add, fromElement, fromInclusive, toElement, inclusive);")
        .addLine("  }")
        .addLine("")
        .addLine("  @Override public %s tailSet(", NavigableSet.class)
        .addLine("      E fromElement,")
        .addLine("      boolean inclusive) {")
        .addLine("    %s.requireNonNull(fromElement);", Objects.class)
        .addLine("    %s tailSet = set.tailSet(fromElement, inclusive);",
            NavigableSet.class)
        .addLine("    return new %s<>(", TYPE)
        .addLine("        tailSet, add, fromElement, inclusive, toElement, toInclusive);")
        .addLine("  }")
        .addLine("}");
  }

  private static void addSubSetMethod(SourceBuilder code) {
    code.addLine("")
        .addLine("  @Override public %s subSet(E fromElement, E toElement) {",
            NavigableSet.class)
        .addLine("    %s.requireNonNull(fromElement);", Objects.class)
        .addLine("    %s.requireNonNull(toElement);", Objects.class)
        .addLine("    %s subSet = set.subSet(fromElement, true, toElement, false);",
            NavigableSet.class)
        .addLine("    return new %s<>(", TYPE)
        .addLine("        subSet, add, fromElement, true, toElement, false);")
        .addLine("  }")
        .addLine("")
        .addLine("  @Override public %s headSet(E toElement) {", NavigableSet.class)
        .addLine("    %s.requireNonNull(toElement);", Objects.class)
        .addLine("    %s headSet = set.headSet(toElement, false);", NavigableSet.class)
        .addLine("    return new %s<>(", TYPE)
        .addLine("        headSet, add, fromElement, fromInclusive, toElement, false);")
        .addLine("  }")
        .addLine("")
        .addLine("  @Override public %s tailSet(E fromElement) {", NavigableSet.class)
        .addLine("    %s.requireNonNull(fromElement);", Objects.class)
        .addLine("    %s tailSet = set.tailSet(fromElement, true);", NavigableSet.class)
        .addLine("    return new %s<>(", TYPE)
        .addLine("        tailSet, add, fromElement, true, toElement, toInclusive);")
        .addLine("  }");
  }

  private static void addAddMethod(SourceBuilder code) {
    code.addLine("")
        .addLine("  @Override public boolean add(E e) {")
        .addLine("    if (fromElement != null || toElement != null) {")
        .addLine("      %s comparator = set.comparator();", Comparator.class)
        .addLine("      if (comparator == null) {")
        .addLine("        @SuppressWarnings(\"unchecked\")")
        .addLine("        %1$s lowerBound = (%1$s) fromElement;",
            Comparable.class)
        .addLine("        @SuppressWarnings(\"unchecked\")")
        .addLine("        %1$s upperBound = (%1$s) toElement;",
            Comparable.class)
        .add(PreconditionExcerpts.checkArgument(
            "lowerBound == null || lowerBound.compareTo(e) <= (fromInclusive ? 0 : -1)",
            "element must be %s %s (got %s)",
            "(fromInclusive ? \"at least\" : \"greater than\")",
            "lowerBound",
            "e"))
        .add(PreconditionExcerpts.checkArgument(
            "upperBound == null || upperBound.compareTo(e) >= (toInclusive ? 0 : 1)",
            "element must be %s %s (got %s)",
            "(toInclusive ? \"at most\" : \"less than\")",
            "upperBound",
            "e"))
        .addLine("      } else {")
        .add(PreconditionExcerpts.checkArgument(
            "fromElement == null "
                + "|| comparator.compare(fromElement, e) <= (fromInclusive ? 0 : -1)",
            "element must be %s %s (got %s) using comparator %s",
            "(fromInclusive ? \"at least\" : \"greater than\")",
            "fromElement",
            "e",
            "comparator"))
        .add(PreconditionExcerpts.checkArgument(
            "toElement == null "
                + "|| comparator.compare(toElement, e) >= (toInclusive ? 0 : 1)",
            "element must be %s %s (got %s) using comparator %s",
            "(toInclusive ? \"at most\" : \"less than\")",
            "toElement",
            "e",
            "comparator"))
        .addLine("      }")
        .addLine("    }")
        .addLine("    if (!set.contains(e)) {")
        .addLine("      add.accept(e);")
        .addLine("      return true;")
        .addLine("    } else {")
        .addLine("      return false;")
        .addLine("    }")
        .addLine("  }");
  }

  @Override
  protected void addFields(FieldReceiver fields) {}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy