001package gudusoft.gsqlparser.pp2.island;
002
003/**
004 * An immutable recognised island: a typed, contiguous token span with its SQL
005 * scope level and completeness state.
006 *
007 * <p>Islands may nest and overlap (e.g. a {@code CASE} island inside a
008 * {@code SELECT} island, or an {@code ERROR_REGION} over the dangling tokens of
009 * an incomplete clause island). Consumers should treat them as hints, not a
010 * strict partition.
011 *
012 * <p>Token indices are inclusive and refer to positions in the
013 * {@link gudusoft.gsqlparser.pp2.token.Pp2TokenStream} the recogniser ran over.
014 *
015 * <p>Plan reference: §7.3/S22, §7.4/S22.
016 */
017public final class IslandScope {
018
019    private final IslandKind kind;
020    private final int startIndex;       // inclusive
021    private final int endIndex;         // inclusive
022    private final int sqlLevel;
023    private final boolean complete;
024    private final IncompleteReason reason;
025
026    public IslandScope(IslandKind kind, int startIndex, int endIndex,
027                       int sqlLevel, boolean complete, IncompleteReason reason) {
028        if (kind == null) throw new NullPointerException("kind");
029        if (reason == null) throw new NullPointerException("reason");
030        if (startIndex < 0) {
031            throw new IllegalArgumentException("startIndex < 0: " + startIndex);
032        }
033        if (endIndex < startIndex) {
034            throw new IllegalArgumentException(
035                "endIndex < startIndex: " + endIndex + " < " + startIndex);
036        }
037        if (sqlLevel < 0) {
038            throw new IllegalArgumentException("sqlLevel < 0: " + sqlLevel);
039        }
040        this.kind = kind;
041        this.startIndex = startIndex;
042        this.endIndex = endIndex;
043        this.sqlLevel = sqlLevel;
044        this.complete = complete;
045        this.reason = reason;
046    }
047
048    public IslandKind getKind() { return kind; }
049    public int getStartIndex() { return startIndex; }
050    public int getEndIndex() { return endIndex; }
051    public int getLength() { return endIndex - startIndex + 1; }
052    public int getSqlLevel() { return sqlLevel; }
053    public boolean isComplete() { return complete; }
054    public IncompleteReason getReason() { return reason; }
055
056    @Override
057    public String toString() {
058        return "IslandScope[" + kind + " " + startIndex + ".." + endIndex
059            + " lvl=" + sqlLevel + (complete ? " complete" : " incomplete:" + reason) + "]";
060    }
061}