294 lines
8.7 KiB
Java
294 lines
8.7 KiB
Java
package com.hypixel.hytale.codec;
|
|
|
|
import com.hypixel.hytale.codec.store.CodecStore;
|
|
import com.hypixel.hytale.codec.util.RawJsonReader;
|
|
import com.hypixel.hytale.codec.validation.ThrowingValidationResults;
|
|
import com.hypixel.hytale.codec.validation.ValidationResults;
|
|
import com.hypixel.hytale.logger.util.GithubMessageUtil;
|
|
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
|
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
|
import java.io.IOException;
|
|
import java.util.Arrays;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import java.util.function.Function;
|
|
import javax.annotation.Nonnull;
|
|
|
|
public class ExtraInfo {
|
|
public static final ThreadLocal<ExtraInfo> THREAD_LOCAL = ThreadLocal.withInitial(ExtraInfo::new);
|
|
public static final String GENERATED_ID_PREFIX = "*";
|
|
public static final int UNSET_VERSION = Integer.MAX_VALUE;
|
|
private final int legacyVersion;
|
|
private final int keysInitialSize = this instanceof EmptyExtraInfo ? 0 : 128;
|
|
@Nonnull
|
|
private String[] stringKeys = new String[this.keysInitialSize];
|
|
@Nonnull
|
|
private int[] intKeys = new int[this.keysInitialSize];
|
|
private int[] lineNumbers = GithubMessageUtil.isGithub() ? new int[this.keysInitialSize] : null;
|
|
private int[] columnNumbers = GithubMessageUtil.isGithub() ? new int[this.keysInitialSize] : null;
|
|
private int keysSize;
|
|
@Nonnull
|
|
private String[] ignoredUnknownKeys = new String[this.keysInitialSize];
|
|
private int ignoredUnknownSize;
|
|
private final List<String> unknownKeys = new ObjectArrayList();
|
|
private final ValidationResults validationResults;
|
|
private final CodecStore codecStore;
|
|
@Deprecated
|
|
private final Map<String, Object> metadata = new Object2ObjectOpenHashMap();
|
|
|
|
public ExtraInfo() {
|
|
this.legacyVersion = Integer.MAX_VALUE;
|
|
this.validationResults = new ThrowingValidationResults(this);
|
|
this.codecStore = CodecStore.STATIC;
|
|
}
|
|
|
|
@Deprecated
|
|
public ExtraInfo(int version) {
|
|
this.legacyVersion = version;
|
|
this.validationResults = new ThrowingValidationResults(this);
|
|
this.codecStore = CodecStore.STATIC;
|
|
}
|
|
|
|
@Deprecated
|
|
public ExtraInfo(int version, @Nonnull Function<ExtraInfo, ValidationResults> validationResultsSupplier) {
|
|
this.legacyVersion = version;
|
|
this.validationResults = validationResultsSupplier.apply(this);
|
|
this.codecStore = CodecStore.STATIC;
|
|
}
|
|
|
|
public int getVersion() {
|
|
return Integer.MAX_VALUE;
|
|
}
|
|
|
|
@Deprecated
|
|
public int getLegacyVersion() {
|
|
return this.legacyVersion;
|
|
}
|
|
|
|
public int getKeysSize() {
|
|
return this.keysSize;
|
|
}
|
|
|
|
public CodecStore getCodecStore() {
|
|
return this.codecStore;
|
|
}
|
|
|
|
private int nextKeyIndex() {
|
|
int index = this.keysSize++;
|
|
if (this.stringKeys.length <= index) {
|
|
int newLength = grow(index);
|
|
this.stringKeys = Arrays.copyOf(this.stringKeys, newLength);
|
|
this.intKeys = Arrays.copyOf(this.intKeys, newLength);
|
|
if (GithubMessageUtil.isGithub()) {
|
|
this.lineNumbers = Arrays.copyOf(this.lineNumbers, newLength);
|
|
this.columnNumbers = Arrays.copyOf(this.columnNumbers, newLength);
|
|
}
|
|
}
|
|
|
|
return index;
|
|
}
|
|
|
|
public void pushKey(String key) {
|
|
int index = this.nextKeyIndex();
|
|
this.stringKeys[index] = key;
|
|
}
|
|
|
|
public void pushIntKey(int key) {
|
|
int index = this.nextKeyIndex();
|
|
this.intKeys[index] = key;
|
|
}
|
|
|
|
public void pushKey(String key, RawJsonReader reader) {
|
|
int index = this.nextKeyIndex();
|
|
this.stringKeys[index] = key;
|
|
if (GithubMessageUtil.isGithub()) {
|
|
this.lineNumbers[index] = reader.getLine();
|
|
this.columnNumbers[index] = reader.getColumn();
|
|
}
|
|
}
|
|
|
|
public void pushIntKey(int key, RawJsonReader reader) {
|
|
int index = this.nextKeyIndex();
|
|
this.intKeys[index] = key;
|
|
if (GithubMessageUtil.isGithub()) {
|
|
this.lineNumbers[index] = reader.getLine();
|
|
this.columnNumbers[index] = reader.getColumn();
|
|
}
|
|
}
|
|
|
|
public void popKey() {
|
|
this.stringKeys[this.keysSize] = null;
|
|
this.keysSize--;
|
|
}
|
|
|
|
private int nextIgnoredUnknownIndex() {
|
|
int index = this.ignoredUnknownSize++;
|
|
if (this.ignoredUnknownKeys.length <= index) {
|
|
this.ignoredUnknownKeys = Arrays.copyOf(this.ignoredUnknownKeys, grow(index));
|
|
}
|
|
|
|
return index;
|
|
}
|
|
|
|
public void ignoreUnusedKey(String key) {
|
|
int index = this.nextIgnoredUnknownIndex();
|
|
this.ignoredUnknownKeys[index] = key;
|
|
}
|
|
|
|
public void popIgnoredUnusedKey() {
|
|
this.ignoredUnknownKeys[this.ignoredUnknownSize] = null;
|
|
this.ignoredUnknownSize--;
|
|
}
|
|
|
|
public boolean consumeIgnoredUnknownKey(@Nonnull RawJsonReader reader) throws IOException {
|
|
if (this.ignoredUnknownSize <= 0) {
|
|
return false;
|
|
} else {
|
|
int lastIndex = this.ignoredUnknownSize - 1;
|
|
String ignoredUnknownKey = this.ignoredUnknownKeys[lastIndex];
|
|
if (ignoredUnknownKey == null) {
|
|
return false;
|
|
} else if (!reader.tryConsumeString(ignoredUnknownKey)) {
|
|
return false;
|
|
} else {
|
|
this.ignoredUnknownKeys[lastIndex] = null;
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
public boolean consumeIgnoredUnknownKey(@Nonnull String key) {
|
|
if (this.ignoredUnknownSize <= 0) {
|
|
return false;
|
|
} else {
|
|
int lastIndex = this.ignoredUnknownSize - 1;
|
|
if (!key.equals(this.ignoredUnknownKeys[lastIndex])) {
|
|
return false;
|
|
} else {
|
|
this.ignoredUnknownKeys[lastIndex] = null;
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
public void readUnknownKey(@Nonnull RawJsonReader reader) throws IOException {
|
|
if (!this.consumeIgnoredUnknownKey(reader)) {
|
|
String key = reader.readString();
|
|
if (this.keysSize == 0) {
|
|
this.unknownKeys.add(key);
|
|
} else {
|
|
this.unknownKeys.add(this.peekKey() + "." + key);
|
|
}
|
|
}
|
|
}
|
|
|
|
public void addUnknownKey(@Nonnull String key) {
|
|
switch (key) {
|
|
case "$Title":
|
|
case "$Comment":
|
|
case "$TODO":
|
|
case "$Author":
|
|
case "$Position":
|
|
case "$FloatingFunctionNodes":
|
|
case "$Groups":
|
|
case "$WorkspaceID":
|
|
case "$NodeEditorMetadata":
|
|
case "$NodeId":
|
|
return;
|
|
default:
|
|
if (!this.consumeIgnoredUnknownKey(key)) {
|
|
if (this.keysSize == 0) {
|
|
if ("Parent".equals(key)) {
|
|
return;
|
|
}
|
|
|
|
this.unknownKeys.add(key);
|
|
} else {
|
|
this.unknownKeys.add(this.peekKey() + "." + key);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public String peekKey() {
|
|
return this.peekKey('.');
|
|
}
|
|
|
|
public String peekKey(char separator) {
|
|
if (this.keysSize == 0) {
|
|
return "";
|
|
} else if (this.keysSize == 1) {
|
|
String str = this.stringKeys[0];
|
|
return str != null ? str : String.valueOf(this.intKeys[0]);
|
|
} else {
|
|
StringBuilder sb = new StringBuilder();
|
|
|
|
for (int i = 0; i < this.keysSize; i++) {
|
|
if (i > 0) {
|
|
sb.append(separator);
|
|
}
|
|
|
|
String str = this.stringKeys[i];
|
|
if (str != null) {
|
|
sb.append(str);
|
|
} else {
|
|
sb.append(this.intKeys[i]);
|
|
}
|
|
}
|
|
|
|
return sb.toString();
|
|
}
|
|
}
|
|
|
|
public int peekLine() {
|
|
return GithubMessageUtil.isGithub() && this.keysSize > 0 ? this.lineNumbers[this.keysSize - 1] : -1;
|
|
}
|
|
|
|
public int peekColumn() {
|
|
return GithubMessageUtil.isGithub() && this.keysSize > 0 ? this.columnNumbers[this.keysSize - 1] : -1;
|
|
}
|
|
|
|
public List<String> getUnknownKeys() {
|
|
return this.unknownKeys;
|
|
}
|
|
|
|
public ValidationResults getValidationResults() {
|
|
return this.validationResults;
|
|
}
|
|
|
|
@Deprecated
|
|
public Map<String, Object> getMetadata() {
|
|
return this.metadata;
|
|
}
|
|
|
|
public void appendDetailsTo(@Nonnull StringBuilder sb) {
|
|
sb.append("ExtraInfo\n");
|
|
}
|
|
|
|
@Nonnull
|
|
@Override
|
|
public String toString() {
|
|
return "ExtraInfo{version="
|
|
+ this.legacyVersion
|
|
+ ", stringKeys="
|
|
+ Arrays.toString((Object[])this.stringKeys)
|
|
+ ", intKeys="
|
|
+ Arrays.toString(this.intKeys)
|
|
+ ", keysSize="
|
|
+ this.keysSize
|
|
+ ", ignoredUnknownKeys="
|
|
+ Arrays.toString((Object[])this.ignoredUnknownKeys)
|
|
+ ", ignoredUnknownSize="
|
|
+ this.ignoredUnknownSize
|
|
+ ", unknownKeys="
|
|
+ this.unknownKeys
|
|
+ ", validationResults="
|
|
+ this.validationResults
|
|
+ "}";
|
|
}
|
|
|
|
private static int grow(int oldSize) {
|
|
return oldSize + (oldSize >> 1);
|
|
}
|
|
}
|