import { STWriter } from "./STWriter.js";
import { ST } from "./ST.js";
import { InstanceScope } from "./InstanceScope.js";
import { IErrorManager, IInstanceScope, IST, ISTGroup } from "./compiler/common.js";
export declare enum InterpreterOption {
ANCHOR = 0,
FORMAT = 1,
NULL = 2,
SEPARATOR = 3,
WRAP = 4
}
/**
* This class knows how to execute template byte codes relative to a particular
* {@link STGroup}. To execute the byte codes, we need an output stream and a
* reference to an {@link ST} instance. That instance's {@link ST#impl} field
* points at a {@link CompiledST}, which contains all of the byte codes and
* other information relevant to execution.
*
* This interpreter is a stack-based bytecode interpreter. All operands go onto
* an operand stack.
*
* If {@link #debug} set, we track interpreter events. For now, I am only
* tracking instance creation events. These are used by {@link STViz} to pair up
* output chunks with the template expressions that generate them.
*
* We create a new interpreter for each invocation of
* {@link ST#render}, {@link ST#inspect}, or {@link ST#getEvents}.
*/
export declare class Interpreter {
static readonly DEFAULT_OPERAND_STACK_SIZE = 100;
static readonly predefinedAnonSubtemplateAttributes: Set;
static readonly supportedOptions: Map;
/**
* Dump bytecode instructions as they are executed. This field is mostly for
* StringTemplate development.
*/
static trace: boolean;
/** Operand stack, grows upwards. */
protected operands: unknown[];
/** Stack pointer register. */
protected sp: number;
/** The number of characters written on this template line so far. */
protected charsWrittenOnLine: number;
/**
* Render template with respect to this group.
*
* @see ST#groupThatCreatedThisInstance
* @see CompiledST#nativeGroup
*/
protected group: ISTGroup;
/** For renderers, we have to pass in the locale. */
protected locale: Intl.Locale;
protected errMgr: IErrorManager;
/** If {@link #trace} is {@code true}, track trace here. */
protected executeTrace: string[];
constructor(group: ISTGroup);
constructor(group: ISTGroup, locale: Intl.Locale);
constructor(group: ISTGroup, errMgr: IErrorManager);
constructor(group: ISTGroup, locale: Intl.Locale, errMgr: IErrorManager);
/**
* If an instance of x is enclosed in a y which is in a
* z, return a {@code String} of these instance names in order from
* topmost to lowest; here that would be {@code [z y x]}.
* @param scope
*/
static getEnclosingInstanceStackString(scope?: InstanceScope): string;
static getEnclosingInstanceStack(scope: InstanceScope | undefined, topDown: boolean): ST[];
static getScopeStack(scope: InstanceScope, topDown: boolean): InstanceScope[];
static getShort(memory: Int8Array, index: number): number;
/**
* Execute template {@code self} and return how many characters it wrote to {@code out}.
*
* @returns the number of characters written to {@code out}
*/
exec(out: STWriter, scope: InstanceScope): number;
/**
* Return the first attribute if multi-valued, or the attribute itself if single-valued.
*
* This method is used for rendering expressions of the form
* {@code }.
*/
first(scope: InstanceScope, v: unknown): unknown;
/**
* Return the last attribute if multi-valued, or the attribute itself if
* single-valued. Unless it's a `List` or array, this is pretty slow
* as it iterates until the last element.
*
* This method is used for rendering expressions of the form
* {@code }.
*/
last(scope: InstanceScope, v: unknown): unknown;
/**
* Return everything but the first attribute if multi-valued, or
* {@code null} if single-valued.
*/
rest(scope: InstanceScope, v: unknown): unknown;
/**
* Return all but the last element. trunc(x)==null if x is single-valued.
*/
trunc(scope: InstanceScope, v: unknown): unknown;
/**
* Return a new list without {@code null} values.
*/
strip(scope: InstanceScope, v: unknown): unknown;
/**
* Return a list with the same elements as {@code v} but in reverse order.
*
* Note that {@code null} values are not stripped out; use
* {@code reverse(strip(v))} to do that.
*/
reverse(scope: InstanceScope, v: unknown): unknown;
/**
* Return the length of a multi-valued attribute or 1 if it is a single
* attribute. If {@code v} is {@code null} return 0.
*
* The implementation treats several common collections and arrays as
* special cases for speed.
*/
length(v: unknown): number;
convertAnythingIteratableToIterator(scope: InstanceScope | null, o: unknown): unknown;
convertAnythingToIterator(scope: InstanceScope, o: unknown): Iterator;
/**
* Find an attribute via dynamic scoping up enclosing scope chain. Only look
* for a dictionary definition if the attribute is not found, so attributes
* sent in to a template override dictionary names.
*
* Return {@link ST#EMPTY_ATTR} if found definition but no value.
*/
getAttribute(scope: InstanceScope, name: string): unknown;
getDictionary(g: ISTGroup, name: string): unknown;
/**
* Set any default argument values that were not set by the invoking
* template or by {@link ST#add} directly. Note that the default values may
* be templates.
*
* The evaluation context is the {@code invokedST} template itself so
* template default arguments can see other arguments.
*/
setDefaultArguments(out: STWriter, scope: InstanceScope): void;
getExecutionTrace(): string[];
protected _exec(out: STWriter, scope: InstanceScope): number;
protected loadStr(self: ST, ip: number): void;
protected superNew(scope: InstanceScope, name: string, argCountOrAttributes: number | Map): void;
protected passthru(scope: InstanceScope, templateName: string, attrs: Map): void;
protected storeArgs(scope: IInstanceScope, attrs: Map, st?: IST): void;
protected storeArgs(scope: IInstanceScope, argCount: number, st?: IST): void;
protected indent(out: STWriter, scope: InstanceScope, strIndex: number): void;
/**
* Write out an expression result that doesn't use expression options.
* E.g., {@code }
*/
protected writeObjectNoOptions(out: STWriter, scope: InstanceScope, o: unknown): number;
/**
* Write out an expression result that uses expression options.
* E.g., {@code }
*/
protected writeObjectWithOptions(out: STWriter, scope: InstanceScope, o: unknown, options: unknown[]): number;
/**
* Generic method to emit text for an object. It differentiates
* between templates, iterable objects, and plain old Java objects (POJOs)
*/
protected writeObject(out: STWriter, scope: InstanceScope, o: unknown, options?: Array): number;
protected writeIterator(out: STWriter, scope: InstanceScope, it?: Iterator, options?: Array): number;
protected writePOJO(out: STWriter, scope: InstanceScope, o: unknown, options?: Array): number;
protected getExprStartChar(scope: InstanceScope): number;
protected getExprStopChar(scope: InstanceScope): number;
protected map(scope: InstanceScope, attr: unknown, st: IST): void;
/**
* Renders expressions of the form {@code } or
* {@code }.
*/
protected rotMap(scope: InstanceScope, attr: unknown, prototypes: IST[]): void;
protected rotateMapIterator(scope: InstanceScope, attr: Iterator, prototypes: IST[]): Array;
/**
* Renders expressions of the form {@code } or
* {@code }.
*/
protected zipMap(scope: InstanceScope, exprs: unknown[], prototype?: IST): IST[] | undefined;
protected setFirstArgument(scope: InstanceScope, st: IST, attr: unknown): void;
protected addToList(scope: InstanceScope, list: unknown[], o: unknown): void;
protected toString(out: STWriter, scope: InstanceScope, value: unknown): string | null;
protected testAttributeTrue(a: unknown): boolean;
protected getObjectProperty(out: STWriter, scope: InstanceScope, o: unknown, property: unknown): unknown;
protected writeTrace(scope: InstanceScope, ip: number): void;
protected printForTrace(tr: string, scope: InstanceScope, o: unknown): string;
private renderObject;
}