package com.mozz.htmlnative.parser.token;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
public final class Token {
public static final int EXTRA_NUMBER_EM = 1;
public static final int EXTRA_NUMBER_PERCENTAGE = 2;
private long startColumn;
private long line;
private TokenType mTokenType;
@Nullable
private Object mValue;
private int mExtra = -1;
@Nullable
private Token next;
// for token pool
@Nullable
private static Token sPool;
private static int sPoolSize = 0;
private static final int MAX_POOL_SIZE = 20;
private Token(@NonNull TokenType tokenType, @NonNull Object value) {
mTokenType = tokenType;
mValue = value;
}
@NonNull
@Override
public String toString() {
String value = mValue == null ? "" : ":" + mValue;
return "[" + mTokenType.toString() + "]" + value;
}
@NonNull
public TokenType type() {
return mTokenType;
}
@Nullable
public Object value() {
return mValue;
}
public void setValue(Object value) {
mValue = value;
}
@Nullable
public String stringValue() {
return mValue.toString();
}
public int intValue() {
if (mValue instanceof Integer) {
return (int) mValue;
} else {
return 0;
}
}
public double doubleValue() {
if (mValue instanceof Double) {
return (double) mValue;
} else if (mValue instanceof Float) {
return (float) mValue;
} else {
return 0d;
}
}
public boolean booleanValue() {
if (mValue instanceof Boolean) {
return (boolean) mValue;
} else {
return false;
}
}
@Nullable
public static Token obtainToken(TokenType tokenType, Object value, long line, long column) {
if (sPool != null) {
Token t = sPool;
sPool = t.next;
t.next = null;
sPoolSize--;
t.mTokenType = tokenType;
t.mValue = value;
t.line = line;
t.startColumn = column;
return t;
}
return new Token(tokenType, value);
}
@Nullable
public static Token obtainToken(TokenType tokenType, long line, long column) {
return obtainToken(tokenType, null, line, column);
}
public static Token obtainToken(TokenType tokenType, Object value, long line, long column,
int extra) {
Token t = obtainToken(tokenType, value, line, column);
t.mExtra = extra;
return t;
}
static void recycleAll() {
sPoolSize = 0;
sPool = null;
}
public void recycle() {
recycleUnchecked();
}
private void recycleUnchecked() {
mTokenType = TokenType.Unknown;
mValue = null;
startColumn = -1;
line = -1;
if (sPoolSize < MAX_POOL_SIZE) {
next = sPool;
sPool = this;
sPoolSize++;
}
}
@Override
public boolean equals(Object obj) {
if (obj instanceof Token) {
Token compare = (Token) obj;
return compare.mValue.equals(mValue) && compare.mTokenType.equals(mTokenType) &&
compare.line == line && compare.startColumn == startColumn;
}
return false;
}
@Override
public int hashCode() {
int r = 17;
r = 31 * r + (int) startColumn;
r = 31 * r + (int) line;
r = 31 * r + mValue.hashCode();
r = 31 * r + mTokenType.hashCode();
return r;
}
public long getColumn() {
return startColumn;
}
public long getLine() {
return line;
}
public int getExtra() {
return mExtra;
}
}