/*
* Copyright © Red Gate Software Ltd 2010-2020
*
* Licensed 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 org.flywaydb.core.internal.parser;
import org.flywaydb.core.api.FlywayException;
import org.flywaydb.core.internal.sqlscript.Delimiter;
import java.security.InvalidParameterException;
import java.util.Stack;
public class ParserContext {
private int parensDepth = 0;
private Stack<String> blockInitiators = new Stack<>();
private String lastClosedBlockInitiator = null;
private int blockDepth = 0;
private Delimiter delimiter;
private StatementType statementType;
public ParserContext(Delimiter delimiter) {
this.delimiter = delimiter;
}
public void increaseParensDepth() {
parensDepth++;
}
public void decreaseParensDepth() {
parensDepth--;
}
public int getParensDepth() {
return parensDepth;
}
// When a block is closed, retain the token that opened it, so that we can determine what the
// context of a given END is.
public String getLastClosedBlockInitiator() {
return lastClosedBlockInitiator;
}
public void increaseBlockDepth(String blockInitiator) {
blockInitiators.push(blockInitiator);
blockDepth++;
}
public void decreaseBlockDepth() {
if (blockDepth == 0) {
throw new FlywayException("Flyway parsing bug: unable to decrease block depth below 0");
}
blockDepth--;
lastClosedBlockInitiator = blockInitiators.pop();
}
public int getBlockDepth() {
return blockDepth;
}
public String getBlockInitiator() {
return blockInitiators.size() > 0 ? blockInitiators.peek() : "";
}
public Delimiter getDelimiter() {
return delimiter;
}
public void setDelimiter(Delimiter delimiter) {
this.delimiter = delimiter;
}
public StatementType getStatementType() {
return statementType;
}
public void setStatementType(StatementType statementType) {
if (statementType == null) {
throw new InvalidParameterException("statementType must be non-null");
}
this.statementType = statementType;
}
public boolean isLetter(char c) {
if (Character.isLetter(c)) {
return true;
}
// Some statement types admit other characters as letters
if (getStatementType() != StatementType.UNKNOWN) {
return statementType.treatAsIfLetter(c);
}
return false;
}
}