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

package io.netty.handler.codec.quic;

import io.netty.util.internal.ClassInitializerUtil;
import io.netty.util.internal.logging.InternalLoggerFactory;
import javax.net.ssl.SSLException;
import javax.net.ssl.SSLHandshakeException;
import java.nio.ByteOrder;
import io.netty.buffer.Unpooled;
import io.netty.buffer.ByteBuf;
import java.nio.ByteBuffer;
import org.jetbrains.annotations.Nullable;
import io.netty.util.internal.NativeLibraryLoader;
import io.netty.util.internal.PlatformDependent;
import io.netty.util.collection.IntObjectHashMap;
import io.netty.util.internal.logging.InternalLogger;

final class Quiche
{
    private static final InternalLogger logger;
    private static final boolean TRACE_LOGGING_ENABLED;
    private static final IntObjectHashMap<QuicTransportErrorHolder> ERROR_MAPPINGS;
    static final short AF_INET;
    static final short AF_INET6;
    static final int SIZEOF_SOCKADDR_STORAGE;
    static final int SIZEOF_SOCKADDR_IN;
    static final int SIZEOF_SOCKADDR_IN6;
    static final int SOCKADDR_IN_OFFSETOF_SIN_FAMILY;
    static final int SOCKADDR_IN_OFFSETOF_SIN_PORT;
    static final int SOCKADDR_IN_OFFSETOF_SIN_ADDR;
    static final int IN_ADDRESS_OFFSETOF_S_ADDR;
    static final int SOCKADDR_IN6_OFFSETOF_SIN6_FAMILY;
    static final int SOCKADDR_IN6_OFFSETOF_SIN6_PORT;
    static final int SOCKADDR_IN6_OFFSETOF_SIN6_FLOWINFO;
    static final int SOCKADDR_IN6_OFFSETOF_SIN6_ADDR;
    static final int SOCKADDR_IN6_OFFSETOF_SIN6_SCOPE_ID;
    static final int IN6_ADDRESS_OFFSETOF_S6_ADDR;
    static final int SIZEOF_SOCKLEN_T;
    static final int SIZEOF_SIZE_T;
    static final int SIZEOF_TIMESPEC;
    static final int SIZEOF_TIME_T;
    static final int SIZEOF_LONG;
    static final int TIMESPEC_OFFSETOF_TV_SEC;
    static final int TIMESPEC_OFFSETOF_TV_NSEC;
    static final int QUICHE_RECV_INFO_OFFSETOF_FROM;
    static final int QUICHE_RECV_INFO_OFFSETOF_FROM_LEN;
    static final int QUICHE_RECV_INFO_OFFSETOF_TO;
    static final int QUICHE_RECV_INFO_OFFSETOF_TO_LEN;
    static final int SIZEOF_QUICHE_RECV_INFO;
    static final int QUICHE_SEND_INFO_OFFSETOF_TO;
    static final int QUICHE_SEND_INFO_OFFSETOF_TO_LEN;
    static final int QUICHE_SEND_INFO_OFFSETOF_FROM;
    static final int QUICHE_SEND_INFO_OFFSETOF_FROM_LEN;
    static final int QUICHE_SEND_INFO_OFFSETOF_AT;
    static final int SIZEOF_QUICHE_SEND_INFO;
    static final int QUICHE_PROTOCOL_VERSION;
    static final int QUICHE_MAX_CONN_ID_LEN;
    static final int QUICHE_SHUTDOWN_READ;
    static final int QUICHE_SHUTDOWN_WRITE;
    static final int QUICHE_ERR_DONE;
    static final int QUICHE_ERR_BUFFER_TOO_SHORT;
    static final int QUICHE_ERR_UNKNOWN_VERSION;
    static final int QUICHE_ERR_INVALID_FRAME;
    static final int QUICHE_ERR_INVALID_PACKET;
    static final int QUICHE_ERR_INVALID_STATE;
    static final int QUICHE_ERR_INVALID_STREAM_STATE;
    static final int QUICHE_ERR_INVALID_TRANSPORT_PARAM;
    static final int QUICHE_ERR_CRYPTO_FAIL;
    static final int QUICHE_ERR_TLS_FAIL;
    static final int QUICHE_ERR_FLOW_CONTROL;
    static final int QUICHE_ERR_STREAM_LIMIT;
    static final int QUICHE_ERR_FINAL_SIZE;
    static final int QUICHE_ERR_CONGESTION_CONTROL;
    static final int QUICHE_ERR_STREAM_RESET;
    static final int QUICHE_ERR_STREAM_STOPPED;
    static final int QUICHE_ERR_ID_LIMIT;
    static final int QUICHE_ERR_OUT_OF_IDENTIFIERS;
    static final int QUICHE_ERR_KEY_UPDATE;
    static final int QUICHE_ERR_CRYPTO_BUFFER_EXCEEDED;
    static final int QUICHE_CC_RENO;
    static final int QUICHE_CC_CUBIC;
    static final int QUICHE_CC_BBR;
    static final int QUICHE_PATH_EVENT_NEW;
    static final int QUICHE_PATH_EVENT_VALIDATED;
    static final int QUICHE_PATH_EVENT_FAILED_VALIDATION;
    static final int QUICHE_PATH_EVENT_CLOSED;
    static final int QUICHE_PATH_EVENT_REUSED_SOURCE_CONNECTION_ID;
    static final int QUICHE_PATH_EVENT_PEER_MIGRATED;
    
    private static void loadNativeLibrary() {
        String libName = "netty_quiche42";
        final ClassLoader cl = PlatformDependent.getClassLoader(Quiche.class);
        if (!PlatformDependent.isAndroid()) {
            libName = libName + '_' + PlatformDependent.normalizedOs() + '_' + PlatformDependent.normalizedArch();
        }
        try {
            NativeLibraryLoader.load(libName, cl);
        }
        catch (final UnsatisfiedLinkError e) {
            Quiche.logger.debug("Failed to load {}", libName, e);
            throw e;
        }
    }
    
    @Nullable
    static native String quiche_version();
    
    static native boolean quiche_version_is_supported(final int p0);
    
    static native int quiche_negotiate_version(final long p0, final int p1, final long p2, final int p3, final long p4, final int p5);
    
    static native int quiche_retry(final long p0, final int p1, final long p2, final int p3, final long p4, final int p5, final long p6, final int p7, final int p8, final long p9, final int p10);
    
    static native long quiche_conn_new_with_tls(final long p0, final int p1, final long p2, final int p3, final long p4, final int p5, final long p6, final int p7, final long p8, final long p9, final boolean p10);
    
    static native boolean quiche_conn_set_qlog_path(final long p0, final String p1, final String p2, final String p3);
    
    static native int quiche_conn_recv(final long p0, final long p1, final int p2, final long p3);
    
    static native int quiche_conn_send(final long p0, final long p1, final int p2, final long p3);
    
    static native void quiche_conn_free(final long p0);
    
    @Nullable
    static QuicConnectionCloseEvent quiche_conn_peer_error(final long connAddr) {
        final Object[] error = quiche_conn_peer_error0(connAddr);
        if (error == null) {
            return null;
        }
        return new QuicConnectionCloseEvent((boolean)error[0], (int)error[1], (byte[])error[2]);
    }
    
    private static native Object[] quiche_conn_peer_error0(final long p0);
    
    static native long quiche_conn_peer_streams_left_bidi(final long p0);
    
    static native long quiche_conn_peer_streams_left_uni(final long p0);
    
    static native int quiche_conn_stream_priority(final long p0, final long p1, final byte p2, final boolean p3);
    
    static native int quiche_conn_send_quantum(final long p0);
    
    static native byte[] quiche_conn_trace_id(final long p0);
    
    static native byte[] quiche_conn_source_id(final long p0);
    
    static native byte[] quiche_conn_destination_id(final long p0);
    
    static native int quiche_conn_stream_recv(final long p0, final long p1, final long p2, final int p3, final long p4, final long p5);
    
    static native int quiche_conn_stream_send(final long p0, final long p1, final long p2, final int p3, final boolean p4);
    
    static native int quiche_conn_stream_shutdown(final long p0, final long p1, final int p2, final long p3);
    
    static native long quiche_conn_stream_capacity(final long p0, final long p1);
    
    static native boolean quiche_conn_stream_finished(final long p0, final long p1);
    
    static native int quiche_conn_close(final long p0, final boolean p1, final long p2, final long p3, final int p4);
    
    static native boolean quiche_conn_is_established(final long p0);
    
    static native boolean quiche_conn_is_in_early_data(final long p0);
    
    static native boolean quiche_conn_is_closed(final long p0);
    
    static native boolean quiche_conn_is_timed_out(final long p0);
    
    static native long[] quiche_conn_stats(final long p0);
    
    static native long[] quiche_conn_peer_transport_params(final long p0);
    
    static native long quiche_conn_timeout_as_nanos(final long p0);
    
    static native void quiche_conn_on_timeout(final long p0);
    
    static native long quiche_conn_readable(final long p0);
    
    static native long quiche_conn_writable(final long p0);
    
    static native int quiche_stream_iter_next(final long p0, final long[] p1);
    
    static native void quiche_stream_iter_free(final long p0);
    
    static native Object[] quiche_conn_path_stats(final long p0, final long p1);
    
    static native int quiche_conn_dgram_max_writable_len(final long p0);
    
    static native int quiche_conn_dgram_recv_front_len(final long p0);
    
    static native int quiche_conn_dgram_recv(final long p0, final long p1, final int p2);
    
    static native int quiche_conn_dgram_send(final long p0, final long p1, final int p2);
    
    static native int quiche_conn_set_session(final long p0, final byte[] p1);
    
    static native int quiche_conn_max_send_udp_payload_size(final long p0);
    
    static native int quiche_conn_scids_left(final long p0);
    
    static native long quiche_conn_new_scid(final long p0, final long p1, final int p2, final byte[] p3, final boolean p4, final long p5);
    
    static native byte[] quiche_conn_retired_scid_next(final long p0);
    
    static native long quiche_conn_path_event_next(final long p0);
    
    static native int quiche_path_event_type(final long p0);
    
    static native void quiche_path_event_free(final long p0);
    
    static native Object[] quiche_path_event_new(final long p0);
    
    static native Object[] quiche_path_event_validated(final long p0);
    
    static native Object[] quiche_path_event_failed_validation(final long p0);
    
    static native Object[] quiche_path_event_closed(final long p0);
    
    static native Object[] quiche_path_event_reused_source_connection_id(final long p0);
    
    static native Object[] quiche_path_event_peer_migrated(final long p0);
    
    static native long quiche_config_new(final int p0);
    
    static native void quiche_config_grease(final long p0, final boolean p1);
    
    static native void quiche_config_set_max_idle_timeout(final long p0, final long p1);
    
    static native void quiche_config_set_max_recv_udp_payload_size(final long p0, final long p1);
    
    static native void quiche_config_set_max_send_udp_payload_size(final long p0, final long p1);
    
    static native void quiche_config_set_initial_max_data(final long p0, final long p1);
    
    static native void quiche_config_set_initial_max_stream_data_bidi_local(final long p0, final long p1);
    
    static native void quiche_config_set_initial_max_stream_data_bidi_remote(final long p0, final long p1);
    
    static native void quiche_config_set_initial_max_stream_data_uni(final long p0, final long p1);
    
    static native void quiche_config_set_initial_max_streams_bidi(final long p0, final long p1);
    
    static native void quiche_config_set_initial_max_streams_uni(final long p0, final long p1);
    
    static native void quiche_config_set_ack_delay_exponent(final long p0, final long p1);
    
    static native void quiche_config_set_max_ack_delay(final long p0, final long p1);
    
    static native void quiche_config_set_disable_active_migration(final long p0, final boolean p1);
    
    static native void quiche_config_set_cc_algorithm(final long p0, final int p1);
    
    static native void quiche_config_set_initial_congestion_window_packets(final long p0, final int p1);
    
    static native void quiche_config_enable_hystart(final long p0, final boolean p1);
    
    static native void quiche_config_discover_pmtu(final long p0, final boolean p1);
    
    static native void quiche_config_enable_dgram(final long p0, final boolean p1, final int p2, final int p3);
    
    static native void quiche_config_set_active_connection_id_limit(final long p0, final long p1);
    
    static native void quiche_config_set_stateless_reset_token(final long p0, final byte[] p1);
    
    static native void quiche_config_free(final long p0);
    
    private static native void quiche_enable_debug_logging(final QuicheLogger p0);
    
    private static native long buffer_memory_address(final ByteBuffer p0);
    
    static native int sockaddr_cmp(final long p0, final long p1);
    
    static long readerMemoryAddress(final ByteBuf buf) {
        return memoryAddress(buf, buf.readerIndex(), buf.readableBytes());
    }
    
    static long writerMemoryAddress(final ByteBuf buf) {
        return memoryAddress(buf, buf.writerIndex(), buf.writableBytes());
    }
    
    static long memoryAddress(final ByteBuf buf, final int offset, final int len) {
        assert buf.isDirect();
        if (buf.hasMemoryAddress()) {
            return buf.memoryAddress() + offset;
        }
        return memoryAddressWithPosition(buf.internalNioBuffer(offset, len));
    }
    
    static long memoryAddressWithPosition(final ByteBuffer buf) {
        assert buf.isDirect();
        return buffer_memory_address(buf) + buf.position();
    }
    
    static ByteBuf allocateNativeOrder(final int capacity) {
        final ByteBuf buffer = Unpooled.directBuffer(capacity);
        return PlatformDependent.BIG_ENDIAN_NATIVE_ORDER ? buffer : buffer.order(ByteOrder.LITTLE_ENDIAN);
    }
    
    static boolean shouldClose(final int res) {
        return res == Quiche.QUICHE_ERR_CRYPTO_FAIL || res == Quiche.QUICHE_ERR_TLS_FAIL;
    }
    
    static boolean isSameAddress(final ByteBuffer memory, final ByteBuffer memory2, final int addressOffset) {
        final long address1 = memoryAddressWithPosition(memory) + addressOffset;
        final long address2 = memoryAddressWithPosition(memory2) + addressOffset;
        return SockaddrIn.cmp(address1, address2) == 0;
    }
    
    static void setPrimitiveValue(final ByteBuffer memory, final int offset, final int valueType, final long value) {
        switch (valueType) {
            case 1: {
                memory.put(offset, (byte)value);
                break;
            }
            case 2: {
                memory.putShort(offset, (short)value);
                break;
            }
            case 4: {
                memory.putInt(offset, (int)value);
                break;
            }
            case 8: {
                memory.putLong(offset, value);
                break;
            }
            default: {
                throw new IllegalStateException();
            }
        }
    }
    
    static long getPrimitiveValue(final ByteBuffer memory, final int offset, final int valueType) {
        switch (valueType) {
            case 1: {
                return memory.get(offset);
            }
            case 2: {
                return memory.getShort(offset);
            }
            case 4: {
                return memory.getInt(offset);
            }
            case 8: {
                return memory.getLong(offset);
            }
            default: {
                throw new IllegalStateException();
            }
        }
    }
    
    static Exception convertToException(final int result) {
        return convertToException(result, -1L);
    }
    
    static Exception convertToException(final int result, final long code) {
        final QuicTransportErrorHolder holder = Quiche.ERROR_MAPPINGS.get(result);
        if (holder == null) {
            final QuicheError error = QuicheError.valueOf(result);
            if (error == QuicheError.STREAM_RESET) {
                return new QuicStreamResetException(error.message(), code);
            }
            return new QuicException(error.message());
        }
        else {
            final Exception exception = new QuicException(holder.error + ": " + holder.quicheErrorName, holder.error);
            if (result == Quiche.QUICHE_ERR_TLS_FAIL) {
                final String lastSslError = BoringSSL.ERR_last_error();
                final SSLHandshakeException sslExc = new SSLHandshakeException(lastSslError);
                sslExc.initCause(exception);
                return sslExc;
            }
            if (result == Quiche.QUICHE_ERR_CRYPTO_FAIL) {
                return new SSLException(exception);
            }
            return exception;
        }
    }
    
    private Quiche() {
    }
    
    static {
        logger = InternalLoggerFactory.getInstance(Quiche.class);
        TRACE_LOGGING_ENABLED = Quiche.logger.isTraceEnabled();
        ERROR_MAPPINGS = new IntObjectHashMap<QuicTransportErrorHolder>();
        ClassInitializerUtil.tryLoadClasses(Quiche.class, byte[].class, String.class, BoringSSLCertificateCallback.class, BoringSSLCertificateVerifyCallback.class, BoringSSLHandshakeCompleteCallback.class, QuicheLogger.class);
        try {
            quiche_version();
        }
        catch (final UnsatisfiedLinkError ignore) {
            loadNativeLibrary();
        }
        if (Quiche.TRACE_LOGGING_ENABLED) {
            quiche_enable_debug_logging(new QuicheLogger(Quiche.logger));
        }
        AF_INET = (short)QuicheNativeStaticallyReferencedJniMethods.afInet();
        AF_INET6 = (short)QuicheNativeStaticallyReferencedJniMethods.afInet6();
        SIZEOF_SOCKADDR_STORAGE = QuicheNativeStaticallyReferencedJniMethods.sizeofSockaddrStorage();
        SIZEOF_SOCKADDR_IN = QuicheNativeStaticallyReferencedJniMethods.sizeofSockaddrIn();
        SIZEOF_SOCKADDR_IN6 = QuicheNativeStaticallyReferencedJniMethods.sizeofSockaddrIn6();
        SOCKADDR_IN_OFFSETOF_SIN_FAMILY = QuicheNativeStaticallyReferencedJniMethods.sockaddrInOffsetofSinFamily();
        SOCKADDR_IN_OFFSETOF_SIN_PORT = QuicheNativeStaticallyReferencedJniMethods.sockaddrInOffsetofSinPort();
        SOCKADDR_IN_OFFSETOF_SIN_ADDR = QuicheNativeStaticallyReferencedJniMethods.sockaddrInOffsetofSinAddr();
        IN_ADDRESS_OFFSETOF_S_ADDR = QuicheNativeStaticallyReferencedJniMethods.inAddressOffsetofSAddr();
        SOCKADDR_IN6_OFFSETOF_SIN6_FAMILY = QuicheNativeStaticallyReferencedJniMethods.sockaddrIn6OffsetofSin6Family();
        SOCKADDR_IN6_OFFSETOF_SIN6_PORT = QuicheNativeStaticallyReferencedJniMethods.sockaddrIn6OffsetofSin6Port();
        SOCKADDR_IN6_OFFSETOF_SIN6_FLOWINFO = QuicheNativeStaticallyReferencedJniMethods.sockaddrIn6OffsetofSin6Flowinfo();
        SOCKADDR_IN6_OFFSETOF_SIN6_ADDR = QuicheNativeStaticallyReferencedJniMethods.sockaddrIn6OffsetofSin6Addr();
        SOCKADDR_IN6_OFFSETOF_SIN6_SCOPE_ID = QuicheNativeStaticallyReferencedJniMethods.sockaddrIn6OffsetofSin6ScopeId();
        IN6_ADDRESS_OFFSETOF_S6_ADDR = QuicheNativeStaticallyReferencedJniMethods.in6AddressOffsetofS6Addr();
        SIZEOF_SOCKLEN_T = QuicheNativeStaticallyReferencedJniMethods.sizeofSocklenT();
        SIZEOF_SIZE_T = QuicheNativeStaticallyReferencedJniMethods.sizeofSizeT();
        SIZEOF_TIMESPEC = QuicheNativeStaticallyReferencedJniMethods.sizeofTimespec();
        SIZEOF_TIME_T = QuicheNativeStaticallyReferencedJniMethods.sizeofTimeT();
        SIZEOF_LONG = QuicheNativeStaticallyReferencedJniMethods.sizeofLong();
        TIMESPEC_OFFSETOF_TV_SEC = QuicheNativeStaticallyReferencedJniMethods.timespecOffsetofTvSec();
        TIMESPEC_OFFSETOF_TV_NSEC = QuicheNativeStaticallyReferencedJniMethods.timespecOffsetofTvNsec();
        QUICHE_RECV_INFO_OFFSETOF_FROM = QuicheNativeStaticallyReferencedJniMethods.quicheRecvInfoOffsetofFrom();
        QUICHE_RECV_INFO_OFFSETOF_FROM_LEN = QuicheNativeStaticallyReferencedJniMethods.quicheRecvInfoOffsetofFromLen();
        QUICHE_RECV_INFO_OFFSETOF_TO = QuicheNativeStaticallyReferencedJniMethods.quicheRecvInfoOffsetofTo();
        QUICHE_RECV_INFO_OFFSETOF_TO_LEN = QuicheNativeStaticallyReferencedJniMethods.quicheRecvInfoOffsetofToLen();
        SIZEOF_QUICHE_RECV_INFO = QuicheNativeStaticallyReferencedJniMethods.sizeofQuicheRecvInfo();
        QUICHE_SEND_INFO_OFFSETOF_TO = QuicheNativeStaticallyReferencedJniMethods.quicheSendInfoOffsetofTo();
        QUICHE_SEND_INFO_OFFSETOF_TO_LEN = QuicheNativeStaticallyReferencedJniMethods.quicheSendInfoOffsetofToLen();
        QUICHE_SEND_INFO_OFFSETOF_FROM = QuicheNativeStaticallyReferencedJniMethods.quicheSendInfoOffsetofFrom();
        QUICHE_SEND_INFO_OFFSETOF_FROM_LEN = QuicheNativeStaticallyReferencedJniMethods.quicheSendInfoOffsetofFromLen();
        QUICHE_SEND_INFO_OFFSETOF_AT = QuicheNativeStaticallyReferencedJniMethods.quicheSendInfoOffsetofAt();
        SIZEOF_QUICHE_SEND_INFO = QuicheNativeStaticallyReferencedJniMethods.sizeofQuicheSendInfo();
        QUICHE_PROTOCOL_VERSION = QuicheNativeStaticallyReferencedJniMethods.quiche_protocol_version();
        QUICHE_MAX_CONN_ID_LEN = QuicheNativeStaticallyReferencedJniMethods.quiche_max_conn_id_len();
        QUICHE_SHUTDOWN_READ = QuicheNativeStaticallyReferencedJniMethods.quiche_shutdown_read();
        QUICHE_SHUTDOWN_WRITE = QuicheNativeStaticallyReferencedJniMethods.quiche_shutdown_write();
        QUICHE_ERR_DONE = QuicheNativeStaticallyReferencedJniMethods.quiche_err_done();
        QUICHE_ERR_BUFFER_TOO_SHORT = QuicheNativeStaticallyReferencedJniMethods.quiche_err_buffer_too_short();
        QUICHE_ERR_UNKNOWN_VERSION = QuicheNativeStaticallyReferencedJniMethods.quiche_err_unknown_version();
        QUICHE_ERR_INVALID_FRAME = QuicheNativeStaticallyReferencedJniMethods.quiche_err_invalid_frame();
        QUICHE_ERR_INVALID_PACKET = QuicheNativeStaticallyReferencedJniMethods.quiche_err_invalid_packet();
        QUICHE_ERR_INVALID_STATE = QuicheNativeStaticallyReferencedJniMethods.quiche_err_invalid_state();
        QUICHE_ERR_INVALID_STREAM_STATE = QuicheNativeStaticallyReferencedJniMethods.quiche_err_invalid_stream_state();
        QUICHE_ERR_INVALID_TRANSPORT_PARAM = QuicheNativeStaticallyReferencedJniMethods.quiche_err_invalid_transport_param();
        QUICHE_ERR_CRYPTO_FAIL = QuicheNativeStaticallyReferencedJniMethods.quiche_err_crypto_fail();
        QUICHE_ERR_TLS_FAIL = QuicheNativeStaticallyReferencedJniMethods.quiche_err_tls_fail();
        QUICHE_ERR_FLOW_CONTROL = QuicheNativeStaticallyReferencedJniMethods.quiche_err_flow_control();
        QUICHE_ERR_STREAM_LIMIT = QuicheNativeStaticallyReferencedJniMethods.quiche_err_stream_limit();
        QUICHE_ERR_FINAL_SIZE = QuicheNativeStaticallyReferencedJniMethods.quiche_err_final_size();
        QUICHE_ERR_CONGESTION_CONTROL = QuicheNativeStaticallyReferencedJniMethods.quiche_err_congestion_control();
        QUICHE_ERR_STREAM_RESET = QuicheNativeStaticallyReferencedJniMethods.quiche_err_stream_reset();
        QUICHE_ERR_STREAM_STOPPED = QuicheNativeStaticallyReferencedJniMethods.quiche_err_stream_stopped();
        QUICHE_ERR_ID_LIMIT = QuicheNativeStaticallyReferencedJniMethods.quiche_err_id_limit();
        QUICHE_ERR_OUT_OF_IDENTIFIERS = QuicheNativeStaticallyReferencedJniMethods.quiche_err_out_of_identifiers();
        QUICHE_ERR_KEY_UPDATE = QuicheNativeStaticallyReferencedJniMethods.quiche_err_key_update();
        QUICHE_ERR_CRYPTO_BUFFER_EXCEEDED = QuicheNativeStaticallyReferencedJniMethods.quiche_err_crypto_buffer_exceeded();
        QUICHE_CC_RENO = QuicheNativeStaticallyReferencedJniMethods.quiche_cc_reno();
        QUICHE_CC_CUBIC = QuicheNativeStaticallyReferencedJniMethods.quiche_cc_cubic();
        QUICHE_CC_BBR = QuicheNativeStaticallyReferencedJniMethods.quiche_cc_bbr();
        QUICHE_PATH_EVENT_NEW = QuicheNativeStaticallyReferencedJniMethods.quiche_path_event_new();
        QUICHE_PATH_EVENT_VALIDATED = QuicheNativeStaticallyReferencedJniMethods.quiche_path_event_validated();
        QUICHE_PATH_EVENT_FAILED_VALIDATION = QuicheNativeStaticallyReferencedJniMethods.quiche_path_event_failed_validation();
        QUICHE_PATH_EVENT_CLOSED = QuicheNativeStaticallyReferencedJniMethods.quiche_path_event_closed();
        QUICHE_PATH_EVENT_REUSED_SOURCE_CONNECTION_ID = QuicheNativeStaticallyReferencedJniMethods.quiche_path_event_reused_source_connection_id();
        QUICHE_PATH_EVENT_PEER_MIGRATED = QuicheNativeStaticallyReferencedJniMethods.quiche_path_event_peer_migrated();
        Quiche.ERROR_MAPPINGS.put(Quiche.QUICHE_ERR_DONE, new QuicTransportErrorHolder(QuicTransportError.NO_ERROR, "QUICHE_ERR_DONE"));
        Quiche.ERROR_MAPPINGS.put(Quiche.QUICHE_ERR_INVALID_FRAME, new QuicTransportErrorHolder(QuicTransportError.FRAME_ENCODING_ERROR, "QUICHE_ERR_INVALID_FRAME"));
        Quiche.ERROR_MAPPINGS.put(Quiche.QUICHE_ERR_INVALID_STREAM_STATE, new QuicTransportErrorHolder(QuicTransportError.STREAM_STATE_ERROR, "QUICHE_ERR_INVALID_STREAM_STATE"));
        Quiche.ERROR_MAPPINGS.put(Quiche.QUICHE_ERR_INVALID_TRANSPORT_PARAM, new QuicTransportErrorHolder(QuicTransportError.TRANSPORT_PARAMETER_ERROR, "QUICHE_ERR_INVALID_TRANSPORT_PARAM"));
        Quiche.ERROR_MAPPINGS.put(Quiche.QUICHE_ERR_FLOW_CONTROL, new QuicTransportErrorHolder(QuicTransportError.FLOW_CONTROL_ERROR, "QUICHE_ERR_FLOW_CONTROL"));
        Quiche.ERROR_MAPPINGS.put(Quiche.QUICHE_ERR_STREAM_LIMIT, new QuicTransportErrorHolder(QuicTransportError.STREAM_LIMIT_ERROR, "QUICHE_ERR_STREAM_LIMIT"));
        Quiche.ERROR_MAPPINGS.put(Quiche.QUICHE_ERR_ID_LIMIT, new QuicTransportErrorHolder(QuicTransportError.CONNECTION_ID_LIMIT_ERROR, "QUICHE_ERR_ID_LIMIT"));
        Quiche.ERROR_MAPPINGS.put(Quiche.QUICHE_ERR_FINAL_SIZE, new QuicTransportErrorHolder(QuicTransportError.FINAL_SIZE_ERROR, "QUICHE_ERR_FINAL_SIZE"));
        Quiche.ERROR_MAPPINGS.put(Quiche.QUICHE_ERR_CRYPTO_BUFFER_EXCEEDED, new QuicTransportErrorHolder(QuicTransportError.CRYPTO_BUFFER_EXCEEDED, "QUICHE_ERR_CRYPTO_BUFFER_EXCEEDED"));
        Quiche.ERROR_MAPPINGS.put(Quiche.QUICHE_ERR_KEY_UPDATE, new QuicTransportErrorHolder(QuicTransportError.KEY_UPDATE_ERROR, "QUICHE_ERR_KEY_UPDATE"));
        Quiche.ERROR_MAPPINGS.put(Quiche.QUICHE_ERR_TLS_FAIL, new QuicTransportErrorHolder(QuicTransportError.valueOf(256L), "QUICHE_ERR_TLS_FAIL"));
        Quiche.ERROR_MAPPINGS.put(Quiche.QUICHE_ERR_CRYPTO_FAIL, new QuicTransportErrorHolder(QuicTransportError.valueOf(256L), "QUICHE_ERR_CRYPTO_FAIL"));
        Quiche.ERROR_MAPPINGS.put(Quiche.QUICHE_ERR_BUFFER_TOO_SHORT, new QuicTransportErrorHolder(QuicTransportError.PROTOCOL_VIOLATION, "QUICHE_ERR_BUFFER_TOO_SHORT"));
        Quiche.ERROR_MAPPINGS.put(Quiche.QUICHE_ERR_UNKNOWN_VERSION, new QuicTransportErrorHolder(QuicTransportError.PROTOCOL_VIOLATION, "QUICHE_ERR_UNKNOWN_VERSION"));
        Quiche.ERROR_MAPPINGS.put(Quiche.QUICHE_ERR_INVALID_PACKET, new QuicTransportErrorHolder(QuicTransportError.PROTOCOL_VIOLATION, "QUICHE_ERR_INVALID_PACKET"));
        Quiche.ERROR_MAPPINGS.put(Quiche.QUICHE_ERR_INVALID_STATE, new QuicTransportErrorHolder(QuicTransportError.PROTOCOL_VIOLATION, "QUICHE_ERR_INVALID_STATE"));
        Quiche.ERROR_MAPPINGS.put(Quiche.QUICHE_ERR_CONGESTION_CONTROL, new QuicTransportErrorHolder(QuicTransportError.PROTOCOL_VIOLATION, "QUICHE_ERR_CONGESTION_CONTROL"));
        Quiche.ERROR_MAPPINGS.put(Quiche.QUICHE_ERR_STREAM_STOPPED, new QuicTransportErrorHolder(QuicTransportError.PROTOCOL_VIOLATION, "QUICHE_ERR_STREAM_STOPPED"));
        Quiche.ERROR_MAPPINGS.put(Quiche.QUICHE_ERR_OUT_OF_IDENTIFIERS, new QuicTransportErrorHolder(QuicTransportError.PROTOCOL_VIOLATION, "QUICHE_ERR_OUT_OF_IDENTIFIERS"));
    }
    
    private static final class QuicTransportErrorHolder
    {
        private final QuicTransportError error;
        private final String quicheErrorName;
        
        QuicTransportErrorHolder(final QuicTransportError error, final String quicheErrorName) {
            this.error = error;
            this.quicheErrorName = quicheErrorName;
        }
    }
}
