# Copyright (c) 2020-now by the Zeek Project. See LICENSE for details.

module spicy_rt {

# Ignore this module for code generation, we just need the declarations.
%skip-implementation;

import hilti;

public type Backtrack = exception &cxxname="spicy::rt::Backtrack";
public type MissingData = exception &cxxname="spicy::rt::MissingData";
public type ParseError = exception &cxxname="spicy::rt::ParseError";
public type UnitAlreadyConnected = exception &cxxname="spicy::rt::UnitAlreadyConnected";

# State stored inside a unit to allow connecting it to a sink.
public type SinkState = __library_type("spicy::rt::sink::detail::State*");

public type ParsedUnit = __library_type("spicy::rt::ParsedUnit");

# Type for a Sink instance. When adding methods here, extend the C++-side spicy::rt::Sink type as well.
public type Sink = struct {
    method void close();
    method void connect(strong_ref<*> unit &requires-type-feature="supports_sinks");
    method void connect_filter(strong_ref<*> unit &requires-type-feature="is_filter");
    method void connect_mime_type(string mime_type);
    method void connect_mime_type(bytes mime_type);
    method void connect_mime_type(string mime_type, uint<64> scope) &internal;
    method void connect_mime_type(bytes mime_type, uint<64> scope) &internal;
    method void gap(uint<64> seq, uint<64> len);
    method uint<64> sequence_number();
    method void set_auto_trim(bool enable);
    method void set_initial_sequence_number(uint<64> seq);
    method void set_policy(any policy);
    method uint<64> size();
    method void skip(uint<64> seq);
    method void trim(uint<64> seq);
    method void write(bytes data, optional<uint<64>> seq = Null, optional<uint<64>> len = Null);
} &cxxname="spicy::rt::Sink";

public type HiltiResumable = __library_type("hilti::rt::Resumable");

public type Filters = __library_type("spicy::rt::filter::detail::Filters");
public type Forward = __library_type("spicy::rt::filter::detail::Forward");

declare public strong_ref<stream> filter_init(inout any unit &requires-type-feature="supports_filters", inout value_ref<stream> data, view<stream> cur) &cxxname="spicy::rt::filter::init" &have_prototype;
declare public void filter_connect(inout any unit &requires-type-feature="supports_filters", strong_ref<*> filter &requires-type-feature="is_filter") &cxxname="spicy::rt::filter::connect" &have_prototype;
declare public void filter_disconnect(inout any unit &requires-type-feature="supports_filters") &cxxname="spicy::rt::filter::disconnect" &have_prototype;
declare public void filter_forward(inout any filter &requires-type-feature="is_filter", bytes b) &cxxname="spicy::rt::filter::forward" &have_prototype;
declare public void filter_forward_eod(inout any filter &requires-type-feature="is_filter") &cxxname="spicy::rt::filter::forward_eod" &have_prototype;

declare public void confirm(inout any unit &requires-type-feature="synchronization") &cxxname="spicy::rt::confirm" &have_prototype;
declare public void reject(inout any unit &requires-type-feature="synchronization") &cxxname="spicy::rt::reject" &have_prototype;

public type UnitContext = __library_type("spicy::rt::UnitContext");
declare public UnitContext createContext(any ctx) &cxxname="spicy::rt::detail::createContext" &have_prototype;
declare public void setContext(inout any unit, optional<UnitContext> ctx, type type_) &cxxname="spicy::rt::detail::setContext" &have_prototype;

# Type for a parser definition. When making changes, adapt the C++-side
# spicy::rt::Parser as well.
public type Parser = struct {
    string name;
    bool is_public;
    any parse1;
    any parse2;
    any parse3;
    any context_new;
    type type_;
    string description;
    vector<MIMEType> mime_types;
    vector<ParserPort> ports;
} &cxxname="spicy::rt::Parser";

public type BitOrder = enum { LSB0, MSB0 } &cxxname="hilti::rt::integer::BitOrder";
public type Direction = enum { Originator, Responder, Both } &cxxname="spicy::rt::Direction";
public type FindDirection = __library_type("hilti::rt::stream::Direction");
public type MIMEType = __library_type("spicy::rt::MIMEType");
public type ParserPort = __library_type("spicy::rt::ParserPort");

declare public void registerParser(inout Parser parse_func, uint<64> linker_scope, any instance) &cxxname="spicy::rt::detail::registerParser" &have_prototype;
declare public void printParserState(string unit_id, value_ref<stream> data, optional<iterator<stream>> begin_, view<stream> cur, int<64> lahead, iterator<stream> lahead_end, string literal_mode, bool trim, optional<hilti::RecoverableFailure> err) &cxxname="spicy::rt::detail::printParserState" &have_prototype;

declare public bool waitForInputOrEod(inout value_ref<stream> data, view<stream> cur, inout strong_ref<Filters> filters) &cxxname="spicy::rt::detail::waitForInputOrEod" &have_prototype;
declare public bool waitForInputOrEod(inout value_ref<stream> data, view<stream> cur, uint<64> n, inout strong_ref<Filters> filters) &cxxname="spicy::rt::detail::waitForInputOrEod" &have_prototype;
declare public void waitForInput(inout value_ref<stream> data, view<stream> cur, string error_msg, string location, inout strong_ref<Filters> filters) &cxxname="spicy::rt::detail::waitForInput" &have_prototype;
declare public void waitForInput(inout value_ref<stream> data, view<stream> cur, uint<64> n, string error_msg, string location, strong_ref<Filters> filters) &cxxname="spicy::rt::detail::waitForInput" &have_prototype;
declare public bool waitForEod(inout value_ref<stream> data, view<stream> cur, inout strong_ref<Filters> filters) &cxxname="spicy::rt::detail::waitForEod" &have_prototype;
declare public bool atEod(inout value_ref<stream> data, view<stream> cur, inout strong_ref<Filters> filters) &cxxname="spicy::rt::detail::atEod" &have_prototype;

declare public optional<iterator<stream>> unit_find(iterator<stream> begin_, iterator<stream> end_, optional<iterator<stream>> i, bytes needle, FindDirection dir) &cxxname="spicy::rt::detail::unitFind" &have_prototype;

declare public void backtrack() &cxxname="spicy::rt::detail::backtrack" &have_prototype;

declare public void initializeParsedUnit(inout ParsedUnit punit, any unit) &cxxname="spicy::rt::ParsedUnit::initialize" &have_prototype;

declare public bytes extractBytes(inout value_ref<stream> data, view<stream> cur, uint<64> n, bool eod_ok, string location, inout strong_ref<Filters> filters) &cxxname="spicy::rt::detail::extractBytes" &have_prototype;
declare public void expectBytesLiteral(inout value_ref<stream> data, view<stream> cur, bytes literal, string location, inout strong_ref<Filters> filters) &cxxname="spicy::rt::detail::expectBytesLiteral" &have_prototype;

}
