/*
** syntaqlite amalgamation — machine generated, do not edit.
*/
#ifndef SYNTAQLITE_PERFETTO_H
#define SYNTAQLITE_PERFETTO_H

#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
#pragma GCC diagnostic ignored "-Wunused-variable"
#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
#pragma GCC diagnostic ignored "-Wtype-limits"
#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
#pragma GCC diagnostic ignored "-Wswitch-enum"
#pragma GCC diagnostic ignored "-Wsign-conversion"
#pragma GCC diagnostic ignored "-Wcast-qual"
#pragma GCC diagnostic ignored "-Wunused-macros"
#pragma GCC diagnostic ignored "-Wformat-nonliteral"
#pragma GCC diagnostic ignored "-Wformat"
#pragma GCC diagnostic ignored "-Wcast-align"
#pragma GCC diagnostic ignored "-Wunreachable-code"
#pragma GCC diagnostic ignored "-Wunused-function"
#pragma GCC diagnostic ignored "-Wswitch-default"
#pragma GCC diagnostic ignored "-Wpadded"
#ifndef __cplusplus
#pragma GCC diagnostic ignored "-Wdeclaration-after-statement"
#pragma GCC diagnostic ignored "-Wmissing-prototypes"
#else
#pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant"
#endif
#ifdef __clang__
#pragma clang diagnostic ignored "-Wunknown-warning-option"
#pragma clang diagnostic ignored "-Wextra-semi-stmt"
#pragma clang diagnostic ignored "-Wold-style-cast"
#pragma clang diagnostic ignored "-Wmissing-variable-declarations"
#pragma clang diagnostic ignored "-Wimplicit-int-conversion"
#pragma clang diagnostic ignored "-Wimplicit-int-enum-cast"
#pragma clang diagnostic ignored "-Wimplicit-void-ptr-cast"
#pragma clang diagnostic ignored "-Wshorten-64-to-32"
#elif defined(__GNUC__) && !defined(__cplusplus)
#pragma GCC diagnostic ignored "-Wold-style-declaration"
#endif
#endif

#ifndef SYNTAQLITE_OMIT_SQLITE_API
#define SYNTAQLITE_OMIT_SQLITE_API
#endif

/* ======== begin: syntaqlite/compiler.h ======== */
#ifndef SYNTAQLITE_COMPILER_H
#define SYNTAQLITE_COMPILER_H
// Copyright 2025 The syntaqlite Authors. All rights reserved.
// Licensed under the Apache License, Version 2.0.

// Compiler abstraction macros.
//
// Wrappers for features that differ across compilers and C/C++ dialects,
// letting the rest of the codebase use a single spelling.


// Portable compile-time assertion. Use in file scope.
//
// MSVC does not support C's `_Static_assert` keyword in C mode unless built
// with `/std:c11` or newer, so we need dialect-specific fallbacks:
//   - C++: `static_assert` is a keyword since C++11.
//   - C23: `static_assert` is a keyword.
//   - C11+: `_Static_assert` is the keyword form.
//   - Older C (including MSVC without /std:c11): typedef a 1- or -1-element
//     char array, which fails to compile on false.
#if defined(__cplusplus)
#define SYNQ_STATIC_ASSERT(cond, msg) static_assert(cond, msg)
#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L
#define SYNQ_STATIC_ASSERT(cond, msg) static_assert(cond, msg)
#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
#define SYNQ_STATIC_ASSERT(cond, msg) _Static_assert(cond, msg)
#else
#define SYNQ_STATIC_ASSERT_CAT_(a, b) a##b
#define SYNQ_STATIC_ASSERT_CAT(a, b) SYNQ_STATIC_ASSERT_CAT_(a, b)
#define SYNQ_STATIC_ASSERT(cond, msg)                      \
  typedef char SYNQ_STATIC_ASSERT_CAT(synq_static_assert_, \
                                      __LINE__)[(cond) ? 1 : -1]
#endif


#endif  /* SYNTAQLITE_COMPILER_H */
/* ======== end: syntaqlite/compiler.h ======== */

/* ======== begin: syntaqlite/cflags.h ======== */
#ifndef SYNTAQLITE_SQLITE_CFLAGS_H
#define SYNTAQLITE_SQLITE_CFLAGS_H
// Copyright 2025 The syntaqlite Authors. All rights reserved.
// Licensed under the Apache License, Version 2.0.
// @generated by syntaqlite-buildtools codegen-sqlite — DO NOT EDIT
//
// SQLite compile-time flag constants for the "parser" group.
// For use with SyntaqliteDialect.cflags.
//
// Indices are group-local (0-based within this group).


#include <stdint.h>
#include <string.h>


// ── Cflag index constants ───────────────────────────────────────────────
//
// These are group-local indices used in keyword/parser tables.

// OMIT flags:
#define SYNQ_CFLAG_IDX_OMIT_ALTERTABLE 0
#define SYNQ_CFLAG_IDX_OMIT_ANALYZE 1
#define SYNQ_CFLAG_IDX_OMIT_ATTACH 2
#define SYNQ_CFLAG_IDX_OMIT_AUTOINCREMENT 3
#define SYNQ_CFLAG_IDX_OMIT_CAST 4
#define SYNQ_CFLAG_IDX_OMIT_COMPOUND_SELECT 5
#define SYNQ_CFLAG_IDX_OMIT_CTE 6
#define SYNQ_CFLAG_IDX_OMIT_EXPLAIN 7
#define SYNQ_CFLAG_IDX_OMIT_FOREIGN_KEY 8
#define SYNQ_CFLAG_IDX_OMIT_GENERATED_COLUMNS 9
#define SYNQ_CFLAG_IDX_OMIT_PRAGMA 10
#define SYNQ_CFLAG_IDX_OMIT_REINDEX 11
#define SYNQ_CFLAG_IDX_OMIT_RETURNING 12
#define SYNQ_CFLAG_IDX_OMIT_SUBQUERY 13
#define SYNQ_CFLAG_IDX_OMIT_TEMPDB 14
#define SYNQ_CFLAG_IDX_OMIT_TRIGGER 15
#define SYNQ_CFLAG_IDX_OMIT_VACUUM 16
#define SYNQ_CFLAG_IDX_OMIT_VIEW 17
#define SYNQ_CFLAG_IDX_OMIT_VIRTUALTABLE 18
#define SYNQ_CFLAG_IDX_OMIT_WINDOWFUNC 19

// ENABLE flags:
#define SYNQ_CFLAG_IDX_ENABLE_ORDERED_SET_AGGREGATES 20
#define SYNQ_CFLAG_IDX_ENABLE_UPDATE_DELETE_LIMIT 21

#define SYNQ_CFLAG_IDX_COUNT 22

// ── Named bitfield struct ───────────────────────────────────────────────

typedef struct SyntaqliteCflags {
  // OMIT flags:
  uint8_t omit_altertable : 1;
  uint8_t omit_analyze : 1;
  uint8_t omit_attach : 1;
  uint8_t omit_autoincrement : 1;
  uint8_t omit_cast : 1;
  uint8_t omit_compound_select : 1;
  uint8_t omit_cte : 1;
  uint8_t omit_explain : 1;
  uint8_t omit_foreign_key : 1;
  uint8_t omit_generated_columns : 1;
  uint8_t omit_pragma : 1;
  uint8_t omit_reindex : 1;
  uint8_t omit_returning : 1;
  uint8_t omit_subquery : 1;
  uint8_t omit_tempdb : 1;
  uint8_t omit_trigger : 1;
  uint8_t omit_vacuum : 1;
  uint8_t omit_view : 1;
  uint8_t omit_virtualtable : 1;
  uint8_t omit_windowfunc : 1;
  // ENABLE flags:
  uint8_t enable_ordered_set_aggregates : 1;
  uint8_t enable_update_delete_limit : 1;
  // Padding to 24 bits (3 bytes):
  uint8_t _reserved : 2;
} SyntaqliteCflags;

SYNQ_STATIC_ASSERT(
    sizeof(SyntaqliteCflags) == 3,
    "SyntaqliteCflags layout must match byte-wise accessor assumptions");

#define SYNQ_CFLAGS_DEFAULT {0}

// ── Indexed accessor ────────────────────────────────────────────────────
//
// For dynamic cflag lookup (keyword tables etc.).

static inline int synq_has_cflag(const SyntaqliteCflags* c, int idx) {
  const uint8_t* bytes = (const uint8_t*)c;
  return (bytes[idx / 8] >> (idx % 8)) & 1;
}

static inline void synq_set_cflag(SyntaqliteCflags* c, int idx) {
  uint8_t* bytes = (uint8_t*)c;
  bytes[idx / 8] |= (uint8_t)(1u << (idx % 8));
}

// ── Compile-time cflag pinning ──────────────────────────────────────────
//
// When SYNTAQLITE_SQLITE_CFLAGS is defined, a static const struct is built
// from individual SYNTAQLITE_CFLAG_* defines.

#ifdef SYNTAQLITE_SQLITE_CFLAGS
static const SyntaqliteCflags synq_pinned_cflags = {
#ifdef SYNTAQLITE_CFLAG_SQLITE_OMIT_ALTERTABLE
    .omit_altertable = 1,
#endif
#ifdef SYNTAQLITE_CFLAG_SQLITE_OMIT_ANALYZE
    .omit_analyze = 1,
#endif
#ifdef SYNTAQLITE_CFLAG_SQLITE_OMIT_ATTACH
    .omit_attach = 1,
#endif
#ifdef SYNTAQLITE_CFLAG_SQLITE_OMIT_AUTOINCREMENT
    .omit_autoincrement = 1,
#endif
#ifdef SYNTAQLITE_CFLAG_SQLITE_OMIT_CAST
    .omit_cast = 1,
#endif
#ifdef SYNTAQLITE_CFLAG_SQLITE_OMIT_COMPOUND_SELECT
    .omit_compound_select = 1,
#endif
#ifdef SYNTAQLITE_CFLAG_SQLITE_OMIT_CTE
    .omit_cte = 1,
#endif
#ifdef SYNTAQLITE_CFLAG_SQLITE_OMIT_EXPLAIN
    .omit_explain = 1,
#endif
#ifdef SYNTAQLITE_CFLAG_SQLITE_OMIT_FOREIGN_KEY
    .omit_foreign_key = 1,
#endif
#ifdef SYNTAQLITE_CFLAG_SQLITE_OMIT_GENERATED_COLUMNS
    .omit_generated_columns = 1,
#endif
#ifdef SYNTAQLITE_CFLAG_SQLITE_OMIT_PRAGMA
    .omit_pragma = 1,
#endif
#ifdef SYNTAQLITE_CFLAG_SQLITE_OMIT_REINDEX
    .omit_reindex = 1,
#endif
#ifdef SYNTAQLITE_CFLAG_SQLITE_OMIT_RETURNING
    .omit_returning = 1,
#endif
#ifdef SYNTAQLITE_CFLAG_SQLITE_OMIT_SUBQUERY
    .omit_subquery = 1,
#endif
#ifdef SYNTAQLITE_CFLAG_SQLITE_OMIT_TEMPDB
    .omit_tempdb = 1,
#endif
#ifdef SYNTAQLITE_CFLAG_SQLITE_OMIT_TRIGGER
    .omit_trigger = 1,
#endif
#ifdef SYNTAQLITE_CFLAG_SQLITE_OMIT_VACUUM
    .omit_vacuum = 1,
#endif
#ifdef SYNTAQLITE_CFLAG_SQLITE_OMIT_VIEW
    .omit_view = 1,
#endif
#ifdef SYNTAQLITE_CFLAG_SQLITE_OMIT_VIRTUALTABLE
    .omit_virtualtable = 1,
#endif
#ifdef SYNTAQLITE_CFLAG_SQLITE_OMIT_WINDOWFUNC
    .omit_windowfunc = 1,
#endif
#ifdef SYNTAQLITE_CFLAG_SQLITE_ENABLE_ORDERED_SET_AGGREGATES
    .enable_ordered_set_aggregates = 1,
#endif
#ifdef SYNTAQLITE_CFLAG_SQLITE_ENABLE_UPDATE_DELETE_LIMIT
    .enable_update_delete_limit = 1,
#endif
};
#endif  // SYNTAQLITE_SQLITE_CFLAGS


#endif  /* SYNTAQLITE_SQLITE_CFLAGS_H */
/* ======== end: syntaqlite/cflags.h ======== */

/* ======== begin: syntaqlite/config.h ======== */
#ifndef SYNTAQLITE_CONFIG_H
#define SYNTAQLITE_CONFIG_H
// Copyright 2025 The syntaqlite Authors. All rights reserved.
// Licensed under the Apache License, Version 2.0.

// Shared types for syntaqlite.
//
// SyntaqliteMemMethods lets callers override the allocator used for all
// internal allocations. Pass a pointer to one when creating a parser or
// tokenizer, or pass NULL to use the default (malloc/free).
//
// Usage:
//   // Pure defaults — no allocator needed:
//   SyntaqliteParser* p = syntaqlite_parser_create(NULL);  // see
//   parser.h
//
//   // Custom allocator:
//   SyntaqliteMemMethods mem = { my_malloc, my_free };
//   SyntaqliteParser* p = syntaqlite_parser_create(&mem);  // see
//   parser.h


#include <stddef.h>
#include <stdlib.h>

// ---------------------------------------------------------------------------
// Shared library export
// ---------------------------------------------------------------------------

#ifndef SYNTAQLITE_API
#if defined(SYNTAQLITE_SHARED)
#if defined(_WIN32) || defined(__CYGWIN__)
#if defined(SYNTAQLITE_BUILDING)
#define SYNTAQLITE_API __declspec(dllexport)
#else
#define SYNTAQLITE_API __declspec(dllimport)
#endif
#elif defined(__GNUC__) && __GNUC__ >= 4
#define SYNTAQLITE_API __attribute__((visibility("default")))
#else
#define SYNTAQLITE_API
#endif
#else
#define SYNTAQLITE_API
#endif
#endif

#ifdef __cplusplus
extern "C" {
#endif

// ---------------------------------------------------------------------------
// Memory methods
// ---------------------------------------------------------------------------

// Allocator for all syntaqlite-internal allocations. All function
// pointers must be non-NULL. Pass a pointer to one of these to
// syntaqlite_*_create() functions, or pass NULL for malloc/realloc/free.
typedef struct SyntaqliteMemMethods {
  void* (*xMalloc)(size_t);  // Allocate size bytes. Must not return NULL.
  void* (*xRealloc)(void*,
                    size_t);  // Resize allocation. May return new pointer.
  void (*xFree)(void*);       // Free a pointer returned by xMalloc/xRealloc.
} SyntaqliteMemMethods;

// Default allocator (system malloc/realloc/free). Use this when you need
// an explicit allocator but have no custom one:
//   SyntaqliteParser* p =
//   syntaqlite_parser_create(&SYNTAQLITE_MEM_METHODS_DEFAULT);
#define SYNTAQLITE_MEM_METHODS_DEFAULT \
  ((SyntaqliteMemMethods){malloc, realloc, free})

#ifdef __cplusplus
}
#endif


#endif  /* SYNTAQLITE_CONFIG_H */
/* ======== end: syntaqlite/config.h ======== */

/* ======== begin: syntaqlite/types.h ======== */
#ifndef SYNTAQLITE_TYPES_H
#define SYNTAQLITE_TYPES_H
// Copyright 2025 The syntaqlite Authors. All rights reserved.
// Licensed under the Apache License, Version 2.0.

// Core types shared between the engine and dialect layers.


#include <stdint.h>

#ifdef __cplusplus
extern "C" {
#endif

#define SYNTAQLITE_NULL_NODE 0xFFFFFFFFu

// ── Position / length / index typedefs ───────────────────────────────────────
//
// These typedefs are documentation aliases over `uint32_t` — they describe
// what *kind* of value a field or parameter holds (which is essential when
// reading the API at a glance) without changing the binary layout or
// imposing any compile-time enforcement.  Mixing them at the call site is
// not a type error in C.
//
// Offsets describe a *position within a specific buffer*, so they are
// split by the buffer they index into.  All are byte-based:
//   - StmtOffset   — byte offset from the start of the current
//                    statement's source slice (`syntaqlite_parser_text`).
//   - DocOffset    — byte offset from the start of the full bound
//                    source (`syntaqlite_parser_full_text`).
//   - LayerOffset  — byte offset into an expansion layer's internal
//                    buffer (e.g. `SyntaqliteTextSpan`,
//                    `SyntaqliteMacroArgSegment`).  Resolve via the
//                    parser's span accessors; never use directly as a
//                    source offset.
//
// Lengths are unitless byte counts — a length of 5 means "5 bytes",
// regardless of which buffer those bytes come from.  A single typedef
// (`SyntaqliteLength`) flags a value as "byte count" rather than an
// opaque id / flag / ordinal.
//
// Indices and numeric positions:
//   - TokenIdx     — 0-based index into a statement's token stream.
//   - LineNumber / ColumnNumber — 1-based, with `0` meaning "unknown".

typedef uint32_t SyntaqliteStmtOffset;
typedef uint32_t SyntaqliteDocOffset;
typedef uint32_t SyntaqliteLayerOffset;

typedef uint32_t SyntaqliteLength;

typedef uint32_t SyntaqliteTokenIdx;

typedef uint32_t SyntaqliteLineNumber;
typedef uint32_t SyntaqliteColumnNumber;

typedef uint32_t SyntaqliteCompletionContext;
#define SYNTAQLITE_COMPLETION_CONTEXT_UNKNOWN ((SyntaqliteCompletionContext)0)
#define SYNTAQLITE_COMPLETION_CONTEXT_EXPRESSION \
  ((SyntaqliteCompletionContext)1)
#define SYNTAQLITE_COMPLETION_CONTEXT_TABLE_REF ((SyntaqliteCompletionContext)2)

// A span field embedded in an AST node.
//
// The `offset` / `length` fields are not directly usable: for spans
// tokenized from a macro expansion they reference an internal expansion
// layer buffer, not the input source.  Always read a span through the
// parser's span accessors:
//
//   - `syntaqlite_parser_span_text(p, &span, &len)` — authored bytes
//     (slice of input source); walks through macro call sites and
//     substituted arg segments.
//   - `syntaqlite_parser_span_expanded_text(p, &span, &len)` — the
//     bytes the tokenizer actually saw, which for macro-expanded spans
//     live in an expansion layer buffer.
//   - `syntaqlite_parser_traceback(p, &span, ...)` — the full outermost
//     → innermost expansion chain for diagnostics, with argument-level
//     drill-through fidelity for spans inside substituted macro args.
typedef struct SyntaqliteTextSpan {
  SyntaqliteLayerOffset offset;
  SyntaqliteLength length;
  uint32_t flags;
  uint32_t _layer_id;  // Internal: 0 = source, >0 = macro expansion layer.
} SyntaqliteTextSpan;

// ── Span flags ───────────────────────────────────────────────────────────────

// Quote character flags on `SyntaqliteTextSpan.flags`.  At most one is
// set; none means the identifier was unquoted.  Prefer the accessors
// below over reading these bits directly.
//
// The span's offset/length point at the *dequoted* inner text — the
// surrounding quote bytes are not part of the span.  These flags are
// the only way to recover which character bracketed the identifier
// after dequoting.
#define SYNTAQLITE_SPAN_FLAG_QUOTE_DOUBLE ((uint32_t)1u)    // "..."
#define SYNTAQLITE_SPAN_FLAG_QUOTE_BACKTICK ((uint32_t)2u)  // `...`
#define SYNTAQLITE_SPAN_FLAG_QUOTE_BRACKET ((uint32_t)4u)   // [...]

#define SYNTAQLITE_SPAN_QUOTE_MASK                                           \
  (SYNTAQLITE_SPAN_FLAG_QUOTE_DOUBLE | SYNTAQLITE_SPAN_FLAG_QUOTE_BACKTICK | \
   SYNTAQLITE_SPAN_FLAG_QUOTE_BRACKET)

// Was this identifier quoted in source?  Returns nonzero if `sp` came
// from any of `"..."`, `` `...` ``, or `[...]`.
static inline int syntaqlite_span_is_quoted(SyntaqliteTextSpan sp) {
  return (sp.flags & SYNTAQLITE_SPAN_QUOTE_MASK) != 0;
}

// The character that opened this identifier's quotes in source: `"`,
// `` ` ``, or `[`.  Returns 0 if the span was unquoted.  For `[...]`
// only the opener is reported; the closer is always `]`.
static inline char syntaqlite_span_quote_char(SyntaqliteTextSpan sp) {
  if (sp.flags & SYNTAQLITE_SPAN_FLAG_QUOTE_DOUBLE)
    return '"';
  if (sp.flags & SYNTAQLITE_SPAN_FLAG_QUOTE_BACKTICK)
    return '`';
  if (sp.flags & SYNTAQLITE_SPAN_FLAG_QUOTE_BRACKET)
    return '[';
  return 0;
}

#ifdef __cplusplus
}
#endif


#endif  /* SYNTAQLITE_TYPES_H */
/* ======== end: syntaqlite/types.h ======== */

/* ======== begin: syntaqlite/dialect.h ======== */
#ifndef SYNTAQLITE_DIALECT_H
#define SYNTAQLITE_DIALECT_H
// Copyright 2025 The syntaqlite Authors. All rights reserved.
// Licensed under the Apache License, Version 2.0.

// Dialect descriptor.
//
// A concrete dialect (e.g. SQLite, Perfetto) fills one static
// SyntaqliteDialectTemplate and exposes it via a SyntaqliteDialect accessor:
//
//   SyntaqliteDialect syntaqlite_<name>_dialect(void);
//
// ── Custom include ──────────────────────────────────────────────────────
//
// Define SYNTAQLITE_CUSTOM_INCLUDE to a filename to have it included before
// any macro decisions. This follows the SQLite SQLITE_CUSTOM_INCLUDE pattern.
//
//   cc -DSYNTAQLITE_CUSTOM_INCLUDE=synq_config.h -I. ...
//
// The config file can set SYNTAQLITE_SQLITE_VERSION, SYNTAQLITE_SQLITE_CFLAGS,
// and individual SYNTAQLITE_CFLAG_* defines.


#ifdef SYNTAQLITE_CUSTOM_INCLUDE
#define SYNQ_STRINGIFY_(x) #x
#define SYNQ_STRINGIFY(x) SYNQ_STRINGIFY_(x)
#include SYNQ_STRINGIFY(SYNTAQLITE_CUSTOM_INCLUDE)
#endif

#include <stddef.h>
#include <stdint.h>
#include <stdio.h>


#ifdef __cplusplus
extern "C" {
#endif

// ── Token category ────────────────────────────────────────────────────────

// Semantic category of a SQL token, used for syntax highlighting.
// Stored as uint8_t in SyntaqliteDialectTemplate::token_categories.
typedef enum {
  SYNQ_TOKEN_CATEGORY_OTHER = 0,
  SYNQ_TOKEN_CATEGORY_KEYWORD = 1,
  SYNQ_TOKEN_CATEGORY_IDENTIFIER = 2,
  SYNQ_TOKEN_CATEGORY_STRING = 3,
  SYNQ_TOKEN_CATEGORY_NUMBER = 4,
  SYNQ_TOKEN_CATEGORY_OPERATOR = 5,
  SYNQ_TOKEN_CATEGORY_PUNCTUATION = 6,
  SYNQ_TOKEN_CATEGORY_COMMENT = 7,
  SYNQ_TOKEN_CATEGORY_VARIABLE = 8,
  SYNQ_TOKEN_CATEGORY_FUNCTION = 9,
  SYNQ_TOKEN_CATEGORY_TYPE = 10,
} SynqTokenCategory;

// ── Macro invocation style ───────────────────────────────────────────────

// How the batch parsing loop (`syntaqlite_parser_next`) auto-detects macro
// invocations in the token stream.  In incremental/embedded mode, callers
// handle macros via `begin_macro`/`end_macro` directly and this is ignored.
typedef enum {
  // No macro detection.
  SYNQ_MACRO_STYLE_NONE = 0,
  // Rust-style: `name!(...)` — ID followed by `!` then balanced parens.
  SYNQ_MACRO_STYLE_RUST = 1,
} SyntaqliteMacroStyle;

// ── Types used by the parser vtable ─────────────────────────────────────
typedef struct SynqParseCtx SynqParseCtx;

typedef struct SynqParseToken {
  const char* z;                 // pointer to start of token in its buffer
  SyntaqliteLength n;            // byte length of token
  uint32_t type;                 // token type ID (SYNTAQLITE_TK_*)
  SyntaqliteTokenIdx token_idx;  // index into parser's token vec
                                 // (0xFFFFFFFF if not collecting)
  SyntaqliteLayerOffset offset;  // byte offset within the token's buffer;
                                 // set at shift time so reductions don't
                                 // depend on ctx->source which may have
                                 // been swapped back after a macro
                                 // expansion
  uint32_t layer_id;             // 0 = original source,
                                 // 1+ = expansion layer index
} SynqParseToken;

typedef struct SyntaqliteFieldRangeMeta SyntaqliteFieldRangeMeta;
typedef struct SyntaqliteRangeMetaEntry SyntaqliteRangeMetaEntry;
typedef struct SyntaqliteFieldMeta SyntaqliteFieldMeta;

// Forward declaration for use in function pointers below.
typedef struct SyntaqliteDialect SyntaqliteDialect;

// ── Dialect template (static dialect data) ────────────────────────────────

// Static dialect descriptor: parser vtable, AST metadata, formatter bytecode,
// and semantic-role tables.  All fields are always present; optional sections
// (fmt, validation) are zeroed when the feature is not compiled in.
typedef struct SyntaqliteDialectTemplate {
  const char* name;

  // Range metadata for the macro straddle check.
  const SyntaqliteRangeMetaEntry* range_meta;

  // AST metadata — all arrays indexed by node tag, length = node_count.
  uint32_t node_count;
  const char* const* node_names;
  const SyntaqliteFieldMeta* const* field_meta;
  const uint8_t* field_meta_counts;
  const uint8_t* list_tags;  // 1 = list node

  // Parser lifecycle (Lemon parser, provided by grammar)
  void* (*parser_alloc)(void* (*mallocProc)(size_t), SynqParseCtx* pCtx);
  void (*parser_init)(void* parser, SynqParseCtx* pCtx);
  void (*parser_finalize)(void* parser);
  void (*parser_free)(void* parser, void (*freeProc)(void*));
  void (*parser_feed)(void* parser, int token_type, SynqParseToken minor);
  void (*parser_trace)(FILE* trace_file, char* prompt);
  uint32_t (*parser_expected_tokens)(void* parser,
                                     uint32_t* out_tokens,
                                     uint32_t out_cap);
  uint32_t (*parser_completion_context)(void* parser);

  // Lemon %fallback lookup: returns the fallback token for `iToken`,
  // or 0 if it has none.  Used by the context-sensitive keyword analysis
  // to determine whether a token can serve as an identifier.
  int (*parser_fallback)(int iToken);

  // Tokenizer (provided by grammar)
  int64_t (*get_token)(const SyntaqliteDialect* env,
                       const unsigned char* z,
                       int* tokenType);

  // Keyword table exported by mkkeywordhash output (`sqlite_keyword.c`).
  const char* keyword_text;         // concatenated keyword bytes
  const uint16_t* keyword_offsets;  // keyword_count entries
  const uint8_t* keyword_lens;      // keyword_count entries
  const uint8_t* keyword_codes;   // keyword_count entries (token type ordinals)
  const uint32_t* keyword_count;  // points to keyword count scalar

  // Token metadata (indexed by token type ordinal)
  // length = token_type_count; NULL = no categories
  const uint8_t* token_categories;
  uint32_t token_type_count;

  // Macro invocation style for the batch parsing loop.
  // Determines how the parser auto-detects macro calls when tokenizing.
  // In incremental/embedded mode, callers handle macros via
  // begin_macro/end_macro directly — this field is only used by
  // syntaqlite_parser_next().
  SyntaqliteMacroStyle macro_style;

  // Formatter bytecode (zeroed when formatting is not compiled in).
  const uint8_t* fmt_str_data;
  const uint32_t* fmt_str_offsets;
  uint32_t fmt_str_count;
  const uint16_t* fmt_enum_display;
  uint32_t fmt_enum_display_count;
  const uint8_t* fmt_ops;
  uint32_t fmt_ops_count;
  const uint32_t* fmt_dispatch;
  uint32_t fmt_dispatch_count;
  const uint8_t* fmt_prec_table;
  uint32_t fmt_prec_table_count;
  const uint32_t* fmt_expr_meta;
  uint32_t fmt_expr_meta_count;

  // Semantic role tables (zeroed when validation is not compiled in).
  const uint8_t* roles_data;
  uint32_t roles_count;
  const uint8_t* macro_defs_data;
  uint32_t macro_defs_count;
} SyntaqliteDialectTemplate;

// ── Configured dialect handle ─────────────────────────────────────────────

typedef struct SyntaqliteDialect {
  const SyntaqliteDialectTemplate* tmpl;
  int32_t sqlite_version;   // Target version (e.g., 3035000). INT32_MAX =
                            // latest.
  SyntaqliteCflags cflags;  // Active compile-time flags.
} SyntaqliteDialect;

// Default dialect: latest version, no cflags.
#define SYNQ_DIALECT_DEFAULT(d) {(d), INT32_MAX, SYNQ_CFLAGS_DEFAULT}

// ── Dynamic dialect loading ───────────────────────────────────────────────

// Opaque handle for a dynamically loaded dialect.
// Owns the library handle; destroy with syntaqlite_loaded_dialect_destroy().
typedef struct SyntaqliteLoadedDialect SyntaqliteLoadedDialect;

// Load a dialect from a shared library (.so / .dylib / .dll).
// `name` may be NULL to resolve `syntaqlite_dialect`; otherwise resolves
// `syntaqlite_{name}_dialect`.
// Always returns a non-NULL handle. Check syntaqlite_loaded_dialect_error()
// to detect failures (returns NULL on success, error string on failure).
SYNTAQLITE_API SyntaqliteLoadedDialect* syntaqlite_dialect_load(
    const char* path,
    const char* name);

// Error message from the load attempt, or NULL on success.
SYNTAQLITE_API const char* syntaqlite_loaded_dialect_error(
    const SyntaqliteLoadedDialect* ld);

// Get the SyntaqliteDialect value from a successfully loaded dialect.
// Undefined if syntaqlite_loaded_dialect_error() returned non-NULL.
SYNTAQLITE_API SyntaqliteDialect
syntaqlite_loaded_dialect_get(const SyntaqliteLoadedDialect* ld);

// Free a loaded dialect. Unloads the shared library. No-op if ld is NULL.
SYNTAQLITE_API void syntaqlite_loaded_dialect_destroy(
    SyntaqliteLoadedDialect* ld);

#ifdef __cplusplus
}
#endif


#endif  /* SYNTAQLITE_DIALECT_H */
/* ======== end: syntaqlite/dialect.h ======== */

/* ======== begin: syntaqlite/parser.h ======== */
#ifndef SYNTAQLITE_PARSER_H
#define SYNTAQLITE_PARSER_H
// Copyright 2025 The syntaqlite Authors. All rights reserved.
// Licensed under the Apache License, Version 2.0.

// Streaming parser for SQL — the main entry point for AST access.
//
// Produces a typed AST from SQL text. Each call to syntaqlite_parser_next()
// parses one statement and returns a SYNTAQLITE_PARSE_* status code. Result
// details are accessed via the syntaqlite_result_*() accessors, which are
// valid until the next syntaqlite_parser_next(), reset(), or destroy() call.
// The arena is reset between statements, so only O(statement) memory is used.
//
// Lifecycle: create → [configure] → reset → next (loop) → read nodes → destroy.
// A single parser can be reused across inputs by calling reset() again.
//
// Usage:
//   SyntaqliteParser* p = syntaqlite_parser_create(NULL);
//   syntaqlite_parser_reset(p, sql, len);
//   for (;;) {
//     int32_t rc = syntaqlite_parser_next(p);
//     switch (rc) {
//       case SYNTAQLITE_PARSE_DONE:
//         goto done;
//       case SYNTAQLITE_PARSE_OK: {
//         uint32_t root = syntaqlite_result_root(p);
//         const void* node = syntaqlite_parser_node(p, root);
//         // cast to dialect-specific node type and switch on tag ...
//         break;
//       }
//       case SYNTAQLITE_PARSE_ERROR: {
//         fprintf(stderr, "%s\n", syntaqlite_result_error_msg(p));
//         // syntaqlite_result_recovery_root(p) may return a partial AST,
//         // or SYNTAQLITE_NULL_NODE if no recovery was possible. Either way,
//         // keep looping — the parser will continue to the next statement.
//         break;
//       }
//     }
//   }
//   syntaqlite_parser_destroy(p);
//
// Token/comment capture is OFF by default. If you need
// syntaqlite_result_tokens() / syntaqlite_result_comments() (for formatting,
// diagnostics, etc.), call syntaqlite_parser_set_collect_tokens(p, 1) before
// the first reset().
// For custom dialects, see the "Advanced" section below.
// For macro-aware or incremental token feeding, see incremental.h.


#include <stdint.h>
#include <stdio.h>


#ifdef __cplusplus
extern "C" {
#endif

// ---------------------------------------------------------------------------
// Parser handle and return codes
// ---------------------------------------------------------------------------

// Opaque parser handle (heap-allocated, reusable across inputs).
typedef struct SyntaqliteParser SyntaqliteParser;

// Return codes from syntaqlite_parser_next() and syntaqlite_parser_finish().
//
//   DONE  = no statement (all input consumed, or only bare semicolons)
//   OK    = statement parsed cleanly; nodes are valid
//   ERROR = statement has syntax/runtime error
//           - use syntaqlite_result_recovery_root() to check whether a
//             partial recovery tree is available
//           - syntaqlite_result_root() is always SYNTAQLITE_NULL_NODE on ERROR
//
// The integer values are stable ABI (DONE=0, OK=1, ERROR=-1).
#define SYNTAQLITE_PARSE_DONE 0
#define SYNTAQLITE_PARSE_OK 1
#define SYNTAQLITE_PARSE_ERROR (-1)

// Generic success/error codes for setters and other small APIs that
// return 0/-1 status.  Stable ABI.
//
//   OK               = operation succeeded
//   ERR_ALREADY_USED = configuration call made after the parser was sealed
//                      (i.e. after the first reset()/next()/feed_token())
//   ERR_OMITTED      = feature compiled out of this build (e.g. macros
//                      disabled via SYNTAQLITE_OMIT_MACROS)
#define SYNTAQLITE_OK 0
#define SYNTAQLITE_ERR_ALREADY_USED (-1)
#define SYNTAQLITE_ERR_OMITTED (-1)

// ---------------------------------------------------------------------------
// Core API — create, reset, parse, destroy
// ---------------------------------------------------------------------------

#ifndef SYNTAQLITE_OMIT_SQLITE_API
// Allocate a parser for the built-in SQLite dialect.  The parser is
// inert until `reset()` binds a source buffer.  Pass NULL for `mem` to
// use malloc/free.
SYNTAQLITE_API SyntaqliteParser* syntaqlite_parser_create(
    const SyntaqliteMemMethods* mem);
#endif

// Bind a source buffer and reset all internal state. The source must remain
// valid until the next reset() or destroy(). Can be called again to parse a
// new input without reallocating — all previous nodes are invalidated.
SYNTAQLITE_API void syntaqlite_parser_reset(SyntaqliteParser* p,
                                            const char* source,
                                            SyntaqliteLength len);

// Parse the next SQL statement. Call in a loop until SYNTAQLITE_PARSE_DONE.
// Bare semicolons between statements are skipped automatically.
// The arena is reset at the start of each call — pointers from the previous
// call become invalid.
//
// Returns one of the SYNTAQLITE_PARSE_* codes.
SYNTAQLITE_API int32_t syntaqlite_parser_next(SyntaqliteParser* p);

// Free the parser, its arena, and all its nodes. No-op if p is NULL.
SYNTAQLITE_API void syntaqlite_parser_destroy(SyntaqliteParser* p);

// ---------------------------------------------------------------------------
// Configuration — call after create(), before the first reset()
// ---------------------------------------------------------------------------

// Enable token/comment collection for result_tokens/result_comments.
// Default: off (0), in which case those arrays are empty.
// Returns SYNTAQLITE_OK on success, SYNTAQLITE_ERR_ALREADY_USED if the
// parser has already been used.
SYNTAQLITE_API int32_t syntaqlite_parser_set_collect_tokens(SyntaqliteParser* p,
                                                            uint32_t enable);

// Enable parser trace output (debug builds only). Default: off (0).
// Returns SYNTAQLITE_OK on success, SYNTAQLITE_ERR_ALREADY_USED if the
// parser has already been used.
SYNTAQLITE_API int32_t syntaqlite_parser_set_trace(SyntaqliteParser* p,
                                                   uint32_t enable);

// Enable macro fallback: when the dialect uses SYNQ_MACRO_STYLE_RUST and a
// name!(args) call is encountered but the name is NOT in the macro registry,
// consume the entire name!(args) as a single TK_ID token instead of raising
// a parse error. A MacroRewrite is recorded so the formatter can emit the
// call verbatim. Default: off (0).
// Returns SYNTAQLITE_OK on success, SYNTAQLITE_ERR_ALREADY_USED if the
// parser has already been used, SYNTAQLITE_ERR_OMITTED if macros are
// compiled out (SYNTAQLITE_OMIT_MACROS).
SYNTAQLITE_API int32_t syntaqlite_parser_set_macro_fallback(SyntaqliteParser* p,
                                                            uint32_t enable);

// Enable per-node extent tracking.  When enabled, the parser records
// the source byte range of every AST node it commits to the arena,
// accessible via `syntaqlite_parser_node_text`.  Default: off (0).
// Returns SYNTAQLITE_OK on success, SYNTAQLITE_ERR_ALREADY_USED if the
// parser has already been used.
SYNTAQLITE_API int32_t
syntaqlite_parser_set_collect_node_extents(SyntaqliteParser* p,
                                           uint32_t enable);

// ---------------------------------------------------------------------------
// Result accessors
// Valid until the next syntaqlite_parser_next(), reset(), or destroy() call.
// ---------------------------------------------------------------------------

// Statement root node ID for SYNTAQLITE_PARSE_OK results.
// Returns SYNTAQLITE_NULL_NODE for DONE/ERROR.
SYNTAQLITE_API uint32_t syntaqlite_result_root(SyntaqliteParser* p);

// Partial recovery root for SYNTAQLITE_PARSE_ERROR results.
// Returns SYNTAQLITE_NULL_NODE when no recovery tree is available.
// Recovery trees may include grammar-level error nodes where parsing resumed.
SYNTAQLITE_API uint32_t syntaqlite_result_recovery_root(SyntaqliteParser* p);

// Human-readable error message, or NULL.
SYNTAQLITE_API const char* syntaqlite_result_error_msg(SyntaqliteParser* p);

// Statement-relative byte offset of error token (0xFFFFFFFF = unknown).
SYNTAQLITE_API SyntaqliteStmtOffset
syntaqlite_result_error_offset(SyntaqliteParser* p);

// Byte length of error token (0 = unknown).
SYNTAQLITE_API SyntaqliteLength
syntaqlite_result_error_length(SyntaqliteParser* p);

// A comment captured during parsing.
//
// Each comment is bound at parse time to one of the statement's tokens:
//   - `side == SYNQ_COMMENT_LEADING` and `token_idx == N` means the comment
//     appears immediately before token N (no significant token between them
//     in the source) and either token N is the first token of the statement
//     or the comment is on its own source line.
//   - `side == SYNQ_COMMENT_TRAILING` and `token_idx == N` means the comment
//     appears on the same source line as token N's end, with no significant
//     token between them.
// `token_idx` indexes into the same per-statement token array returned by
// `syntaqlite_result_tokens`.  When the comment trails the last token of a
// statement and no following statement exists, `token_idx` may equal
// `count` (one past the last token) — consumers should treat that as
// "statement-trailing with no owner."
typedef uint8_t SyntaqliteCommentSide;
#define SYNQ_COMMENT_LEADING ((SyntaqliteCommentSide)0)
#define SYNQ_COMMENT_TRAILING ((SyntaqliteCommentSide)1)

typedef struct SyntaqliteComment {
  SyntaqliteStmtOffset offset;
  SyntaqliteLength length;
  SyntaqliteTokenIdx token_idx;  // Index of the owning token in p->tokens.
  uint8_t kind;      // 0 = line comment (--), 1 = block comment (/* */).
  uint8_t side;      // SYNQ_COMMENT_LEADING or SYNQ_COMMENT_TRAILING.
  uint8_t layer_id;  // Layer the comment was tokenized from.
                     // Currently always 0 (authored source): the main
                     // tokenizer only records comments from layer 0.
                     // The field is ABI-stable so future versions can
                     // expose expansion-layer comments without a
                     // breaking change; callers that only want authored
                     // source comments should filter on `layer_id == 0`.
  uint8_t _pad;      // reserved for future use; zero-initialized.
} SyntaqliteComment;

// Token-usage flags: set by the parser during disambiguation to record how
// each token was consumed.  Use SYNQ_TOKEN_FLAG_* as bitmasks on the flags
// field of SyntaqliteParserToken.
typedef uint32_t SyntaqliteParserTokenFlags;
#define SYNQ_TOKEN_FLAG_AS_ID \
  ((SyntaqliteParserTokenFlags)1)  // Consumed as identifier (keyword fallback).
#define SYNQ_TOKEN_FLAG_AS_FUNCTION \
  ((SyntaqliteParserTokenFlags)2)  // Consumed as function name.
#define SYNQ_TOKEN_FLAG_AS_TYPE \
  ((SyntaqliteParserTokenFlags)4)  // Consumed as type name.

// A non-whitespace, non-comment token position captured during parsing.
//
// For tokens produced by macro expansion, `offset` is a byte position in
// the expansion layer's internal buffer (identified by `_layer_id`), not a
// position in the input source.  Consumers that need source-level
// positions should resolve the token's span via the parser's span
// accessors rather than using `offset` directly.
typedef struct SyntaqliteParserToken {
  SyntaqliteLayerOffset offset;
  SyntaqliteLength length;
  uint32_t type;  // Original token type from tokenizer (pre-fallback).
  SyntaqliteParserTokenFlags flags;  // Bitmask of SYNQ_TOKEN_FLAG_* values.
  uint32_t _layer_id;  // Internal: 0 = original source, >0 = expansion layer.
} SyntaqliteParserToken;

// Per-statement token/comment arrays.
// Empty unless collect_tokens is enabled via
// syntaqlite_parser_set_collect_tokens(p, 1) before first reset().
SYNTAQLITE_API const SyntaqliteComment* syntaqlite_result_comments(
    SyntaqliteParser* p,
    uint32_t* count);
SYNTAQLITE_API const SyntaqliteParserToken* syntaqlite_result_tokens(
    SyntaqliteParser* p,
    uint32_t* count);

// Get the comments attached to a specific token.
//
// Returns a pointer to the first comment in `p->comments` whose
// `token_idx == token_idx` and `side == side`, and writes the count of
// such comments to `*count`.  Comments attached to the same token are
// contiguous in `p->comments` and recorded in source order.
//
// Returns NULL with `*count == 0` when there are no matching comments.
SYNTAQLITE_API const SyntaqliteComment* syntaqlite_token_leading_comments(
    SyntaqliteParser* p,
    SyntaqliteTokenIdx token_idx,
    uint32_t* count);

SYNTAQLITE_API const SyntaqliteComment* syntaqlite_token_trailing_comments(
    SyntaqliteParser* p,
    SyntaqliteTokenIdx token_idx,
    uint32_t* count);

// Get the inclusive range of `p->tokens` indices the parser shifted
// while reducing AST node `node_id`.  Since the token-stream
// unification, every shifted terminal — authored source and macro-
// expansion alike — carries a real `token_idx`, so the returned range
// spans all layers the node reduced over.  O(1): the range is
// maintained alongside the byte extent on one shadow stack.
//
// Returns 1 and writes `*first_tok` / `*last_tok` on success.
// Returns 0 when collect_node_extents was not enabled, `node_id` is
// out of range or the null sentinel, or the node reduced over zero
// tokens (pure epsilon).
//
// Typical use is composed with the `syntaqlite_token_{leading,trailing}
// _comments` primitives, or with the `syntaqlite_node_{leading,trailing}
// _comments` helpers below for the boundary-comment case.  Walk the
// full `[first_tok, last_tok]` range when interior comments (on
// keywords, between children) are needed.
SYNTAQLITE_API int32_t
syntaqlite_node_token_range(SyntaqliteParser* p,
                            uint32_t node_id,
                            SyntaqliteTokenIdx* first_tok,
                            SyntaqliteTokenIdx* last_tok);

// Get the comments attached to the boundary tokens of AST node
// `node_id`.  Thin wrappers over
// `syntaqlite_token_leading_comments(first_tok)` and
// `syntaqlite_token_trailing_comments(last_tok)` respectively, where
// (first_tok, last_tok) come from `syntaqlite_node_token_range`.
// Returns NULL with `*count == 0` when the node has no token range
// or no comments on the boundary.  Interior comments (attached to a
// keyword or an intermediate token inside the node) are NOT surfaced
// here — iterate `syntaqlite_token_*_comments` across
// `node_token_range` for those.
SYNTAQLITE_API const SyntaqliteComment* syntaqlite_node_leading_comments(
    SyntaqliteParser* p,
    uint32_t node_id,
    uint32_t* count);

SYNTAQLITE_API const SyntaqliteComment* syntaqlite_node_trailing_comments(
    SyntaqliteParser* p,
    uint32_t node_id,
    uint32_t* count);

// Sentinel value for `SyntaqliteMacroRewrite::parent_idx` meaning "this
// rewrite applies directly to the authored source" (i.e. the rewrite is
// not nested inside another macro's expansion).
#define SYNTAQLITE_MACRO_PARENT_SOURCE UINT32_MAX

// Sentinel value for `SyntaqliteMacroRewrite::body_call_offset` and
// `body_call_length` meaning "this call was tokenized from a $param
// substitution — it has no position in the parent's authored body;
// consumers should descend through the matching arg segment instead."
#define SYNTAQLITE_MACRO_BODY_CALL_ARG_INTERNAL UINT32_MAX

// A recorded macro invocation — enough information to reconstruct a
// source-to-expanded rewrite tree (e.g. to drive Perfetto's
// SqlSource::Rewriter or an equivalent).
//
// Entries are reported in insertion order: outer macros appear before the
// nested macros they contain, and macros at the same nesting level appear
// in source order.
//
// `parent_idx` is either SYNTAQLITE_MACRO_PARENT_SOURCE (the rewrite
// replaces a range in the authored source) or the index of another entry
// in this same flat list (the rewrite replaces a range in that entry's
// `expansion` buffer).
//
// `call_offset` / `call_length` describe the byte range of the macro
// call inside the parent's text: statement-relative when `parent_idx`
// is the source sentinel, otherwise relative to the parent entry's
// `expansion` buffer.
//
// `expansion` is the replacement text for that range.  It is NOT
// NUL-terminated; use `expansion_len`.  Nested macro calls appearing
// inside `expansion` are reported as separate entries that reference this
// entry via their `parent_idx`.
//
// `name` is the macro name as it appears at the call site (NOT
// NUL-terminated; use `name_len`).
//
// `def_line` / `def_col` record the 1-based line/column of the macro
// definition (0 if unknown), for traceback purposes.
//
// Pointers (`expansion`, `name`) are owned by the parser and remain valid
// until the next `syntaqlite_parser_next`, `syntaqlite_parser_reset`, or
// `syntaqlite_parser_destroy` call.
typedef struct SyntaqliteMacroRewrite {
  uint32_t parent_idx;
  // Statement-relative when parent_idx == SYNTAQLITE_MACRO_PARENT_SOURCE,
  // otherwise relative to the parent entry's `expansion` buffer.
  SyntaqliteLayerOffset call_offset;
  SyntaqliteLength call_length;
  const char* expansion;
  SyntaqliteLength expansion_len;
  const char* name;
  SyntaqliteLength name_len;
  SyntaqliteLineNumber def_line;
  SyntaqliteColumnNumber def_col;
  // Position of this call in the *parent's authored body*, computed by
  // inverting the length shifts the parent's $param substitutions
  // introduced.  Both fields equal SYNTAQLITE_MACRO_BODY_CALL_ARG_INTERNAL
  // (UINT32_MAX) when the call was tokenized from a substituted arg's
  // text (no meaningful body position) and consumers should descend
  // through the matching arg segment instead.
  //
  // For top-level rewrites (parent_idx == SYNTAQLITE_MACRO_PARENT_SOURCE)
  // the parent is the authored source, so these equal call_offset /
  // call_length.
  SyntaqliteLayerOffset body_call_offset;
  SyntaqliteLength body_call_length;
  // The buffer the `call_offset` — and every arg offset returned by
  // syntaqlite_macro_rewrite_arg_at — indexes into.  For top-level
  // rewrites (parent_idx == SYNTAQLITE_MACRO_PARENT_SOURCE) this is
  // the current statement source slice; for nested rewrites it is
  // the parent entry's `expansion` buffer.  Consumers can slice the
  // call text as `parent_buffer + call_offset` and the arg texts
  // likewise, without resolving parent_idx themselves.
  //
  // Not NUL-terminated; use `parent_buffer_len`.  Owned by the
  // parser and valid until the next reset / next / destroy call.
  const char* parent_buffer;
  SyntaqliteLength parent_buffer_len;
  // 1 if this call went down the fallback path (unregistered name!
  // kept verbatim as a TK_ID, no expansion, no $param substitutions);
  // 0 if it was expanded by a registered macro.  `expansion_len` is
  // also a useful tell (0 for fallback), but this flag is the
  // authoritative signal.
  uint32_t is_fallback;
} SyntaqliteMacroRewrite;

// Number of macro rewrites recorded for the current statement.
SYNTAQLITE_API uint32_t syntaqlite_result_macro_count(SyntaqliteParser* p);

// Returns the rewrite at `idx` (0-based).  Returns a zero-initialized
// struct if `idx >= syntaqlite_result_macro_count(p)`.
SYNTAQLITE_API SyntaqliteMacroRewrite
syntaqlite_result_macro_rewrite_at(SyntaqliteParser* p, uint32_t idx);

// One $param substitution within a macro expansion.
//
// `body_offset` / `body_length` locate the `$param` token in the macro's
// authored body.  Populated by the template-expansion path; zero for
// macros registered via the raw set_result_with_arg_map API.
//
// `expansion_offset` / `expansion_length` locate the substituted arg
// text in the rewrite's `expansion` buffer.
//
// `origin_parent_idx` + `origin_offset` + `origin_length` locate the
// arg text where it was authored — either in the original source
// (`origin_parent_idx == SYNTAQLITE_MACRO_PARENT_SOURCE`) or in another
// rewrite's `expansion` buffer (rewrite index).  Consumers walk the
// chain of $param substitutions by recursing into the origin rewrite's
// arg segments.
typedef struct SyntaqliteMacroArgSegment {
  SyntaqliteLayerOffset body_offset;
  SyntaqliteLength body_length;
  SyntaqliteLayerOffset expansion_offset;
  SyntaqliteLength expansion_length;
  uint32_t origin_parent_idx;
  SyntaqliteLayerOffset origin_offset;
  SyntaqliteLength origin_length;
} SyntaqliteMacroArgSegment;

// Number of arg segments recorded on the rewrite at `rewrite_idx`.
// Returns 0 if `rewrite_idx` is out of range.
SYNTAQLITE_API uint32_t
syntaqlite_macro_rewrite_arg_segment_count(SyntaqliteParser* p,
                                           uint32_t rewrite_idx);

// Returns the arg segment at `segment_idx` on the rewrite at
// `rewrite_idx`.  Returns a zero-initialized struct if either index is
// out of range.
SYNTAQLITE_API SyntaqliteMacroArgSegment
syntaqlite_macro_rewrite_arg_segment_at(SyntaqliteParser* p,
                                        uint32_t rewrite_idx,
                                        uint32_t segment_idx);

// One top-level argument of a macro call, as written at the call
// site.  Populated for both registered (expanded) and fallback calls:
// the parser scans `name!(a, b, c)` the same way regardless of
// whether `name` resolved to a registered macro.
//
// `offset` is in the same coordinate system as the enclosing
// rewrite's `call_offset`, and indexes into the enclosing rewrite's
// `parent_buffer`.  Slice the arg text as
// `rewrite.parent_buffer + offset` for `length` bytes.  Leading and
// trailing whitespace / comments are trimmed from the range.
typedef struct SyntaqliteMacroCallArg {
  SyntaqliteLayerOffset offset;
  SyntaqliteLength length;
} SyntaqliteMacroCallArg;

// Number of top-level call-site arg spans recorded on the rewrite at
// `rewrite_idx`.  Returns 0 for `name!()` with no args, calls whose
// arity exceeded the scan buffer (rare; >64 args), or out-of-range
// indices.
SYNTAQLITE_API uint32_t
syntaqlite_macro_rewrite_arg_count(SyntaqliteParser* p, uint32_t rewrite_idx);

// Returns the call-site arg at `arg_idx` on the rewrite at
// `rewrite_idx`.  Returns a zero-initialized struct if either index
// is out of range.
SYNTAQLITE_API SyntaqliteMacroCallArg
syntaqlite_macro_rewrite_arg_at(SyntaqliteParser* p,
                                uint32_t rewrite_idx,
                                uint32_t arg_idx);

// ---------------------------------------------------------------------------
// Arena accessors
// ---------------------------------------------------------------------------

// Look up a node by its arena ID. The returned pointer is valid until the
// next syntaqlite_parser_next(), reset(), or destroy(). Cast to the
// dialect-specific node union type and use the tag field to determine which
// member to read.
SYNTAQLITE_API const void* syntaqlite_parser_node(SyntaqliteParser* p,
                                                  uint32_t node_id);

// Source slice for the last-completed statement.  Writes the
// statement's document-absolute byte offset within the bound source to
// `*out_offset` (optional) and its length to `*out_len` (optional).
// Every offset the parser emits for this statement — tokens, comments,
// node extents, spans, error offset, macro rewrite call offsets — is
// measured from the returned pointer.  Returns NULL / 0 / 0 when no
// statement has been produced yet.
SYNTAQLITE_API const char* syntaqlite_parser_text(
    SyntaqliteParser* p,
    SyntaqliteDocOffset* out_offset,
    SyntaqliteLength* out_len);

// Full SQL source bound by the last reset() call.  For multi-statement
// input, this is the whole input.
SYNTAQLITE_API const char* syntaqlite_parser_full_text(
    SyntaqliteParser* p,
    SyntaqliteLength* out_len);

// Post-expansion text for the current statement — materializes the
// statement's source with every currently-active macro call replaced
// by its expansion into a parser-owned scratch buffer.  The returned
// pointer is valid until the next `*_expanded_text` call on the same
// parser or until the parser advances to the next statement.
//
// `*out_len` receives the byte length of the materialized buffer,
// which may differ from the authored statement length.
SYNTAQLITE_API const char* syntaqlite_parser_expanded_text(
    SyntaqliteParser* p,
    SyntaqliteLength* out_len);

// Return the number of nodes currently in the arena.
SYNTAQLITE_API uint32_t syntaqlite_parser_node_count(SyntaqliteParser* p);

// ---------------------------------------------------------------------------
// Source text accessors — spans, nodes, and tracebacks
// ---------------------------------------------------------------------------

// One frame in a span traceback, produced by
// `syntaqlite_parser_traceback`.  Each frame is self-contained: it
// carries a snippet buffer to render the caret against, the offset
// within that buffer, and an optional macro name for non-root frames.
//
// `name` is `NULL` (and `name_len == 0`) for the root source frame, and
// borrows from the macro registry entry (valid for the parse's lifetime)
// for macro expansion frames.  `snippet` borrows either the user's input
// source (for the root frame) or the corresponding expansion layer's
// buffer (for macro frames).
//
// `line` and `col` are 1-based and computed from `offset_in_snippet`
// within `snippet`.
typedef struct SyntaqliteTracebackFrame {
  const char* name;
  SyntaqliteLength name_len;
  SyntaqliteLineNumber line;
  SyntaqliteColumnNumber col;
  const char* snippet;
  SyntaqliteLength snippet_len;
  SyntaqliteLayerOffset offset_in_snippet;
  SyntaqliteLength length_in_snippet;
} SyntaqliteTracebackFrame;

// Build a traceback for a span and return a pointer to a parser-owned
// frame array.  Frames are ordered from outermost (the root source
// frame) to innermost (the position inside the deepest macro
// expansion layer).
//
// When the span was tokenized inside a substituted macro argument, the
// walk drills through the substitution to the argument's origin layer
// — the innermost frame points at the user's authored arg text rather
// than at the macro call site.
//
// Writes the number of frames into `*out_count`.  For a span not
// inside any macro expansion, returns a single-frame slice with
// `name == NULL`.  Returns NULL (and writes 0 to `*out_count`) for
// empty or invalid spans.
//
// The returned pointer is valid until the next call to
// `syntaqlite_parser_traceback` on the same parser or until the next
// `syntaqlite_parser_next` resets the current statement — callers
// that need to retain frames across such calls must copy them out.
SYNTAQLITE_API const SyntaqliteTracebackFrame* syntaqlite_parser_traceback(
    SyntaqliteParser* p,
    const SyntaqliteTextSpan* span,
    uint32_t* out_count);

// Post-expansion text for `span` — the bytes the tokenizer actually saw.
// For macro-free spans, a slice of the input source.  For spans inside a
// macro expansion, a slice of the expansion layer's buffer.  Writes the
// slice's byte length to `*out_len`.  Always a direct slice — no
// allocation.
//
// Returns NULL (and writes 0 to `*out_len`) for empty or invalid spans.
SYNTAQLITE_API const char* syntaqlite_parser_span_expanded_text(
    SyntaqliteParser* p,
    const SyntaqliteTextSpan* span,
    SyntaqliteLength* out_len);

// Authored text for `span` — always a slice of the current statement's
// source (the same buffer `syntaqlite_parser_text` returns).
//
// For macro-free spans, identical to `span_expanded_text`.  For spans
// inside a macro expansion, walks the expansion-layer chain:
//   - If the span falls inside a substituted `$param` arg segment, drills
//     to the arg's origin text in the caller's layer (recursively).
//   - Otherwise, collapses to the outermost `name!(...)` call site.
//
// Always a direct slice of the statement source — no allocation.
// Returns NULL (and writes 0 to `*out_len`) for empty or invalid spans.
//
// `out_offset` is optional; when non-NULL it receives the
// statement-relative byte offset where the returned slice begins.
// To convert to a document-absolute offset, add the offset
// `syntaqlite_parser_text` writes to its own `out_offset`.
// Written 0 for empty or invalid spans.
SYNTAQLITE_API const char* syntaqlite_parser_span_text(
    SyntaqliteParser* p,
    const SyntaqliteTextSpan* span,
    SyntaqliteLength* out_len,
    SyntaqliteStmtOffset* out_offset);

// Authored source text for AST node `node_id` — the analogue of
// `syntaqlite_parser_span_text` for whole nodes rather than spans.
// Offsets are statement-relative, same as `syntaqlite_parser_span_text`.
//
// Requires per-node extent tracking to be enabled via
// `syntaqlite_parser_set_collect_node_extents` before the first
// `reset()`.  Returns a direct slice of the current statement's
// source — no allocation.
//
// Returns NULL (and writes 0 to `*out_len` / `*out_offset`) when
// extent tracking is disabled, the node id is unknown, or no extent
// was recorded for it.
SYNTAQLITE_API const char* syntaqlite_parser_node_text(
    SyntaqliteParser* p,
    uint32_t node_id,
    SyntaqliteLength* out_len,
    SyntaqliteStmtOffset* out_offset);

// Post-expansion text for AST node `node_id` — the analogue of
// `syntaqlite_parser_span_expanded_text` for whole nodes.
//
// For nodes whose tokens all live in a single layer (the common
// case), the return value is a direct slice of that layer's buffer —
// the input source for root-layer nodes, or a macro expansion buffer
// for nodes built entirely from one expansion.
//
// For nodes whose tokens cross layers (e.g. `SELECT id!(42)` where
// `SELECT` lives in the root source and `42` lives in `id`'s
// expansion), the result is materialized into a parser-owned scratch
// buffer by walking the node's root range and inlining each enclosed
// macro call's expansion.  The returned pointer is valid until the
// next call to `syntaqlite_parser_node_expanded_text` on the same
// parser or until the parser advances to the next statement — copy
// the bytes out if you need them to outlive that.
//
// Returns NULL (and writes 0 to `*out_len`) when extent tracking is
// disabled, the node id is unknown, or no extent was recorded for it.
SYNTAQLITE_API const char* syntaqlite_parser_node_expanded_text(
    SyntaqliteParser* p,
    uint32_t node_id,
    SyntaqliteLength* out_len);

// ---------------------------------------------------------------------------
// Macro-expansion queries
// ---------------------------------------------------------------------------

// Returns 1 if `span` was tokenized from the original source (layer 0),
// 0 if it was produced by a macro expansion.  Returns 0 for empty spans.
static inline int syntaqlite_span_is_macro_free(
    const SyntaqliteTextSpan* span) {
  return span->length > 0 && span->_layer_id == 0;
}

// Returns 1 if all tokens of AST node `node_id` live in layer 0 (original
// source), 0 otherwise.  Returns 0 when extent tracking is disabled, the
// node id is unknown, or no extent was recorded.
//
// Requires `syntaqlite_parser_set_collect_node_extents(p, 1)` before the
// first `reset()`.
SYNTAQLITE_API int syntaqlite_node_is_macro_free(SyntaqliteParser* p,
                                                 uint32_t node_id);

// ---------------------------------------------------------------------------
// Node and list helpers
// ---------------------------------------------------------------------------

static inline uint32_t syntaqlite_node_is_present(uint32_t node_id) {
  return node_id != SYNTAQLITE_NULL_NODE;
}

static inline uint32_t syntaqlite_list_count(const void* list_node) {
  const uint32_t* raw = (const uint32_t*)list_node;
  return raw[1];
}

static inline uint32_t syntaqlite_list_child_id(const void* list_node,
                                                uint32_t index) {
  const uint32_t* raw = (const uint32_t*)list_node;
  return raw[2 + index];
}

static inline const void* syntaqlite_list_child(SyntaqliteParser* p,
                                                const void* list_node,
                                                uint32_t index) {
  uint32_t child_id = syntaqlite_list_child_id(list_node, index);
  if (child_id == SYNTAQLITE_NULL_NODE)
    return NULL;
  return syntaqlite_parser_node(p, child_id);
}

// ---------------------------------------------------------------------------
// Typed access macros
// ---------------------------------------------------------------------------

#define SYNTAQLITE_NODE(p, Type, id) \
  ((id) == SYNTAQLITE_NULL_NODE      \
       ? (const Type*)0              \
       : (const Type*)syntaqlite_parser_node((p), (id)))

#define SYNTAQLITE_LIST_ITEM(p, Type, list, i) \
  ((const Type*)syntaqlite_list_child((p), (list), (i)))

#define SYNTAQLITE_LIST_FOREACH(p, Type, var, list_id)                    \
  for (const void *                                                       \
           _sqlist_##var = syntaqlite_node_is_present(list_id)            \
                               ? syntaqlite_parser_node((p), (list_id))   \
                               : 0,                                       \
          *_sqonce_##var = 0;                                             \
       !_sqonce_##var; _sqonce_##var = (const void*)1)                    \
    for (uint32_t _sqi_##var = 0,                                         \
                  _sqn_##var = _sqlist_##var                              \
                                   ? syntaqlite_list_count(_sqlist_##var) \
                                   : 0;                                   \
         _sqi_##var < _sqn_##var; _sqi_##var++)                           \
      for (const Type* var =                                              \
               SYNTAQLITE_LIST_ITEM(p, Type, _sqlist_##var, _sqi_##var);  \
           var; var = 0)

// ---------------------------------------------------------------------------
// Debugging
// ---------------------------------------------------------------------------

// Dump an AST node tree as indented text. Returns a malloc'd NUL-terminated
// string. The caller must free() the result. Returns NULL on allocation
// failure.
SYNTAQLITE_API char* syntaqlite_dump_node(SyntaqliteParser* p,
                                          uint32_t node_id,
                                          uint32_t indent);

// ---------------------------------------------------------------------------
// Advanced: custom dialects
// ---------------------------------------------------------------------------

// Allocate a parser bound to a specific dialect environment.  Use this
// for custom dialects; for the built-in SQLite dialect prefer
// `syntaqlite_parser_create`.
SYNTAQLITE_API SyntaqliteParser* syntaqlite_parser_create_with_dialect(
    const SyntaqliteMemMethods* mem,
    SyntaqliteDialect env);

#ifndef SYNTAQLITE_OMIT_SQLITE_API
// Return the built-in SQLite dialect handle.
SYNTAQLITE_API SyntaqliteDialect syntaqlite_sqlite_dialect(void);
#endif

#ifdef __cplusplus
}
#endif


#endif  /* SYNTAQLITE_PARSER_H */
/* ======== end: syntaqlite/parser.h ======== */

/* ======== begin: syntaqlite/tokenizer.h ======== */
#ifndef SYNTAQLITE_TOKENIZER_H
#define SYNTAQLITE_TOKENIZER_H
// Copyright 2025 The syntaqlite Authors. All rights reserved.
// Licensed under the Apache License, Version 2.0.

// Streaming tokenizer for SQLite SQL.
//
// The lowest-level entry point — splits SQL text into a flat sequence of
// tokens without any parsing or tree structure. Most users don't need this
// directly; the parser (parser.h) handles tokenization internally.
// Use this when you need raw token access
// (syntax highlighting, custom analysis, etc.).
//
// Lifecycle: create → reset → next (loop) → destroy.
//
// Usage:
//   SyntaqliteTokenizer* tok = syntaqlite_tokenizer_create(NULL);
//   syntaqlite_tokenizer_reset(tok, sql, len);
//   SyntaqliteToken token;
//   while (syntaqlite_tokenizer_next(tok, &token)) {
//     // process token.type, token.text, token.length
//   }
//   syntaqlite_tokenizer_destroy(tok);


#include <stdint.h>


#ifdef __cplusplus
extern "C" {
#endif

// ---------------------------------------------------------------------------
// Types
// ---------------------------------------------------------------------------

// Opaque tokenizer handle (heap-allocated, reusable across inputs).
typedef struct SyntaqliteTokenizer SyntaqliteTokenizer;

// A single token produced by the tokenizer. The text pointer points into
// the source buffer bound by the last reset() call, so it is only valid
// while that buffer is alive. The text is NOT null-terminated.
typedef struct SyntaqliteToken {
  const char* text;         // Pointer into source text.
  SyntaqliteLength length;  // Token length in bytes.
  uint32_t type;            // Token type ordinal.
} SyntaqliteToken;

// ---------------------------------------------------------------------------
// Lifecycle
// ---------------------------------------------------------------------------

// Allocate a tokenizer bound to a dialect environment. The env is copied —
// the caller's struct does not need to outlive the tokenizer, but the dialect
// pointer inside must remain valid for the tokenizer's lifetime.
// The mem methods are copied — pass NULL for all defaults (malloc/free).
SYNTAQLITE_API SyntaqliteTokenizer* syntaqlite_tokenizer_create_with_dialect(
    const SyntaqliteMemMethods* mem,
    SyntaqliteDialect env);

// Bind a source buffer and start tokenizing from the beginning. The source
// must remain valid until the next reset() or destroy(). Can be called
// again to tokenize a new input without reallocating.
SYNTAQLITE_API void syntaqlite_tokenizer_reset(SyntaqliteTokenizer* tok,
                                               const char* source,
                                               SyntaqliteLength len);

// Advance to the next token. Returns 1 if a token was written to *out,
// 0 at end-of-input. Every token is returned, including whitespace and
// comments.
SYNTAQLITE_API uint32_t syntaqlite_tokenizer_next(SyntaqliteTokenizer* tok,
                                                  SyntaqliteToken* out);

// Free the tokenizer and all its memory. No-op if tok is NULL.
SYNTAQLITE_API void syntaqlite_tokenizer_destroy(SyntaqliteTokenizer* tok);

// ---------------------------------------------------------------------------
// SQLite dialect convenience (opt-out: -DSYNTAQLITE_OMIT_SQLITE_API)
// ---------------------------------------------------------------------------

#ifndef SYNTAQLITE_OMIT_SQLITE_API
// Allocate a tokenizer for the built-in SQLite dialect.
// The mem methods are copied — pass NULL for all defaults (malloc/free).
SYNTAQLITE_API SyntaqliteTokenizer* syntaqlite_tokenizer_create(
    const SyntaqliteMemMethods* mem);

SYNTAQLITE_API SyntaqliteDialect syntaqlite_sqlite_dialect(void);
#endif

#ifdef __cplusplus
}
#endif


#endif  /* SYNTAQLITE_TOKENIZER_H */
/* ======== end: syntaqlite/tokenizer.h ======== */

/* ======== begin: syntaqlite/incremental.h ======== */
#ifndef SYNTAQLITE_INCREMENTAL_PARSER_H
#define SYNTAQLITE_INCREMENTAL_PARSER_H
// Copyright 2025 The syntaqlite Authors. All rights reserved.
// Licensed under the Apache License, Version 2.0.

// Incremental (token-feeding) parser API.
//
// An alternative to syntaqlite_parser_next() for embedders that perform their
// own tokenization — for example, to support macro expansion before parsing.
// Feed tokens one at a time after calling syntaqlite_parser_reset(); the
// parser signals statement boundaries as tokens arrive.
//
// When feed_token or finish returns SYNTAQLITE_PARSE_OK, read the successful
// tree via syntaqlite_result_root(). When the status is
// SYNTAQLITE_PARSE_ERROR, read diagnostics via syntaqlite_result_error_*()
// and inspect syntaqlite_result_recovery_root() for an optional partial tree
// (which may include grammar-level error nodes).
// The result is valid until the next feed_token, finish, reset, or destroy.
//
// Usage:
//   SyntaqliteParser* p = syntaqlite_parser_create(NULL);
//   // Optional: enable if you need result_tokens/result_comments.
//   syntaqlite_parser_set_collect_tokens(p, 1);
//   syntaqlite_parser_reset(p, source, len);
//   while (has_more_tokens) {
//     int32_t rc = syntaqlite_parser_feed_token(p, type, text, tlen);
//     switch (rc) {
//       case SYNTAQLITE_PARSE_DONE:
//         break;
//       case SYNTAQLITE_PARSE_OK: {
//         uint32_t root = syntaqlite_result_root(p);
//         // read nodes ...
//         break;
//       }
//       case SYNTAQLITE_PARSE_ERROR:
//         if (syntaqlite_result_recovery_root(p) == SYNTAQLITE_NULL_NODE)
//           goto done;
//         break;
//     }
//   }
//   int32_t rc = syntaqlite_parser_finish(p);
//   if (rc == SYNTAQLITE_PARSE_OK) { /* final statement complete */ }
// done:
//   syntaqlite_parser_destroy(p);
//
// Read accumulated macro rewrites via syntaqlite_result_macro_count() /
// syntaqlite_result_macro_rewrite_at() after parsing.



#ifdef __cplusplus
extern "C" {
#endif

// ---------------------------------------------------------------------------
// Token feeding
// ---------------------------------------------------------------------------

// Feed a single token. TK_SPACE is silently skipped. TK_COMMENT is recorded
// as a comment only when collect_tokens is enabled, and is not fed to parser.
//
// Returns a SYNTAQLITE_PARSE_* code:
//   DONE      = keep going (statement not yet complete)
//   OK        = statement completed cleanly
//   ERROR     = statement has parse/runtime error (may still have recovery
//   root)
SYNTAQLITE_API int32_t syntaqlite_parser_feed_token(SyntaqliteParser* p,
                                                    uint32_t token_type,
                                                    const char* text,
                                                    SyntaqliteLength len);

// Signal end-of-input. Synthesizes a SEMI if needed and sends EOF to the
// parser. Returns a SYNTAQLITE_PARSE_* code.
SYNTAQLITE_API int32_t syntaqlite_parser_finish(SyntaqliteParser* p);

// ---------------------------------------------------------------------------
// Completion / lookahead
// ---------------------------------------------------------------------------

// Enumerate terminal tokens that are valid next lookaheads at the parser's
// current state. Returns the total number of expected tokens.
// If out_tokens is non-NULL, up to out_cap token IDs are written.
SYNTAQLITE_API uint32_t syntaqlite_parser_expected_tokens(SyntaqliteParser* p,
                                                          uint32_t* out_tokens,
                                                          uint32_t out_cap);

// Return the semantic completion context at the parser's current state.
// One of SYNTAQLITE_COMPLETION_CONTEXT_*.
SYNTAQLITE_API SyntaqliteCompletionContext
syntaqlite_parser_completion_context(SyntaqliteParser* p);

// ---------------------------------------------------------------------------
// Macro lookup callback
// ---------------------------------------------------------------------------

// Return codes for SyntaqliteMacroLookupFn callbacks. Stable ABI.
//   OK        = macro found and expansion set via set_result*
//   NOT_FOUND = no macro with that name is registered
//   ERROR     = macro was found but expansion failed
#define SYNTAQLITE_MACRO_LOOKUP_OK 0
#define SYNTAQLITE_MACRO_LOOKUP_NOT_FOUND (-1)
#define SYNTAQLITE_MACRO_LOOKUP_ERROR (-2)

// Returns SYNTAQLITE_MACRO_LOOKUP_OK on success (the callback must call
// set_result first), SYNTAQLITE_MACRO_LOOKUP_NOT_FOUND if the macro does
// not exist, SYNTAQLITE_MACRO_LOOKUP_ERROR on expansion error.
typedef int (*SyntaqliteMacroLookupFn)(void* user_data,
                                       SyntaqliteParser* parser,
                                       const char* name,
                                       SyntaqliteLength name_len,
                                       const SyntaqliteToken* args,
                                       uint32_t arg_count);

// Returns SYNTAQLITE_OK on success, SYNTAQLITE_ERR_OMITTED if macros are
// compiled out (SYNTAQLITE_OMIT_MACROS).
SYNTAQLITE_API int32_t
syntaqlite_parser_set_macro_lookup(SyntaqliteParser* p,
                                   SyntaqliteMacroLookupFn fn,
                                   void* user_data);

// ---------------------------------------------------------------------------
// Macro expansion result (called from inside the lookup callback)
// ---------------------------------------------------------------------------

// Set the expanded body for the current macro invocation.
// `def_line` / `def_col` are 1-based definition position for tracebacks
// (pass 0/0 if unknown).
SYNTAQLITE_API void syntaqlite_macro_expansion_set_result(
    SyntaqliteParser* p,
    const char* body,
    SyntaqliteLength body_len,
    SyntaqliteLineNumber def_line,
    SyntaqliteColumnNumber def_col);

// Describes where one macro argument was pasted into the expansion body.
// Used by set_result_with_arg_map to enable span drilling through
// $param substitutions.
typedef struct SyntaqliteArgMapping {
  SyntaqliteLayerOffset body_offset;  // Byte offset in `body` where arg
                                      // text starts.
  uint32_t arg_index;  // Index into the args array passed to the callback.
} SyntaqliteArgMapping;

// Like set_result, but with arg-mapping metadata for span drilling.
// Each mapping says "at body_offset, I pasted arg[arg_index]".
// Enables span_text to drill through substitutions to the caller's
// authored arg text instead of collapsing to the whole call site.
SYNTAQLITE_API void syntaqlite_macro_expansion_set_result_with_arg_map(
    SyntaqliteParser* p,
    const char* body,
    SyntaqliteLength body_len,
    SyntaqliteLineNumber def_line,
    SyntaqliteColumnNumber def_col,
    const SyntaqliteArgMapping* mappings,
    uint32_t mapping_count);

// Template expansion helper: substitute `$param` placeholders with the
// current invocation's args and call set_result.  Arg segments are built
// automatically.  Returns SYNTAQLITE_OK on success.
//
// `flags` is a bitwise OR of SYNTAQLITE_EXPAND_* constants (0 for defaults).
//
// By default, encountering a `$param` that does not match any entry in
// `param_names` is an error (returns -1).  Pass
// SYNTAQLITE_EXPAND_PASSTHROUGH_UNKNOWN to copy unknown `$param` tokens
// verbatim into the expansion buffer instead.
#define SYNTAQLITE_EXPAND_PASSTHROUGH_UNKNOWN 0x1u

SYNTAQLITE_API int syntaqlite_macro_expansion_expand_and_set_result(
    SyntaqliteParser* p,
    const char* body,
    SyntaqliteLength body_len,
    const char* const* param_names,
    const SyntaqliteLength* param_name_lens,
    uint32_t param_count,
    uint32_t flags);

#ifdef __cplusplus
}
#endif


#endif  /* SYNTAQLITE_INCREMENTAL_PARSER_H */
/* ======== end: syntaqlite/incremental.h ======== */

/* ======== begin: syntaqlite_perfetto/perfetto.h ======== */
#ifndef SYNTAQLITE_PERFETTO_GRAMMAR_H
#define SYNTAQLITE_PERFETTO_GRAMMAR_H
// Copyright 2025 The syntaqlite Authors. All rights reserved.
// Licensed under the Apache License, Version 2.0.
//
// @generated by syntaqlite-buildtools — DO NOT EDIT




#ifdef __cplusplus
extern "C" {
#endif

SYNTAQLITE_API SyntaqliteDialect syntaqlite_perfetto_dialect(void);
SYNTAQLITE_API const SyntaqliteDialectTemplate* syntaqlite_perfetto_dialect_template(void);

#ifdef __cplusplus
}
#endif


#endif  /* SYNTAQLITE_PERFETTO_GRAMMAR_H */
/* ======== end: syntaqlite_perfetto/perfetto.h ======== */

/* ======== begin: syntaqlite_perfetto/perfetto_node.h ======== */
#ifndef SYNTAQLITE_PERFETTO_NODE_H
#define SYNTAQLITE_PERFETTO_NODE_H
// Copyright 2025 The syntaqlite Authors. All rights reserved.
// Licensed under the Apache License, Version 2.0.
//
// @generated by syntaqlite-buildtools — DO NOT EDIT


#include <stddef.h>
#include <stdint.h>


#ifdef __cplusplus
#define SYNTAQLITE_FLEXIBLE_ARRAY 1
#else
#define SYNTAQLITE_FLEXIBLE_ARRAY
#endif

#ifdef __cplusplus
extern "C" {
#endif

// ============ Value Enums ============

typedef enum SyntaqliteBool {
    SYNTAQLITE_BOOL_FALSE = 0,
    SYNTAQLITE_BOOL_TRUE = 1
} SyntaqliteBool;

typedef enum SyntaqliteLiteralType {
    SYNTAQLITE_LITERAL_TYPE_INTEGER = 0,
    SYNTAQLITE_LITERAL_TYPE_FLOAT = 1,
    SYNTAQLITE_LITERAL_TYPE_STRING = 2,
    SYNTAQLITE_LITERAL_TYPE_BLOB = 3,
    SYNTAQLITE_LITERAL_TYPE_NULL = 4,
    SYNTAQLITE_LITERAL_TYPE_CURRENT = 5,
    SYNTAQLITE_LITERAL_TYPE_QNUMBER = 6
} SyntaqliteLiteralType;

typedef enum SyntaqliteBinaryOp {
    SYNTAQLITE_BINARY_OP_PLUS = 0,
    SYNTAQLITE_BINARY_OP_MINUS = 1,
    SYNTAQLITE_BINARY_OP_STAR = 2,
    SYNTAQLITE_BINARY_OP_SLASH = 3,
    SYNTAQLITE_BINARY_OP_REM = 4,
    SYNTAQLITE_BINARY_OP_LT = 5,
    SYNTAQLITE_BINARY_OP_GT = 6,
    SYNTAQLITE_BINARY_OP_LE = 7,
    SYNTAQLITE_BINARY_OP_GE = 8,
    SYNTAQLITE_BINARY_OP_EQ = 9,
    SYNTAQLITE_BINARY_OP_NE = 10,
    SYNTAQLITE_BINARY_OP_AND = 11,
    SYNTAQLITE_BINARY_OP_OR = 12,
    SYNTAQLITE_BINARY_OP_BIT_AND = 13,
    SYNTAQLITE_BINARY_OP_BIT_OR = 14,
    SYNTAQLITE_BINARY_OP_LSHIFT = 15,
    SYNTAQLITE_BINARY_OP_RSHIFT = 16,
    SYNTAQLITE_BINARY_OP_CONCAT = 17,
    SYNTAQLITE_BINARY_OP_PTR = 18,
    SYNTAQLITE_BINARY_OP_PTR2 = 19
} SyntaqliteBinaryOp;

typedef enum SyntaqliteUnaryOp {
    SYNTAQLITE_UNARY_OP_MINUS = 0,
    SYNTAQLITE_UNARY_OP_PLUS = 1,
    SYNTAQLITE_UNARY_OP_BIT_NOT = 2,
    SYNTAQLITE_UNARY_OP_NOT = 3
} SyntaqliteUnaryOp;

typedef enum SyntaqliteCompoundOp {
    SYNTAQLITE_COMPOUND_OP_UNION = 0,
    SYNTAQLITE_COMPOUND_OP_UNION_ALL = 1,
    SYNTAQLITE_COMPOUND_OP_INTERSECT = 2,
    SYNTAQLITE_COMPOUND_OP_EXCEPT = 3
} SyntaqliteCompoundOp;

typedef enum SyntaqliteIsOp {
    SYNTAQLITE_IS_OP_IS = 0,
    SYNTAQLITE_IS_OP_IS_NOT = 1,
    SYNTAQLITE_IS_OP_IS_NULL = 2,
    SYNTAQLITE_IS_OP_NOT_NULL = 3,
    SYNTAQLITE_IS_OP_IS_NOT_DISTINCT = 4,
    SYNTAQLITE_IS_OP_IS_DISTINCT = 5
} SyntaqliteIsOp;

typedef enum SyntaqliteLikeKeyword {
    SYNTAQLITE_LIKE_KEYWORD_LIKE = 0,
    SYNTAQLITE_LIKE_KEYWORD_GLOB = 1,
    SYNTAQLITE_LIKE_KEYWORD_MATCH = 2,
    SYNTAQLITE_LIKE_KEYWORD_REGEXP = 3
} SyntaqliteLikeKeyword;

typedef enum SyntaqliteForeignKeyAction {
    SYNTAQLITE_FOREIGN_KEY_ACTION_NO_ACTION = 0,
    SYNTAQLITE_FOREIGN_KEY_ACTION_SET_NULL = 1,
    SYNTAQLITE_FOREIGN_KEY_ACTION_SET_DEFAULT = 2,
    SYNTAQLITE_FOREIGN_KEY_ACTION_CASCADE = 3,
    SYNTAQLITE_FOREIGN_KEY_ACTION_RESTRICT = 4
} SyntaqliteForeignKeyAction;

typedef enum SyntaqliteGeneratedColumnStorage {
    SYNTAQLITE_GENERATED_COLUMN_STORAGE_VIRTUAL = 0,
    SYNTAQLITE_GENERATED_COLUMN_STORAGE_STORED = 1
} SyntaqliteGeneratedColumnStorage;

typedef enum SyntaqliteColumnConstraintType {
    SYNTAQLITE_COLUMN_CONSTRAINT_TYPE_DEFAULT = 0,
    SYNTAQLITE_COLUMN_CONSTRAINT_TYPE_NOT_NULL = 1,
    SYNTAQLITE_COLUMN_CONSTRAINT_TYPE_PRIMARY_KEY = 2,
    SYNTAQLITE_COLUMN_CONSTRAINT_TYPE_UNIQUE = 3,
    SYNTAQLITE_COLUMN_CONSTRAINT_TYPE_CHECK = 4,
    SYNTAQLITE_COLUMN_CONSTRAINT_TYPE_REFERENCES = 5,
    SYNTAQLITE_COLUMN_CONSTRAINT_TYPE_COLLATE = 6,
    SYNTAQLITE_COLUMN_CONSTRAINT_TYPE_GENERATED = 7,
    SYNTAQLITE_COLUMN_CONSTRAINT_TYPE_NULL = 8
} SyntaqliteColumnConstraintType;

typedef enum SyntaqliteTableConstraintType {
    SYNTAQLITE_TABLE_CONSTRAINT_TYPE_PRIMARY_KEY = 0,
    SYNTAQLITE_TABLE_CONSTRAINT_TYPE_UNIQUE = 1,
    SYNTAQLITE_TABLE_CONSTRAINT_TYPE_CHECK = 2,
    SYNTAQLITE_TABLE_CONSTRAINT_TYPE_FOREIGN_KEY = 3
} SyntaqliteTableConstraintType;

typedef enum SyntaqliteMaterialized {
    SYNTAQLITE_MATERIALIZED_DEFAULT = 0,
    SYNTAQLITE_MATERIALIZED_MATERIALIZED = 1,
    SYNTAQLITE_MATERIALIZED_NOT_MATERIALIZED = 2
} SyntaqliteMaterialized;

typedef enum SyntaqliteConflictAction {
    SYNTAQLITE_CONFLICT_ACTION_DEFAULT = 0,
    SYNTAQLITE_CONFLICT_ACTION_ROLLBACK = 1,
    SYNTAQLITE_CONFLICT_ACTION_ABORT = 2,
    SYNTAQLITE_CONFLICT_ACTION_FAIL = 3,
    SYNTAQLITE_CONFLICT_ACTION_IGNORE = 4,
    SYNTAQLITE_CONFLICT_ACTION_REPLACE = 5
} SyntaqliteConflictAction;

typedef enum SyntaqliteUpsertAction {
    SYNTAQLITE_UPSERT_ACTION_NOTHING = 0,
    SYNTAQLITE_UPSERT_ACTION_UPDATE = 1
} SyntaqliteUpsertAction;

typedef enum SyntaqliteIndexHint {
    SYNTAQLITE_INDEX_HINT_DEFAULT = 0,
    SYNTAQLITE_INDEX_HINT_NOT_INDEXED = 1,
    SYNTAQLITE_INDEX_HINT_INDEXED = 2
} SyntaqliteIndexHint;

typedef enum SyntaqliteRaiseType {
    SYNTAQLITE_RAISE_TYPE_IGNORE = 0,
    SYNTAQLITE_RAISE_TYPE_ROLLBACK = 1,
    SYNTAQLITE_RAISE_TYPE_ABORT = 2,
    SYNTAQLITE_RAISE_TYPE_FAIL = 3
} SyntaqliteRaiseType;

typedef enum SyntaqliteDropObjectType {
    SYNTAQLITE_DROP_OBJECT_TYPE_TABLE = 0,
    SYNTAQLITE_DROP_OBJECT_TYPE_INDEX = 1,
    SYNTAQLITE_DROP_OBJECT_TYPE_VIEW = 2,
    SYNTAQLITE_DROP_OBJECT_TYPE_TRIGGER = 3
} SyntaqliteDropObjectType;

typedef enum SyntaqliteAlterOp {
    SYNTAQLITE_ALTER_OP_RENAME_TABLE = 0,
    SYNTAQLITE_ALTER_OP_RENAME_COLUMN = 1,
    SYNTAQLITE_ALTER_OP_DROP_COLUMN = 2,
    SYNTAQLITE_ALTER_OP_ADD_COLUMN = 3
} SyntaqliteAlterOp;

typedef enum SyntaqliteTransactionType {
    SYNTAQLITE_TRANSACTION_TYPE_DEFERRED = 0,
    SYNTAQLITE_TRANSACTION_TYPE_IMMEDIATE = 1,
    SYNTAQLITE_TRANSACTION_TYPE_EXCLUSIVE = 2
} SyntaqliteTransactionType;

typedef enum SyntaqliteTransactionOp {
    SYNTAQLITE_TRANSACTION_OP_BEGIN = 0,
    SYNTAQLITE_TRANSACTION_OP_COMMIT = 1,
    SYNTAQLITE_TRANSACTION_OP_ROLLBACK = 2
} SyntaqliteTransactionOp;

typedef enum SyntaqliteSavepointOp {
    SYNTAQLITE_SAVEPOINT_OP_SAVEPOINT = 0,
    SYNTAQLITE_SAVEPOINT_OP_RELEASE = 1,
    SYNTAQLITE_SAVEPOINT_OP_ROLLBACK_TO = 2
} SyntaqliteSavepointOp;

typedef enum SyntaqliteSortOrder {
    SYNTAQLITE_SORT_ORDER_ASC = 0,
    SYNTAQLITE_SORT_ORDER_DESC = 1
} SyntaqliteSortOrder;

typedef enum SyntaqliteNullsOrder {
    SYNTAQLITE_NULLS_ORDER_NONE = 0,
    SYNTAQLITE_NULLS_ORDER_FIRST = 1,
    SYNTAQLITE_NULLS_ORDER_LAST = 2
} SyntaqliteNullsOrder;

typedef enum SyntaqliteJoinType {
    SYNTAQLITE_JOIN_TYPE_COMMA = 0,
    SYNTAQLITE_JOIN_TYPE_INNER = 1,
    SYNTAQLITE_JOIN_TYPE_LEFT = 2,
    SYNTAQLITE_JOIN_TYPE_RIGHT = 3,
    SYNTAQLITE_JOIN_TYPE_FULL = 4,
    SYNTAQLITE_JOIN_TYPE_CROSS = 5,
    SYNTAQLITE_JOIN_TYPE_NATURAL_INNER = 6,
    SYNTAQLITE_JOIN_TYPE_NATURAL_LEFT = 7,
    SYNTAQLITE_JOIN_TYPE_NATURAL_RIGHT = 8,
    SYNTAQLITE_JOIN_TYPE_NATURAL_FULL = 9
} SyntaqliteJoinType;

typedef enum SyntaqliteTriggerTiming {
    SYNTAQLITE_TRIGGER_TIMING_BEFORE = 0,
    SYNTAQLITE_TRIGGER_TIMING_AFTER = 1,
    SYNTAQLITE_TRIGGER_TIMING_INSTEAD_OF = 2
} SyntaqliteTriggerTiming;

typedef enum SyntaqliteTriggerEventType {
    SYNTAQLITE_TRIGGER_EVENT_TYPE_DELETE = 0,
    SYNTAQLITE_TRIGGER_EVENT_TYPE_INSERT = 1,
    SYNTAQLITE_TRIGGER_EVENT_TYPE_UPDATE = 2
} SyntaqliteTriggerEventType;

typedef enum SyntaqliteExplainMode {
    SYNTAQLITE_EXPLAIN_MODE_EXPLAIN = 0,
    SYNTAQLITE_EXPLAIN_MODE_QUERY_PLAN = 1
} SyntaqliteExplainMode;

typedef enum SyntaqlitePragmaForm {
    SYNTAQLITE_PRAGMA_FORM_BARE = 0,
    SYNTAQLITE_PRAGMA_FORM_EQ = 1,
    SYNTAQLITE_PRAGMA_FORM_CALL = 2
} SyntaqlitePragmaForm;

typedef enum SyntaqliteAnalyzeOrReindexOp {
    SYNTAQLITE_ANALYZE_OR_REINDEX_OP_ANALYZE = 0,
    SYNTAQLITE_ANALYZE_OR_REINDEX_OP_REINDEX = 1
} SyntaqliteAnalyzeOrReindexOp;

typedef enum SyntaqliteFrameType {
    SYNTAQLITE_FRAME_TYPE_NONE = 0,
    SYNTAQLITE_FRAME_TYPE_RANGE = 1,
    SYNTAQLITE_FRAME_TYPE_ROWS = 2,
    SYNTAQLITE_FRAME_TYPE_GROUPS = 3
} SyntaqliteFrameType;

typedef enum SyntaqliteFrameBoundType {
    SYNTAQLITE_FRAME_BOUND_TYPE_UNBOUNDED_PRECEDING = 0,
    SYNTAQLITE_FRAME_BOUND_TYPE_EXPR_PRECEDING = 1,
    SYNTAQLITE_FRAME_BOUND_TYPE_CURRENT_ROW = 2,
    SYNTAQLITE_FRAME_BOUND_TYPE_EXPR_FOLLOWING = 3,
    SYNTAQLITE_FRAME_BOUND_TYPE_UNBOUNDED_FOLLOWING = 4
} SyntaqliteFrameBoundType;

typedef enum SyntaqliteFrameExclude {
    SYNTAQLITE_FRAME_EXCLUDE_NONE = 0,
    SYNTAQLITE_FRAME_EXCLUDE_NO_OTHERS = 1,
    SYNTAQLITE_FRAME_EXCLUDE_CURRENT_ROW = 2,
    SYNTAQLITE_FRAME_EXCLUDE_GROUP = 3,
    SYNTAQLITE_FRAME_EXCLUDE_TIES = 4
} SyntaqliteFrameExclude;

typedef enum SyntaqlitePerfettoReturnKind {
    SYNTAQLITE_PERFETTO_RETURN_KIND_SCALAR = 0,
    SYNTAQLITE_PERFETTO_RETURN_KIND_TABLE = 1
} SyntaqlitePerfettoReturnKind;

// ============ Flags Types ============

typedef union SyntaqliteAggregateFunctionCallFlags {
    uint8_t raw;
    struct {
        uint8_t distinct : 1;
    } bits;
} SyntaqliteAggregateFunctionCallFlags;

typedef union SyntaqliteCreateTableStmtFlags {
    uint8_t raw;
    struct {
        uint8_t without_rowid : 1;
        uint8_t strict : 1;
    } bits;
} SyntaqliteCreateTableStmtFlags;

typedef union SyntaqliteFunctionCallFlags {
    uint8_t raw;
    struct {
        uint8_t distinct : 1;
        uint8_t star : 1;
    } bits;
} SyntaqliteFunctionCallFlags;

typedef union SyntaqliteResultColumnFlags {
    uint8_t raw;
    struct {
        uint8_t star : 1;
    } bits;
} SyntaqliteResultColumnFlags;

typedef union SyntaqliteSelectStmtFlags {
    uint8_t raw;
    struct {
        uint8_t distinct : 1;
    } bits;
} SyntaqliteSelectStmtFlags;

// ============ Node Tags ============

typedef enum SyntaqliteNodeTag {
    SYNTAQLITE_NODE_NULL = 0,
    SYNTAQLITE_NODE_AGGREGATE_FUNCTION_CALL = 1,
    SYNTAQLITE_NODE_ORDERED_SET_FUNCTION_CALL = 2,
    SYNTAQLITE_NODE_CAST_EXPR = 3,
    SYNTAQLITE_NODE_COLUMN_REF = 4,
    SYNTAQLITE_NODE_COMPOUND_SELECT = 5,
    SYNTAQLITE_NODE_SUBQUERY_EXPR = 6,
    SYNTAQLITE_NODE_EXISTS_EXPR = 7,
    SYNTAQLITE_NODE_IN_EXPR = 8,
    SYNTAQLITE_NODE_IS_EXPR = 9,
    SYNTAQLITE_NODE_BETWEEN_EXPR = 10,
    SYNTAQLITE_NODE_LIKE_EXPR = 11,
    SYNTAQLITE_NODE_CASE_EXPR = 12,
    SYNTAQLITE_NODE_CASE_WHEN = 13,
    SYNTAQLITE_NODE_CASE_WHEN_LIST = 14,
    SYNTAQLITE_NODE_FOREIGN_KEY_CLAUSE = 15,
    SYNTAQLITE_NODE_COLUMN_CONSTRAINT = 16,
    SYNTAQLITE_NODE_COLUMN_CONSTRAINT_LIST = 17,
    SYNTAQLITE_NODE_COLUMN_DEF = 18,
    SYNTAQLITE_NODE_COLUMN_DEF_LIST = 19,
    SYNTAQLITE_NODE_TABLE_CONSTRAINT = 20,
    SYNTAQLITE_NODE_TABLE_CONSTRAINT_LIST = 21,
    SYNTAQLITE_NODE_CREATE_TABLE_STMT = 22,
    SYNTAQLITE_NODE_CTE_DEFINITION = 23,
    SYNTAQLITE_NODE_CTE_LIST = 24,
    SYNTAQLITE_NODE_WITH_CLAUSE = 25,
    SYNTAQLITE_NODE_UPSERT_CLAUSE = 26,
    SYNTAQLITE_NODE_UPSERT_CLAUSE_LIST = 27,
    SYNTAQLITE_NODE_DELETE_STMT = 28,
    SYNTAQLITE_NODE_SET_CLAUSE = 29,
    SYNTAQLITE_NODE_SET_CLAUSE_LIST = 30,
    SYNTAQLITE_NODE_UPDATE_STMT = 31,
    SYNTAQLITE_NODE_INSERT_STMT = 32,
    SYNTAQLITE_NODE_BINARY_EXPR = 33,
    SYNTAQLITE_NODE_UNARY_EXPR = 34,
    SYNTAQLITE_NODE_LITERAL = 35,
    SYNTAQLITE_NODE_PAREN_EXPR = 36,
    SYNTAQLITE_NODE_IDENT_NAME = 37,
    SYNTAQLITE_NODE_ERROR = 38,
    SYNTAQLITE_NODE_EXPR_LIST = 39,
    SYNTAQLITE_NODE_FUNCTION_CALL = 40,
    SYNTAQLITE_NODE_VARIABLE = 41,
    SYNTAQLITE_NODE_COLLATE_EXPR = 42,
    SYNTAQLITE_NODE_RAISE_EXPR = 43,
    SYNTAQLITE_NODE_QUALIFIED_NAME = 44,
    SYNTAQLITE_NODE_DROP_STMT = 45,
    SYNTAQLITE_NODE_ALTER_TABLE_STMT = 46,
    SYNTAQLITE_NODE_TRANSACTION_STMT = 47,
    SYNTAQLITE_NODE_SAVEPOINT_STMT = 48,
    SYNTAQLITE_NODE_RESULT_COLUMN = 49,
    SYNTAQLITE_NODE_RESULT_COLUMN_LIST = 50,
    SYNTAQLITE_NODE_SELECT_STMT = 51,
    SYNTAQLITE_NODE_ORDERING_TERM = 52,
    SYNTAQLITE_NODE_ORDER_BY_LIST = 53,
    SYNTAQLITE_NODE_LIMIT_CLAUSE = 54,
    SYNTAQLITE_NODE_TABLE_REF = 55,
    SYNTAQLITE_NODE_SUBQUERY_TABLE_SOURCE = 56,
    SYNTAQLITE_NODE_JOIN_CLAUSE = 57,
    SYNTAQLITE_NODE_JOIN_PREFIX = 58,
    SYNTAQLITE_NODE_TRIGGER_EVENT = 59,
    SYNTAQLITE_NODE_TRIGGER_CMD_LIST = 60,
    SYNTAQLITE_NODE_CREATE_TRIGGER_STMT = 61,
    SYNTAQLITE_NODE_CREATE_VIRTUAL_TABLE_STMT = 62,
    SYNTAQLITE_NODE_PRAGMA_STMT = 63,
    SYNTAQLITE_NODE_ANALYZE_OR_REINDEX_STMT = 64,
    SYNTAQLITE_NODE_ATTACH_STMT = 65,
    SYNTAQLITE_NODE_DETACH_STMT = 66,
    SYNTAQLITE_NODE_VACUUM_STMT = 67,
    SYNTAQLITE_NODE_EXPLAIN_STMT = 68,
    SYNTAQLITE_NODE_CREATE_INDEX_STMT = 69,
    SYNTAQLITE_NODE_CREATE_VIEW_STMT = 70,
    SYNTAQLITE_NODE_VALUES_ROW_LIST = 71,
    SYNTAQLITE_NODE_VALUES_CLAUSE = 72,
    SYNTAQLITE_NODE_FRAME_BOUND = 73,
    SYNTAQLITE_NODE_FRAME_SPEC = 74,
    SYNTAQLITE_NODE_WINDOW_DEF = 75,
    SYNTAQLITE_NODE_WINDOW_DEF_LIST = 76,
    SYNTAQLITE_NODE_NAMED_WINDOW_DEF = 77,
    SYNTAQLITE_NODE_NAMED_WINDOW_DEF_LIST = 78,
    SYNTAQLITE_NODE_FILTER_OVER = 79,
    SYNTAQLITE_NODE_PERFETTO_ARG_DEF = 80,
    SYNTAQLITE_NODE_PERFETTO_ARG_DEF_LIST = 81,
    SYNTAQLITE_NODE_PERFETTO_MACRO_ARG = 82,
    SYNTAQLITE_NODE_PERFETTO_MACRO_ARG_LIST = 83,
    SYNTAQLITE_NODE_PERFETTO_INDEXED_COLUMN = 84,
    SYNTAQLITE_NODE_PERFETTO_INDEXED_COLUMN_LIST = 85,
    SYNTAQLITE_NODE_PERFETTO_RETURN_TYPE = 86,
    SYNTAQLITE_NODE_PERFETTO_TABLE_IMPL = 87,
    SYNTAQLITE_NODE_CREATE_PERFETTO_TABLE_STMT = 88,
    SYNTAQLITE_NODE_CREATE_PERFETTO_VIEW_STMT = 89,
    SYNTAQLITE_NODE_CREATE_PERFETTO_FUNCTION_STMT = 90,
    SYNTAQLITE_NODE_CREATE_PERFETTO_DELEGATING_FUNCTION_STMT = 91,
    SYNTAQLITE_NODE_CREATE_PERFETTO_INDEX_STMT = 92,
    SYNTAQLITE_NODE_CREATE_PERFETTO_MACRO_STMT = 93,
    SYNTAQLITE_NODE_INCLUDE_PERFETTO_MODULE_STMT = 94,
    SYNTAQLITE_NODE_DROP_PERFETTO_INDEX_STMT = 95,
    SYNTAQLITE_NODE_COUNT
} SyntaqliteNodeTag;
SYNQ_STATIC_ASSERT(sizeof(SyntaqliteNodeTag) == sizeof(uint32_t),
                   "SyntaqliteNodeTag must be 32 bits for FFI compatibility");

// ============ Node Structs ============

typedef struct SyntaqliteAggregateFunctionCall {
    SyntaqliteNodeTag tag;
    SyntaqliteTextSpan func_name;
    SyntaqliteAggregateFunctionCallFlags flags;
    uint32_t args;
    uint32_t orderby;
    uint32_t filter_clause;
    uint32_t over_clause;
} SyntaqliteAggregateFunctionCall;

typedef struct SyntaqliteOrderedSetFunctionCall {
    SyntaqliteNodeTag tag;
    SyntaqliteTextSpan func_name;
    SyntaqliteAggregateFunctionCallFlags flags;
    uint32_t args;
    uint32_t orderby_expr;
    uint32_t filter_clause;
    uint32_t over_clause;
} SyntaqliteOrderedSetFunctionCall;

typedef struct SyntaqliteCastExpr {
    SyntaqliteNodeTag tag;
    uint32_t expr;
    SyntaqliteTextSpan type_name;
} SyntaqliteCastExpr;

typedef struct SyntaqliteColumnRef {
    SyntaqliteNodeTag tag;
    SyntaqliteTextSpan column;
    SyntaqliteTextSpan table;
    SyntaqliteTextSpan schema;
} SyntaqliteColumnRef;

typedef struct SyntaqliteCompoundSelect {
    SyntaqliteNodeTag tag;
    SyntaqliteCompoundOp op;
    uint32_t left;
    uint32_t right;
} SyntaqliteCompoundSelect;

typedef struct SyntaqliteSubqueryExpr {
    SyntaqliteNodeTag tag;
    uint32_t select;
} SyntaqliteSubqueryExpr;

typedef struct SyntaqliteExistsExpr {
    SyntaqliteNodeTag tag;
    uint32_t select;
} SyntaqliteExistsExpr;

typedef struct SyntaqliteInExpr {
    SyntaqliteNodeTag tag;
    SyntaqliteBool negated;
    SyntaqliteBool bare_source;
    uint32_t operand;
    uint32_t source;
} SyntaqliteInExpr;

typedef struct SyntaqliteIsExpr {
    SyntaqliteNodeTag tag;
    SyntaqliteIsOp op;
    uint32_t left;
    uint32_t right;
} SyntaqliteIsExpr;

typedef struct SyntaqliteBetweenExpr {
    SyntaqliteNodeTag tag;
    SyntaqliteBool negated;
    uint32_t operand;
    uint32_t low;
    uint32_t high;
} SyntaqliteBetweenExpr;

typedef struct SyntaqliteLikeExpr {
    SyntaqliteNodeTag tag;
    SyntaqliteBool negated;
    SyntaqliteLikeKeyword keyword;
    uint32_t operand;
    uint32_t pattern;
    uint32_t escape;
} SyntaqliteLikeExpr;

typedef struct SyntaqliteCaseExpr {
    SyntaqliteNodeTag tag;
    uint32_t operand;
    uint32_t else_expr;
    uint32_t whens;
} SyntaqliteCaseExpr;

typedef struct SyntaqliteCaseWhen {
    SyntaqliteNodeTag tag;
    uint32_t when_expr;
    uint32_t then_expr;
} SyntaqliteCaseWhen;

// List of CaseWhen
typedef struct SyntaqliteCaseWhenList {
    uint32_t tag;
    uint32_t count;
    uint32_t children[SYNTAQLITE_FLEXIBLE_ARRAY];
} SyntaqliteCaseWhenList;

typedef struct SyntaqliteForeignKeyClause {
    SyntaqliteNodeTag tag;
    SyntaqliteTextSpan ref_table;
    uint32_t ref_columns;
    SyntaqliteForeignKeyAction on_delete;
    SyntaqliteForeignKeyAction on_update;
    SyntaqliteBool is_deferred;
} SyntaqliteForeignKeyClause;

typedef struct SyntaqliteColumnConstraint {
    SyntaqliteNodeTag tag;
    SyntaqliteColumnConstraintType kind;
    SyntaqliteTextSpan constraint_name;
    SyntaqliteConflictAction onconf;
    SyntaqliteSortOrder sort_order;
    SyntaqliteBool is_autoincrement;
    SyntaqliteTextSpan collation_name;
    SyntaqliteGeneratedColumnStorage generated_storage;
    uint32_t default_expr;
    uint32_t check_expr;
    uint32_t generated_expr;
    uint32_t fk_clause;
} SyntaqliteColumnConstraint;

// List of ColumnConstraint
typedef struct SyntaqliteColumnConstraintList {
    uint32_t tag;
    uint32_t count;
    uint32_t children[SYNTAQLITE_FLEXIBLE_ARRAY];
} SyntaqliteColumnConstraintList;

typedef struct SyntaqliteColumnDef {
    SyntaqliteNodeTag tag;
    uint32_t column_name;
    SyntaqliteTextSpan type_name;
    uint32_t constraints;
} SyntaqliteColumnDef;

// List of ColumnDef
typedef struct SyntaqliteColumnDefList {
    uint32_t tag;
    uint32_t count;
    uint32_t children[SYNTAQLITE_FLEXIBLE_ARRAY];
} SyntaqliteColumnDefList;

typedef struct SyntaqliteTableConstraint {
    SyntaqliteNodeTag tag;
    SyntaqliteTableConstraintType kind;
    SyntaqliteTextSpan constraint_name;
    SyntaqliteConflictAction onconf;
    SyntaqliteBool is_autoincrement;
    uint32_t pk_columns;
    uint32_t fk_columns;
    uint32_t check_expr;
    uint32_t fk_clause;
} SyntaqliteTableConstraint;

// List of TableConstraint
typedef struct SyntaqliteTableConstraintList {
    uint32_t tag;
    uint32_t count;
    uint32_t children[SYNTAQLITE_FLEXIBLE_ARRAY];
} SyntaqliteTableConstraintList;

typedef struct SyntaqliteCreateTableStmt {
    SyntaqliteNodeTag tag;
    SyntaqliteTextSpan table_name;
    SyntaqliteTextSpan schema;
    SyntaqliteBool is_temp;
    SyntaqliteBool if_not_exists;
    SyntaqliteCreateTableStmtFlags flags;
    uint32_t columns;
    uint32_t table_constraints;
    uint32_t as_select;
} SyntaqliteCreateTableStmt;

typedef struct SyntaqliteCteDefinition {
    SyntaqliteNodeTag tag;
    SyntaqliteTextSpan cte_name;
    SyntaqliteMaterialized materialized;
    uint32_t columns;
    uint32_t select;
} SyntaqliteCteDefinition;

// List of CteDefinition
typedef struct SyntaqliteCteList {
    uint32_t tag;
    uint32_t count;
    uint32_t children[SYNTAQLITE_FLEXIBLE_ARRAY];
} SyntaqliteCteList;

typedef struct SyntaqliteWithClause {
    SyntaqliteNodeTag tag;
    SyntaqliteBool recursive;
    uint32_t ctes;
    uint32_t select;
} SyntaqliteWithClause;

typedef struct SyntaqliteUpsertClause {
    SyntaqliteNodeTag tag;
    uint32_t columns;
    uint32_t target_where;
    SyntaqliteUpsertAction action;
    uint32_t setlist;
    uint32_t update_where;
} SyntaqliteUpsertClause;

// List of UpsertClause
typedef struct SyntaqliteUpsertClauseList {
    uint32_t tag;
    uint32_t count;
    uint32_t children[SYNTAQLITE_FLEXIBLE_ARRAY];
} SyntaqliteUpsertClauseList;

typedef struct SyntaqliteDeleteStmt {
    SyntaqliteNodeTag tag;
    uint32_t with_ctes;
    SyntaqliteBool with_recursive;
    uint32_t table;
    SyntaqliteIndexHint index_hint;
    SyntaqliteTextSpan index_name;
    uint32_t where_clause;
    uint32_t orderby;
    uint32_t limit_clause;
    uint32_t returning;
} SyntaqliteDeleteStmt;

typedef struct SyntaqliteSetClause {
    SyntaqliteNodeTag tag;
    SyntaqliteTextSpan column;
    uint32_t columns;
    uint32_t value;
} SyntaqliteSetClause;

// List of SetClause
typedef struct SyntaqliteSetClauseList {
    uint32_t tag;
    uint32_t count;
    uint32_t children[SYNTAQLITE_FLEXIBLE_ARRAY];
} SyntaqliteSetClauseList;

typedef struct SyntaqliteUpdateStmt {
    SyntaqliteNodeTag tag;
    uint32_t with_ctes;
    SyntaqliteBool with_recursive;
    SyntaqliteConflictAction conflict_action;
    uint32_t table;
    SyntaqliteIndexHint index_hint;
    SyntaqliteTextSpan index_name;
    uint32_t setlist;
    uint32_t from_clause;
    uint32_t where_clause;
    uint32_t orderby;
    uint32_t limit_clause;
    uint32_t returning;
} SyntaqliteUpdateStmt;

typedef struct SyntaqliteInsertStmt {
    SyntaqliteNodeTag tag;
    uint32_t with_ctes;
    SyntaqliteBool with_recursive;
    SyntaqliteConflictAction conflict_action;
    uint32_t table;
    uint32_t columns;
    uint32_t source;
    uint32_t upsert;
    uint32_t returning;
} SyntaqliteInsertStmt;

typedef struct SyntaqliteBinaryExpr {
    SyntaqliteNodeTag tag;
    SyntaqliteBinaryOp op;
    uint32_t left;
    uint32_t right;
} SyntaqliteBinaryExpr;

typedef struct SyntaqliteUnaryExpr {
    SyntaqliteNodeTag tag;
    SyntaqliteUnaryOp op;
    uint32_t operand;
} SyntaqliteUnaryExpr;

typedef struct SyntaqliteLiteral {
    SyntaqliteNodeTag tag;
    SyntaqliteLiteralType literal_type;
    SyntaqliteTextSpan source;
} SyntaqliteLiteral;

typedef struct SyntaqliteParenExpr {
    SyntaqliteNodeTag tag;
    uint32_t expr;
} SyntaqliteParenExpr;

typedef struct SyntaqliteIdentName {
    SyntaqliteNodeTag tag;
    SyntaqliteTextSpan source;
} SyntaqliteIdentName;

typedef struct SyntaqliteError {
    SyntaqliteNodeTag tag;
    SyntaqliteTextSpan source;
} SyntaqliteError;

// List of Expr
typedef struct SyntaqliteExprList {
    uint32_t tag;
    uint32_t count;
    uint32_t children[SYNTAQLITE_FLEXIBLE_ARRAY];
} SyntaqliteExprList;

typedef struct SyntaqliteFunctionCall {
    SyntaqliteNodeTag tag;
    SyntaqliteTextSpan func_name;
    SyntaqliteFunctionCallFlags flags;
    uint32_t args;
    uint32_t filter_clause;
    uint32_t over_clause;
} SyntaqliteFunctionCall;

typedef struct SyntaqliteVariable {
    SyntaqliteNodeTag tag;
    SyntaqliteTextSpan source;
} SyntaqliteVariable;

typedef struct SyntaqliteCollateExpr {
    SyntaqliteNodeTag tag;
    uint32_t expr;
    SyntaqliteTextSpan collation;
} SyntaqliteCollateExpr;

typedef struct SyntaqliteRaiseExpr {
    SyntaqliteNodeTag tag;
    SyntaqliteRaiseType raise_type;
    uint32_t error_message;
} SyntaqliteRaiseExpr;

typedef struct SyntaqliteQualifiedName {
    SyntaqliteNodeTag tag;
    uint32_t object_name;
    uint32_t schema;
} SyntaqliteQualifiedName;

typedef struct SyntaqliteDropStmt {
    SyntaqliteNodeTag tag;
    SyntaqliteDropObjectType object_type;
    SyntaqliteBool if_exists;
    uint32_t target;
} SyntaqliteDropStmt;

typedef struct SyntaqliteAlterTableStmt {
    SyntaqliteNodeTag tag;
    SyntaqliteAlterOp op;
    uint32_t target;
    uint32_t new_name;
    uint32_t old_name;
} SyntaqliteAlterTableStmt;

typedef struct SyntaqliteTransactionStmt {
    SyntaqliteNodeTag tag;
    SyntaqliteTransactionOp op;
    SyntaqliteTransactionType trans_type;
} SyntaqliteTransactionStmt;

typedef struct SyntaqliteSavepointStmt {
    SyntaqliteNodeTag tag;
    SyntaqliteSavepointOp op;
    uint32_t savepoint_name;
} SyntaqliteSavepointStmt;

typedef struct SyntaqliteResultColumn {
    SyntaqliteNodeTag tag;
    SyntaqliteResultColumnFlags flags;
    uint32_t alias;
    uint32_t expr;
} SyntaqliteResultColumn;

// List of ResultColumn
typedef struct SyntaqliteResultColumnList {
    uint32_t tag;
    uint32_t count;
    uint32_t children[SYNTAQLITE_FLEXIBLE_ARRAY];
} SyntaqliteResultColumnList;

typedef struct SyntaqliteSelectStmt {
    SyntaqliteNodeTag tag;
    SyntaqliteSelectStmtFlags flags;
    uint32_t columns;
    uint32_t from_clause;
    uint32_t where_clause;
    uint32_t groupby;
    uint32_t having;
    uint32_t orderby;
    uint32_t limit_clause;
    uint32_t window_clause;
} SyntaqliteSelectStmt;

typedef struct SyntaqliteOrderingTerm {
    SyntaqliteNodeTag tag;
    uint32_t expr;
    SyntaqliteSortOrder sort_order;
    SyntaqliteNullsOrder nulls_order;
} SyntaqliteOrderingTerm;

// List of OrderingTerm
typedef struct SyntaqliteOrderByList {
    uint32_t tag;
    uint32_t count;
    uint32_t children[SYNTAQLITE_FLEXIBLE_ARRAY];
} SyntaqliteOrderByList;

typedef struct SyntaqliteLimitClause {
    SyntaqliteNodeTag tag;
    uint32_t limit;
    uint32_t offset;
} SyntaqliteLimitClause;

typedef struct SyntaqliteTableRef {
    SyntaqliteNodeTag tag;
    SyntaqliteTextSpan table_name;
    SyntaqliteTextSpan schema;
    SyntaqliteBool has_parens;
    uint32_t alias;
    uint32_t args;
} SyntaqliteTableRef;

typedef struct SyntaqliteSubqueryTableSource {
    SyntaqliteNodeTag tag;
    uint32_t select;
    uint32_t alias;
} SyntaqliteSubqueryTableSource;

typedef struct SyntaqliteJoinClause {
    SyntaqliteNodeTag tag;
    SyntaqliteJoinType join_type;
    uint32_t left;
    uint32_t right;
    uint32_t on_expr;
    uint32_t using_columns;
} SyntaqliteJoinClause;

typedef struct SyntaqliteJoinPrefix {
    SyntaqliteNodeTag tag;
    uint32_t source;
    SyntaqliteJoinType join_type;
} SyntaqliteJoinPrefix;

typedef struct SyntaqliteTriggerEvent {
    SyntaqliteNodeTag tag;
    SyntaqliteTriggerEventType event_type;
    uint32_t columns;
} SyntaqliteTriggerEvent;

// List of Stmt
typedef struct SyntaqliteTriggerCmdList {
    uint32_t tag;
    uint32_t count;
    uint32_t children[SYNTAQLITE_FLEXIBLE_ARRAY];
} SyntaqliteTriggerCmdList;

typedef struct SyntaqliteCreateTriggerStmt {
    SyntaqliteNodeTag tag;
    SyntaqliteTextSpan trigger_name;
    SyntaqliteTextSpan schema;
    SyntaqliteBool is_temp;
    SyntaqliteBool if_not_exists;
    SyntaqliteTriggerTiming timing;
    uint32_t event;
    uint32_t table;
    uint32_t when_expr;
    uint32_t body;
} SyntaqliteCreateTriggerStmt;

typedef struct SyntaqliteCreateVirtualTableStmt {
    SyntaqliteNodeTag tag;
    SyntaqliteTextSpan table_name;
    SyntaqliteTextSpan schema;
    SyntaqliteTextSpan module_name;
    SyntaqliteBool if_not_exists;
    SyntaqliteTextSpan module_args;
} SyntaqliteCreateVirtualTableStmt;

typedef struct SyntaqlitePragmaStmt {
    SyntaqliteNodeTag tag;
    SyntaqliteTextSpan pragma_name;
    SyntaqliteTextSpan schema;
    SyntaqliteTextSpan value;
    SyntaqlitePragmaForm pragma_form;
} SyntaqlitePragmaStmt;

typedef struct SyntaqliteAnalyzeOrReindexStmt {
    SyntaqliteNodeTag tag;
    SyntaqliteTextSpan target_name;
    SyntaqliteTextSpan schema;
    SyntaqliteAnalyzeOrReindexOp kind;
} SyntaqliteAnalyzeOrReindexStmt;

typedef struct SyntaqliteAttachStmt {
    SyntaqliteNodeTag tag;
    uint32_t filename;
    uint32_t db_name;
    uint32_t key;
} SyntaqliteAttachStmt;

typedef struct SyntaqliteDetachStmt {
    SyntaqliteNodeTag tag;
    uint32_t db_name;
} SyntaqliteDetachStmt;

typedef struct SyntaqliteVacuumStmt {
    SyntaqliteNodeTag tag;
    SyntaqliteTextSpan schema;
    uint32_t filename;
} SyntaqliteVacuumStmt;

typedef struct SyntaqliteExplainStmt {
    SyntaqliteNodeTag tag;
    SyntaqliteExplainMode explain_mode;
    uint32_t stmt;
} SyntaqliteExplainStmt;

typedef struct SyntaqliteCreateIndexStmt {
    SyntaqliteNodeTag tag;
    SyntaqliteTextSpan index_name;
    SyntaqliteTextSpan schema;
    SyntaqliteTextSpan table_name;
    SyntaqliteBool is_unique;
    SyntaqliteBool if_not_exists;
    uint32_t columns;
    uint32_t where_clause;
} SyntaqliteCreateIndexStmt;

typedef struct SyntaqliteCreateViewStmt {
    SyntaqliteNodeTag tag;
    SyntaqliteTextSpan view_name;
    SyntaqliteTextSpan schema;
    SyntaqliteBool is_temp;
    SyntaqliteBool if_not_exists;
    uint32_t column_names;
    uint32_t select;
} SyntaqliteCreateViewStmt;

// List of ExprList
typedef struct SyntaqliteValuesRowList {
    uint32_t tag;
    uint32_t count;
    uint32_t children[SYNTAQLITE_FLEXIBLE_ARRAY];
} SyntaqliteValuesRowList;

typedef struct SyntaqliteValuesClause {
    SyntaqliteNodeTag tag;
    uint32_t rows;
} SyntaqliteValuesClause;

typedef struct SyntaqliteFrameBound {
    SyntaqliteNodeTag tag;
    SyntaqliteFrameBoundType bound_type;
    uint32_t expr;
} SyntaqliteFrameBound;

typedef struct SyntaqliteFrameSpec {
    SyntaqliteNodeTag tag;
    SyntaqliteFrameType frame_type;
    SyntaqliteFrameExclude exclude;
    uint32_t start_bound;
    uint32_t end_bound;
} SyntaqliteFrameSpec;

typedef struct SyntaqliteWindowDef {
    SyntaqliteNodeTag tag;
    SyntaqliteTextSpan base_window_name;
    uint32_t partition_by;
    uint32_t orderby;
    uint32_t frame;
} SyntaqliteWindowDef;

// List of WindowDef
typedef struct SyntaqliteWindowDefList {
    uint32_t tag;
    uint32_t count;
    uint32_t children[SYNTAQLITE_FLEXIBLE_ARRAY];
} SyntaqliteWindowDefList;

typedef struct SyntaqliteNamedWindowDef {
    SyntaqliteNodeTag tag;
    SyntaqliteTextSpan window_name;
    uint32_t window_def;
} SyntaqliteNamedWindowDef;

// List of NamedWindowDef
typedef struct SyntaqliteNamedWindowDefList {
    uint32_t tag;
    uint32_t count;
    uint32_t children[SYNTAQLITE_FLEXIBLE_ARRAY];
} SyntaqliteNamedWindowDefList;

typedef struct SyntaqliteFilterOver {
    SyntaqliteNodeTag tag;
    uint32_t filter_expr;
    uint32_t over_def;
    SyntaqliteTextSpan over_name;
} SyntaqliteFilterOver;

typedef struct SyntaqlitePerfettoArgDef {
    SyntaqliteNodeTag tag;
    uint32_t arg_name;
    SyntaqliteTextSpan arg_type;
    SyntaqliteBool is_variadic;
} SyntaqlitePerfettoArgDef;

// List of PerfettoArgDef
typedef struct SyntaqlitePerfettoArgDefList {
    uint32_t tag;
    uint32_t count;
    uint32_t children[SYNTAQLITE_FLEXIBLE_ARRAY];
} SyntaqlitePerfettoArgDefList;

typedef struct SyntaqlitePerfettoMacroArg {
    SyntaqliteNodeTag tag;
    SyntaqliteTextSpan arg_name;
    SyntaqliteTextSpan arg_type;
} SyntaqlitePerfettoMacroArg;

// List of PerfettoMacroArg
typedef struct SyntaqlitePerfettoMacroArgList {
    uint32_t tag;
    uint32_t count;
    uint32_t children[SYNTAQLITE_FLEXIBLE_ARRAY];
} SyntaqlitePerfettoMacroArgList;

typedef struct SyntaqlitePerfettoIndexedColumn {
    SyntaqliteNodeTag tag;
    SyntaqliteTextSpan column_name;
} SyntaqlitePerfettoIndexedColumn;

// List of PerfettoIndexedColumn
typedef struct SyntaqlitePerfettoIndexedColumnList {
    uint32_t tag;
    uint32_t count;
    uint32_t children[SYNTAQLITE_FLEXIBLE_ARRAY];
} SyntaqlitePerfettoIndexedColumnList;

typedef struct SyntaqlitePerfettoReturnType {
    SyntaqliteNodeTag tag;
    SyntaqlitePerfettoReturnKind kind;
    SyntaqliteTextSpan scalar_type;
    uint32_t table_columns;
} SyntaqlitePerfettoReturnType;

typedef struct SyntaqlitePerfettoTableImpl {
    SyntaqliteNodeTag tag;
    SyntaqliteTextSpan name;
} SyntaqlitePerfettoTableImpl;

typedef struct SyntaqliteCreatePerfettoTableStmt {
    SyntaqliteNodeTag tag;
    SyntaqliteTextSpan table_name;
    SyntaqliteBool or_replace;
    uint32_t table_impl;
    uint32_t schema;
    uint32_t select;
    SyntaqliteTextSpan select_span;
} SyntaqliteCreatePerfettoTableStmt;

typedef struct SyntaqliteCreatePerfettoViewStmt {
    SyntaqliteNodeTag tag;
    SyntaqliteTextSpan view_name;
    SyntaqliteBool or_replace;
    uint32_t schema;
    uint32_t select;
    SyntaqliteTextSpan select_span;
} SyntaqliteCreatePerfettoViewStmt;

typedef struct SyntaqliteCreatePerfettoFunctionStmt {
    SyntaqliteNodeTag tag;
    SyntaqliteTextSpan function_name;
    SyntaqliteBool or_replace;
    uint32_t args;
    uint32_t return_type;
    uint32_t select;
    SyntaqliteTextSpan select_span;
} SyntaqliteCreatePerfettoFunctionStmt;

typedef struct SyntaqliteCreatePerfettoDelegatingFunctionStmt {
    SyntaqliteNodeTag tag;
    SyntaqliteTextSpan function_name;
    SyntaqliteBool or_replace;
    uint32_t args;
    uint32_t return_type;
    SyntaqliteTextSpan delegate_to;
} SyntaqliteCreatePerfettoDelegatingFunctionStmt;

typedef struct SyntaqliteCreatePerfettoIndexStmt {
    SyntaqliteNodeTag tag;
    SyntaqliteTextSpan index_name;
    SyntaqliteBool or_replace;
    SyntaqliteTextSpan table_name;
    uint32_t columns;
} SyntaqliteCreatePerfettoIndexStmt;

typedef struct SyntaqliteCreatePerfettoMacroStmt {
    SyntaqliteNodeTag tag;
    SyntaqliteTextSpan macro_name;
    SyntaqliteBool or_replace;
    SyntaqliteTextSpan return_type;
    SyntaqliteTextSpan body;
    uint32_t args;
} SyntaqliteCreatePerfettoMacroStmt;

typedef struct SyntaqliteIncludePerfettoModuleStmt {
    SyntaqliteNodeTag tag;
    SyntaqliteTextSpan module_name;
} SyntaqliteIncludePerfettoModuleStmt;

typedef struct SyntaqliteDropPerfettoIndexStmt {
    SyntaqliteNodeTag tag;
    SyntaqliteTextSpan index_name;
    SyntaqliteTextSpan table_name;
} SyntaqliteDropPerfettoIndexStmt;

// ============ Node Union ============

typedef union SyntaqliteNode {
    SyntaqliteNodeTag tag;
    SyntaqliteAggregateFunctionCall aggregate_function_call;
    SyntaqliteOrderedSetFunctionCall ordered_set_function_call;
    SyntaqliteCastExpr cast_expr;
    SyntaqliteColumnRef column_ref;
    SyntaqliteCompoundSelect compound_select;
    SyntaqliteSubqueryExpr subquery_expr;
    SyntaqliteExistsExpr exists_expr;
    SyntaqliteInExpr in_expr;
    SyntaqliteIsExpr is_expr;
    SyntaqliteBetweenExpr between_expr;
    SyntaqliteLikeExpr like_expr;
    SyntaqliteCaseExpr case_expr;
    SyntaqliteCaseWhen case_when;
    SyntaqliteCaseWhenList case_when_list;
    SyntaqliteForeignKeyClause foreign_key_clause;
    SyntaqliteColumnConstraint column_constraint;
    SyntaqliteColumnConstraintList column_constraint_list;
    SyntaqliteColumnDef column_def;
    SyntaqliteColumnDefList column_def_list;
    SyntaqliteTableConstraint table_constraint;
    SyntaqliteTableConstraintList table_constraint_list;
    SyntaqliteCreateTableStmt create_table_stmt;
    SyntaqliteCteDefinition cte_definition;
    SyntaqliteCteList cte_list;
    SyntaqliteWithClause with_clause;
    SyntaqliteUpsertClause upsert_clause;
    SyntaqliteUpsertClauseList upsert_clause_list;
    SyntaqliteDeleteStmt delete_stmt;
    SyntaqliteSetClause set_clause;
    SyntaqliteSetClauseList set_clause_list;
    SyntaqliteUpdateStmt update_stmt;
    SyntaqliteInsertStmt insert_stmt;
    SyntaqliteBinaryExpr binary_expr;
    SyntaqliteUnaryExpr unary_expr;
    SyntaqliteLiteral literal;
    SyntaqliteParenExpr paren_expr;
    SyntaqliteIdentName ident_name;
    SyntaqliteError error;
    SyntaqliteExprList expr_list;
    SyntaqliteFunctionCall function_call;
    SyntaqliteVariable variable;
    SyntaqliteCollateExpr collate_expr;
    SyntaqliteRaiseExpr raise_expr;
    SyntaqliteQualifiedName qualified_name;
    SyntaqliteDropStmt drop_stmt;
    SyntaqliteAlterTableStmt alter_table_stmt;
    SyntaqliteTransactionStmt transaction_stmt;
    SyntaqliteSavepointStmt savepoint_stmt;
    SyntaqliteResultColumn result_column;
    SyntaqliteResultColumnList result_column_list;
    SyntaqliteSelectStmt select_stmt;
    SyntaqliteOrderingTerm ordering_term;
    SyntaqliteOrderByList order_by_list;
    SyntaqliteLimitClause limit_clause;
    SyntaqliteTableRef table_ref;
    SyntaqliteSubqueryTableSource subquery_table_source;
    SyntaqliteJoinClause join_clause;
    SyntaqliteJoinPrefix join_prefix;
    SyntaqliteTriggerEvent trigger_event;
    SyntaqliteTriggerCmdList trigger_cmd_list;
    SyntaqliteCreateTriggerStmt create_trigger_stmt;
    SyntaqliteCreateVirtualTableStmt create_virtual_table_stmt;
    SyntaqlitePragmaStmt pragma_stmt;
    SyntaqliteAnalyzeOrReindexStmt analyze_or_reindex_stmt;
    SyntaqliteAttachStmt attach_stmt;
    SyntaqliteDetachStmt detach_stmt;
    SyntaqliteVacuumStmt vacuum_stmt;
    SyntaqliteExplainStmt explain_stmt;
    SyntaqliteCreateIndexStmt create_index_stmt;
    SyntaqliteCreateViewStmt create_view_stmt;
    SyntaqliteValuesRowList values_row_list;
    SyntaqliteValuesClause values_clause;
    SyntaqliteFrameBound frame_bound;
    SyntaqliteFrameSpec frame_spec;
    SyntaqliteWindowDef window_def;
    SyntaqliteWindowDefList window_def_list;
    SyntaqliteNamedWindowDef named_window_def;
    SyntaqliteNamedWindowDefList named_window_def_list;
    SyntaqliteFilterOver filter_over;
    SyntaqlitePerfettoArgDef perfetto_arg_def;
    SyntaqlitePerfettoArgDefList perfetto_arg_def_list;
    SyntaqlitePerfettoMacroArg perfetto_macro_arg;
    SyntaqlitePerfettoMacroArgList perfetto_macro_arg_list;
    SyntaqlitePerfettoIndexedColumn perfetto_indexed_column;
    SyntaqlitePerfettoIndexedColumnList perfetto_indexed_column_list;
    SyntaqlitePerfettoReturnType perfetto_return_type;
    SyntaqlitePerfettoTableImpl perfetto_table_impl;
    SyntaqliteCreatePerfettoTableStmt create_perfetto_table_stmt;
    SyntaqliteCreatePerfettoViewStmt create_perfetto_view_stmt;
    SyntaqliteCreatePerfettoFunctionStmt create_perfetto_function_stmt;
    SyntaqliteCreatePerfettoDelegatingFunctionStmt create_perfetto_delegating_function_stmt;
    SyntaqliteCreatePerfettoIndexStmt create_perfetto_index_stmt;
    SyntaqliteCreatePerfettoMacroStmt create_perfetto_macro_stmt;
    SyntaqliteIncludePerfettoModuleStmt include_perfetto_module_stmt;
    SyntaqliteDropPerfettoIndexStmt drop_perfetto_index_stmt;
} SyntaqliteNode;

// ============ Abstract Type: Select ============

typedef union SyntaqliteSelect {
    SyntaqliteNodeTag tag;
    SyntaqliteSelectStmt select_stmt;
    SyntaqliteCompoundSelect compound_select;
    SyntaqliteWithClause with_clause;
    SyntaqliteValuesClause values_clause;
} SyntaqliteSelect;

static inline int syntaqlite_is_select(SyntaqliteNodeTag tag) {
    switch (tag) {
        case SYNTAQLITE_NODE_SELECT_STMT: return 1;
        case SYNTAQLITE_NODE_COMPOUND_SELECT: return 1;
        case SYNTAQLITE_NODE_WITH_CLAUSE: return 1;
        case SYNTAQLITE_NODE_VALUES_CLAUSE: return 1;
        default: return 0;
    }
}

static inline const SyntaqliteSelectStmt* syntaqlite_select_as_select_stmt(const SyntaqliteSelect* node) {
    return node->tag == SYNTAQLITE_NODE_SELECT_STMT ? &node->select_stmt : NULL;
}

static inline const SyntaqliteCompoundSelect* syntaqlite_select_as_compound_select(const SyntaqliteSelect* node) {
    return node->tag == SYNTAQLITE_NODE_COMPOUND_SELECT ? &node->compound_select : NULL;
}

static inline const SyntaqliteWithClause* syntaqlite_select_as_with_clause(const SyntaqliteSelect* node) {
    return node->tag == SYNTAQLITE_NODE_WITH_CLAUSE ? &node->with_clause : NULL;
}

static inline const SyntaqliteValuesClause* syntaqlite_select_as_values_clause(const SyntaqliteSelect* node) {
    return node->tag == SYNTAQLITE_NODE_VALUES_CLAUSE ? &node->values_clause : NULL;
}

// ============ Abstract Type: InExprSource ============

typedef union SyntaqliteInExprSource {
    SyntaqliteNodeTag tag;
    SyntaqliteExprList expr_list;
    SyntaqliteSubqueryExpr subquery_expr;
    SyntaqliteSelectStmt select_stmt;
    SyntaqliteCompoundSelect compound_select;
    SyntaqliteWithClause with_clause;
    SyntaqliteValuesClause values_clause;
    SyntaqliteTableRef table_ref;
} SyntaqliteInExprSource;

static inline int syntaqlite_is_in_expr_source(SyntaqliteNodeTag tag) {
    switch (tag) {
        case SYNTAQLITE_NODE_EXPR_LIST: return 1;
        case SYNTAQLITE_NODE_SUBQUERY_EXPR: return 1;
        case SYNTAQLITE_NODE_SELECT_STMT: return 1;
        case SYNTAQLITE_NODE_COMPOUND_SELECT: return 1;
        case SYNTAQLITE_NODE_WITH_CLAUSE: return 1;
        case SYNTAQLITE_NODE_VALUES_CLAUSE: return 1;
        case SYNTAQLITE_NODE_TABLE_REF: return 1;
        default: return 0;
    }
}

static inline const SyntaqliteExprList* syntaqlite_in_expr_source_as_expr_list(const SyntaqliteInExprSource* node) {
    return node->tag == SYNTAQLITE_NODE_EXPR_LIST ? &node->expr_list : NULL;
}

static inline const SyntaqliteSubqueryExpr* syntaqlite_in_expr_source_as_subquery_expr(const SyntaqliteInExprSource* node) {
    return node->tag == SYNTAQLITE_NODE_SUBQUERY_EXPR ? &node->subquery_expr : NULL;
}

static inline const SyntaqliteSelectStmt* syntaqlite_in_expr_source_as_select_stmt(const SyntaqliteInExprSource* node) {
    return node->tag == SYNTAQLITE_NODE_SELECT_STMT ? &node->select_stmt : NULL;
}

static inline const SyntaqliteCompoundSelect* syntaqlite_in_expr_source_as_compound_select(const SyntaqliteInExprSource* node) {
    return node->tag == SYNTAQLITE_NODE_COMPOUND_SELECT ? &node->compound_select : NULL;
}

static inline const SyntaqliteWithClause* syntaqlite_in_expr_source_as_with_clause(const SyntaqliteInExprSource* node) {
    return node->tag == SYNTAQLITE_NODE_WITH_CLAUSE ? &node->with_clause : NULL;
}

static inline const SyntaqliteValuesClause* syntaqlite_in_expr_source_as_values_clause(const SyntaqliteInExprSource* node) {
    return node->tag == SYNTAQLITE_NODE_VALUES_CLAUSE ? &node->values_clause : NULL;
}

static inline const SyntaqliteTableRef* syntaqlite_in_expr_source_as_table_ref(const SyntaqliteInExprSource* node) {
    return node->tag == SYNTAQLITE_NODE_TABLE_REF ? &node->table_ref : NULL;
}

// ============ Abstract Type: Name ============

typedef union SyntaqliteName {
    SyntaqliteNodeTag tag;
    SyntaqliteIdentName ident_name;
    SyntaqliteError error;
} SyntaqliteName;

static inline int syntaqlite_is_name(SyntaqliteNodeTag tag) {
    switch (tag) {
        case SYNTAQLITE_NODE_IDENT_NAME: return 1;
        case SYNTAQLITE_NODE_ERROR: return 1;
        default: return 0;
    }
}

static inline const SyntaqliteIdentName* syntaqlite_name_as_ident_name(const SyntaqliteName* node) {
    return node->tag == SYNTAQLITE_NODE_IDENT_NAME ? &node->ident_name : NULL;
}

static inline const SyntaqliteError* syntaqlite_name_as_error(const SyntaqliteName* node) {
    return node->tag == SYNTAQLITE_NODE_ERROR ? &node->error : NULL;
}

// ============ Abstract Type: Expr ============

typedef union SyntaqliteExpr {
    SyntaqliteNodeTag tag;
    SyntaqliteBinaryExpr binary_expr;
    SyntaqliteUnaryExpr unary_expr;
    SyntaqliteParenExpr paren_expr;
    SyntaqliteLiteral literal;
    SyntaqliteColumnRef column_ref;
    SyntaqliteVariable variable;
    SyntaqliteError error;
    SyntaqliteFunctionCall function_call;
    SyntaqliteAggregateFunctionCall aggregate_function_call;
    SyntaqliteOrderedSetFunctionCall ordered_set_function_call;
    SyntaqliteCastExpr cast_expr;
    SyntaqliteCollateExpr collate_expr;
    SyntaqliteCaseExpr case_expr;
    SyntaqliteIsExpr is_expr;
    SyntaqliteBetweenExpr between_expr;
    SyntaqliteLikeExpr like_expr;
    SyntaqliteInExpr in_expr;
    SyntaqliteSubqueryExpr subquery_expr;
    SyntaqliteExistsExpr exists_expr;
    SyntaqliteRaiseExpr raise_expr;
} SyntaqliteExpr;

static inline int syntaqlite_is_expr(SyntaqliteNodeTag tag) {
    switch (tag) {
        case SYNTAQLITE_NODE_BINARY_EXPR: return 1;
        case SYNTAQLITE_NODE_UNARY_EXPR: return 1;
        case SYNTAQLITE_NODE_PAREN_EXPR: return 1;
        case SYNTAQLITE_NODE_LITERAL: return 1;
        case SYNTAQLITE_NODE_COLUMN_REF: return 1;
        case SYNTAQLITE_NODE_VARIABLE: return 1;
        case SYNTAQLITE_NODE_ERROR: return 1;
        case SYNTAQLITE_NODE_FUNCTION_CALL: return 1;
        case SYNTAQLITE_NODE_AGGREGATE_FUNCTION_CALL: return 1;
        case SYNTAQLITE_NODE_ORDERED_SET_FUNCTION_CALL: return 1;
        case SYNTAQLITE_NODE_CAST_EXPR: return 1;
        case SYNTAQLITE_NODE_COLLATE_EXPR: return 1;
        case SYNTAQLITE_NODE_CASE_EXPR: return 1;
        case SYNTAQLITE_NODE_IS_EXPR: return 1;
        case SYNTAQLITE_NODE_BETWEEN_EXPR: return 1;
        case SYNTAQLITE_NODE_LIKE_EXPR: return 1;
        case SYNTAQLITE_NODE_IN_EXPR: return 1;
        case SYNTAQLITE_NODE_SUBQUERY_EXPR: return 1;
        case SYNTAQLITE_NODE_EXISTS_EXPR: return 1;
        case SYNTAQLITE_NODE_RAISE_EXPR: return 1;
        default: return 0;
    }
}

static inline const SyntaqliteBinaryExpr* syntaqlite_expr_as_binary_expr(const SyntaqliteExpr* node) {
    return node->tag == SYNTAQLITE_NODE_BINARY_EXPR ? &node->binary_expr : NULL;
}

static inline const SyntaqliteUnaryExpr* syntaqlite_expr_as_unary_expr(const SyntaqliteExpr* node) {
    return node->tag == SYNTAQLITE_NODE_UNARY_EXPR ? &node->unary_expr : NULL;
}

static inline const SyntaqliteParenExpr* syntaqlite_expr_as_paren_expr(const SyntaqliteExpr* node) {
    return node->tag == SYNTAQLITE_NODE_PAREN_EXPR ? &node->paren_expr : NULL;
}

static inline const SyntaqliteLiteral* syntaqlite_expr_as_literal(const SyntaqliteExpr* node) {
    return node->tag == SYNTAQLITE_NODE_LITERAL ? &node->literal : NULL;
}

static inline const SyntaqliteColumnRef* syntaqlite_expr_as_column_ref(const SyntaqliteExpr* node) {
    return node->tag == SYNTAQLITE_NODE_COLUMN_REF ? &node->column_ref : NULL;
}

static inline const SyntaqliteVariable* syntaqlite_expr_as_variable(const SyntaqliteExpr* node) {
    return node->tag == SYNTAQLITE_NODE_VARIABLE ? &node->variable : NULL;
}

static inline const SyntaqliteError* syntaqlite_expr_as_error(const SyntaqliteExpr* node) {
    return node->tag == SYNTAQLITE_NODE_ERROR ? &node->error : NULL;
}

static inline const SyntaqliteFunctionCall* syntaqlite_expr_as_function_call(const SyntaqliteExpr* node) {
    return node->tag == SYNTAQLITE_NODE_FUNCTION_CALL ? &node->function_call : NULL;
}

static inline const SyntaqliteAggregateFunctionCall* syntaqlite_expr_as_aggregate_function_call(const SyntaqliteExpr* node) {
    return node->tag == SYNTAQLITE_NODE_AGGREGATE_FUNCTION_CALL ? &node->aggregate_function_call : NULL;
}

static inline const SyntaqliteOrderedSetFunctionCall* syntaqlite_expr_as_ordered_set_function_call(const SyntaqliteExpr* node) {
    return node->tag == SYNTAQLITE_NODE_ORDERED_SET_FUNCTION_CALL ? &node->ordered_set_function_call : NULL;
}

static inline const SyntaqliteCastExpr* syntaqlite_expr_as_cast_expr(const SyntaqliteExpr* node) {
    return node->tag == SYNTAQLITE_NODE_CAST_EXPR ? &node->cast_expr : NULL;
}

static inline const SyntaqliteCollateExpr* syntaqlite_expr_as_collate_expr(const SyntaqliteExpr* node) {
    return node->tag == SYNTAQLITE_NODE_COLLATE_EXPR ? &node->collate_expr : NULL;
}

static inline const SyntaqliteCaseExpr* syntaqlite_expr_as_case_expr(const SyntaqliteExpr* node) {
    return node->tag == SYNTAQLITE_NODE_CASE_EXPR ? &node->case_expr : NULL;
}

static inline const SyntaqliteIsExpr* syntaqlite_expr_as_is_expr(const SyntaqliteExpr* node) {
    return node->tag == SYNTAQLITE_NODE_IS_EXPR ? &node->is_expr : NULL;
}

static inline const SyntaqliteBetweenExpr* syntaqlite_expr_as_between_expr(const SyntaqliteExpr* node) {
    return node->tag == SYNTAQLITE_NODE_BETWEEN_EXPR ? &node->between_expr : NULL;
}

static inline const SyntaqliteLikeExpr* syntaqlite_expr_as_like_expr(const SyntaqliteExpr* node) {
    return node->tag == SYNTAQLITE_NODE_LIKE_EXPR ? &node->like_expr : NULL;
}

static inline const SyntaqliteInExpr* syntaqlite_expr_as_in_expr(const SyntaqliteExpr* node) {
    return node->tag == SYNTAQLITE_NODE_IN_EXPR ? &node->in_expr : NULL;
}

static inline const SyntaqliteSubqueryExpr* syntaqlite_expr_as_subquery_expr(const SyntaqliteExpr* node) {
    return node->tag == SYNTAQLITE_NODE_SUBQUERY_EXPR ? &node->subquery_expr : NULL;
}

static inline const SyntaqliteExistsExpr* syntaqlite_expr_as_exists_expr(const SyntaqliteExpr* node) {
    return node->tag == SYNTAQLITE_NODE_EXISTS_EXPR ? &node->exists_expr : NULL;
}

static inline const SyntaqliteRaiseExpr* syntaqlite_expr_as_raise_expr(const SyntaqliteExpr* node) {
    return node->tag == SYNTAQLITE_NODE_RAISE_EXPR ? &node->raise_expr : NULL;
}

// ============ Abstract Type: Stmt ============

typedef union SyntaqliteStmt {
    SyntaqliteNodeTag tag;
    SyntaqliteSelectStmt select_stmt;
    SyntaqliteCompoundSelect compound_select;
    SyntaqliteValuesClause values_clause;
    SyntaqliteWithClause with_clause;
    SyntaqliteInsertStmt insert_stmt;
    SyntaqliteUpdateStmt update_stmt;
    SyntaqliteDeleteStmt delete_stmt;
    SyntaqliteCreateTableStmt create_table_stmt;
    SyntaqliteCreateIndexStmt create_index_stmt;
    SyntaqliteCreateViewStmt create_view_stmt;
    SyntaqliteCreateTriggerStmt create_trigger_stmt;
    SyntaqliteCreateVirtualTableStmt create_virtual_table_stmt;
    SyntaqliteDropStmt drop_stmt;
    SyntaqliteAlterTableStmt alter_table_stmt;
    SyntaqliteTransactionStmt transaction_stmt;
    SyntaqliteSavepointStmt savepoint_stmt;
    SyntaqlitePragmaStmt pragma_stmt;
    SyntaqliteAnalyzeOrReindexStmt analyze_or_reindex_stmt;
    SyntaqliteAttachStmt attach_stmt;
    SyntaqliteDetachStmt detach_stmt;
    SyntaqliteVacuumStmt vacuum_stmt;
    SyntaqliteExplainStmt explain_stmt;
} SyntaqliteStmt;

static inline int syntaqlite_is_stmt(SyntaqliteNodeTag tag) {
    switch (tag) {
        case SYNTAQLITE_NODE_SELECT_STMT: return 1;
        case SYNTAQLITE_NODE_COMPOUND_SELECT: return 1;
        case SYNTAQLITE_NODE_VALUES_CLAUSE: return 1;
        case SYNTAQLITE_NODE_WITH_CLAUSE: return 1;
        case SYNTAQLITE_NODE_INSERT_STMT: return 1;
        case SYNTAQLITE_NODE_UPDATE_STMT: return 1;
        case SYNTAQLITE_NODE_DELETE_STMT: return 1;
        case SYNTAQLITE_NODE_CREATE_TABLE_STMT: return 1;
        case SYNTAQLITE_NODE_CREATE_INDEX_STMT: return 1;
        case SYNTAQLITE_NODE_CREATE_VIEW_STMT: return 1;
        case SYNTAQLITE_NODE_CREATE_TRIGGER_STMT: return 1;
        case SYNTAQLITE_NODE_CREATE_VIRTUAL_TABLE_STMT: return 1;
        case SYNTAQLITE_NODE_DROP_STMT: return 1;
        case SYNTAQLITE_NODE_ALTER_TABLE_STMT: return 1;
        case SYNTAQLITE_NODE_TRANSACTION_STMT: return 1;
        case SYNTAQLITE_NODE_SAVEPOINT_STMT: return 1;
        case SYNTAQLITE_NODE_PRAGMA_STMT: return 1;
        case SYNTAQLITE_NODE_ANALYZE_OR_REINDEX_STMT: return 1;
        case SYNTAQLITE_NODE_ATTACH_STMT: return 1;
        case SYNTAQLITE_NODE_DETACH_STMT: return 1;
        case SYNTAQLITE_NODE_VACUUM_STMT: return 1;
        case SYNTAQLITE_NODE_EXPLAIN_STMT: return 1;
        default: return 0;
    }
}

static inline const SyntaqliteSelectStmt* syntaqlite_stmt_as_select_stmt(const SyntaqliteStmt* node) {
    return node->tag == SYNTAQLITE_NODE_SELECT_STMT ? &node->select_stmt : NULL;
}

static inline const SyntaqliteCompoundSelect* syntaqlite_stmt_as_compound_select(const SyntaqliteStmt* node) {
    return node->tag == SYNTAQLITE_NODE_COMPOUND_SELECT ? &node->compound_select : NULL;
}

static inline const SyntaqliteValuesClause* syntaqlite_stmt_as_values_clause(const SyntaqliteStmt* node) {
    return node->tag == SYNTAQLITE_NODE_VALUES_CLAUSE ? &node->values_clause : NULL;
}

static inline const SyntaqliteWithClause* syntaqlite_stmt_as_with_clause(const SyntaqliteStmt* node) {
    return node->tag == SYNTAQLITE_NODE_WITH_CLAUSE ? &node->with_clause : NULL;
}

static inline const SyntaqliteInsertStmt* syntaqlite_stmt_as_insert_stmt(const SyntaqliteStmt* node) {
    return node->tag == SYNTAQLITE_NODE_INSERT_STMT ? &node->insert_stmt : NULL;
}

static inline const SyntaqliteUpdateStmt* syntaqlite_stmt_as_update_stmt(const SyntaqliteStmt* node) {
    return node->tag == SYNTAQLITE_NODE_UPDATE_STMT ? &node->update_stmt : NULL;
}

static inline const SyntaqliteDeleteStmt* syntaqlite_stmt_as_delete_stmt(const SyntaqliteStmt* node) {
    return node->tag == SYNTAQLITE_NODE_DELETE_STMT ? &node->delete_stmt : NULL;
}

static inline const SyntaqliteCreateTableStmt* syntaqlite_stmt_as_create_table_stmt(const SyntaqliteStmt* node) {
    return node->tag == SYNTAQLITE_NODE_CREATE_TABLE_STMT ? &node->create_table_stmt : NULL;
}

static inline const SyntaqliteCreateIndexStmt* syntaqlite_stmt_as_create_index_stmt(const SyntaqliteStmt* node) {
    return node->tag == SYNTAQLITE_NODE_CREATE_INDEX_STMT ? &node->create_index_stmt : NULL;
}

static inline const SyntaqliteCreateViewStmt* syntaqlite_stmt_as_create_view_stmt(const SyntaqliteStmt* node) {
    return node->tag == SYNTAQLITE_NODE_CREATE_VIEW_STMT ? &node->create_view_stmt : NULL;
}

static inline const SyntaqliteCreateTriggerStmt* syntaqlite_stmt_as_create_trigger_stmt(const SyntaqliteStmt* node) {
    return node->tag == SYNTAQLITE_NODE_CREATE_TRIGGER_STMT ? &node->create_trigger_stmt : NULL;
}

static inline const SyntaqliteCreateVirtualTableStmt* syntaqlite_stmt_as_create_virtual_table_stmt(const SyntaqliteStmt* node) {
    return node->tag == SYNTAQLITE_NODE_CREATE_VIRTUAL_TABLE_STMT ? &node->create_virtual_table_stmt : NULL;
}

static inline const SyntaqliteDropStmt* syntaqlite_stmt_as_drop_stmt(const SyntaqliteStmt* node) {
    return node->tag == SYNTAQLITE_NODE_DROP_STMT ? &node->drop_stmt : NULL;
}

static inline const SyntaqliteAlterTableStmt* syntaqlite_stmt_as_alter_table_stmt(const SyntaqliteStmt* node) {
    return node->tag == SYNTAQLITE_NODE_ALTER_TABLE_STMT ? &node->alter_table_stmt : NULL;
}

static inline const SyntaqliteTransactionStmt* syntaqlite_stmt_as_transaction_stmt(const SyntaqliteStmt* node) {
    return node->tag == SYNTAQLITE_NODE_TRANSACTION_STMT ? &node->transaction_stmt : NULL;
}

static inline const SyntaqliteSavepointStmt* syntaqlite_stmt_as_savepoint_stmt(const SyntaqliteStmt* node) {
    return node->tag == SYNTAQLITE_NODE_SAVEPOINT_STMT ? &node->savepoint_stmt : NULL;
}

static inline const SyntaqlitePragmaStmt* syntaqlite_stmt_as_pragma_stmt(const SyntaqliteStmt* node) {
    return node->tag == SYNTAQLITE_NODE_PRAGMA_STMT ? &node->pragma_stmt : NULL;
}

static inline const SyntaqliteAnalyzeOrReindexStmt* syntaqlite_stmt_as_analyze_or_reindex_stmt(const SyntaqliteStmt* node) {
    return node->tag == SYNTAQLITE_NODE_ANALYZE_OR_REINDEX_STMT ? &node->analyze_or_reindex_stmt : NULL;
}

static inline const SyntaqliteAttachStmt* syntaqlite_stmt_as_attach_stmt(const SyntaqliteStmt* node) {
    return node->tag == SYNTAQLITE_NODE_ATTACH_STMT ? &node->attach_stmt : NULL;
}

static inline const SyntaqliteDetachStmt* syntaqlite_stmt_as_detach_stmt(const SyntaqliteStmt* node) {
    return node->tag == SYNTAQLITE_NODE_DETACH_STMT ? &node->detach_stmt : NULL;
}

static inline const SyntaqliteVacuumStmt* syntaqlite_stmt_as_vacuum_stmt(const SyntaqliteStmt* node) {
    return node->tag == SYNTAQLITE_NODE_VACUUM_STMT ? &node->vacuum_stmt : NULL;
}

static inline const SyntaqliteExplainStmt* syntaqlite_stmt_as_explain_stmt(const SyntaqliteStmt* node) {
    return node->tag == SYNTAQLITE_NODE_EXPLAIN_STMT ? &node->explain_stmt : NULL;
}

// ============ Abstract Type: TableSource ============

typedef union SyntaqliteTableSource {
    SyntaqliteNodeTag tag;
    SyntaqliteTableRef table_ref;
    SyntaqliteSubqueryTableSource subquery_table_source;
    SyntaqliteJoinClause join_clause;
    SyntaqliteJoinPrefix join_prefix;
} SyntaqliteTableSource;

static inline int syntaqlite_is_table_source(SyntaqliteNodeTag tag) {
    switch (tag) {
        case SYNTAQLITE_NODE_TABLE_REF: return 1;
        case SYNTAQLITE_NODE_SUBQUERY_TABLE_SOURCE: return 1;
        case SYNTAQLITE_NODE_JOIN_CLAUSE: return 1;
        case SYNTAQLITE_NODE_JOIN_PREFIX: return 1;
        default: return 0;
    }
}

static inline const SyntaqliteTableRef* syntaqlite_table_source_as_table_ref(const SyntaqliteTableSource* node) {
    return node->tag == SYNTAQLITE_NODE_TABLE_REF ? &node->table_ref : NULL;
}

static inline const SyntaqliteSubqueryTableSource* syntaqlite_table_source_as_subquery_table_source(const SyntaqliteTableSource* node) {
    return node->tag == SYNTAQLITE_NODE_SUBQUERY_TABLE_SOURCE ? &node->subquery_table_source : NULL;
}

static inline const SyntaqliteJoinClause* syntaqlite_table_source_as_join_clause(const SyntaqliteTableSource* node) {
    return node->tag == SYNTAQLITE_NODE_JOIN_CLAUSE ? &node->join_clause : NULL;
}

static inline const SyntaqliteJoinPrefix* syntaqlite_table_source_as_join_prefix(const SyntaqliteTableSource* node) {
    return node->tag == SYNTAQLITE_NODE_JOIN_PREFIX ? &node->join_prefix : NULL;
}

#ifdef __cplusplus
}
#endif

#if defined(__cplusplus) && __cplusplus >= 201703L

namespace syntaqlite {

template <typename T> struct NodeTag { static constexpr bool kHasTag = false; };

template <> struct NodeTag<SyntaqliteAggregateFunctionCall> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_AGGREGATE_FUNCTION_CALL;
};
template <> struct NodeTag<SyntaqliteOrderedSetFunctionCall> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_ORDERED_SET_FUNCTION_CALL;
};
template <> struct NodeTag<SyntaqliteCastExpr> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_CAST_EXPR;
};
template <> struct NodeTag<SyntaqliteColumnRef> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_COLUMN_REF;
};
template <> struct NodeTag<SyntaqliteCompoundSelect> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_COMPOUND_SELECT;
};
template <> struct NodeTag<SyntaqliteSubqueryExpr> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_SUBQUERY_EXPR;
};
template <> struct NodeTag<SyntaqliteExistsExpr> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_EXISTS_EXPR;
};
template <> struct NodeTag<SyntaqliteInExpr> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_IN_EXPR;
};
template <> struct NodeTag<SyntaqliteIsExpr> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_IS_EXPR;
};
template <> struct NodeTag<SyntaqliteBetweenExpr> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_BETWEEN_EXPR;
};
template <> struct NodeTag<SyntaqliteLikeExpr> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_LIKE_EXPR;
};
template <> struct NodeTag<SyntaqliteCaseExpr> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_CASE_EXPR;
};
template <> struct NodeTag<SyntaqliteCaseWhen> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_CASE_WHEN;
};
template <> struct NodeTag<SyntaqliteCaseWhenList> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_CASE_WHEN_LIST;
};
template <> struct NodeTag<SyntaqliteForeignKeyClause> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_FOREIGN_KEY_CLAUSE;
};
template <> struct NodeTag<SyntaqliteColumnConstraint> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_COLUMN_CONSTRAINT;
};
template <> struct NodeTag<SyntaqliteColumnConstraintList> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_COLUMN_CONSTRAINT_LIST;
};
template <> struct NodeTag<SyntaqliteColumnDef> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_COLUMN_DEF;
};
template <> struct NodeTag<SyntaqliteColumnDefList> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_COLUMN_DEF_LIST;
};
template <> struct NodeTag<SyntaqliteTableConstraint> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_TABLE_CONSTRAINT;
};
template <> struct NodeTag<SyntaqliteTableConstraintList> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_TABLE_CONSTRAINT_LIST;
};
template <> struct NodeTag<SyntaqliteCreateTableStmt> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_CREATE_TABLE_STMT;
};
template <> struct NodeTag<SyntaqliteCteDefinition> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_CTE_DEFINITION;
};
template <> struct NodeTag<SyntaqliteCteList> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_CTE_LIST;
};
template <> struct NodeTag<SyntaqliteWithClause> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_WITH_CLAUSE;
};
template <> struct NodeTag<SyntaqliteUpsertClause> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_UPSERT_CLAUSE;
};
template <> struct NodeTag<SyntaqliteUpsertClauseList> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_UPSERT_CLAUSE_LIST;
};
template <> struct NodeTag<SyntaqliteDeleteStmt> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_DELETE_STMT;
};
template <> struct NodeTag<SyntaqliteSetClause> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_SET_CLAUSE;
};
template <> struct NodeTag<SyntaqliteSetClauseList> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_SET_CLAUSE_LIST;
};
template <> struct NodeTag<SyntaqliteUpdateStmt> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_UPDATE_STMT;
};
template <> struct NodeTag<SyntaqliteInsertStmt> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_INSERT_STMT;
};
template <> struct NodeTag<SyntaqliteBinaryExpr> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_BINARY_EXPR;
};
template <> struct NodeTag<SyntaqliteUnaryExpr> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_UNARY_EXPR;
};
template <> struct NodeTag<SyntaqliteLiteral> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_LITERAL;
};
template <> struct NodeTag<SyntaqliteParenExpr> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_PAREN_EXPR;
};
template <> struct NodeTag<SyntaqliteIdentName> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_IDENT_NAME;
};
template <> struct NodeTag<SyntaqliteError> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_ERROR;
};
template <> struct NodeTag<SyntaqliteExprList> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_EXPR_LIST;
};
template <> struct NodeTag<SyntaqliteFunctionCall> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_FUNCTION_CALL;
};
template <> struct NodeTag<SyntaqliteVariable> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_VARIABLE;
};
template <> struct NodeTag<SyntaqliteCollateExpr> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_COLLATE_EXPR;
};
template <> struct NodeTag<SyntaqliteRaiseExpr> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_RAISE_EXPR;
};
template <> struct NodeTag<SyntaqliteQualifiedName> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_QUALIFIED_NAME;
};
template <> struct NodeTag<SyntaqliteDropStmt> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_DROP_STMT;
};
template <> struct NodeTag<SyntaqliteAlterTableStmt> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_ALTER_TABLE_STMT;
};
template <> struct NodeTag<SyntaqliteTransactionStmt> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_TRANSACTION_STMT;
};
template <> struct NodeTag<SyntaqliteSavepointStmt> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_SAVEPOINT_STMT;
};
template <> struct NodeTag<SyntaqliteResultColumn> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_RESULT_COLUMN;
};
template <> struct NodeTag<SyntaqliteResultColumnList> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_RESULT_COLUMN_LIST;
};
template <> struct NodeTag<SyntaqliteSelectStmt> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_SELECT_STMT;
};
template <> struct NodeTag<SyntaqliteOrderingTerm> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_ORDERING_TERM;
};
template <> struct NodeTag<SyntaqliteOrderByList> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_ORDER_BY_LIST;
};
template <> struct NodeTag<SyntaqliteLimitClause> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_LIMIT_CLAUSE;
};
template <> struct NodeTag<SyntaqliteTableRef> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_TABLE_REF;
};
template <> struct NodeTag<SyntaqliteSubqueryTableSource> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_SUBQUERY_TABLE_SOURCE;
};
template <> struct NodeTag<SyntaqliteJoinClause> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_JOIN_CLAUSE;
};
template <> struct NodeTag<SyntaqliteJoinPrefix> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_JOIN_PREFIX;
};
template <> struct NodeTag<SyntaqliteTriggerEvent> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_TRIGGER_EVENT;
};
template <> struct NodeTag<SyntaqliteTriggerCmdList> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_TRIGGER_CMD_LIST;
};
template <> struct NodeTag<SyntaqliteCreateTriggerStmt> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_CREATE_TRIGGER_STMT;
};
template <> struct NodeTag<SyntaqliteCreateVirtualTableStmt> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_CREATE_VIRTUAL_TABLE_STMT;
};
template <> struct NodeTag<SyntaqlitePragmaStmt> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_PRAGMA_STMT;
};
template <> struct NodeTag<SyntaqliteAnalyzeOrReindexStmt> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_ANALYZE_OR_REINDEX_STMT;
};
template <> struct NodeTag<SyntaqliteAttachStmt> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_ATTACH_STMT;
};
template <> struct NodeTag<SyntaqliteDetachStmt> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_DETACH_STMT;
};
template <> struct NodeTag<SyntaqliteVacuumStmt> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_VACUUM_STMT;
};
template <> struct NodeTag<SyntaqliteExplainStmt> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_EXPLAIN_STMT;
};
template <> struct NodeTag<SyntaqliteCreateIndexStmt> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_CREATE_INDEX_STMT;
};
template <> struct NodeTag<SyntaqliteCreateViewStmt> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_CREATE_VIEW_STMT;
};
template <> struct NodeTag<SyntaqliteValuesRowList> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_VALUES_ROW_LIST;
};
template <> struct NodeTag<SyntaqliteValuesClause> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_VALUES_CLAUSE;
};
template <> struct NodeTag<SyntaqliteFrameBound> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_FRAME_BOUND;
};
template <> struct NodeTag<SyntaqliteFrameSpec> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_FRAME_SPEC;
};
template <> struct NodeTag<SyntaqliteWindowDef> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_WINDOW_DEF;
};
template <> struct NodeTag<SyntaqliteWindowDefList> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_WINDOW_DEF_LIST;
};
template <> struct NodeTag<SyntaqliteNamedWindowDef> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_NAMED_WINDOW_DEF;
};
template <> struct NodeTag<SyntaqliteNamedWindowDefList> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_NAMED_WINDOW_DEF_LIST;
};
template <> struct NodeTag<SyntaqliteFilterOver> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_FILTER_OVER;
};
template <> struct NodeTag<SyntaqlitePerfettoArgDef> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_PERFETTO_ARG_DEF;
};
template <> struct NodeTag<SyntaqlitePerfettoArgDefList> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_PERFETTO_ARG_DEF_LIST;
};
template <> struct NodeTag<SyntaqlitePerfettoMacroArg> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_PERFETTO_MACRO_ARG;
};
template <> struct NodeTag<SyntaqlitePerfettoMacroArgList> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_PERFETTO_MACRO_ARG_LIST;
};
template <> struct NodeTag<SyntaqlitePerfettoIndexedColumn> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_PERFETTO_INDEXED_COLUMN;
};
template <> struct NodeTag<SyntaqlitePerfettoIndexedColumnList> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_PERFETTO_INDEXED_COLUMN_LIST;
};
template <> struct NodeTag<SyntaqlitePerfettoReturnType> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_PERFETTO_RETURN_TYPE;
};
template <> struct NodeTag<SyntaqlitePerfettoTableImpl> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_PERFETTO_TABLE_IMPL;
};
template <> struct NodeTag<SyntaqliteCreatePerfettoTableStmt> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_CREATE_PERFETTO_TABLE_STMT;
};
template <> struct NodeTag<SyntaqliteCreatePerfettoViewStmt> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_CREATE_PERFETTO_VIEW_STMT;
};
template <> struct NodeTag<SyntaqliteCreatePerfettoFunctionStmt> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_CREATE_PERFETTO_FUNCTION_STMT;
};
template <> struct NodeTag<SyntaqliteCreatePerfettoDelegatingFunctionStmt> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_CREATE_PERFETTO_DELEGATING_FUNCTION_STMT;
};
template <> struct NodeTag<SyntaqliteCreatePerfettoIndexStmt> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_CREATE_PERFETTO_INDEX_STMT;
};
template <> struct NodeTag<SyntaqliteCreatePerfettoMacroStmt> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_CREATE_PERFETTO_MACRO_STMT;
};
template <> struct NodeTag<SyntaqliteIncludePerfettoModuleStmt> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_INCLUDE_PERFETTO_MODULE_STMT;
};
template <> struct NodeTag<SyntaqliteDropPerfettoIndexStmt> {
  static constexpr bool kHasTag = true;
  static constexpr uint32_t kValue = SYNTAQLITE_NODE_DROP_PERFETTO_INDEX_STMT;
};

}  // namespace syntaqlite
#endif


#endif  /* SYNTAQLITE_PERFETTO_NODE_H */
/* ======== end: syntaqlite_perfetto/perfetto_node.h ======== */

/* ======== begin: syntaqlite_perfetto/perfetto_tokens.h ======== */
#ifndef SYNTAQLITE_PERFETTO_TOKENS_H
#define SYNTAQLITE_PERFETTO_TOKENS_H
#define SYNTAQLITE_TK_ABORT                            1
#define SYNTAQLITE_TK_ACTION                           2
#define SYNTAQLITE_TK_AFTER                            3
#define SYNTAQLITE_TK_ANALYZE                          4
#define SYNTAQLITE_TK_ASC                              5
#define SYNTAQLITE_TK_ATTACH                           6
#define SYNTAQLITE_TK_BEFORE                           7
#define SYNTAQLITE_TK_BEGIN                            8
#define SYNTAQLITE_TK_BY                               9
#define SYNTAQLITE_TK_CASCADE                         10
#define SYNTAQLITE_TK_CAST                            11
#define SYNTAQLITE_TK_CONFLICT                        12
#define SYNTAQLITE_TK_DATABASE                        13
#define SYNTAQLITE_TK_DEFERRED                        14
#define SYNTAQLITE_TK_DESC                            15
#define SYNTAQLITE_TK_DETACH                          16
#define SYNTAQLITE_TK_EACH                            17
#define SYNTAQLITE_TK_END                             18
#define SYNTAQLITE_TK_EXCLUSIVE                       19
#define SYNTAQLITE_TK_EXPLAIN                         20
#define SYNTAQLITE_TK_FAIL                            21
#define SYNTAQLITE_TK_OR                              22
#define SYNTAQLITE_TK_AND                             23
#define SYNTAQLITE_TK_NOT                             24
#define SYNTAQLITE_TK_IS                              25
#define SYNTAQLITE_TK_ISNOT                           26
#define SYNTAQLITE_TK_MATCH                           27
#define SYNTAQLITE_TK_LIKE_KW                         28
#define SYNTAQLITE_TK_BETWEEN                         29
#define SYNTAQLITE_TK_IN                              30
#define SYNTAQLITE_TK_ISNULL                          31
#define SYNTAQLITE_TK_NOTNULL                         32
#define SYNTAQLITE_TK_NE                              33
#define SYNTAQLITE_TK_EQ                              34
#define SYNTAQLITE_TK_GT                              35
#define SYNTAQLITE_TK_LE                              36
#define SYNTAQLITE_TK_LT                              37
#define SYNTAQLITE_TK_GE                              38
#define SYNTAQLITE_TK_ESCAPE                          39
#define SYNTAQLITE_TK_ID                              40
#define SYNTAQLITE_TK_COLUMNKW                        41
#define SYNTAQLITE_TK_DO                              42
#define SYNTAQLITE_TK_FOR                             43
#define SYNTAQLITE_TK_IGNORE                          44
#define SYNTAQLITE_TK_IMMEDIATE                       45
#define SYNTAQLITE_TK_INITIALLY                       46
#define SYNTAQLITE_TK_INSTEAD                         47
#define SYNTAQLITE_TK_NO                              48
#define SYNTAQLITE_TK_PLAN                            49
#define SYNTAQLITE_TK_QUERY                           50
#define SYNTAQLITE_TK_KEY                             51
#define SYNTAQLITE_TK_OF                              52
#define SYNTAQLITE_TK_OFFSET                          53
#define SYNTAQLITE_TK_PRAGMA                          54
#define SYNTAQLITE_TK_RAISE                           55
#define SYNTAQLITE_TK_RECURSIVE                       56
#define SYNTAQLITE_TK_RELEASE                         57
#define SYNTAQLITE_TK_REPLACE                         58
#define SYNTAQLITE_TK_RESTRICT                        59
#define SYNTAQLITE_TK_ROW                             60
#define SYNTAQLITE_TK_ROWS                            61
#define SYNTAQLITE_TK_ROLLBACK                        62
#define SYNTAQLITE_TK_SAVEPOINT                       63
#define SYNTAQLITE_TK_TEMP                            64
#define SYNTAQLITE_TK_TRIGGER                         65
#define SYNTAQLITE_TK_VACUUM                          66
#define SYNTAQLITE_TK_VIEW                            67
#define SYNTAQLITE_TK_VIRTUAL                         68
#define SYNTAQLITE_TK_WITH                            69
#define SYNTAQLITE_TK_WITHOUT                         70
#define SYNTAQLITE_TK_NULLS                           71
#define SYNTAQLITE_TK_FIRST                           72
#define SYNTAQLITE_TK_LAST                            73
#define SYNTAQLITE_TK_CURRENT                         74
#define SYNTAQLITE_TK_FOLLOWING                       75
#define SYNTAQLITE_TK_PARTITION                       76
#define SYNTAQLITE_TK_PRECEDING                       77
#define SYNTAQLITE_TK_RANGE                           78
#define SYNTAQLITE_TK_UNBOUNDED                       79
#define SYNTAQLITE_TK_EXCLUDE                         80
#define SYNTAQLITE_TK_GROUPS                          81
#define SYNTAQLITE_TK_OTHERS                          82
#define SYNTAQLITE_TK_TIES                            83
#define SYNTAQLITE_TK_GENERATED                       84
#define SYNTAQLITE_TK_ALWAYS                          85
#define SYNTAQLITE_TK_WITHIN                          86
#define SYNTAQLITE_TK_MATERIALIZED                    87
#define SYNTAQLITE_TK_REINDEX                         88
#define SYNTAQLITE_TK_RENAME                          89
#define SYNTAQLITE_TK_CTIME_KW                        90
#define SYNTAQLITE_TK_IF                              91
#define SYNTAQLITE_TK_ANY                             92
#define SYNTAQLITE_TK_BITAND                          93
#define SYNTAQLITE_TK_BITOR                           94
#define SYNTAQLITE_TK_LSHIFT                          95
#define SYNTAQLITE_TK_RSHIFT                          96
#define SYNTAQLITE_TK_PLUS                            97
#define SYNTAQLITE_TK_MINUS                           98
#define SYNTAQLITE_TK_STAR                            99
#define SYNTAQLITE_TK_SLASH                          100
#define SYNTAQLITE_TK_REM                            101
#define SYNTAQLITE_TK_CONCAT                         102
#define SYNTAQLITE_TK_PTR                            103
#define SYNTAQLITE_TK_COLLATE                        104
#define SYNTAQLITE_TK_BITNOT                         105
#define SYNTAQLITE_TK_ON                             106
#define SYNTAQLITE_TK_INDEXED                        107
#define SYNTAQLITE_TK_STRING                         108
#define SYNTAQLITE_TK_JOIN_KW                        109
#define SYNTAQLITE_TK_INTEGER                        110
#define SYNTAQLITE_TK_FLOAT                          111
#define SYNTAQLITE_TK_SEMI                           112
#define SYNTAQLITE_TK_LP                             113
#define SYNTAQLITE_TK_ORDER                          114
#define SYNTAQLITE_TK_RP                             115
#define SYNTAQLITE_TK_GROUP                          116
#define SYNTAQLITE_TK_AS                             117
#define SYNTAQLITE_TK_COMMA                          118
#define SYNTAQLITE_TK_DOT                            119
#define SYNTAQLITE_TK_UNION                          120
#define SYNTAQLITE_TK_ALL                            121
#define SYNTAQLITE_TK_EXCEPT                         122
#define SYNTAQLITE_TK_INTERSECT                      123
#define SYNTAQLITE_TK_EXISTS                         124
#define SYNTAQLITE_TK_NULL                           125
#define SYNTAQLITE_TK_DISTINCT                       126
#define SYNTAQLITE_TK_FROM                           127
#define SYNTAQLITE_TK_CASE                           128
#define SYNTAQLITE_TK_WHEN                           129
#define SYNTAQLITE_TK_THEN                           130
#define SYNTAQLITE_TK_ELSE                           131
#define SYNTAQLITE_TK_TABLE                          132
#define SYNTAQLITE_TK_CONSTRAINT                     133
#define SYNTAQLITE_TK_DEFAULT                        134
#define SYNTAQLITE_TK_PRIMARY                        135
#define SYNTAQLITE_TK_UNIQUE                         136
#define SYNTAQLITE_TK_CHECK                          137
#define SYNTAQLITE_TK_REFERENCES                     138
#define SYNTAQLITE_TK_AUTOINCR                       139
#define SYNTAQLITE_TK_INSERT                         140
#define SYNTAQLITE_TK_DELETE                         141
#define SYNTAQLITE_TK_UPDATE                         142
#define SYNTAQLITE_TK_SET                            143
#define SYNTAQLITE_TK_DEFERRABLE                     144
#define SYNTAQLITE_TK_FOREIGN                        145
#define SYNTAQLITE_TK_INTO                           146
#define SYNTAQLITE_TK_VALUES                         147
#define SYNTAQLITE_TK_WHERE                          148
#define SYNTAQLITE_TK_RETURNING                      149
#define SYNTAQLITE_TK_NOTHING                        150
#define SYNTAQLITE_TK_BLOB                           151
#define SYNTAQLITE_TK_QNUMBER                        152
#define SYNTAQLITE_TK_VARIABLE                       153
#define SYNTAQLITE_TK_DROP                           154
#define SYNTAQLITE_TK_INDEX                          155
#define SYNTAQLITE_TK_ALTER                          156
#define SYNTAQLITE_TK_TO                             157
#define SYNTAQLITE_TK_ADD                            158
#define SYNTAQLITE_TK_COMMIT                         159
#define SYNTAQLITE_TK_TRANSACTION                    160
#define SYNTAQLITE_TK_SELECT                         161
#define SYNTAQLITE_TK_HAVING                         162
#define SYNTAQLITE_TK_LIMIT                          163
#define SYNTAQLITE_TK_JOIN                           164
#define SYNTAQLITE_TK_USING                          165
#define SYNTAQLITE_TK_CREATE                         166
#define SYNTAQLITE_TK_WINDOW                         167
#define SYNTAQLITE_TK_OVER                           168
#define SYNTAQLITE_TK_FILTER                         169
#define SYNTAQLITE_TK_COLUMN                         170
#define SYNTAQLITE_TK_AGG_FUNCTION                   171
#define SYNTAQLITE_TK_AGG_COLUMN                     172
#define SYNTAQLITE_TK_TRUEFALSE                      173
#define SYNTAQLITE_TK_FUNCTION                       174
#define SYNTAQLITE_TK_UPLUS                          175
#define SYNTAQLITE_TK_UMINUS                         176
#define SYNTAQLITE_TK_TRUTH                          177
#define SYNTAQLITE_TK_REGISTER                       178
#define SYNTAQLITE_TK_VECTOR                         179
#define SYNTAQLITE_TK_SELECT_COLUMN                  180
#define SYNTAQLITE_TK_IF_NULL_ROW                    181
#define SYNTAQLITE_TK_ASTERISK                       182
#define SYNTAQLITE_TK_SPAN                           183
#define SYNTAQLITE_TK_ERROR                          184
#define SYNTAQLITE_TK_SPACE                          185
#define SYNTAQLITE_TK_COMMENT                        186
#define SYNTAQLITE_TK_ILLEGAL                        187
#define SYNTAQLITE_TK_BANG                           188
#define SYNTAQLITE_TK_PERFETTO                       189
#define SYNTAQLITE_TK_MODULE                         190
#define SYNTAQLITE_TK_RETURNS                        191
#define SYNTAQLITE_TK_MACRO                          192
#define SYNTAQLITE_TK_DELEGATES                      193
#define SYNTAQLITE_TK_INCLUDE                        194

/* syntaqlite extension: expected terminals for current parser state. */
uint32_t SynqPerfettoParseExpectedTokens(void* parser, uint32_t* out_tokens, uint32_t out_cap);

/* syntaqlite extension: completion context from parser stack. */
uint32_t SynqPerfettoParseCompletionContext(void* parser);

#endif  /* SYNTAQLITE_PERFETTO_TOKENS_H */
/* ======== end: syntaqlite_perfetto/perfetto_tokens.h ======== */


#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif

#endif  /* SYNTAQLITE_PERFETTO_H */
