import { IResolvable, IResolveContext } from './resolvable';
/**
 * (experimental) Interface for lazy string producers.
 *
 * @experimental
 */
export interface IStringProducer {
    /**
     * (experimental) Produce the string value.
     *
     * @experimental
     */
    produce(context: IResolveContext): string | undefined;
}
/**
 * (experimental) Interface for (stable) lazy string producers.
 *
 * @experimental
 */
export interface IStableStringProducer {
    /**
     * (experimental) Produce the string value.
     *
     * @experimental
     */
    produce(): string | undefined;
}
/**
 * (experimental) Interface for lazy list producers.
 *
 * @experimental
 */
export interface IListProducer {
    /**
     * (experimental) Produce the list value.
     *
     * @experimental
     */
    produce(context: IResolveContext): string[] | undefined;
}
/**
 * (experimental) Interface for (stable) lazy list producers.
 *
 * @experimental
 */
export interface IStableListProducer {
    /**
     * (experimental) Produce the list value.
     *
     * @experimental
     */
    produce(): string[] | undefined;
}
/**
 * (experimental) Interface for lazy number producers.
 *
 * @experimental
 */
export interface INumberProducer {
    /**
     * (experimental) Produce the number value.
     *
     * @experimental
     */
    produce(context: IResolveContext): number | undefined;
}
/**
 * (experimental) Interface for (stable) lazy number producers.
 *
 * @experimental
 */
export interface IStableNumberProducer {
    /**
     * (experimental) Produce the number value.
     *
     * @experimental
     */
    produce(): number | undefined;
}
/**
 * (experimental) Interface for lazy untyped value producers.
 *
 * @experimental
 */
export interface IAnyProducer {
    /**
     * (experimental) Produce the value.
     *
     * @experimental
     */
    produce(context: IResolveContext): any;
}
/**
 * (experimental) Interface for (stable) lazy untyped value producers.
 *
 * @experimental
 */
export interface IStableAnyProducer {
    /**
     * (experimental) Produce the value.
     *
     * @experimental
     */
    produce(): any;
}
/**
 * (experimental) Options for creating a lazy string token.
 *
 * @experimental
 */
export interface LazyStringValueOptions {
    /**
     * (experimental) Use the given name as a display hint.
     *
     * @default - No hint
     * @experimental
     */
    readonly displayHint?: string;
}
/**
 * (experimental) Options for creating a lazy list token.
 *
 * @experimental
 */
export interface LazyListValueOptions {
    /**
     * (experimental) Use the given name as a display hint.
     *
     * @default - No hint
     * @experimental
     */
    readonly displayHint?: string;
    /**
     * (experimental) If the produced list is empty, return 'undefined' instead.
     *
     * @default false
     * @experimental
     */
    readonly omitEmpty?: boolean;
}
/**
 * (experimental) Options for creating lazy untyped tokens.
 *
 * @experimental
 */
export interface LazyAnyValueOptions {
    /**
     * (experimental) Use the given name as a display hint.
     *
     * @default - No hint
     * @experimental
     */
    readonly displayHint?: string;
    /**
     * (experimental) If the produced value is an array and it is empty, return 'undefined' instead.
     *
     * @default false
     * @experimental
     */
    readonly omitEmptyArray?: boolean;
}
/**
 * (experimental) Lazily produce a value.
 *
 * Can be used to return a string, list or numeric value whose actual value
 * will only be calculated later, during synthesis.
 *
 * @experimental
 */
export declare class Lazy {
    /**
     * (experimental) Defer the one-time calculation of a string value to synthesis time.
     *
     * Use this if you want to render a string to a template whose actual value depends on
     * some state mutation that may happen after the construct has been created.
     *
     * If you are simply looking to force a value to a `string` type and don't need
     * the calculation to be deferred, use `Token.asString()` instead.
     *
     * The inner function will only be invoked once, and the resolved value
     * cannot depend on the Stack the Token is used in.
     *
     * @experimental
     */
    static string(producer: IStableStringProducer, options?: LazyStringValueOptions): string;
    /**
     * (experimental) Defer the calculation of a string value to synthesis time.
     *
     * Use of this function is not recommended; unless you know you need it for sure, you
     * probably don't. Use `Lazy.string()` instead.
     *
     * The inner function may be invoked multiple times during synthesis. You
     * should only use this method if the returned value depends on variables
     * that may change during the Aspect application phase of synthesis, or if
     * the value depends on the Stack the value is being used in. Both of these
     * cases are rare, and only ever occur for AWS Construct Library authors.
     *
     * @experimental
     */
    static uncachedString(producer: IStringProducer, options?: LazyStringValueOptions): string;
    /**
     * (experimental) Defer the one-time calculation of a number value to synthesis time.
     *
     * Use this if you want to render a number to a template whose actual value depends on
     * some state mutation that may happen after the construct has been created.
     *
     * If you are simply looking to force a value to a `number` type and don't need
     * the calculation to be deferred, use `Token.asNumber()` instead.
     *
     * The inner function will only be invoked once, and the resolved value
     * cannot depend on the Stack the Token is used in.
     *
     * @experimental
     */
    static number(producer: IStableNumberProducer): number;
    /**
     * (experimental) Defer the calculation of a number value to synthesis time.
     *
     * Use of this function is not recommended; unless you know you need it for sure, you
     * probably don't. Use `Lazy.number()` instead.
     *
     * The inner function may be invoked multiple times during synthesis. You
     * should only use this method if the returned value depends on variables
     * that may change during the Aspect application phase of synthesis, or if
     * the value depends on the Stack the value is being used in. Both of these
     * cases are rare, and only ever occur for AWS Construct Library authors.
     *
     * @experimental
     */
    static uncachedNumber(producer: INumberProducer): number;
    /**
     * (experimental) Defer the calculation of a list value to synthesis time.
     *
     * Use of this function is not recommended; unless you know you need it for sure, you
     * probably don't. Use `Lazy.list()` instead.
     *
     * The inner function may be invoked multiple times during synthesis. You
     * should only use this method if the returned value depends on variables
     * that may change during the Aspect application phase of synthesis, or if
     * the value depends on the Stack the value is being used in. Both of these
     * cases are rare, and only ever occur for AWS Construct Library authors.
     *
     * @experimental
     */
    static uncachedList(producer: IListProducer, options?: LazyListValueOptions): string[];
    /**
     * (experimental) Defer the one-time calculation of a list value to synthesis time.
     *
     * Use this if you want to render a list to a template whose actual value depends on
     * some state mutation that may happen after the construct has been created.
     *
     * If you are simply looking to force a value to a `string[]` type and don't need
     * the calculation to be deferred, use `Token.asList()` instead.
     *
     * The inner function will only be invoked once, and the resolved value
     * cannot depend on the Stack the Token is used in.
     *
     * @experimental
     */
    static list(producer: IStableListProducer, options?: LazyListValueOptions): string[];
    /**
     * (experimental) Defer the one-time calculation of an arbitrarily typed value to synthesis time.
     *
     * Use this if you want to render an object to a template whose actual value depends on
     * some state mutation that may happen after the construct has been created.
     *
     * The inner function will only be invoked one time and cannot depend on
     * resolution context.
     *
     * @experimental
     */
    static any(producer: IStableAnyProducer, options?: LazyAnyValueOptions): IResolvable;
    /**
     * (experimental) Defer the calculation of an untyped value to synthesis time.
     *
     * Use of this function is not recommended; unless you know you need it for sure, you
     * probably don't. Use `Lazy.any()` instead.
     *
     * The inner function may be invoked multiple times during synthesis. You
     * should only use this method if the returned value depends on variables
     * that may change during the Aspect application phase of synthesis, or if
     * the value depends on the Stack the value is being used in. Both of these
     * cases are rare, and only ever occur for AWS Construct Library authors.
     *
     * @experimental
     */
    static uncachedAny(producer: IAnyProducer, options?: LazyAnyValueOptions): IResolvable;
    private constructor();
}
