ThriftToken.java
package net.morimekta.providence.reflect.parser;
import net.morimekta.util.lexer.Token;
import javax.annotation.Nonnull;
import java.util.regex.Pattern;
public class ThriftToken extends Token<ThriftTokenType> {
// Various symbols.
public static final char kGenericStart = '<';
public static final char kGenericEnd = '>';
public static final char kMessageStart = '{';
public static final char kMessageEnd = '}';
public static final char kKeyValueSep = ':';
public static final char kFieldValueSep = '=';
public static final char kParamsStart = '(';
public static final char kParamsEnd = ')';
public static final char kListStart = '[';
public static final char kListEnd = ']';
public static final char kLineSep1 = ',';
public static final char kLineSep2 = ';';
/**
* Create a slice instance. The slice is only meant to be internal state
* immutable, and not representing an immutable byte content.
*
* @param fb The buffer to wrap.
* @param off The start offset to wrap.
* @param len The length to represent.
* @param type The token type represented.
* @param lineNo The current line number.
* @param linePos The current line position.
*/
public ThriftToken(char[] fb, int off, int len,
@Nonnull ThriftTokenType type, int lineNo, int linePos) {
super(fb, off, len, type, lineNo, linePos);
}
public boolean isSymbol(char symbol) {
return len == 1 && fb[off] == symbol;
}
/**
* Parse token content as documentation.
*
* @return The documentation string.
*/
public String parseDocumentation() {
String block = toString().trim();
String[] lines = block.split("\\r?\\n", Short.MAX_VALUE);
StringBuilder builder = new StringBuilder();
for (String line : lines) {
builder.append(RE_BLOCK_LINE.matcher(line).replaceFirst(""));
builder.append('\n');
}
return builder.toString().trim();
}
public boolean isFieldId() {
return RE_FIELD_ID.matcher(this).matches();
}
public boolean isEnumValueId() {
return RE_ENUM_ID.matcher(this).matches();
}
public boolean isInteger() {
return RE_INTEGER.matcher(this).matches();
}
public boolean isReal() {
return RE_REAL.matcher(this).matches();
}
public boolean isIdentifier() {
return RE_IDENTIFIER.matcher(this).matches();
}
public boolean isQualifiedIdentifier() {
return RE_QUALIFIED_IDENTIFIER.matcher(this).matches();
}
public boolean isDoubleQualifiedIdentifier() {
return RE_DOUBLE_QUALIFIED_IDENTIFIER.matcher(this).matches();
}
public boolean isReferenceIdentifier() {
return RE_REFERENCE_IDENTIFIER.matcher(this).matches();
}
// ---- INTERNAL ----
private static final Pattern RE_IDENTIFIER = Pattern.compile(
"[_a-zA-Z][_a-zA-Z0-9]*");
private static final Pattern RE_QUALIFIED_IDENTIFIER = Pattern.compile(
"[_a-zA-Z][_a-zA-Z0-9]*[.][_a-zA-Z][_a-zA-Z0-9]*");
private static final Pattern RE_DOUBLE_QUALIFIED_IDENTIFIER = Pattern.compile(
"[_a-zA-Z][_a-zA-Z0-9]*[.][_a-zA-Z][_a-zA-Z0-9]*[.][_a-zA-Z][_a-zA-Z0-9]*");
private static final Pattern RE_REFERENCE_IDENTIFIER = Pattern.compile(
"[_a-zA-Z][_a-zA-Z0-9]*([.][_a-zA-Z][_a-zA-Z0-9]*)*");
private final static Pattern RE_BLOCK_LINE = Pattern.compile(
"^([\\s]*[*])?[\\s]?");
private static final Pattern RE_FIELD_ID = Pattern.compile(
"([1-9][0-9]*)");
private static final Pattern RE_ENUM_ID = Pattern.compile(
"(0|[1-9][0-9]*)");
private static final Pattern RE_INTEGER = Pattern.compile(
"-?(0|[1-9][0-9]*|0[0-7]+|0x[0-9a-fA-F]+)");
private static final Pattern RE_REAL = Pattern.compile(
"-?(0?\\.[0-9]+|[1-9][0-9]*\\.[0-9]*)([eE][+-]?[0-9][0-9]*)?");
}