import { Opaque, Option, Dict, Slice as ListSlice } from '@glimmer/util';
import { RevisionTag, VersionedPathReference } from '@glimmer/reference';
import { VM, UpdatingVM } from './vm';
import { CompiledExpression, CompiledArgs } from './compiled/expressions';
import { InlineBlock } from './scanner';
import { Opcode } from './environment';
export interface OpcodeJSON {
    type: number | string;
    guid?: Option<number>;
    deopted?: boolean;
    args?: string[];
    details?: Dict<Option<string>>;
    children?: OpcodeJSON[];
}
export declare function pretty(json: OpcodeJSON): string;
export declare const enum OpcodeName {
    PushChildScope = 0,
    PopScope = 1,
    PushDynamicScope = 2,
    PopDynamicScope = 3,
    Put = 4,
    EvaluatePut = 5,
    PutArgs = 6,
    BindPositionalArgs = 7,
    BindNamedArgs = 8,
    BindBlocks = 9,
    BindPartialArgs = 10,
    BindCallerScope = 11,
    BindDynamicScope = 12,
    Enter = 13,
    Exit = 14,
    Evaluate = 15,
    Jump = 16,
    JumpIf = 17,
    JumpUnless = 18,
    Test = 19,
    OpenBlock = 20,
    CloseBlock = 21,
    PutDynamicComponent = 22,
    PutComponent = 23,
    OpenComponent = 24,
    DidCreateElement = 25,
    ShadowAttributes = 26,
    DidRenderLayout = 27,
    CloseComponent = 28,
    Text = 29,
    Comment = 30,
    DynamicContent = 31,
    OpenElement = 32,
    PushRemoteElement = 33,
    PopRemoteElement = 34,
    OpenComponentElement = 35,
    OpenDynamicElement = 36,
    FlushElement = 37,
    CloseElement = 38,
    PopElement = 39,
    StaticAttr = 40,
    Modifier = 41,
    DynamicAttrNS = 42,
    DynamicAttr = 43,
    PutIterator = 44,
    EnterList = 45,
    ExitList = 46,
    EnterWithKey = 47,
    NextIter = 48,
    PutDynamicPartial = 49,
    PutPartial = 50,
    EvaluatePartial = 51,
}
export declare type ConstantType = 'slice' | 'block' | 'reference' | 'string' | 'number' | 'expression';
export declare type ConstantReference = number;
export declare type ConstantString = number;
export declare type ConstantExpression = number;
export declare type ConstantSlice = number;
export declare type ConstantBlock = number;
export declare type ConstantFunction = number;
export declare type ConstantArray = number;
export declare type ConstantOther = number;
export declare class Constants {
    private references;
    private strings;
    private expressions;
    private arrays;
    private blocks;
    private functions;
    private others;
    NULL_REFERENCE: number;
    UNDEFINED_REFERENCE: number;
    constructor();
    getReference<T extends Opaque>(value: ConstantReference): VersionedPathReference<T>;
    reference(value: VersionedPathReference<Opaque>): ConstantReference;
    getString(value: ConstantString): string;
    string(value: string): ConstantString;
    getExpression<T>(value: ConstantExpression): T;
    expression(value: CompiledExpression<Opaque> | CompiledArgs): ConstantExpression;
    getArray(value: ConstantArray): number[];
    array(values: number[]): ConstantArray;
    getBlock(value: ConstantBlock): InlineBlock;
    block(block: InlineBlock): ConstantBlock;
    getFunction<T extends Function>(value: ConstantFunction): T;
    function(f: Function): ConstantFunction;
    getOther<T>(value: ConstantOther): T;
    other(other: Opaque): ConstantOther;
}
export declare type Operand1 = number;
export declare type Operand2 = number;
export declare type Operand3 = number;
export declare type EvaluateOpcode = (vm: VM, opcode: Opcode) => void;
export declare class AppendOpcodes {
    private evaluateOpcode;
    add<Name extends OpcodeName>(name: Name, evaluate: EvaluateOpcode): void;
    evaluate(vm: VM, opcode: Opcode): void;
}
export declare const APPEND_OPCODES: AppendOpcodes;
export declare abstract class AbstractOpcode {
    type: string;
    _guid: number;
    constructor();
    toJSON(): OpcodeJSON;
}
export declare abstract class UpdatingOpcode extends AbstractOpcode {
    tag: RevisionTag;
    next: Option<UpdatingOpcode>;
    prev: Option<UpdatingOpcode>;
    abstract evaluate(vm: UpdatingVM): void;
}
export declare type UpdatingOpSeq = ListSlice<UpdatingOpcode>;
export declare function inspect(opcodes: ReadonlyArray<AbstractOpcode>): string;
