package io.ebeaninternal.server.querydefn;
public class SimpleTextParser {
private final String oql;
private final char[] chars;
private final int eof;
private int pos;
private String word;
private String lowerWord;
public SimpleTextParser(String oql) {
this.oql = oql;
this.chars = oql.toCharArray();
this.eof = oql.length();
}
public boolean isEmpty() {
return oql.isEmpty();
}
public int getPos() {
return pos;
}
String getOql() {
return oql;
}
public String getWord() {
return word;
}
private String peekNextWord() {
int origPos = pos;
String nw = nextWordInternal();
pos = origPos;
return nw;
}
public boolean isMatch(String lowerMatch, String nextWordMatch) {
if (isMatch(lowerMatch)) {
String nw = peekNextWord();
if (nw != null) {
nw = nw.toLowerCase();
return nw.equals(nextWordMatch);
}
}
return false;
}
public boolean isFinished() {
return word == null;
}
public int findWordLower(String lowerMatch, int afterPos) {
this.pos = afterPos;
return findWordLower(lowerMatch);
}
public int findWordLower(String lowerMatch) {
do {
if (nextWord() == null) {
return -1;
}
if (lowerMatch.equals(lowerWord)) {
return pos - lowerWord.length();
}
} while (true);
}
public boolean isMatch(String lowerMatch) {
return lowerMatch.equals(lowerWord);
}
public String nextWord() {
word = nextWordInternal();
if (word != null) {
lowerWord = word.toLowerCase();
}
return word;
}
private String nextWordInternal() {
trimLeadingWhitespace();
if (pos >= eof) {
return null;
}
int start = pos;
if (chars[pos] == '(') {
moveToClose();
} else {
moveToEndOfWord();
}
return oql.substring(start, pos);
}
private void moveToClose() {
pos++;
int openParenthesisCount = 0;
for (; pos < eof; pos++) {
char c = chars[pos];
if (c == '(') {
openParenthesisCount++;
} else if (c == ')') {
if (openParenthesisCount > 0) {
--openParenthesisCount;
} else {
pos++;
return;
}
}
}
}
private void moveToEndOfWord() {
char c = chars[pos];
boolean isOperator = isOperator(c);
for (; pos < eof; pos++) {
c = chars[pos];
if (isWordTerminator(c, isOperator)) {
return;
}
}
}
private boolean isWordTerminator(char c, boolean isOperator) {
return Character.isWhitespace(c) || (isOperator(c) ? !isOperator : c == '(' || isOperator);
}
private boolean isOperator(char c) {
switch (c) {
case '<':
return true;
case '>':
return true;
case '=':
return true;
case '!':
return true;
default:
return false;
}
}
private void trimLeadingWhitespace() {
for (; pos < eof; pos++) {
char c = chars[pos];
if (!Character.isWhitespace(c)) {
break;
}
}
}
}