import type { WgslStorageTexture, WgslTexture } from '../../data/texture.ts';
import type { BaseData } from '../../data/wgslTypes.ts';
import type { TgpuNamable } from '../../shared/meta.ts';
import type { GPUValueOf, Infer, InferGPU } from '../../shared/repr.ts';
import type { TgpuSoul } from '../../shared/soul.ts';
import { $gpuValueOf, $internal, $providing, $soul } from '../../shared/symbols.ts';
import type { UnwrapRuntimeConstructor } from '../../tgpuBindGroupLayout.ts';
import type { TgpuBufferBinding } from '../buffer/bufferBinding.ts';
import type { TgpuConst } from '../constant/tgpuConstant.ts';
import type { Withable } from '../root/rootTypes.ts';
import type { TgpuTextureView } from '../texture/texture.ts';
import type { TgpuVar, VariableScope } from '../variable/tgpuVariable.ts';
export interface TgpuSlotSoul<T = unknown> extends TgpuSoul<'slot'> {
    readonly defaultValue: T | undefined;
}
export interface TgpuAccessorSoul<T extends BaseData = BaseData, TValue = unknown> extends TgpuSoul<'accessor' | 'mutable-accessor'> {
    readonly schema: T;
    readonly defaultValue: TValue | undefined;
}
export interface TgpuSlot<T> extends TgpuNamable {
    readonly [$internal]: true;
    readonly [$soul]: TgpuSlotSoul<T>;
    readonly resourceType: 'slot';
    readonly defaultValue: T | undefined;
    /**
     * Used to determine if code generated using either value `a` or `b` in place
     * of the slot will be equivalent. Defaults to `Object.is`.
     */
    areEqual(a: T, b: T): boolean;
    readonly [$gpuValueOf]: GPUValueOf<T>;
    readonly $: GPUValueOf<T>;
    toString(): string;
}
export interface TgpuLazy<out T> extends Withable<TgpuLazy<T>> {
    readonly [$internal]: {
        compute(): T;
    };
    readonly resourceType: 'lazy';
    readonly [$gpuValueOf]: GPUValueOf<T>;
    readonly $: GPUValueOf<T>;
    readonly [$providing]?: Providing | undefined;
}
export interface TgpuAccessor<T extends BaseData = BaseData> extends TgpuNamable {
    readonly [$internal]: true;
    readonly [$soul]: TgpuAccessorSoul<T, TgpuAccessor.In<T>>;
    readonly resourceType: 'accessor';
    readonly schema: T;
    readonly defaultValue: TgpuAccessor.In<T> | undefined;
    readonly slot: TgpuSlot<TgpuAccessor.In<T>>;
    readonly [$gpuValueOf]: InferGPU<T>;
    readonly $: InferGPU<T>;
    toString(): string;
}
type DataAccessorIn<T extends BaseData> = (() => DataAccessorIn<T>) | TgpuBufferBinding<T> | TgpuVar<VariableScope, T> | TgpuConst<T> | Infer<T>;
type TextureAccessorIn<T extends WgslTexture | WgslStorageTexture> = (() => TextureAccessorIn<T>) | Infer<T> | TgpuTextureView<T>;
export declare namespace TgpuAccessor {
    type In<T extends BaseData | ((count: number) => BaseData)> = UnwrapRuntimeConstructor<T> extends WgslTexture | WgslStorageTexture ? TextureAccessorIn<UnwrapRuntimeConstructor<T>> : DataAccessorIn<UnwrapRuntimeConstructor<T>>;
}
export interface TgpuMutableAccessor<T extends BaseData = BaseData> extends TgpuNamable {
    readonly [$internal]: true;
    readonly [$soul]: TgpuAccessorSoul<T, TgpuMutableAccessor.In<T>>;
    readonly resourceType: 'mutable-accessor';
    readonly schema: T;
    readonly defaultValue: TgpuMutableAccessor.In<T> | undefined;
    readonly slot: TgpuSlot<TgpuMutableAccessor.In<T>>;
    readonly [$gpuValueOf]: InferGPU<T>;
    $: InferGPU<T>;
}
type MutableDataAccessorIn<T extends BaseData> = (() => Infer<T> | MutableDataAccessorIn<T>) | TgpuBufferBinding<T> | TgpuVar<VariableScope, T>;
type MutableTextureAccessorIn<T extends WgslTexture | WgslStorageTexture> = (() => Infer<T> | TgpuTextureView<T> | MutableTextureAccessorIn<T>) | TgpuTextureView<T>;
export declare namespace TgpuMutableAccessor {
    type In<T extends BaseData | ((count: number) => BaseData)> = UnwrapRuntimeConstructor<T> extends WgslTexture | WgslStorageTexture ? MutableTextureAccessorIn<UnwrapRuntimeConstructor<T>> : MutableDataAccessorIn<UnwrapRuntimeConstructor<T>>;
}
/**
 * Represents a value that is available at resolution time.
 */
export type Eventual<T> = T | TgpuSlot<T> | TgpuLazy<T>;
export type SlotValuePair<T = unknown> = [TgpuSlot<T>, T];
export type Providing = {
    inner: object;
    pairs: SlotValuePair[];
};
export declare function isSlot<T>(value: unknown): value is TgpuSlot<T>;
export declare function isLazy<T>(value: unknown): value is TgpuLazy<T>;
export declare function isProviding(value: unknown): value is {
    [$providing]: Providing;
};
export declare function isAccessor<T extends BaseData>(value: unknown): value is TgpuAccessor<T>;
export declare function isMutableAccessor<T extends BaseData>(value: unknown): value is TgpuMutableAccessor<T>;
export {};
