com.hazelcast.org.apache.calcite.sql.parser.Span Maven / Gradle / Ivy
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to you 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.hazelcast.org.apache.calcite.sql.parser;
import com.hazelcast.org.apache.calcite.sql.SqlNode;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
/**
* Builder for {@link SqlParserPos}.
*
* Because it is mutable, it is convenient for keeping track of the
* positions of the tokens that go into a non-terminal. It can be passed
* into methods, which can add the positions of tokens consumed to it.
*
*
Some patterns:
*
*
* - {@code final Span s;} declaration of a Span at the top of a production
*
- {@code s = span();} initializes s to a Span that includes the token we
* just saw; very often occurs immediately after the first token in the
* production
*
- {@code s.end(this);} adds the most recent token to span s and evaluates
* to a SqlParserPosition that spans from beginning to end; commonly used
* when making a call to a function
*
- {@code s.pos()} returns a position spanning all tokens in the list
*
- {@code s.add(node);} adds a SqlNode's parser position to a span
*
- {@code s.addAll(nodeList);} adds several SqlNodes' parser positions to
* a span
*
- {@code s = Span.of();} initializes s to an empty Span, not even
* including the most recent token; rarely used
*
*/
public final class Span {
private final List posList = new ArrayList<>();
/** Use one of the {@link #of} methods. */
private Span() {}
/** Creates an empty Span. */
public static Span of() {
return new Span();
}
/** Creates a Span with one position. */
public static Span of(SqlParserPos p) {
return new Span().add(p);
}
/** Creates a Span of one node. */
public static Span of(SqlNode n) {
return new Span().add(n);
}
/** Creates a Span between two nodes. */
public static Span of(SqlNode n0, SqlNode n1) {
return new Span().add(n0).add(n1);
}
/** Creates a Span of a list of nodes. */
public static Span of(Collection extends SqlNode> nodes) {
return new Span().addAll(nodes);
}
/** Adds a node's position to the list,
* and returns this Span. */
public Span add(SqlNode n) {
return add(n.getParserPosition());
}
/** Adds a node's position to the list if the node is not null,
* and returns this Span. */
public Span addIf(SqlNode n) {
return n == null ? this : add(n);
}
/** Adds a position to the list,
* and returns this Span. */
public Span add(SqlParserPos pos) {
posList.add(pos);
return this;
}
/** Adds the positions of a collection of nodes to the list,
* and returns this Span. */
public Span addAll(Iterable extends SqlNode> nodes) {
for (SqlNode node : nodes) {
add(node);
}
return this;
}
/** Adds the position of the last token emitted by a parser to the list,
* and returns this Span. */
public Span add(SqlAbstractParserImpl parser) {
try {
final SqlParserPos pos = parser.getPos();
return add(pos);
} catch (Exception e) {
// getPos does not really throw an exception
throw new AssertionError(e);
}
}
/** Returns a position spanning the earliest position to the latest.
* Does not assume that the positions are sorted.
* Throws if the list is empty. */
public SqlParserPos pos() {
switch (posList.size()) {
case 0:
throw new AssertionError();
case 1:
return posList.get(0);
default:
return SqlParserPos.sum(posList);
}
}
/** Adds the position of the last token emitted by a parser to the list,
* and returns a position that covers the whole range. */
public SqlParserPos end(SqlAbstractParserImpl parser) {
return add(parser).pos();
}
/** Adds a node's position to the list,
* and returns a position that covers the whole range. */
public SqlParserPos end(SqlNode n) {
return add(n).pos();
}
/** Clears the contents of this Span, and returns this Span. */
public Span clear() {
posList.clear();
return this;
}
}