package {{ package_name }};

import java.util.concurrent.atomic.AtomicBoolean;
{%- if class.has_async_methods() && async_mode.is_completable_future() %}
import java.util.concurrent.CompletableFuture;
{%- endif %}

{{ self::javadoc_block(class.doc, "") }}public final class {{ class.class_name }} implements AutoCloseable {
    private final long handle;
    private final AtomicBoolean closed = new AtomicBoolean(false);

    private {{ class.class_name }}(long handle) {
        this.handle = handle;
    }
{%- for ctor in class.constructors %}{% if !ctor.is_factory() %}

{{ self::javadoc_block(ctor.doc, "    ") }}    public {{ class.class_name }}({% for param in ctor.params %}{{ param.java_type }} {{ param.name }}{% if !loop.last %}, {% endif %}{% endfor %}) {
        this({{ class.class_name }}.createHandle{{ loop.index0 }}({% for param in ctor.params %}{{ param.name }}{% if !loop.last %}, {% endif %}{% endfor %}));
    }

    private static long createHandle{{ loop.index0 }}({% for param in ctor.params %}{{ param.java_type }} {{ param.name }}{% if !loop.last %}, {% endif %}{% endfor %}) {
{%- for binding in ctor.input_bindings.direct_composites %}
        {{ binding.declaration() }};
{%- endfor %}
{%- if ctor.input_bindings.wire_writers.is_empty() %}
{%- if ctor.is_fallible %}
        long _handle = Native.{{ ctor.ffi_name }}({% for param in ctor.params %}{{ param.native_expr }}{% if !loop.last %}, {% endif %}{% endfor %});
        if (_handle == 0L) throw new RuntimeException("Constructor failed");
        return _handle;
{%- else %}
        return Native.{{ ctor.ffi_name }}({% for param in ctor.params %}{{ param.native_expr }}{% if !loop.last %}, {% endif %}{% endfor %});
{%- endif %}
{%- else %}
        try (
{%- for writer in ctor.input_bindings.wire_writers %}
            WireWriter {{ writer.binding_name }} = new WireWriter({{ writer.size_expr }}){% if !loop.last %};{% endif %}
{%- endfor %}
        ) {
{%- for writer in ctor.input_bindings.wire_writers %}
            {{ writer.encode_expr }};
{%- endfor %}
{%- if ctor.is_fallible %}
            long _handle = Native.{{ ctor.ffi_name }}({% for param in ctor.params %}{{ param.native_expr }}{% if !loop.last %}, {% endif %}{% endfor %});
            if (_handle == 0L) throw new RuntimeException("Constructor failed");
            return _handle;
{%- else %}
            return Native.{{ ctor.ffi_name }}({% for param in ctor.params %}{{ param.native_expr }}{% if !loop.last %}, {% endif %}{% endfor %});
{%- endif %}
        }
{%- endif %}
    }
{%- endif %}{% endfor %}

    long rawHandle() {
        return handle;
    }

    @Override
    public void close() {
        if (!closed.compareAndSet(false, true)) return;
        Native.{{ class.ffi_free }}(handle);
    }
{%- if class.has_factory_constructors() || class.has_static_methods() || class.has_async_methods() %}
{%- for ctor in class.constructors %}{% if ctor.is_factory() %}

{{ self::javadoc_block(ctor.doc, "    ") }}    public static {{ class.class_name }} {{ ctor.name }}({% for param in ctor.params %}{{ param.java_type }} {{ param.name }}{% if !loop.last %}, {% endif %}{% endfor %}) {
{%- for binding in ctor.input_bindings.direct_composites %}
        {{ binding.declaration() }};
{%- endfor %}
{%- if ctor.input_bindings.wire_writers.is_empty() %}
{%- if ctor.is_fallible %}
        long _handle = Native.{{ ctor.ffi_name }}({% for param in ctor.params %}{{ param.native_expr }}{% if !loop.last %}, {% endif %}{% endfor %});
        if (_handle == 0L) throw new RuntimeException("Factory constructor failed");
        return new {{ class.class_name }}(_handle);
{%- else %}
        return new {{ class.class_name }}(Native.{{ ctor.ffi_name }}({% for param in ctor.params %}{{ param.native_expr }}{% if !loop.last %}, {% endif %}{% endfor %}));
{%- endif %}
{%- else %}
        try (
{%- for writer in ctor.input_bindings.wire_writers %}
            WireWriter {{ writer.binding_name }} = new WireWriter({{ writer.size_expr }}){% if !loop.last %};{% endif %}
{%- endfor %}
        ) {
{%- for writer in ctor.input_bindings.wire_writers %}
            {{ writer.encode_expr }};
{%- endfor %}
{%- if ctor.is_fallible %}
            long _handle = Native.{{ ctor.ffi_name }}({% for param in ctor.params %}{{ param.native_expr }}{% if !loop.last %}, {% endif %}{% endfor %});
            if (_handle == 0L) throw new RuntimeException("Factory constructor failed");
            return new {{ class.class_name }}(_handle);
{%- else %}
            return new {{ class.class_name }}(Native.{{ ctor.ffi_name }}({% for param in ctor.params %}{{ param.native_expr }}{% if !loop.last %}, {% endif %}{% endfor %}));
{%- endif %}
        }
{%- endif %}
    }
{%- endif %}{% endfor %}
{%- for method in class.methods %}{% if method.is_static && !method.is_async() %}

{{ self::javadoc_block(method.doc, "    ") }}    public static {{ method.return_type }} {{ method.name }}({% for param in method.params %}{{ param.java_type }} {{ param.name }}{% if !loop.last %}, {% endif %}{% endfor %}) {
{%- for binding in method.input_bindings.direct_composites %}
        {{ binding.declaration() }};
{%- endfor %}
{%- if method.input_bindings.wire_writers.is_empty() %}
{%- if method.return_plan.is_void() %}
        Native.{{ method.ffi_name }}({% for param in method.params %}{{ param.native_expr }}{% if !loop.last %}, {% endif %}{% endfor %});
{%- elif method.return_plan.is_direct() %}
        return Native.{{ method.ffi_name }}({% for param in method.params %}{{ param.native_expr }}{% if !loop.last %}, {% endif %}{% endfor %});
{%- elif method.return_plan.is_c_style_enum() %}
        return {{ method.return_plan.c_style_enum_class() }}.fromValue(Native.{{ method.ffi_name }}({% for param in method.params %}{{ param.native_expr }}{% if !loop.last %}, {% endif %}{% endfor %}));
{%- elif method.return_plan.is_handle() %}
        long _handle = Native.{{ method.ffi_name }}({% for param in method.params %}{{ param.native_expr }}{% if !loop.last %}, {% endif %}{% endfor %});
{%- if method.return_plan.handle_nullable() %}
        if (_handle == 0L) return null;
{%- endif %}
        return new {{ method.return_plan.handle_class() }}(_handle);
{%- elif method.return_plan.is_callback() %}
        long _handle = Native.{{ method.ffi_name }}({% for param in method.params %}{{ param.native_expr }}{% if !loop.last %}, {% endif %}{% endfor %});
{%- if method.return_plan.callback_nullable() %}
        if (_handle == 0L) return null;
{%- endif %}
        return {{ method.return_plan.callback_bridge_class() }}.wrap(_handle);
{%- elif method.return_plan.is_decode() %}
        byte[] _buf = Native.{{ method.ffi_name }}({% for param in method.params %}{{ param.native_expr }}{% if !loop.last %}, {% endif %}{% endfor %});
        if (_buf == null) throw new RuntimeException("FFI call returned null buffer");
        WireReader reader = new WireReader(_buf);
        return {{ method.return_plan.decode_expr() }};
{%- elif method.return_plan.is_result() %}
        byte[] _buf = Native.{{ method.ffi_name }}({% for param in method.params %}{{ param.native_expr }}{% if !loop.last %}, {% endif %}{% endfor %});
        if (_buf == null) throw new RuntimeException("FFI call returned null buffer");
        WireReader reader = new WireReader(_buf);
        if (reader.readI8() != 0) {
{%- if method.return_plan.result_err_throws_directly() %}
            throw {{ method.return_plan.result_err_decode() }};
{%- elif method.return_plan.result_has_typed_exception() %}
            throw new {{ method.return_plan.result_err_exception_class() }}({{ method.return_plan.result_err_decode() }});
{%- elif method.return_plan.result_err_is_string() %}
            throw new RuntimeException({{ method.return_plan.result_err_decode() }});
{%- else %}
            throw new RuntimeException(String.valueOf({{ method.return_plan.result_err_decode() }}));
{%- endif %}
        }
{%- if method.return_type == "void" %}
{%- else %}
        return {{ method.return_plan.result_ok_decode() }};
{%- endif %}
{%- endif %}
{%- else %}
        try (
{%- for writer in method.input_bindings.wire_writers %}
            WireWriter {{ writer.binding_name }} = new WireWriter({{ writer.size_expr }}){% if !loop.last %};{% endif %}
{%- endfor %}
        ) {
{%- for writer in method.input_bindings.wire_writers %}
            {{ writer.encode_expr }};
{%- endfor %}
{%- if method.return_plan.is_void() %}
            Native.{{ method.ffi_name }}({% for param in method.params %}{{ param.native_expr }}{% if !loop.last %}, {% endif %}{% endfor %});
{%- elif method.return_plan.is_direct() %}
            return Native.{{ method.ffi_name }}({% for param in method.params %}{{ param.native_expr }}{% if !loop.last %}, {% endif %}{% endfor %});
{%- elif method.return_plan.is_c_style_enum() %}
            return {{ method.return_plan.c_style_enum_class() }}.fromValue(Native.{{ method.ffi_name }}({% for param in method.params %}{{ param.native_expr }}{% if !loop.last %}, {% endif %}{% endfor %}));
{%- elif method.return_plan.is_handle() %}
            long _handle = Native.{{ method.ffi_name }}({% for param in method.params %}{{ param.native_expr }}{% if !loop.last %}, {% endif %}{% endfor %});
{%- if method.return_plan.handle_nullable() %}
            if (_handle == 0L) return null;
{%- endif %}
            return new {{ method.return_plan.handle_class() }}(_handle);
{%- elif method.return_plan.is_callback() %}
            long _handle = Native.{{ method.ffi_name }}({% for param in method.params %}{{ param.native_expr }}{% if !loop.last %}, {% endif %}{% endfor %});
{%- if method.return_plan.callback_nullable() %}
            if (_handle == 0L) return null;
{%- endif %}
            return {{ method.return_plan.callback_bridge_class() }}.wrap(_handle);
{%- elif method.return_plan.is_decode() %}
            byte[] _buf = Native.{{ method.ffi_name }}({% for param in method.params %}{{ param.native_expr }}{% if !loop.last %}, {% endif %}{% endfor %});
            if (_buf == null) throw new RuntimeException("FFI call returned null buffer");
            WireReader reader = new WireReader(_buf);
            return {{ method.return_plan.decode_expr() }};
{%- elif method.return_plan.is_result() %}
            byte[] _buf = Native.{{ method.ffi_name }}({% for param in method.params %}{{ param.native_expr }}{% if !loop.last %}, {% endif %}{% endfor %});
            if (_buf == null) throw new RuntimeException("FFI call returned null buffer");
            WireReader reader = new WireReader(_buf);
            if (reader.readI8() != 0) {
{%- if method.return_plan.result_err_throws_directly() %}
                throw {{ method.return_plan.result_err_decode() }};
{%- elif method.return_plan.result_has_typed_exception() %}
                throw new {{ method.return_plan.result_err_exception_class() }}({{ method.return_plan.result_err_decode() }});
{%- elif method.return_plan.result_err_is_string() %}
                throw new RuntimeException({{ method.return_plan.result_err_decode() }});
{%- else %}
                throw new RuntimeException(String.valueOf({{ method.return_plan.result_err_decode() }}));
{%- endif %}
            }
{%- if method.return_type == "void" %}
{%- else %}
            return {{ method.return_plan.result_ok_decode() }};
{%- endif %}
{%- endif %}
        }
{%- endif %}
    }
{%- endif %}{% endfor %}
{%- for method in class.methods %}{% if method.is_async() %}
{%- let ac = method.async_call.as_ref().unwrap() %}
{% if async_mode.is_virtual_thread() %}
{%- if ac.complete_return_plan.is_void() %}
{{ self::javadoc_block(method.doc, "    ") }}    public{% if method.is_static %} static{% endif %} void {{ method.name }}({% for param in method.params %}{{ param.java_type }} {{ param.name }}{% if !loop.last %}, {% endif %}{% endfor %}) {
        BoltFFIAsync.callAsyncVoid(
{%- else %}
{{ self::javadoc_block(method.doc, "    ") }}    public{% if method.is_static %} static{% endif %} {{ method.return_type }} {{ method.name }}({% for param in method.params %}{{ param.java_type }} {{ param.name }}{% if !loop.last %}, {% endif %}{% endfor %}) {
        return BoltFFIAsync.callAsync(
{%- endif %}
{%- else %}
{%- if ac.complete_return_plan.is_void() %}
{{ self::javadoc_block(method.doc, "    ") }}    public{% if method.is_static %} static{% endif %} CompletableFuture<Void> {{ method.name }}({% for param in method.params %}{{ param.java_type }} {{ param.name }}{% if !loop.last %}, {% endif %}{% endfor %}) {
        return BoltFFIAsync.callAsyncVoid(
{%- else %}
{{ self::javadoc_block(method.doc, "    ") }}    public{% if method.is_static %} static{% endif %} CompletableFuture<{{ method.boxed_return_type() }}> {{ method.name }}({% for param in method.params %}{{ param.java_type }} {{ param.name }}{% if !loop.last %}, {% endif %}{% endfor %}) {
        return BoltFFIAsync.callAsync(
{%- endif %}
{%- endif %}
{%- if method.input_bindings.is_empty() %}
                () -> Native.{{ method.ffi_name }}({% if !method.is_static %}handle{% if !method.params.is_empty() %}, {% endif %}{% endif %}{% for param in method.params %}{{ param.native_expr }}{% if !loop.last %}, {% endif %}{% endfor %}),
{%- else %}
                () -> {
{%- for binding in method.input_bindings.direct_composites %}
                    {{ binding.declaration() }};
{%- endfor %}
{%- for writer in method.input_bindings.wire_writers %}
                    try (WireWriter {{ writer.binding_name }} = new WireWriter({{ writer.size_expr }})) {
                        {{ writer.encode_expr }};
{%- endfor %}
                        return Native.{{ method.ffi_name }}({% if !method.is_static %}handle{% if !method.params.is_empty() %}, {% endif %}{% endif %}{% for param in method.params %}{{ param.native_expr }}{% if !loop.last %}, {% endif %}{% endfor %});
{%- for _writer in method.input_bindings.wire_writers %}
                    }
{%- endfor %}
                },
{%- endif %}
                (future, contHandle) -> Native.{{ ac.poll }}({% if !method.is_static %}handle, {% endif %}future, contHandle),
{%- if ac.complete_return_plan.is_void() %}
                future -> Native.{{ ac.complete }}({% if !method.is_static %}handle, {% endif %}future),
{%- elif ac.complete_return_plan.is_direct() %}
                future -> Native.{{ ac.complete }}({% if !method.is_static %}handle, {% endif %}future),
{%- elif ac.complete_return_plan.is_decode() %}
                future -> {
                    byte[] _buf = Native.{{ ac.complete }}({% if !method.is_static %}handle, {% endif %}future);
                    if (_buf == null) throw new RuntimeException("FFI call returned null buffer");
                    WireReader reader = new WireReader(_buf);
                    return {{ ac.complete_return_plan.decode_expr() }};
                },
{%- elif ac.complete_return_plan.is_c_style_enum() %}
                future -> {{ ac.complete_return_plan.c_style_enum_class() }}.fromValue(Native.{{ ac.complete }}({% if !method.is_static %}handle, {% endif %}future)),
{%- elif ac.complete_return_plan.is_handle() %}
                future -> {
                    long _handle = Native.{{ ac.complete }}({% if !method.is_static %}handle, {% endif %}future);
{%- if ac.complete_return_plan.handle_nullable() %}
                    if (_handle == 0L) return null;
{%- endif %}
                    return new {{ ac.complete_return_plan.handle_class() }}(_handle);
                },
{%- elif ac.complete_return_plan.is_callback() %}
                future -> {
                    long _handle = Native.{{ ac.complete }}({% if !method.is_static %}handle, {% endif %}future);
{%- if ac.complete_return_plan.callback_nullable() %}
                    if (_handle == 0L) return null;
{%- endif %}
                    return {{ ac.complete_return_plan.callback_bridge_class() }}.wrap(_handle);
                },
{%- elif ac.complete_return_plan.is_result() %}
                future -> {
                    byte[] _buf = Native.{{ ac.complete }}({% if !method.is_static %}handle, {% endif %}future);
                    if (_buf == null) throw new RuntimeException("FFI call returned null buffer");
                    WireReader reader = new WireReader(_buf);
                    if (reader.readI8() != 0) {
{%- if ac.complete_return_plan.result_err_throws_directly() %}
                        throw {{ ac.complete_return_plan.result_err_decode() }};
{%- elif ac.complete_return_plan.result_has_typed_exception() %}
                        throw new {{ ac.complete_return_plan.result_err_exception_class() }}({{ ac.complete_return_plan.result_err_decode() }});
{%- elif ac.complete_return_plan.result_err_is_string() %}
                        throw new RuntimeException({{ ac.complete_return_plan.result_err_decode() }});
{%- else %}
                        throw new RuntimeException(String.valueOf({{ ac.complete_return_plan.result_err_decode() }}));
{%- endif %}
                    }
{%- if method.return_type == "void" %}
                    return null;
{%- else %}
                    return {{ ac.complete_return_plan.result_ok_decode() }};
{%- endif %}
                },
{%- endif %}
                future -> Native.{{ ac.free }}({% if !method.is_static %}handle, {% endif %}future),
                future -> Native.{{ ac.cancel }}({% if !method.is_static %}handle, {% endif %}future)
        );
    }
{%- endif %}{% endfor %}
{%- endif %}
{%- for method in class.methods %}{% if !method.is_static && !method.is_async() %}

{{ self::javadoc_block(method.doc, "    ") }}    public {{ method.return_type }} {{ method.name }}({% for param in method.params %}{{ param.java_type }} {{ param.name }}{% if !loop.last %}, {% endif %}{% endfor %}) {
{%- for binding in method.input_bindings.direct_composites %}
        {{ binding.declaration() }};
{%- endfor %}
{%- if method.input_bindings.wire_writers.is_empty() %}
{%- if method.return_plan.is_void() %}
        Native.{{ method.ffi_name }}(handle{% if !method.params.is_empty() %}, {% endif %}{% for param in method.params %}{{ param.native_expr }}{% if !loop.last %}, {% endif %}{% endfor %});
{%- elif method.return_plan.is_direct() %}
        return Native.{{ method.ffi_name }}(handle{% if !method.params.is_empty() %}, {% endif %}{% for param in method.params %}{{ param.native_expr }}{% if !loop.last %}, {% endif %}{% endfor %});
{%- elif method.return_plan.is_c_style_enum() %}
        return {{ method.return_plan.c_style_enum_class() }}.fromValue(Native.{{ method.ffi_name }}(handle{% if !method.params.is_empty() %}, {% endif %}{% for param in method.params %}{{ param.native_expr }}{% if !loop.last %}, {% endif %}{% endfor %}));
{%- elif method.return_plan.is_handle() %}
        long _handle = Native.{{ method.ffi_name }}(handle{% if !method.params.is_empty() %}, {% endif %}{% for param in method.params %}{{ param.native_expr }}{% if !loop.last %}, {% endif %}{% endfor %});
{%- if method.return_plan.handle_nullable() %}
        if (_handle == 0L) return null;
{%- endif %}
        return new {{ method.return_plan.handle_class() }}(_handle);
{%- elif method.return_plan.is_callback() %}
        long _handle = Native.{{ method.ffi_name }}(handle{% if !method.params.is_empty() %}, {% endif %}{% for param in method.params %}{{ param.native_expr }}{% if !loop.last %}, {% endif %}{% endfor %});
{%- if method.return_plan.callback_nullable() %}
        if (_handle == 0L) return null;
{%- endif %}
        return {{ method.return_plan.callback_bridge_class() }}.wrap(_handle);
{%- elif method.return_plan.is_decode() %}
        byte[] _buf = Native.{{ method.ffi_name }}(handle{% if !method.params.is_empty() %}, {% endif %}{% for param in method.params %}{{ param.native_expr }}{% if !loop.last %}, {% endif %}{% endfor %});
        if (_buf == null) throw new RuntimeException("FFI call returned null buffer");
        WireReader reader = new WireReader(_buf);
        return {{ method.return_plan.decode_expr() }};
{%- elif method.return_plan.is_result() %}
        byte[] _buf = Native.{{ method.ffi_name }}(handle{% if !method.params.is_empty() %}, {% endif %}{% for param in method.params %}{{ param.native_expr }}{% if !loop.last %}, {% endif %}{% endfor %});
        if (_buf == null) throw new RuntimeException("FFI call returned null buffer");
        WireReader reader = new WireReader(_buf);
        if (reader.readI8() != 0) {
{%- if method.return_plan.result_err_throws_directly() %}
            throw {{ method.return_plan.result_err_decode() }};
{%- elif method.return_plan.result_has_typed_exception() %}
            throw new {{ method.return_plan.result_err_exception_class() }}({{ method.return_plan.result_err_decode() }});
{%- elif method.return_plan.result_err_is_string() %}
            throw new RuntimeException({{ method.return_plan.result_err_decode() }});
{%- else %}
            throw new RuntimeException(String.valueOf({{ method.return_plan.result_err_decode() }}));
{%- endif %}
        }
{%- if method.return_type == "void" %}
{%- else %}
        return {{ method.return_plan.result_ok_decode() }};
{%- endif %}
{%- endif %}
{%- else %}
        try (
{%- for writer in method.input_bindings.wire_writers %}
            WireWriter {{ writer.binding_name }} = new WireWriter({{ writer.size_expr }}){% if !loop.last %};{% endif %}
{%- endfor %}
        ) {
{%- for writer in method.input_bindings.wire_writers %}
            {{ writer.encode_expr }};
{%- endfor %}
{%- if method.return_plan.is_void() %}
            Native.{{ method.ffi_name }}(handle{% if !method.params.is_empty() %}, {% endif %}{% for param in method.params %}{{ param.native_expr }}{% if !loop.last %}, {% endif %}{% endfor %});
{%- elif method.return_plan.is_direct() %}
            return Native.{{ method.ffi_name }}(handle{% if !method.params.is_empty() %}, {% endif %}{% for param in method.params %}{{ param.native_expr }}{% if !loop.last %}, {% endif %}{% endfor %});
{%- elif method.return_plan.is_c_style_enum() %}
            return {{ method.return_plan.c_style_enum_class() }}.fromValue(Native.{{ method.ffi_name }}(handle{% if !method.params.is_empty() %}, {% endif %}{% for param in method.params %}{{ param.native_expr }}{% if !loop.last %}, {% endif %}{% endfor %}));
{%- elif method.return_plan.is_handle() %}
            long _handle = Native.{{ method.ffi_name }}(handle{% if !method.params.is_empty() %}, {% endif %}{% for param in method.params %}{{ param.native_expr }}{% if !loop.last %}, {% endif %}{% endfor %});
{%- if method.return_plan.handle_nullable() %}
            if (_handle == 0L) return null;
{%- endif %}
            return new {{ method.return_plan.handle_class() }}(_handle);
{%- elif method.return_plan.is_callback() %}
            long _handle = Native.{{ method.ffi_name }}(handle{% if !method.params.is_empty() %}, {% endif %}{% for param in method.params %}{{ param.native_expr }}{% if !loop.last %}, {% endif %}{% endfor %});
{%- if method.return_plan.callback_nullable() %}
            if (_handle == 0L) return null;
{%- endif %}
            return {{ method.return_plan.callback_bridge_class() }}.wrap(_handle);
{%- elif method.return_plan.is_decode() %}
            byte[] _buf = Native.{{ method.ffi_name }}(handle{% if !method.params.is_empty() %}, {% endif %}{% for param in method.params %}{{ param.native_expr }}{% if !loop.last %}, {% endif %}{% endfor %});
            if (_buf == null) throw new RuntimeException("FFI call returned null buffer");
            WireReader reader = new WireReader(_buf);
            return {{ method.return_plan.decode_expr() }};
{%- elif method.return_plan.is_result() %}
            byte[] _buf = Native.{{ method.ffi_name }}(handle{% if !method.params.is_empty() %}, {% endif %}{% for param in method.params %}{{ param.native_expr }}{% if !loop.last %}, {% endif %}{% endfor %});
            if (_buf == null) throw new RuntimeException("FFI call returned null buffer");
            WireReader reader = new WireReader(_buf);
            if (reader.readI8() != 0) {
{%- if method.return_plan.result_err_throws_directly() %}
                throw {{ method.return_plan.result_err_decode() }};
{%- elif method.return_plan.result_has_typed_exception() %}
                throw new {{ method.return_plan.result_err_exception_class() }}({{ method.return_plan.result_err_decode() }});
{%- elif method.return_plan.result_err_is_string() %}
                throw new RuntimeException({{ method.return_plan.result_err_decode() }});
{%- else %}
                throw new RuntimeException(String.valueOf({{ method.return_plan.result_err_decode() }}));
{%- endif %}
            }
{%- if method.return_type == "void" %}
{%- else %}
            return {{ method.return_plan.result_ok_decode() }};
{%- endif %}
{%- endif %}
        }
{%- endif %}
    }
{%- endif %}{% endfor %}
{%- for stream in class.streams %}
{%- match stream.mode %}
{%- when crate::render::java::plan::JavaStreamMode::Async %}

{{ self::javadoc_block(stream.doc, "    ") }}    public StreamSubscription<{{ stream.item_type }}> {{ stream.name }}(java.util.function.Consumer<{{ stream.item_type }}> callback) {
        long subscription = Native.{{ stream.subscribe }}(handle);
        if (subscription == 0L) return StreamSubscription.callback(() -> {});
        BoltFFIStreamContext context = new BoltFFIStreamContext(
            subscription, 16L,
            Native::{{ stream.pop_batch }},
            Native::{{ stream.poll }},
            Native::{{ stream.unsubscribe }},
            Native::{{ stream.free }},
            _bytes -> { for ({{ stream.item_type }} item : {{ stream.pop_batch_items_expr }}) callback.accept(item); },
            () -> {}
        );
        context.start();
        return StreamSubscription.callback(context::requestTermination);
    }
{%- when crate::render::java::plan::JavaStreamMode::Batch %}

{{ self::javadoc_block(stream.doc, "    ") }}    public StreamSubscription<{{ stream.item_type }}> {{ stream.name }}() {
        return StreamSubscription.batch(
            Native.{{ stream.subscribe }}(handle),
            Native::{{ stream.pop_batch }},
            Native::{{ stream.wait }},
            Native::{{ stream.unsubscribe }},
            Native::{{ stream.free }},
            _bytes -> {{ stream.pop_batch_items_expr }}
        );
    }
{%- when crate::render::java::plan::JavaStreamMode::Callback %}

{{ self::javadoc_block(stream.doc, "    ") }}    public StreamSubscription<{{ stream.item_type }}> {{ stream.name }}(java.util.function.Consumer<{{ stream.item_type }}> callback) {
        long subscription = Native.{{ stream.subscribe }}(handle);
        if (subscription == 0L) return StreamSubscription.callback(() -> {});
        BoltFFIStreamContext context = new BoltFFIStreamContext(
            subscription, 16L,
            Native::{{ stream.pop_batch }},
            Native::{{ stream.poll }},
            Native::{{ stream.unsubscribe }},
            Native::{{ stream.free }},
            _bytes -> { for ({{ stream.item_type }} item : {{ stream.pop_batch_items_expr }}) callback.accept(item); },
            () -> {}
        );
        context.start();
        return StreamSubscription.callback(context::requestTermination);
    }
{%- endmatch %}
{%- endfor %}
}
