// 
// Decompiled by Procyon v0.6.0
// 

package com.hypixel.hytale.server.core;

import java.lang.invoke.CallSite;
import java.lang.reflect.UndeclaredThrowableException;
import java.lang.invoke.MethodHandle;
import java.lang.runtime.SwitchBootstraps;
import java.lang.invoke.MethodType;
import java.lang.invoke.MethodHandles;
import com.hypixel.hytale.codec.schema.config.NullSchema;
import org.bson.BsonNull;
import com.hypixel.hytale.codec.schema.config.StringSchema;
import com.hypixel.hytale.codec.schema.config.IntegerSchema;
import com.hypixel.hytale.codec.schema.config.NumberSchema;
import com.hypixel.hytale.codec.schema.config.BooleanSchema;
import com.hypixel.hytale.codec.schema.config.Schema;
import com.hypixel.hytale.codec.schema.SchemaContext;
import org.bson.BsonInt64;
import org.bson.BsonInt32;
import org.bson.BsonDouble;
import org.bson.BsonBoolean;
import org.bson.BsonString;
import java.util.Objects;
import org.bson.BsonValue;
import java.io.IOException;
import com.hypixel.hytale.sneakythrow.SneakyThrow;
import com.hypixel.hytale.codec.ExtraInfo;
import com.hypixel.hytale.codec.EmptyExtraInfo;
import com.hypixel.hytale.codec.util.RawJsonReader;
import java.util.Map;
import com.hypixel.hytale.server.core.util.MessageUtil;
import com.hypixel.hytale.server.core.modules.i18n.I18nModule;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import java.util.Collections;
import javax.annotation.Nullable;
import java.util.Iterator;
import java.util.List;
import java.util.Arrays;
import com.hypixel.hytale.common.util.ArrayUtil;
import com.hypixel.hytale.server.core.asset.util.ColorParseUtil;
import java.awt.Color;
import com.hypixel.hytale.protocol.LongParamValue;
import com.hypixel.hytale.protocol.IntParamValue;
import com.hypixel.hytale.protocol.DoubleParamValue;
import com.hypixel.hytale.protocol.BoolParamValue;
import com.hypixel.hytale.protocol.StringParamValue;
import java.util.HashMap;
import javax.annotation.Nonnull;
import com.hypixel.hytale.codec.function.FunctionCodec;
import com.hypixel.hytale.protocol.MaybeBool;
import com.hypixel.hytale.protocol.ParamValue;
import com.hypixel.hytale.codec.Codec;
import com.hypixel.hytale.protocol.FormattedMessage;
import com.hypixel.hytale.codec.builder.BuilderCodec;

public class Message
{
    private static final BuilderCodec.Builder<FormattedMessage> MESSAGE_CODEC_BUILDER;
    private static final BuilderCodec<FormattedMessage> MESSAGE_CODEC;
    private static final Codec<ParamValue> PARAM_CODEC;
    private static final Codec<MaybeBool> MAYBE_BOOL_CODEC;
    public static final FunctionCodec<FormattedMessage, Message> CODEC;
    private final FormattedMessage message;
    
    protected Message(@Nonnull final String message, final boolean i18n) {
        this();
        if (i18n) {
            this.message.messageId = message;
        }
        else {
            this.message.rawText = message;
        }
    }
    
    protected Message() {
        this.message = new FormattedMessage();
    }
    
    public Message(@Nonnull final FormattedMessage message) {
        this.message = message;
    }
    
    @Nonnull
    public Message param(@Nonnull final String key, @Nonnull final String value) {
        if (this.message.params == null) {
            this.message.params = new HashMap<String, ParamValue>();
        }
        final StringParamValue val = new StringParamValue();
        val.value = value;
        this.message.params.put(key, val);
        return this;
    }
    
    @Nonnull
    public Message param(@Nonnull final String key, final boolean value) {
        if (this.message.params == null) {
            this.message.params = new HashMap<String, ParamValue>();
        }
        final BoolParamValue val = new BoolParamValue();
        val.value = value;
        this.message.params.put(key, val);
        return this;
    }
    
    @Nonnull
    public Message param(@Nonnull final String key, final double value) {
        if (this.message.params == null) {
            this.message.params = new HashMap<String, ParamValue>();
        }
        final DoubleParamValue val = new DoubleParamValue();
        val.value = value;
        this.message.params.put(key, val);
        return this;
    }
    
    @Nonnull
    public Message param(@Nonnull final String key, final int value) {
        if (this.message.params == null) {
            this.message.params = new HashMap<String, ParamValue>();
        }
        final IntParamValue val = new IntParamValue();
        val.value = value;
        this.message.params.put(key, val);
        return this;
    }
    
    @Nonnull
    public Message param(@Nonnull final String key, final long value) {
        if (this.message.params == null) {
            this.message.params = new HashMap<String, ParamValue>();
        }
        final LongParamValue val = new LongParamValue();
        val.value = value;
        this.message.params.put(key, val);
        return this;
    }
    
    @Nonnull
    public Message param(@Nonnull final String key, final float value) {
        if (this.message.params == null) {
            this.message.params = new HashMap<String, ParamValue>();
        }
        final DoubleParamValue val = new DoubleParamValue();
        val.value = value;
        this.message.params.put(key, val);
        return this;
    }
    
    @Nonnull
    public Message param(@Nonnull final String key, @Nonnull final Message formattedMessage) {
        if (this.message.messageParams == null) {
            this.message.messageParams = new HashMap<String, FormattedMessage>();
        }
        this.message.messageParams.put(key, formattedMessage.message);
        return this;
    }
    
    @Nonnull
    public Message bold(final boolean bold) {
        this.message.bold = (bold ? MaybeBool.True : MaybeBool.False);
        return this;
    }
    
    @Nonnull
    public Message italic(final boolean italic) {
        this.message.italic = (italic ? MaybeBool.True : MaybeBool.False);
        return this;
    }
    
    @Nonnull
    public Message monospace(final boolean monospace) {
        this.message.monospace = (monospace ? MaybeBool.True : MaybeBool.False);
        return this;
    }
    
    @Nonnull
    public Message color(@Nonnull final String color) {
        this.message.color = color;
        return this;
    }
    
    @Nonnull
    public Message color(@Nonnull final Color color) {
        this.message.color = ColorParseUtil.colorToHex(color);
        return this;
    }
    
    @Nonnull
    public Message link(@Nonnull final String url) {
        this.message.link = url;
        return this;
    }
    
    @Nonnull
    public Message insert(@Nonnull final Message formattedMessage) {
        this.message.children = ArrayUtil.append(this.message.children, formattedMessage.message);
        return this;
    }
    
    @Nonnull
    public Message insert(@Nonnull final String message) {
        return this.insert(raw(message));
    }
    
    @Nonnull
    public Message insertAll(@Nonnull final Message... formattedMessages) {
        int offset = 0;
        if (this.message.children != null) {
            offset = this.message.children.length;
            this.message.children = Arrays.copyOf(this.message.children, this.message.children.length + formattedMessages.length);
        }
        else {
            this.message.children = new FormattedMessage[formattedMessages.length];
        }
        for (final Message formattedMessage : formattedMessages) {
            this.message.children[offset++] = formattedMessage.message;
        }
        return this;
    }
    
    @Nonnull
    public Message insertAll(@Nonnull final List<Message> formattedMessages) {
        int offset = 0;
        if (this.message.children != null) {
            offset = this.message.children.length;
            this.message.children = Arrays.copyOf(this.message.children, this.message.children.length + formattedMessages.size());
        }
        else {
            this.message.children = new FormattedMessage[formattedMessages.size()];
        }
        for (final Message formattedMessage : formattedMessages) {
            this.message.children[offset++] = formattedMessage.message;
        }
        return this;
    }
    
    @Nullable
    public String getRawText() {
        return this.message.rawText;
    }
    
    @Nullable
    public String getMessageId() {
        return this.message.messageId;
    }
    
    @Nullable
    public String getColor() {
        return this.message.color;
    }
    
    @Nonnull
    public List<Message> getChildren() {
        if (this.message.children == null) {
            return Collections.emptyList();
        }
        final List<Message> children = new ObjectArrayList<Message>();
        for (final FormattedMessage value : this.message.children) {
            children.add(new Message(value));
        }
        return children;
    }
    
    @Nonnull
    public String getAnsiMessage() {
        final String rawText = this.getRawText();
        if (rawText != null) {
            return rawText;
        }
        final String messageId = this.getMessageId();
        if (messageId == null) {
            return "";
        }
        final String message = I18nModule.get().getMessage("en-US", messageId);
        if (message != null) {
            return MessageUtil.formatText(message, this.message.params, this.message.messageParams);
        }
        final StringBuilder rawMessage = new StringBuilder(messageId);
        if (this.message.params != null) {
            rawMessage.append(this.message.params);
        }
        if (this.message.messageParams != null) {
            for (final Map.Entry<String, FormattedMessage> p : this.message.messageParams.entrySet()) {
                rawMessage.append(p.getValue()).append("=").append(new Message(p.getValue()).getAnsiMessage());
            }
        }
        return rawMessage.toString();
    }
    
    public FormattedMessage getFormattedMessage() {
        return this.message;
    }
    
    @Override
    public String toString() {
        return this.message.toString();
    }
    
    @Nonnull
    public static Message empty() {
        return new Message();
    }
    
    @Nonnull
    public static Message translation(@Nonnull final String messageId) {
        return new Message(messageId, true);
    }
    
    @Nonnull
    public static Message raw(@Nonnull final String message) {
        return new Message(message, false);
    }
    
    @Nonnull
    public static Message parse(@Nonnull final String message) {
        try {
            return Message.CODEC.decodeJson(new RawJsonReader(message.toCharArray()), EmptyExtraInfo.EMPTY);
        }
        catch (final IOException e) {
            throw SneakyThrow.sneakyThrow(e);
        }
    }
    
    @Nonnull
    public static Message join(@Nonnull final Message... messages) {
        return new Message().insertAll(messages);
    }
    
    static {
        // 
        // This method could not be decompiled.
        // 
        // Original Bytecode:
        // 
        //     2: invokedynamic   BootstrapMethod #0, get:()Ljava/util/function/Supplier;
        //     7: invokestatic    com/hypixel/hytale/codec/builder/BuilderCodec.builder:(Ljava/lang/Class;Ljava/util/function/Supplier;)Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
        //    10: putstatic       com/hypixel/hytale/server/core/Message.MESSAGE_CODEC_BUILDER:Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
        //    13: getstatic       com/hypixel/hytale/server/core/Message.MESSAGE_CODEC_BUILDER:Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
        //    16: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.build:()Lcom/hypixel/hytale/codec/builder/BuilderCodec;
        //    19: putstatic       com/hypixel/hytale/server/core/Message.MESSAGE_CODEC:Lcom/hypixel/hytale/codec/builder/BuilderCodec;
        //    22: new             Lcom/hypixel/hytale/server/core/Message$ParamValueCodec;
        //    25: dup            
        //    26: invokespecial   com/hypixel/hytale/server/core/Message$ParamValueCodec.<init>:()V
        //    29: putstatic       com/hypixel/hytale/server/core/Message.PARAM_CODEC:Lcom/hypixel/hytale/codec/Codec;
        //    32: new             Lcom/hypixel/hytale/server/core/Message$MaybeBoolCodec;
        //    35: dup            
        //    36: invokespecial   com/hypixel/hytale/server/core/Message$MaybeBoolCodec.<init>:()V
        //    39: putstatic       com/hypixel/hytale/server/core/Message.MAYBE_BOOL_CODEC:Lcom/hypixel/hytale/codec/Codec;
        //    42: getstatic       com/hypixel/hytale/server/core/Message.MESSAGE_CODEC_BUILDER:Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
        //    45: new             Lcom/hypixel/hytale/codec/KeyedCodec;
        //    48: dup            
        //    49: ldc_w           "RawText"
        //    52: getstatic       com/hypixel/hytale/codec/Codec.STRING:Lcom/hypixel/hytale/codec/codecs/simple/StringCodec;
        //    55: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
        //    58: invokedynamic   BootstrapMethod #1, accept:()Ljava/util/function/BiConsumer;
        //    63: invokedynamic   BootstrapMethod #2, apply:()Ljava/util/function/Function;
        //    68: invokedynamic   BootstrapMethod #3, accept:()Ljava/util/function/BiConsumer;
        //    73: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.appendInherited:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;Ljava/util/function/BiConsumer;)Lcom/hypixel/hytale/codec/builder/BuilderField$FieldBuilder;
        //    76: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.add:()Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
        //    79: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
        //    82: new             Lcom/hypixel/hytale/codec/KeyedCodec;
        //    85: dup            
        //    86: ldc_w           "MessageId"
        //    89: getstatic       com/hypixel/hytale/codec/Codec.STRING:Lcom/hypixel/hytale/codec/codecs/simple/StringCodec;
        //    92: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
        //    95: invokedynamic   BootstrapMethod #4, accept:()Ljava/util/function/BiConsumer;
        //   100: invokedynamic   BootstrapMethod #5, apply:()Ljava/util/function/Function;
        //   105: invokedynamic   BootstrapMethod #6, accept:()Ljava/util/function/BiConsumer;
        //   110: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.appendInherited:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;Ljava/util/function/BiConsumer;)Lcom/hypixel/hytale/codec/builder/BuilderField$FieldBuilder;
        //   113: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.add:()Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
        //   116: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
        //   119: new             Lcom/hypixel/hytale/codec/KeyedCodec;
        //   122: dup            
        //   123: ldc_w           "Params"
        //   126: new             Lcom/hypixel/hytale/codec/codecs/map/MapCodec;
        //   129: dup            
        //   130: getstatic       com/hypixel/hytale/server/core/Message.PARAM_CODEC:Lcom/hypixel/hytale/codec/Codec;
        //   133: invokedynamic   BootstrapMethod #7, get:()Ljava/util/function/Supplier;
        //   138: invokespecial   com/hypixel/hytale/codec/codecs/map/MapCodec.<init>:(Lcom/hypixel/hytale/codec/Codec;Ljava/util/function/Supplier;)V
        //   141: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
        //   144: invokedynamic   BootstrapMethod #8, accept:()Ljava/util/function/BiConsumer;
        //   149: invokedynamic   BootstrapMethod #9, apply:()Ljava/util/function/Function;
        //   154: invokedynamic   BootstrapMethod #10, accept:()Ljava/util/function/BiConsumer;
        //   159: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.appendInherited:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;Ljava/util/function/BiConsumer;)Lcom/hypixel/hytale/codec/builder/BuilderField$FieldBuilder;
        //   162: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.add:()Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
        //   165: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
        //   168: new             Lcom/hypixel/hytale/codec/KeyedCodec;
        //   171: dup            
        //   172: ldc_w           "MessageParams"
        //   175: new             Lcom/hypixel/hytale/codec/codecs/map/MapCodec;
        //   178: dup            
        //   179: getstatic       com/hypixel/hytale/server/core/Message.MESSAGE_CODEC:Lcom/hypixel/hytale/codec/builder/BuilderCodec;
        //   182: invokedynamic   BootstrapMethod #7, get:()Ljava/util/function/Supplier;
        //   187: invokespecial   com/hypixel/hytale/codec/codecs/map/MapCodec.<init>:(Lcom/hypixel/hytale/codec/Codec;Ljava/util/function/Supplier;)V
        //   190: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
        //   193: invokedynamic   BootstrapMethod #11, accept:()Ljava/util/function/BiConsumer;
        //   198: invokedynamic   BootstrapMethod #12, apply:()Ljava/util/function/Function;
        //   203: invokedynamic   BootstrapMethod #13, accept:()Ljava/util/function/BiConsumer;
        //   208: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.appendInherited:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;Ljava/util/function/BiConsumer;)Lcom/hypixel/hytale/codec/builder/BuilderField$FieldBuilder;
        //   211: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.add:()Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
        //   214: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
        //   217: new             Lcom/hypixel/hytale/codec/KeyedCodec;
        //   220: dup            
        //   221: ldc_w           "Children"
        //   224: new             Lcom/hypixel/hytale/codec/codecs/array/ArrayCodec;
        //   227: dup            
        //   228: getstatic       com/hypixel/hytale/server/core/Message.MESSAGE_CODEC:Lcom/hypixel/hytale/codec/builder/BuilderCodec;
        //   231: invokedynamic   BootstrapMethod #14, apply:()Ljava/util/function/IntFunction;
        //   236: invokespecial   com/hypixel/hytale/codec/codecs/array/ArrayCodec.<init>:(Lcom/hypixel/hytale/codec/Codec;Ljava/util/function/IntFunction;)V
        //   239: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
        //   242: invokedynamic   BootstrapMethod #15, accept:()Ljava/util/function/BiConsumer;
        //   247: invokedynamic   BootstrapMethod #16, apply:()Ljava/util/function/Function;
        //   252: invokedynamic   BootstrapMethod #17, accept:()Ljava/util/function/BiConsumer;
        //   257: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.appendInherited:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;Ljava/util/function/BiConsumer;)Lcom/hypixel/hytale/codec/builder/BuilderField$FieldBuilder;
        //   260: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.add:()Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
        //   263: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
        //   266: new             Lcom/hypixel/hytale/codec/KeyedCodec;
        //   269: dup            
        //   270: ldc_w           "Bold"
        //   273: getstatic       com/hypixel/hytale/server/core/Message.MAYBE_BOOL_CODEC:Lcom/hypixel/hytale/codec/Codec;
        //   276: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
        //   279: invokedynamic   BootstrapMethod #18, accept:()Ljava/util/function/BiConsumer;
        //   284: invokedynamic   BootstrapMethod #19, apply:()Ljava/util/function/Function;
        //   289: invokedynamic   BootstrapMethod #20, accept:()Ljava/util/function/BiConsumer;
        //   294: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.appendInherited:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;Ljava/util/function/BiConsumer;)Lcom/hypixel/hytale/codec/builder/BuilderField$FieldBuilder;
        //   297: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.add:()Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
        //   300: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
        //   303: new             Lcom/hypixel/hytale/codec/KeyedCodec;
        //   306: dup            
        //   307: ldc_w           "Italic"
        //   310: getstatic       com/hypixel/hytale/server/core/Message.MAYBE_BOOL_CODEC:Lcom/hypixel/hytale/codec/Codec;
        //   313: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
        //   316: invokedynamic   BootstrapMethod #21, accept:()Ljava/util/function/BiConsumer;
        //   321: invokedynamic   BootstrapMethod #22, apply:()Ljava/util/function/Function;
        //   326: invokedynamic   BootstrapMethod #23, accept:()Ljava/util/function/BiConsumer;
        //   331: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.appendInherited:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;Ljava/util/function/BiConsumer;)Lcom/hypixel/hytale/codec/builder/BuilderField$FieldBuilder;
        //   334: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.add:()Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
        //   337: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
        //   340: new             Lcom/hypixel/hytale/codec/KeyedCodec;
        //   343: dup            
        //   344: ldc_w           "Monospace"
        //   347: getstatic       com/hypixel/hytale/server/core/Message.MAYBE_BOOL_CODEC:Lcom/hypixel/hytale/codec/Codec;
        //   350: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
        //   353: invokedynamic   BootstrapMethod #24, accept:()Ljava/util/function/BiConsumer;
        //   358: invokedynamic   BootstrapMethod #25, apply:()Ljava/util/function/Function;
        //   363: invokedynamic   BootstrapMethod #26, accept:()Ljava/util/function/BiConsumer;
        //   368: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.appendInherited:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;Ljava/util/function/BiConsumer;)Lcom/hypixel/hytale/codec/builder/BuilderField$FieldBuilder;
        //   371: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.add:()Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
        //   374: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
        //   377: new             Lcom/hypixel/hytale/codec/KeyedCodec;
        //   380: dup            
        //   381: ldc_w           "Underline"
        //   384: getstatic       com/hypixel/hytale/server/core/Message.MAYBE_BOOL_CODEC:Lcom/hypixel/hytale/codec/Codec;
        //   387: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
        //   390: invokedynamic   BootstrapMethod #27, accept:()Ljava/util/function/BiConsumer;
        //   395: invokedynamic   BootstrapMethod #28, apply:()Ljava/util/function/Function;
        //   400: invokedynamic   BootstrapMethod #29, accept:()Ljava/util/function/BiConsumer;
        //   405: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.appendInherited:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;Ljava/util/function/BiConsumer;)Lcom/hypixel/hytale/codec/builder/BuilderField$FieldBuilder;
        //   408: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.add:()Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
        //   411: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
        //   414: new             Lcom/hypixel/hytale/codec/KeyedCodec;
        //   417: dup            
        //   418: ldc_w           "Color"
        //   421: getstatic       com/hypixel/hytale/codec/Codec.STRING:Lcom/hypixel/hytale/codec/codecs/simple/StringCodec;
        //   424: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
        //   427: invokedynamic   BootstrapMethod #30, accept:()Ljava/util/function/BiConsumer;
        //   432: invokedynamic   BootstrapMethod #31, apply:()Ljava/util/function/Function;
        //   437: invokedynamic   BootstrapMethod #32, accept:()Ljava/util/function/BiConsumer;
        //   442: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.appendInherited:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;Ljava/util/function/BiConsumer;)Lcom/hypixel/hytale/codec/builder/BuilderField$FieldBuilder;
        //   445: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.add:()Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
        //   448: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
        //   451: new             Lcom/hypixel/hytale/codec/KeyedCodec;
        //   454: dup            
        //   455: ldc_w           "Link"
        //   458: getstatic       com/hypixel/hytale/codec/Codec.STRING:Lcom/hypixel/hytale/codec/codecs/simple/StringCodec;
        //   461: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
        //   464: invokedynamic   BootstrapMethod #33, accept:()Ljava/util/function/BiConsumer;
        //   469: invokedynamic   BootstrapMethod #34, apply:()Ljava/util/function/Function;
        //   474: invokedynamic   BootstrapMethod #35, accept:()Ljava/util/function/BiConsumer;
        //   479: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.appendInherited:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;Ljava/util/function/BiConsumer;)Lcom/hypixel/hytale/codec/builder/BuilderField$FieldBuilder;
        //   482: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.add:()Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
        //   485: pop            
        //   486: new             Lcom/hypixel/hytale/codec/function/FunctionCodec;
        //   489: dup            
        //   490: getstatic       com/hypixel/hytale/server/core/Message.MESSAGE_CODEC:Lcom/hypixel/hytale/codec/builder/BuilderCodec;
        //   493: invokedynamic   BootstrapMethod #36, apply:()Ljava/util/function/Function;
        //   498: invokedynamic   BootstrapMethod #37, apply:()Ljava/util/function/Function;
        //   503: invokespecial   com/hypixel/hytale/codec/function/FunctionCodec.<init>:(Lcom/hypixel/hytale/codec/Codec;Ljava/util/function/Function;Ljava/util/function/Function;)V
        //   506: putstatic       com/hypixel/hytale/server/core/Message.CODEC:Lcom/hypixel/hytale/codec/function/FunctionCodec;
        //   509: return         
        // 
        // The error that occurred was:
        // 
        // java.lang.UnsupportedOperationException: The requested operation is not supported.
        //     at com.strobel.util.ContractUtils.unsupported(ContractUtils.java:27)
        //     at com.strobel.assembler.metadata.TypeReference.getRawType(TypeReference.java:284)
        //     at com.strobel.assembler.metadata.TypeReference.getRawType(TypeReference.java:279)
        //     at com.strobel.assembler.metadata.TypeReference.makeGenericType(TypeReference.java:154)
        //     at com.strobel.assembler.metadata.TypeSubstitutionVisitor.visitClassType(TypeSubstitutionVisitor.java:267)
        //     at com.strobel.assembler.metadata.TypeSubstitutionVisitor.visitClassType(TypeSubstitutionVisitor.java:25)
        //     at com.strobel.assembler.metadata.TypeDefinition.accept(TypeDefinition.java:189)
        //     at com.strobel.assembler.metadata.TypeSubstitutionVisitor.visit(TypeSubstitutionVisitor.java:40)
        //     at com.strobel.assembler.metadata.TypeSubstitutionVisitor.visitMethod(TypeSubstitutionVisitor.java:324)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2586)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:790)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2689)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1510)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:790)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2689)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:790)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2689)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1510)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:790)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2689)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:790)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2689)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1510)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:790)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2689)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:790)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2689)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1510)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:790)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2689)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:790)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2689)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1510)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:790)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2689)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2483)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1510)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2483)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2483)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1510)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2483)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2483)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1510)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2483)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2483)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1510)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2483)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2483)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.runInference(TypeAnalysis.java:684)
        //     at com.strobel.decompiler.ast.TypeAnalysis.runInference(TypeAnalysis.java:667)
        //     at com.strobel.decompiler.ast.TypeAnalysis.runInference(TypeAnalysis.java:373)
        //     at com.strobel.decompiler.ast.TypeAnalysis.run(TypeAnalysis.java:95)
        //     at com.strobel.decompiler.ast.AstOptimizer.optimize(AstOptimizer.java:344)
        //     at com.strobel.decompiler.ast.AstOptimizer.optimize(AstOptimizer.java:42)
        //     at com.strobel.decompiler.languages.java.ast.AstMethodBodyBuilder.createMethodBody(AstMethodBodyBuilder.java:206)
        //     at com.strobel.decompiler.languages.java.ast.AstMethodBodyBuilder.createMethodBody(AstMethodBodyBuilder.java:93)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createMethodBody(AstBuilder.java:868)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createMethod(AstBuilder.java:761)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.addTypeMembers(AstBuilder.java:638)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createTypeCore(AstBuilder.java:605)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createTypeNoCache(AstBuilder.java:195)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createType(AstBuilder.java:162)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.addType(AstBuilder.java:137)
        //     at com.strobel.decompiler.languages.java.JavaLanguage.buildAst(JavaLanguage.java:71)
        //     at com.strobel.decompiler.languages.java.JavaLanguage.decompileType(JavaLanguage.java:59)
        //     at com.strobel.decompiler.DecompilerDriver.decompileType(DecompilerDriver.java:333)
        //     at com.strobel.decompiler.DecompilerDriver.decompileJar(DecompilerDriver.java:254)
        //     at com.strobel.decompiler.DecompilerDriver.main(DecompilerDriver.java:129)
        // 
        throw new IllegalStateException("An error occurred while decompiling this method.");
    }
    
    private static class ParamValueCodec implements Codec<ParamValue>
    {
        @Nullable
        @Override
        public ParamValue decode(final BsonValue bsonValue, final ExtraInfo extraInfo) {
            return switch (bsonValue.getBsonType()) {
                case DOUBLE -> {
                    final DoubleParamValue value = new DoubleParamValue();
                    value.value = bsonValue.asDouble().getValue();
                    yield value;
                }
                case STRING -> {
                    final StringParamValue value2 = new StringParamValue();
                    value2.value = bsonValue.asString().getValue();
                    yield value2;
                }
                case BOOLEAN -> {
                    final BoolParamValue value3 = new BoolParamValue();
                    value3.value = bsonValue.asBoolean().getValue();
                    yield value3;
                }
                case INT32 -> {
                    final IntParamValue value4 = new IntParamValue();
                    value4.value = bsonValue.asInt32().getValue();
                    yield value4;
                }
                case INT64 -> {
                    final LongParamValue value5 = new LongParamValue();
                    value5.value = bsonValue.asInt64().getValue();
                    yield value5;
                }
                default -> throw new IllegalArgumentException("Unsupported bson type: " + String.valueOf(bsonValue.getBsonType()));
            };
        }
        
        @Override
        public BsonValue encode(final ParamValue paramValue, final ExtraInfo extraInfo) {
            Objects.requireNonNull(paramValue);
            return switch (/* invokedynamic(!) */ProcyonInvokeDynamicHelper_7.invoke(paramValue, false)) {
                case 0 -> {
                    final StringParamValue s = (StringParamValue)paramValue;
                    yield new BsonString(s.value);
                }
                case 1 -> {
                    final BoolParamValue b = (BoolParamValue)paramValue;
                    yield BsonBoolean.valueOf(b.value);
                }
                case 2 -> {
                    final DoubleParamValue d = (DoubleParamValue)paramValue;
                    yield new BsonDouble(d.value);
                }
                case 3 -> {
                    final IntParamValue i = (IntParamValue)paramValue;
                    yield new BsonInt32(i.value);
                }
                case 4 -> {
                    final LongParamValue l = (LongParamValue)paramValue;
                    yield new BsonInt64(l.value);
                }
                default -> throw new IllegalArgumentException("Unknown ParamValue type: " + String.valueOf(paramValue.getClass()));
            };
        }
        
        @Nullable
        @Override
        public ParamValue decodeJson(@Nonnull final RawJsonReader reader, final ExtraInfo extraInfo) throws IOException {
            if (reader.peekFor('\"')) {
                final StringParamValue param = new StringParamValue();
                param.value = reader.readString();
                return param;
            }
            if (!reader.peekFor('f') && !reader.peekFor('t')) {
                final double value = reader.readDoubleValue();
                final DoubleParamValue param2 = new DoubleParamValue();
                param2.value = value;
                return param2;
            }
            if (!reader.tryConsume("false")) {
                throw new IllegalArgumentException("Invalid boolean value");
            }
            final BoolParamValue param3 = new BoolParamValue();
            param3.value = reader.readBooleanValue();
            return param3;
        }
        
        @Nonnull
        @Override
        public Schema toSchema(@Nonnull final SchemaContext context) {
            return Schema.anyOf(new BooleanSchema(), new NumberSchema(), new IntegerSchema(), new StringSchema());
        }
        
        // This helper class was generated by Procyon to approximate the behavior of an
        // 'invokedynamic' instruction that it doesn't know how to interpret.
        private static final class ProcyonInvokeDynamicHelper_7
        {
            private static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup();
            private static MethodHandle handle;
            private static volatile int fence;
            
            private static MethodHandle handle() {
                final MethodHandle handle = ProcyonInvokeDynamicHelper_7.handle;
                if (handle != null)
                    return handle;
                return ProcyonInvokeDynamicHelper_7.ensureHandle();
            }
            
            private static MethodHandle ensureHandle() {
                ProcyonInvokeDynamicHelper_7.fence = 0;
                MethodHandle handle = ProcyonInvokeDynamicHelper_7.handle;
                if (handle == null) {
                    MethodHandles.Lookup lookup = ProcyonInvokeDynamicHelper_7.LOOKUP;
                    try {
                        handle = ((CallSite)SwitchBootstraps.typeSwitch(lookup, "typeSwitch", MethodType.methodType(int.class, Object.class, int.class), StringParamValue.class, BoolParamValue.class, DoubleParamValue.class, IntParamValue.class, LongParamValue.class)).dynamicInvoker();
                    }
                    catch (Throwable t) {
                        throw new UndeclaredThrowableException(t);
                    }
                    ProcyonInvokeDynamicHelper_7.fence = 1;
                    ProcyonInvokeDynamicHelper_7.handle = handle;
                    ProcyonInvokeDynamicHelper_7.fence = 0;
                }
                return handle;
            }
            
            private static int invoke(Object p0, int p1) {
                try {
                    return ProcyonInvokeDynamicHelper_7.handle().invokeExact(p0, p1);
                }
                catch (Throwable t) {
                    throw new UndeclaredThrowableException(t);
                }
            }
        }
    }
    
    private static class MaybeBoolCodec implements Codec<MaybeBool>
    {
        @Nullable
        @Override
        public MaybeBool decode(final BsonValue bsonValue, final ExtraInfo extraInfo) {
            if (bsonValue.isNull()) {
                return MaybeBool.Null;
            }
            return bsonValue.asBoolean().getValue() ? MaybeBool.True : MaybeBool.False;
        }
        
        @Override
        public BsonValue encode(final MaybeBool maybeBool, final ExtraInfo extraInfo) {
            return switch (maybeBool) {
                default -> throw new MatchException(null, null);
                case Null -> BsonNull.VALUE;
                case False -> BsonBoolean.FALSE;
                case True -> BsonBoolean.TRUE;
            };
        }
        
        @Nullable
        @Override
        public MaybeBool decodeJson(@Nonnull final RawJsonReader reader, final ExtraInfo extraInfo) throws IOException {
            if (reader.peekFor('n')) {
                if (!reader.tryConsume("null")) {
                    throw new IllegalArgumentException("Invalid null value");
                }
                return MaybeBool.Null;
            }
            else {
                if (!reader.peekFor('N')) {
                    return reader.readBooleanValue() ? MaybeBool.True : MaybeBool.False;
                }
                if (!reader.tryConsume("NULL")) {
                    throw new IllegalArgumentException("Invalid null value");
                }
                return MaybeBool.Null;
            }
        }
        
        @Nonnull
        @Override
        public Schema toSchema(@Nonnull final SchemaContext context) {
            return Schema.anyOf(new BooleanSchema(), new NullSchema());
        }
    }
}
