import { ATN, ATNState } from "antlr4ng";
import type { Constructor } from "../misc/Utils.js";
import { ActionAST } from "../tool/ast/ActionAST.js";
import { BlockAST } from "../tool/ast/BlockAST.js";
import { GrammarAST } from "../tool/ast/GrammarAST.js";
import { PredAST } from "../tool/ast/PredAST.js";
import { TerminalAST } from "../tool/ast/TerminalAST.js";
import { Rule } from "../tool/Rule.js";
import type { IGrammar, IParserATNFactory } from "../types.js";
import { IATNFactory, type IStatePair } from "./IATNFactory.js";
/**
 * ATN construction routines triggered by ATNBuilder.g.
 *
 *  No side-effects. It builds an {@link ATN} object and returns it.
 */
export declare class ParserATNFactory implements IParserATNFactory, IATNFactory {
    currentRule?: Rule;
    currentOuterAlt: number;
    protected readonly g: IGrammar;
    protected readonly atn: ATN;
    private readonly preventEpsilonClosureBlocks;
    private readonly preventEpsilonOptionalBlocks;
    constructor(g: IGrammar);
    /**
     * `(BLOCK (ALT .))` or `(BLOCK (ALT 'a') (ALT .))`.
     */
    private static blockHasWildcardAlt;
    createATN(): ATN;
    setCurrentRuleName(name: string): void;
    /** From label `A` build graph `o-A->o`. */
    tokenRef(node: TerminalAST): IStatePair | null;
    /**
     * From set build single edge graph `o->o-set->o`. To conform to what an alt block looks like, must have extra
     * state on left. This also handles `~A`, converted to `~{A}` set.
     */
    set(associatedAST: GrammarAST, terminals: GrammarAST[], invert: boolean): IStatePair;
    /** Not valid for non-lexers. */
    range(a: GrammarAST, b: GrammarAST): IStatePair | null;
    /** For a non-lexer, just build a simple token reference atom. */
    stringLiteral(stringLiteralAST: TerminalAST): IStatePair | null;
    /** `[Aa]` char sets not allowed in parser */
    charSetLiteral(charSetAST: GrammarAST): IStatePair | null;
    /**
     * For reference to rule `r`, build
     *
     * ```
     *  o->(r)  o
     * ```
     *
     * where `(r)` is the start of rule `r` and the trailing `o` is not linked to from rule ref state directly (uses
     * {@link RuleTransition.followState}).
     */
    ruleRef(node: GrammarAST): IStatePair | null;
    /** From an empty alternative build `o-e->o`. */
    epsilon(node: GrammarAST): IStatePair;
    epsilon(a: ATNState | null, b: ATNState, prepend?: boolean): void;
    /**
     * Build what amounts to an epsilon transition with a semantic predicate action.  The `pred` is a pointer
     *  into the AST of the {@link ANTLRParser#SEMPRED} token.
     */
    sempred(pred: PredAST): IStatePair;
    /**
     * Build what amounts to an epsilon transition with an action.
     *  The action goes into ATN though it is ignored during prediction
     *  if {@link ActionTransition.actionIndex actionIndex} `< 0`.
     */
    action(astOrString: ActionAST | string): IStatePair;
    /**
     * From `A|B|..|Z` alternative block build
     *
     * ```
     *  o->o-A->o->o (last ATNState is BlockEndState pointed to by all alts)
     *  |          ^
     *  |->o-B->o--|
     *  |          |
     *  ...        |
     *  |          |
     *  |->o-Z->o--|
     * ```
     *
     * So start node points at every alternative with epsilon transition and
     * every alt right side points at a block end ATNState.
     *
     * Special case: only one alternative: don't make a block with alt
     * begin/end.
     *
     * Special case: if just a list of tokens/chars/sets, then collapse to a
     * single edged o-set->o graph.
     *
     * TODO: Set alt number (1..n) in the states?
     */
    block(blkAST: BlockAST, ebnfRoot: GrammarAST | null, alts: IStatePair[]): IStatePair | undefined;
    alt(els: IStatePair[]): IStatePair;
    /** Build an atom with all possible values in its label. */
    wildcard(node: GrammarAST): IStatePair;
    label(t: IStatePair): IStatePair;
    listLabel(t: IStatePair): IStatePair;
    lexerAltCommands(alt: IStatePair, commands: IStatePair): IStatePair;
    lexerCallCommand(_id: GrammarAST, arg: GrammarAST): IStatePair;
    lexerCommand(id: GrammarAST): IStatePair;
    /** start-> rule - block -> end */
    protected rule(ruleAST: GrammarAST, name: string, blk: IStatePair): IStatePair;
    protected _ruleRef(node: GrammarAST): IStatePair | null;
    protected newState<T extends ATNState>(nodeType: Constructor<T>): T;
    protected checkEpsilonClosure(): void;
    protected doCreateATN(rules: Rule[]): void;
    private addFollowLink;
    private elemList;
    /**
     * From `(A)?` build either:
     *
     * ```
     *  o--A->o
     *  |     ^
     *  o---->|
     * ```
     *
     * or, if `A` is a block, just add an empty alt to the end of the block.
     */
    private optional;
    /**
     * From `(blk)+` build
     *
     * ```
     *   |---------|
     *   v         |
     *  [o-blk-o]->o->o
     * ```
     *
     * We add a decision for loop back node to the existing one at `blk` start.
     */
    private plus;
    /**
     * From `(blk)*` build `( blk+ )?` with *two* decisions, one for entry and one for choosing alts of `blk`.
     *
     * ```
     *   |-------------|
     *   v             |
     *   o--[o-blk-o]->o  o
     *   |                ^
     *   -----------------|
     * ```
     *
     * Note that the optional bypass must jump outside the loop as `(A|B)*` is not the same thing as `(A|B|)+`.
     */
    private star;
    private addRuleFollowLinks;
    /**
     * Add an EOF transition to any rule end ATNState that points to nothing (i.e., for all those rules not invoked
     * by another rule).  These are start symbols then.
     *
     * Return the number of grammar entry points; i.e., how many rules are not invoked by another rule (they can
     * only be invoked from outside). These are the start rules.
     */
    private addEOFTransitionToStartRules;
    private expectNonGreedy;
    private makeBlock;
    /** Define all the rule begin/end ATNStates to solve forward reference issues. */
    private createRuleStartAndStopATNStates;
}
