KeyEntry class
Пакет: com.hypixel.hytale.codec.builder
Файл: com/hypixel/hytale/codec/builder/BuilderCodec.java
Поля (1)
| Модификаторы | Тип | Имя |
|---|---|---|
|
private final BuilderCodec.EntryType |
type |
Методы (1)
| Модификаторы | Возврат | Сигнатура |
|---|---|---|
|
public BuilderCodec.EntryType |
getTypepublic BuilderCodec.EntryType getType() |
Исходный код
Показать/скрыть
class="kw">package com.hypixel.hytale.codec.builder;
class="kw">import com.hypixel.hytale.codec.Codec;
class="kw">import com.hypixel.hytale.codec.DirectDecodeCodec;
class="kw">import com.hypixel.hytale.codec.EmptyExtraInfo;
class="kw">import com.hypixel.hytale.codec.ExtraInfo;
class="kw">import com.hypixel.hytale.codec.InheritCodec;
class="kw">import com.hypixel.hytale.codec.KeyedCodec;
class="kw">import com.hypixel.hytale.codec.RawJsonCodec;
class="kw">import com.hypixel.hytale.codec.VersionedExtraInfo;
class="kw">import com.hypixel.hytale.codec.exception.CodecException;
class="kw">import com.hypixel.hytale.codec.schema.SchemaContext;
class="kw">import com.hypixel.hytale.codec.schema.config.NullSchema;
class="kw">import com.hypixel.hytale.codec.schema.config.ObjectSchema;
class="kw">import com.hypixel.hytale.codec.schema.config.Schema;
class="kw">import com.hypixel.hytale.codec.schema.metadata.Metadata;
class="kw">import com.hypixel.hytale.codec.schema.metadata.ui.UIDisplayMode;
class="kw">import com.hypixel.hytale.codec.util.RawJsonReader;
class="kw">import com.hypixel.hytale.codec.validation.ValidatableCodec;
class="kw">import com.hypixel.hytale.codec.validation.ValidationResults;
class="kw">import com.hypixel.hytale.function.consumer.TriConsumer;
class="kw">import it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap;
class="kw">import it.unimi.dsi.fastutil.objects.ObjectArrayList;
class="kw">import java.io.IOException;
class="kw">import java.util.Collections;
class="kw">import java.util.Comparator;
class="kw">import java.util.List;
class="kw">import java.util.Map;
class="kw">import java.util.Objects;
class="kw">import java.util.Set;
class="kw">import java.util.Map.Entry;
class="kw">import java.util.function.BiConsumer;
class="kw">import java.util.function.BiFunction;
class="kw">import java.util.function.Consumer;
class="kw">import java.util.function.Function;
class="kw">import java.util.function.Supplier;
class="kw">import javax.annotation.Nonnull;
class="kw">import javax.annotation.Nullable;
class="kw">import org.bson.BsonDocument;
class="kw">import org.bson.BsonValue;
class="kw">public class BuilderCodec<T> class="kw">implements Codec<T>, DirectDecodeCodec<T>, RawJsonCodec<T>, InheritCodec<T>, ValidatableCodec<T> {
class="kw">public class="kw">static class="kw">final int UNSET_VERSION = Integer.MIN_VALUE;
class="kw">public class="kw">static class="kw">final int UNSET_MAX_VERSION = Integer.MAX_VALUE;
class="kw">public class="kw">static class="kw">final int INITIAL_VERSION = 0;
class="kw">public class="kw">static class="kw">final BuilderCodec<?>[] EMPTY_ARRAY = new BuilderCodec[0];
class="kw">private class="kw">static class="kw">final KeyedCodec<Integer> VERSION = new KeyedCodec<>("Version", INTEGER);
class="kw">private class="kw">static class="kw">final Map<String, BuilderCodec.EntryType> BASE_IGNORED_KEYS = Map.ofEntries(
Map.entry("$Title", BuilderCodec.EntryType.IGNORE),
Map.entry("$Comment", BuilderCodec.EntryType.IGNORE),
Map.entry("$TODO", BuilderCodec.EntryType.IGNORE),
Map.entry("$Author", BuilderCodec.EntryType.IGNORE),
Map.entry("$Position", BuilderCodec.EntryType.IGNORE),
Map.entry("$FloatingFunctionNodes", BuilderCodec.EntryType.IGNORE),
Map.entry("$Groups", BuilderCodec.EntryType.IGNORE),
Map.entry("$WorkspaceID", BuilderCodec.EntryType.IGNORE),
Map.entry("$NodeEditorMetadata", BuilderCodec.EntryType.IGNORE),
Map.entry("$NodeId", BuilderCodec.EntryType.IGNORE),
Map.entry("Parent", BuilderCodec.EntryType.IGNORE_IN_BASE_OBJECT)
);
class="kw">protected class="kw">final Class<T> tClass;
class="kw">protected class="kw">final Supplier<T> supplier;
@Nullable
class="kw">protected class="kw">final BuilderCodec<? super T> parentCodec;
@Nonnull
class="kw">protected class="kw">final Map<String, List<BuilderField<T, ?>>> entries;
@Nonnull
class="kw">protected class="kw">final Map<String, List<BuilderField<T, ?>>> unmodifiableEntries;
class="kw">protected class="kw">final BiConsumer<T, ValidationResults> validator;
class="kw">protected class="kw">final BiConsumer<T, ExtraInfo> afterDecode;
class="kw">protected class="kw">final boolean hasNonNullValidator;
class="kw">protected class="kw">final String documentation;
class="kw">protected class="kw">final List<Metadata> metadata;
class="kw">protected class="kw">final int codecVersion;
class="kw">protected class="kw">final int minCodecVersion;
class="kw">protected class="kw">final boolean versioned;
@Deprecated
class="kw">protected class="kw">final boolean useLegacyVersion;
@Nonnull
class="kw">protected class="kw">final StringTreeMap<BuilderCodec.KeyEntry<T>> stringTreeMap;
class="kw">protected BuilderCodec(@Nonnull BuilderCodec.BuilderBase<T, ?> var1) {
this.tClass = var1.tClass;
this.supplier = var1.supplier;
this.parentCodec = var1.parentCodec;
this.entries = Objects.requireNonNull(var1.entries, "entries parameter can't be null");
this.unmodifiableEntries = Collections.unmodifiableMap(var1.entries);
this.stringTreeMap = var1.stringTreeMap;
this.validator = var1.validator;
this.afterDecode = var1.afterDecode;
this.documentation = var1.documentation;
this.metadata = var1.metadata;
boolean var2 = false;
for (List var4 : this.entries.values()) {
var4.sort(Comparator.comparingInt(BuilderField::getMinVersion));
for (BuilderField var6 : var4) {
var2 |= var6.hasNonNullValidator();
}
}
this.hasNonNullValidator = var2;
int var11;
if (var1.codecVersion != Integer.MIN_VALUE) {
var11 = var1.codecVersion;
} else {
int var12 = Integer.MIN_VALUE;
for (List var16 : this.entries.values()) {
for (BuilderField var8 : var16) {
var12 = Math.max(var12, var8.getHighestSupportedVersion());
}
}
var11 = var12;
}
int var13;
if (var1.minCodecVersion != Integer.MAX_VALUE) {
var13 = var1.minCodecVersion;
} else {
int var15 = Integer.MAX_VALUE;
for (List var18 : this.entries.values()) {
for (BuilderField var9 : var18) {
int var10 = var9.getMinVersion();
if (var10 != Integer.MIN_VALUE) {
var15 = Math.min(var15, var10);
}
}
}
var13 = var15;
}
if (this.parentCodec != null) {
var11 = Math.max(var11, this.parentCodec.codecVersion);
var13 = Math.min(var13, this.parentCodec.minCodecVersion);
this.versioned = var1.versioned || this.parentCodec.versioned;
this.useLegacyVersion = var1.useLegacyVersion || this.parentCodec.useLegacyVersion;
} else {
this.versioned = var1.versioned;
this.useLegacyVersion = var1.useLegacyVersion;
}
this.codecVersion = var11;
this.minCodecVersion = var13;
if (this.versioned && !this.declaresVersionField()) {
this.stringTreeMap.put(VERSION.getKey(), new BuilderCodec.KeyEntry<>(BuilderCodec.EntryType.IGNORE));
}
}
class="kw">private boolean declaresVersionField() {
for (BuilderCodec var1 = this; var1 != null; var1 = var1.parentCodec) {
if (var1.entries.containsKey(VERSION.getKey())) {
class="kw">return true;
}
}
class="kw">return false;
}
class="kw">public Class<T> getInnerClass() {
class="kw">return this.tClass;
}
class="kw">public Supplier<T> getSupplier() {
class="kw">return this.supplier;
}
class="kw">public T getDefaultValue() {
class="kw">return this.getDefaultValue(EmptyExtraInfo.EMPTY);
}
class="kw">public T getDefaultValue(ExtraInfo var1) {
Object var2 = this.supplier.get();
this.afterDecode(var2, var1);
class="kw">return var2;
}
@Nonnull
class="kw">public Map<String, List<BuilderField<T, ?>>> getEntries() {
class="kw">return this.unmodifiableEntries;
}
class="kw">public BiConsumer<T, ExtraInfo> getAfterDecode() {
class="kw">return this.afterDecode;
}
@Nullable
class="kw">public BuilderCodec<? super T> getParent() {
class="kw">return this.parentCodec;
}
class="kw">public String getDocumentation() {
class="kw">return this.documentation;
}
class="kw">public int getCodecVersion() {
class="kw">return this.codecVersion;
}
class="kw">public void inherit(T var1, @Nonnull T var2, @Nonnull ExtraInfo var3) {
if (this.parentCodec != null) {
this.parentCodec.inherit(var1, var2, var3);
}
if (this.getInnerClass().isAssignableFrom(var2.getClass())) {
for (List var5 : this.entries.values()) {
BuilderField var6 = findField(var5, var3);
if (var6 != null) {
var6.inherit(var1, var2, var3);
}
}
}
}
class="kw">public void afterDecode(T var1, ExtraInfo var2) {
if (this.parentCodec != null) {
this.parentCodec.afterDecode(var1, var2);
}
if (this.afterDecode != null) {
this.afterDecode.accept(var1, var2);
}
}
class="kw">public void afterDecodeAndValidate(T var1, @Nonnull ExtraInfo var2) {
if (this.parentCodec != null) {
this.parentCodec.afterDecodeAndValidate(var1, var2);
}
if (this.afterDecode != null) {
this.afterDecode.accept(var1, var2);
}
ValidationResults var3 = var2.getValidationResults();
if (this.hasNonNullValidator) {
for (List var5 : this.entries.values()) {
BuilderField var6 = findField(var5, var2);
if (var6 != null) {
var2.pushKey(var6.codec.getKey());
try {
var6.nullValidate(var1, var3, var2);
} class="kw">finally {
var2.popKey();
}
}
}
if (this.validator != null) {
this.validator.accept(var1, var3);
}
var3._processValidationResults();
} else if (this.validator != null) {
this.validator.accept(var1, var3);
var3._processValidationResults();
}
}
@Override
class="kw">public T decode(@Nonnull BsonValue var1, @Nonnull ExtraInfo var2) {
if (this.supplier == null) {
throw new CodecException("This BuilderCodec is for an class="kw">abstract or direct codec. To use this codec you must specify an existing object to decode into.");
}
Object var3 = this.supplier.get();
this.decode(var1.asDocument(), var3, var2);
class="kw">return var3;
}
@Nonnull
class="kw">public BsonDocument encode(T var1, @Nonnull ExtraInfo var2) {
BsonDocument var3 = new BsonDocument();
if (this.versioned) {
if (this.codecVersion != 0) {
VERSION.put(var3, this.codecVersion, var2);
}
var2 = new VersionedExtraInfo(this.codecVersion, var2);
}
class="kw">return this.encode0(var1, var3, var2);
}
@Override
class="kw">public void decode(@Nonnull BsonValue var1, T var2, @Nonnull ExtraInfo var3) {
BsonDocument var4 = var1.asDocument();
if (this.versioned) {
var3 = this.decodeVersion(var4, var3);
}
this.decode0(var4, var2, var3);
this.afterDecodeAndValidate(var2, var3);
}
class="kw">protected void decode0(@Nonnull BsonDocument var1, T var2, ExtraInfo var3) {
for (Entry var5 : var1.entrySet()) {
String var6 = var5.getKey();
BuilderField var7 = findEntry(this, var6, var3);
if (var7 != null) {
var7.decode(var1, var2, var3);
} else if (!this.isIgnoredKey(var6, var3)) {
var3.addUnknownKey(var6);
}
}
}
@Nonnull
class="kw">protected BsonDocument encode0(T var1, @Nonnull BsonDocument var2, @Nonnull ExtraInfo var3) {
if (this.parentCodec != null) {
this.parentCodec.encode0(var1, var2, var3);
}
for (List var5 : this.entries.values()) {
BuilderField var6 = findField(var5, var3);
if (var6 != null) {
var6.encode(var2, var1, var3);
}
}
class="kw">return var2;
}
@Override
class="kw">public T decodeJson(@Nonnull RawJsonReader var1, @Nonnull ExtraInfo var2) class="kw">throws IOException {
if (this.supplier == null) {
throw new CodecException("This BuilderCodec is for an class="kw">abstract or direct codec. To use this codec you must specify an existing object to decode into.");
}
Object var3 = this.supplier.get();
if (this.versioned) {
var2 = this.decodeVersion(var1, var2);
}
this.decodeJson0(var1, var3, var2);
this.afterDecodeAndValidate(var3, var2);
class="kw">return var3;
}
class="kw">private void decodeJson0(@Nonnull RawJsonReader var1, T var2, ExtraInfo var3) class="kw">throws IOException {
var1.expect('{');
var1.consumeWhiteSpace();
if (!var1.tryConsume('}')) {
while (true) {
this.readEntry(var1, var2, var3);
var1.consumeWhiteSpace();
if (var1.tryConsumeOrExpect('}', ',')) {
class="kw">return;
}
var1.consumeWhiteSpace();
}
}
}
class="kw">protected void readEntry(@Nonnull RawJsonReader var1, T var2, @Nonnull ExtraInfo var3) class="kw">throws IOException {
var1.mark();
StringTreeMap var4 = this.stringTreeMap.findEntry(var1);
BuilderCodec.KeyEntry var5;
if (var4 != null && (var5 = var4.getValue()) != null) {
class="kw">switch (var5.getType()) {
case FIELD:
String var6 = var4.getKey();
List var7 = var5.getFields();
this.readField(var1, var2, var3, var6, var7);
break;
case IGNORE:
var1.unmark();
this.skipField(var1);
break;
case IGNORE_IN_BASE_OBJECT:
if (var3.getKeysSize() == 0) {
var1.unmark();
this.skipField(var1);
} else {
var1.reset();
this.readUnknownField(var1, var3);
}
}
} else {
var1.reset();
this.readUnknownField(var1, var3);
}
}
class="kw">private void skipField(@Nonnull RawJsonReader var1) class="kw">throws IOException {
var1.consumeWhiteSpace();
var1.expect(':');
var1.consumeWhiteSpace();
var1.skipValue();
}
class="kw">private void readField(@Nonnull RawJsonReader var1, T var2, @Nonnull ExtraInfo var3, String var4, @Nonnull List<BuilderField<T, ?>> var5) class="kw">throws IOException {
BuilderField var6 = null;
for (BuilderField var8 : var5) {
if (var8.supportsVersion(var3.getVersion())) {
var6 = var8;
break;
}
}
if (var6 == null) {
var1.reset();
this.readUnknownField(var1, var3);
} else {
var1.unmark();
var1.consumeWhiteSpace();
var1.expect(':');
var1.consumeWhiteSpace();
var3.pushKey(var4, var1);
try {
var6.decodeJson(var1, var2, var3);
} catch (Exception var12) {
throw new CodecException("Failed to decode", var1, var3, var12);
} class="kw">finally {
var3.popKey();
}
}
}
class="kw">private void readUnknownField(@Nonnull RawJsonReader var1, @Nonnull ExtraInfo var2) class="kw">throws IOException {
var2.readUnknownKey(var1);
var1.consumeWhiteSpace();
var1.expect(':');
var1.consumeWhiteSpace();
var1.skipValue();
}
class="kw">public void decodeJson(@Nonnull RawJsonReader var1, T var2, @Nonnull ExtraInfo var3) class="kw">throws IOException {
if (this.versioned) {
var3 = this.decodeVersion(var1, var3);
}
this.decodeJson0(var1, var2, var3);
this.afterDecodeAndValidate(var2, var3);
}
@Override
class="kw">public T decodeAndInherit(@Nonnull BsonDocument var1, T var2, ExtraInfo var3) {
Object var4 = this.supplier.get();
this.decodeAndInherit(var1, var4, var2, var3);
class="kw">return var4;
}
@Override
class="kw">public void decodeAndInherit(@Nonnull BsonDocument var1, T var2, @Nullable T var3, ExtraInfo var4) {
if (this.versioned) {
var4 = this.decodeVersion(var1, var4);
}
if (var3 != null) {
this.inherit(var2, var3, var4);
}
this.decodeAndInherit0(var1, var2, var3, var4);
this.afterDecodeAndValidate(var2, var4);
}
class="kw">protected void decodeAndInherit0(@Nonnull BsonDocument var1, T var2, T var3, @Nonnull ExtraInfo var4) {
for (Entry var6 : var1.entrySet()) {
String var7 = var6.getKey();
BuilderField var8 = findEntry(this, var7, var4);
if (var8 != null) {
if (var8.codec.getChildCodec() class="kw">instanceof BuilderCodec) {
decodeAndInherit(var8, var1, var2, var3, var4);
} else {
var8.decodeAndInherit(var1, var2, var3, var4);
}
} else if (!this.isIgnoredKey(var7, var4)) {
var4.addUnknownKey(var7);
}
}
}
class="kw">private class="kw">static <Type, FieldType> void decodeAndInherit(
@Nonnull BuilderField<Type, FieldType> var0, @Nonnull BsonDocument var1, Type var2, @Nullable Type var3, @Nonnull ExtraInfo var4
) {
KeyedCodec var5 = var0.codec;
String var6 = var5.getKey();
BsonValue var7 = var1.get(var6);
if (Codec.isNullBsonValue(var7)) {
if (var7 != null && var7.isNull()) {
var0.setValue(var2, null, var4);
}
} else {
var4.pushKey(var6);
try {
BuilderCodec var8 = (BuilderCodec<FieldType>)var5.getChildCodec();
Object var9 = var8.getSupplier().get();
Object var10 = var3 != null ? var0.getter.apply(var3, var4) : null;
var8.decodeAndInherit(var7.asDocument(), var9, var10, var4);
var0.setValue(var2, var9, var4);
} catch (Exception var14) {
throw new CodecException("Failed to decode", var7, var4, var14);
} class="kw">finally {
var4.popKey();
}
}
}
@Override
class="kw">public T decodeAndInheritJson(@Nonnull RawJsonReader var1, T var2, ExtraInfo var3) class="kw">throws IOException {
Object var4 = this.supplier.get();
this.decodeAndInheritJson(var1, var4, var2, var3);
class="kw">return var4;
}
@Override
class="kw">public void decodeAndInheritJson(@Nonnull RawJsonReader var1, T var2, @Nullable T var3, ExtraInfo var4) class="kw">throws IOException {
if (this.versioned) {
var4 = this.decodeVersion(var1, var4);
}
if (var3 != null) {
this.inherit(var2, var3, var4);
}
this.decodeAndInheritJson0(var1, var2, var3, var4);
this.afterDecodeAndValidate(var2, var4);
}
class="kw">public void decodeAndInheritJson0(@Nonnull RawJsonReader var1, T var2, T var3, @Nonnull ExtraInfo var4) class="kw">throws IOException {
var1.expect('{');
var1.consumeWhiteSpace();
if (!var1.tryConsume('}')) {
while (true) {
this.readAndInheritEntry(var1, var2, var3, var4);
var1.consumeWhiteSpace();
if (var1.tryConsumeOrExpect('}', ',')) {
class="kw">return;
}
var1.consumeWhiteSpace();
}
}
}
class="kw">protected void readAndInheritEntry(@Nonnull RawJsonReader var1, T var2, T var3, @Nonnull ExtraInfo var4) class="kw">throws IOException {
var1.mark();
StringTreeMap var5 = this.stringTreeMap.findEntry(var1);
BuilderCodec.KeyEntry var6;
if (var5 != null && (var6 = var5.getValue()) != null) {
class="kw">switch (var6.getType()) {
case FIELD:
String var7 = var5.getKey();
List var8 = var6.getFields();
this.readAndInheritField(var1, var2, var3, var4, var7, var8);
break;
case IGNORE:
var1.unmark();
this.skipField(var1);
break;
case IGNORE_IN_BASE_OBJECT:
if (var4.getKeysSize() == 0) {
var1.unmark();
this.skipField(var1);
} else {
var1.reset();
this.readUnknownField(var1, var4);
}
}
} else {
var1.reset();
this.readUnknownField(var1, var4);
}
}
class="kw">private void readAndInheritField(@Nonnull RawJsonReader var1, T var2, T var3, @Nonnull ExtraInfo var4, String var5, @Nonnull List<BuilderField<T, ?>> var6) class="kw">throws IOException {
BuilderField var7 = null;
for (BuilderField var9 : var6) {
if (var9.supportsVersion(var4.getVersion())) {
var7 = var9;
break;
}
}
if (var7 == null) {
var1.reset();
this.readUnknownField(var1, var4);
} else {
var1.unmark();
var1.consumeWhiteSpace();
var1.expect(':');
var1.consumeWhiteSpace();
var4.pushKey(var5, var1);
try {
if (var7.codec.getChildCodec() class="kw">instanceof BuilderCodec) {
decodeAndInheritJson(var7, var1, var2, var3, var4);
} else {
var7.decodeAndInheritJson(var1, var2, var3, var4);
}
} catch (Exception var13) {
throw new CodecException("Failed to decode", var1, var4, var13);
} class="kw">finally {
var4.popKey();
}
}
}
class="kw">private class="kw">static <Type, FieldType> void decodeAndInheritJson(
@Nonnull BuilderField<Type, FieldType> var0, @Nonnull RawJsonReader var1, Type var2, @Nullable Type var3, @Nonnull ExtraInfo var4
) class="kw">throws IOException {
int var5 = var1.peek();
if (var5 == -1) {
throw new IOException("Unexpected EOF!");
}
class="kw">switch (var5) {
case 78:
case 110:
var1.readNullValue();
var0.setValue(var2, null, var4);
class="kw">return;
class="kw">default:
BuilderCodec var6 = (BuilderCodec<FieldType>)var0.codec.getChildCodec();
Object var7 = var6.getSupplier().get();
Object var8 = var3 != null ? var0.getter.apply(var3, var4) : null;
var6.decodeAndInheritJson(var1, var7, var8, var4);
var0.setValue(var2, var7, var4);
}
}
class="kw">private boolean isIgnoredKey(@Nonnull String var1, @Nonnull ExtraInfo var2) {
StringTreeMap var3 = this.stringTreeMap.findEntry(var1);
if (var3 == null) {
class="kw">return false;
}
BuilderCodec.KeyEntry var4 = var3.getValue();
if (var4 == null) {
class="kw">return false;
}
class="kw">return class="kw">switch (var4.getType()) {
case FIELD -> false;
case IGNORE -> true;
case IGNORE_IN_BASE_OBJECT -> var2.getKeysSize() == 0;
};
}
@Nonnull
class="kw">protected ExtraInfo decodeVersion(BsonDocument var1, @Nonnull ExtraInfo var2) {
if (this.useLegacyVersion && var2.getLegacyVersion() != Integer.MAX_VALUE) {
class="kw">return new VersionedExtraInfo(var2.getLegacyVersion(), var2);
} else {
int var3 = VERSION.get(var1, var2).orElse(0);
if (var3 > this.codecVersion) {
throw new IllegalArgumentException("Version " + var3 + " is newer than expected version " + this.codecVersion);
} else if (this.minCodecVersion != Integer.MAX_VALUE && var3 < this.minCodecVersion) {
throw new IllegalArgumentException("Version " + var3 + " is older than min supported version " + this.minCodecVersion);
} else {
class="kw">return new VersionedExtraInfo(var3, var2);
}
}
}
@Nonnull
class="kw">protected ExtraInfo decodeVersion(@Nonnull RawJsonReader var1, @Nonnull ExtraInfo var2) class="kw">throws IOException {
if (this.useLegacyVersion && var2.getLegacyVersion() != Integer.MAX_VALUE) {
class="kw">return new VersionedExtraInfo(var2.getLegacyVersion(), var2);
}
var1.mark();
int var3 = 0;
if (RawJsonReader.seekToKey(var1, VERSION.getKey())) {
var3 = var1.readIntValue();
}
if (var3 > this.codecVersion) {
throw new IllegalArgumentException("Version " + var3 + " is newer than expected version " + this.codecVersion);
}
if (this.minCodecVersion != Integer.MAX_VALUE && var3 < this.minCodecVersion) {
throw new IllegalArgumentException("Version " + var3 + " is older than min supported version " + this.minCodecVersion);
}
var1.reset();
class="kw">return new VersionedExtraInfo(var3, var2);
}
@Override
class="kw">public void validate(T var1, @Nonnull ExtraInfo var2) {
if (this.parentCodec != null) {
this.parentCodec.validate(var1, var2);
}
for (List var4 : this.entries.values()) {
BuilderField var5 = findField(var4, var2);
if (var5 != null) {
var2.pushKey(var5.codec.getKey());
try {
var5.validate(var1, var2);
} class="kw">finally {
var2.popKey();
}
}
}
}
@Override
class="kw">public void validateDefaults(@Nonnull ExtraInfo var1, @Nonnull Set<Codec<?>> var2) {
if (var2.add(this)) {
Object var3 = this.supplier.get();
this.afterDecode(var3, var1);
for (BuilderCodec var4 = this; var4 != null; var4 = (BuilderCodec<T>)var4.parentCodec) {
for (List var6 : var4.entries.values()) {
BuilderField var7 = findField(var6, var1);
if (var7 != null) {
var1.pushKey(var7.codec.getKey());
try {
var7.validateDefaults(var3, var1, var2);
} class="kw">finally {
var1.popKey();
}
}
}
}
}
}
@Nonnull
class="kw">public ObjectSchema toSchema(@Nonnull SchemaContext var1) {
Object var2 = this.getDefaultValue();
class="kw">return this.toSchema(var1, var2);
}
@Nonnull
class="kw">public ObjectSchema toSchema(@Nonnull SchemaContext var1, @Nullable T var2) {
ObjectSchema var3 = new ObjectSchema();
var3.setAdditionalProperties(false);
var3.setTitle(this.tClass.getSimpleName());
var3.setMarkdownDescription(this.documentation);
var3.getHytale().setMergesProperties(true);
Map var4 = new Object2ObjectLinkedOpenHashMap();
if (this.versioned) {
var4.put(VERSION.getKey(), VERSION.getChildCodec().toSchema(var1));
}
Schema var5 = new Schema();
var5.getHytale().setUiPropertyTitle("Comment");
var5.setDoNotSuggest(true);
var5.setDescription("Comments don't have any function other than allowing users to add certain internal comments or notes to an asset");
UIDisplayMode.HIDDEN.modify(var5);
var4.put("$Title", var5);
var4.put("$Comment", var5);
var4.put("$Author", var5);
var4.put("$TODO", var5);
var4.put("$Position", var5);
var4.put("$FloatingFunctionNodes", var5);
var4.put("$Groups", var5);
var4.put("$WorkspaceID", var5);
var4.put("$NodeId", var5);
var4.put("$NodeEditorMetadata", var5);
var3.setProperties(var4);
createSchemaFields(var1, var2, this, var4);
if (this.metadata != null) {
for (int var6 = 0; var6 < this.metadata.size(); var6++) {
Metadata var7 = this.metadata.get(var6);
var7.modify(var3);
}
}
class="kw">return var3;
}
class="kw">private class="kw">static <T> void createSchemaFields(@Nonnull SchemaContext var0, @Nullable T var1, @Nonnull BuilderCodec<T> var2, @Nonnull Map<String, Schema> var3) {
if (var2.parentCodec != null) {
createSchemaFields(var0, var1, var2.parentCodec, var3);
}
for (Entry var5 : var2.getEntries().entrySet()) {
String var6 = var5.getKey();
List var7 = var5.getValue();
BuilderField var8 = var7.getLast();
Codec var9 = var8.getCodec().getChildCodec();
Object var10;
try {
var10 = var8.getter.apply(var1, EmptyExtraInfo.EMPTY);
} catch (UnsupportedOperationException var14) {
class="kw">continue;
}
Schema var11 = var0.refDefinition(var9, (T)var10);
var8.updateSchema(var0, var11);
Schema var12 = var11;
String var13 = Schema.CODEC.getIdFor((Class<? class="kw">extends Schema>)var11.getClass());
if (!var13.isEmpty()) {
if (!var8.hasNonNullValidator() && !var8.isPrimitive) {
var11.setTypes(new String[]{var13, "null"});
}
var3.put(var6, var11);
} else if (var8.hasNonNullValidator()) {
var3.put(var6, var11);
} else {
var3.put(var6, var12 = Schema.anyOf(var11, NullSchema.INSTANCE));
}
var12.setMarkdownDescription(var8.getDocumentation());
}
}
@Nonnull
@Override
class="kw">public String toString() {
class="kw">return "BuilderCodec{supplier="
+ this.supplier
+ ", parentCodec="
+ this.parentCodec
+ ", entries="
+ this.entries
+ ", afterDecode="
+ this.afterDecode
+ "}";
}
@Nullable
class="kw">protected class="kw">static <T> BuilderField<? super T, ?> findEntry(@Nonnull BuilderCodec<? super T> var0, String var1, @Nonnull ExtraInfo var2) {
List var3 = var0.entries.get(var1);
if (var3 != null && var3.size() == 1) {
BuilderField var4 = (BuilderField<? super T, ?>)var3.getFirst();
if (var4.supportsVersion(var2.getVersion())) {
class="kw">return var4;
}
}
BuilderField var5 = null;
while (var0 != null) {
var5 = findField(var0.entries.get(var1), var2);
if (var5 != null) {
class="kw">return var5;
}
var0 = var0.parentCodec;
}
class="kw">return var5;
}
@Nullable
class="kw">protected class="kw">static <T, F class="kw">extends BuilderField<T, ?>> F findField(@Nullable List<F> var0, @Nonnull ExtraInfo var1) {
if (var0 == null) {
class="kw">return null;
}
int var2 = 0;
for (int var3 = var0.size(); var2 < var3; var2++) {
BuilderField var4 = (F)var0.get(var2);
if (var4.supportsVersion(var1.getVersion())) {
class="kw">return var4;
}
}
class="kw">return null;
}
@Nonnull
class="kw">public class="kw">static <T> BuilderCodec.Builder<T> builder(Class<T> var0, Supplier<T> var1) {
class="kw">return new BuilderCodec.Builder<>(var0, var1);
}
@Nonnull
class="kw">public class="kw">static <T> BuilderCodec.Builder<T> builder(Class<T> var0, Supplier<T> var1, BuilderCodec<? super T> var2) {
class="kw">return new BuilderCodec.Builder<>(var0, var1, var2);
}
@Nonnull
class="kw">public class="kw">static <T> BuilderCodec.Builder<T> abstractBuilder(Class<T> var0) {
class="kw">return new BuilderCodec.Builder<>(var0, null);
}
@Nonnull
class="kw">public class="kw">static <T> BuilderCodec.Builder<T> abstractBuilder(Class<T> var0, BuilderCodec<? super T> var1) {
class="kw">return new BuilderCodec.Builder<>(var0, null, var1);
}
class="kw">public class="kw">static class Builder<T> class="kw">extends BuilderCodec.BuilderBase<T, BuilderCodec.Builder<T>> {
class="kw">protected Builder(Class<T> var1, Supplier<T> var2) {
super(var1, var2);
}
class="kw">protected Builder(Class<T> var1, Supplier<T> var2, @Nullable BuilderCodec<? super T> var3) {
super(var1, var2, var3);
}
}
class="kw">public class="kw">abstract class="kw">static class BuilderBase<T, S class="kw">extends BuilderCodec.BuilderBase<T, S>> {
class="kw">protected class="kw">final Class<T> tClass;
class="kw">protected class="kw">final Supplier<T> supplier;
@Nullable
class="kw">protected class="kw">final BuilderCodec<? super T> parentCodec;
class="kw">protected class="kw">final Map<String, List<BuilderField<T, ?>>> entries = new Object2ObjectLinkedOpenHashMap();
@Nonnull
class="kw">protected class="kw">final StringTreeMap<BuilderCodec.KeyEntry<T>> stringTreeMap;
class="kw">protected BiConsumer<T, ValidationResults> validator;
class="kw">protected BiConsumer<T, ExtraInfo> afterDecode;
class="kw">protected String documentation;
class="kw">protected List<Metadata> metadata;
class="kw">protected int codecVersion = Integer.MIN_VALUE;
class="kw">protected int minCodecVersion = Integer.MAX_VALUE;
class="kw">protected boolean versioned = false;
class="kw">protected boolean useLegacyVersion = false;
class="kw">protected BuilderBase(Class<T> var1, Supplier<T> var2) {
this(var1, var2, null);
}
class="kw">protected BuilderBase(Class<T> var1, Supplier<T> var2, @Nullable BuilderCodec<? super T> var3) {
this.tClass = var1;
this.supplier = var2;
this.parentCodec = var3;
if (var3 != null) {
this.stringTreeMap = new StringTreeMap<>((StringTreeMap<BuilderCodec.KeyEntry<T>>)var3.stringTreeMap);
} else {
this.stringTreeMap = new StringTreeMap<>();
BuilderCodec.BASE_IGNORED_KEYS.forEach((var1x, var2x) -> this.stringTreeMap.put(var1x, new BuilderCodec.KeyEntry<>(var2x)));
}
}
class="kw">private S self() {
class="kw">return (S)this;
}
@Nonnull
class="kw">public S documentation(String var1) {
this.documentation = var1;
class="kw">return this.self();
}
@Nonnull
class="kw">public S versioned() {
this.versioned = true;
class="kw">return this.self();
}
@Nonnull
@Deprecated
class="kw">public S legacyVersioned() {
this.versioned = true;
this.useLegacyVersion = true;
class="kw">return this.self();
}
@Nonnull
@Deprecated
class="kw">public <FieldType> S addField(@Nonnull KeyedCodec<FieldType> var1, @Nonnull BiConsumer<T, FieldType> var2, @Nonnull Function<T, FieldType> var3) {
class="kw">return this.addField(new BuilderField<>(var1, (var1x, var2x, var3x) -> var2.accept(var1x, var2x), (var1x, var2x) -> var3.apply(var1x), null));
}
@Nonnull
class="kw">public <FieldType> BuilderField.FieldBuilder<T, FieldType, S> append(
KeyedCodec<FieldType> var1, @Nonnull BiConsumer<T, FieldType> var2, @Nonnull Function<T, FieldType> var3
) {
class="kw">return this.append(var1, (var1x, var2x, var3x) -> var2.accept(var1x, var2x), (var1x, var2x) -> var3.apply(var1x));
}
@Nonnull
class="kw">public <FieldType> BuilderField.FieldBuilder<T, FieldType, S> append(
KeyedCodec<FieldType> var1, TriConsumer<T, FieldType, ExtraInfo> var2, BiFunction<T, ExtraInfo, FieldType> var3
) {
class="kw">return new BuilderField.FieldBuilder<>(this.self(), var1, var2, var3, null);
}
@Nonnull
class="kw">public <FieldType> BuilderField.FieldBuilder<T, FieldType, S> appendInherited(
KeyedCodec<FieldType> var1, @Nonnull BiConsumer<T, FieldType> var2, @Nonnull Function<T, FieldType> var3, @Nonnull BiConsumer<T, T> var4
) {
class="kw">return this.appendInherited(
var1, (var1x, var2x, var3x) -> var2.accept(var1x, var2x), (var1x, var2x) -> var3.apply(var1x), (var1x, var2x, var3x) -> var4.accept(var1x, var2x)
);
}
@Nonnull
class="kw">public <FieldType> BuilderField.FieldBuilder<T, FieldType, S> appendInherited(
KeyedCodec<FieldType> var1, TriConsumer<T, FieldType, ExtraInfo> var2, BiFunction<T, ExtraInfo, FieldType> var3, TriConsumer<T, T, ExtraInfo> var4
) {
class="kw">return new BuilderField.FieldBuilder<>(this.self(), var1, var2, var3, var4);
}
@Nonnull
class="kw">public <FieldType> S addField(@Nonnull BuilderField<T, FieldType> var1) {
if (var1.getMinVersion() > var1.getMaxVersion()) {
throw new IllegalArgumentException("Min version must be less than the max version: " + var1);
}
List var2 = this.entries.computeIfAbsent(var1.getCodec().getKey(), var0 -> new ObjectArrayList());
for (BuilderField var4 : var2) {
if (var1.getMaxVersion() >= var4.getMinVersion() && var1.getMinVersion() <= var4.getMaxVersion()) {
throw new IllegalArgumentException("Field already defined for this version range!");
}
}
var2.add(var1);
this.stringTreeMap.put(var1.getCodec().getKey(), new BuilderCodec.KeyEntry<>(var2));
class="kw">return this.self();
}
@Nonnull
class="kw">public S afterDecode(@Nonnull Consumer<T> var1) {
Objects.requireNonNull(var1, "afterDecodeAndValidate can't be null!");
class="kw">return this.afterDecode((var1x, var2) -> var1.accept(var1x));
}
@Nonnull
class="kw">public S afterDecode(BiConsumer<T, ExtraInfo> var1) {
this.afterDecode = Objects.requireNonNull(var1, "afterDecodeAndValidate can't be null!");
class="kw">return this.self();
}
@Nonnull
@Deprecated
class="kw">public S validator(BiConsumer<T, ValidationResults> var1) {
this.validator = Objects.requireNonNull(var1, "validator can't be null!");
class="kw">return this.self();
}
@Nonnull
class="kw">public S metadata(Metadata var1) {
if (this.metadata == null) {
this.metadata = new ObjectArrayList();
}
this.metadata.add(var1);
class="kw">return this.self();
}
@Nonnull
class="kw">public S codecVersion(int var1, int var2) {
this.minCodecVersion = var1;
this.codecVersion = var2;
class="kw">return this.self();
}
@Nonnull
class="kw">public S codecVersion(int var1) {
this.minCodecVersion = 0;
this.codecVersion = var1;
class="kw">return this.self();
}
@Nonnull
class="kw">public BuilderCodec<T> build() {
class="kw">return new BuilderCodec<>(this);
}
}
class="kw">protected enum EntryType {
FIELD,
IGNORE,
IGNORE_IN_BASE_OBJECT;
EntryType() {
}
}
class="kw">protected class="kw">static class KeyEntry<T> {
class="kw">private class="kw">final BuilderCodec.EntryType type;
@Nullable
class="kw">private class="kw">final List<BuilderField<T, ?>> fields;
class="kw">public KeyEntry(BuilderCodec.EntryType var1) {
this.type = var1;
this.fields = null;
}
class="kw">public KeyEntry(List<BuilderField<T, ?>> var1) {
this.type = BuilderCodec.EntryType.FIELD;
this.fields = var1;
}
class="kw">public BuilderCodec.EntryType getType() {
class="kw">return this.type;
}
@Nullable
class="kw">public List<BuilderField<T, ?>> getFields() {
class="kw">return this.fields;
}
}
}