import * as tinyest from 'tinyest';
import { type ResolvedSnippet, type Snippet } from '../data/snippet.ts';
import * as wgsl from '../data/wgslTypes.ts';
import { type ResolutionCtx } from '../types.ts';
import type { ShaderGenerator, ConstantDefinitionOptions, FunctionDefinitionOptions, VariableDefinitionOptions, BinaryOperator, ResolvedStatement } from './shaderGenerator.ts';
import type { AnyFn } from '../core/function/fnTypes.ts';
import type { ExternalMap } from '../core/resolve/externals.ts';
export declare class WgslGenerator implements ShaderGenerator {
    #private;
    languageKey: string;
    initGenerator(ctx: ResolutionCtx): void;
    protected get ctx(): ResolutionCtx;
    protected _block([_, statementNodes]: tinyest.Block, allowInlining: boolean, externalMap?: ExternalMap): ResolvedStatement;
    protected _blockStatement(block: tinyest.Block, externalMap?: ExternalMap): ResolvedStatement;
    refVariable(id: string, dataType: wgsl.StorableData): string;
    /**
     * Creates a variable declaration string.
     * `keyword` may be a placeholder filled in later.
     */
    protected _emitVarDecl(keyword: 'var' | 'let' | 'const' | `#VAR_${number}#`, name: string, _dataType: wgsl.BaseData, rhsStr: string): string;
    protected _identifier(id: string): Snippet;
    protected _callShellless(callee: AnyFn, args: readonly Snippet[]): ResolvedSnippet | undefined;
    /**
     * A wrapper for `generateExpression` that updates `ctx.expectedType`
     * and tries to convert the result when it does not match the expected type.
     */
    protected _typedExpression(expression: tinyest.Expression, expectedType: wgsl.BaseData | wgsl.BaseData[]): Snippet;
    protected _expression(expression: tinyest.Expression): Snippet;
    declareGlobalConst(options: ConstantDefinitionOptions): ResolvedSnippet;
    declareGlobalVar(options: VariableDefinitionOptions): ResolvedSnippet;
    functionDefinition(options: FunctionDefinitionOptions): string;
    /**
     * Generates a WGSL type string for the given data type, and adds necessary
     * definitions to the shader preamble. This shouldn't be called directly, only
     * through `ctx.resolve` to properly cache the result.
     */
    emitTypeAnnotation(data: wgsl.BaseData): string;
    typeInstantiation(schema: wgsl.BaseData, args: readonly Snippet[]): ResolvedSnippet;
    numericLiteral(value: number, schema: wgsl.BaseData): ResolvedSnippet;
    emitCall(name: string, templateParams: readonly Snippet[], args: readonly Snippet[]): string;
    emitBinaryOp(lhs: Snippet, op: BinaryOperator, rhs: Snippet): string;
    protected _return(statement: tinyest.Return): string;
    protected _letStatement(statement: tinyest.Let): ResolvedStatement;
    protected _constStatement(statement: tinyest.Const): ResolvedStatement;
    /**
     * Handles `const x = <rhs>;` declarations in which the right-hand side aliases memory
     * that outlives the expression (a buffer, a local variable, an array element, ...).
     *
     * In WGSL we store an *implicit* pointer to that memory, so mutations done through `x`
     * affect the original. Languages without pointers (e.g. GLSL) override this.
     */
    protected _aliasConstStatement(rawId: string, eqNode: tinyest.Expression, eq: Snippet): ResolvedStatement;
    protected _statement(statement: tinyest.Statement): ResolvedStatement;
    /**
     * Attempts a member access lookup to mark a variable as modified.
     * @example
     * // given `let a; a = 1;`
     * tryMarkModified('a') // `a` is marked in the function scope
     *
     * // given `const obj; obj.prop = 1;`
     * tryMarkModified('obj.prop') // `obj` is marked in the function scope
     *
     * // given `this.buffer.$;`
     * tryMarkModified('this.buffer.$') // `this` is not marked, since there is no placeholder for it
     */
    private tryMarkModified;
}
