//! Provides low-level bindings to `tarantool`'s VDBE subsystem.
//! Guaranteed to match the exact version and build configuration of `tarantool` picodata was built with.

// The functions and types we bind to don't follow rust naming conventions
// Relax the style rules to accommodate that
#[expect(
    non_snake_case,
    non_camel_case_types,
    non_upper_case_globals,
    unnecessary_transmutes,
    unused
)]
// Some hand-rolled bindings in the picodata crate use different pointer types for simplicity
// They cause this lint to go off
#[expect(clashing_extern_declarations)]
// Clippy raises a lot of various diagnostics for the bindings regarding "smelly" code.
// They are autogenerated, so we don't intend to fix them.
#[allow(clippy::all)]
// `bindgen` tries to convert tarantool's code docs to rustdoc.
// `tarantool` does not follow the same conventions as rustdoc,
//  so some docs will not look right or will be outright broken.
// Can't do much about it.
#[allow(
    rustdoc::broken_intra_doc_links,
    rustdoc::invalid_html_tags,
    rustdoc::bare_urls
)]
mod sys {
    // generated by `generate_vdbe_bindings` in picodata's `build.rs`
    include!(concat!(env!("OUT_DIR"), "/vdbe-bindings.rs"));
}
pub use sys::*;

pub fn with_parser<R>(cb: impl FnOnce(&mut Parse) -> R) -> R {
    use std::mem::MaybeUninit;

    let mut parser = unsafe { MaybeUninit::<Parse>::zeroed().assume_init() };
    unsafe { sql_parser_create(&mut parser, SQL_DEFAULT_FLAGS) };

    let res = cb(&mut parser);

    unsafe { sql_parser_destroy(&mut parser) };

    res
}

macro_rules! sqlVdbeAddOp {
    ($vdbe:ident, $op:ident $(,)?) => {
        sqlVdbeAddOp0($vdbe, $op)
    };
    ($vdbe:ident, $op:ident, $p1:expr $(,)?) => {
        sqlVdbeAddOp1($vdbe, $op, $p1)
    };
    ($vdbe:ident, $op:ident, $p1:expr, $p2:expr $(,)?) => {
        sqlVdbeAddOp2($vdbe, $op, $p1, $p2)
    };
    ($vdbe:ident, $op:ident, $p1:expr, $p2:expr, $p3:expr $(,)?) => {
        sqlVdbeAddOp3($vdbe, $op, $p1, $p2, $p3)
    };
    ($vdbe:ident, $op:ident, $p1:expr, $p2:expr, $p3:expr, $p4:expr => $p4type:ident $(,)?) => {
        sqlVdbeAddOp4($vdbe, $op, $p1, $p2, $p3, $p4, $p4type)
    };
}

pub(crate) use sqlVdbeAddOp;
