import { CodeBlock } from './CodeBlock';
import { DecoratorSpec } from './DecoratorSpec';
import { Modifier } from './Modifier';
import { StringBuffer } from './StringBuffer';
import { SymbolReferenceTracker } from './SymbolReferenceTracker';
import { Imported, SymbolSpec } from './SymbolSpecs';
import { TypeVariable } from './TypeNames';
/**
 * Converts a [FileSpec] to a string suitable to both human- and tsc-consumption. This honors
 * imports, indentation, and deferred variable names.
 */
export declare class CodeWriter implements SymbolReferenceTracker {
    private indentString;
    static emitToString(emittable: {
        emit(cw: CodeWriter): void;
    }): string;
    private readonly out;
    private readonly referencedSymbols;
    private indentLevel;
    private javaDoc;
    private comment;
    private trailingNewline;
    constructor(out: StringBuffer, indentString?: string, referencedSymbols?: Set<SymbolSpec>);
    referenced(symbol: SymbolSpec): void;
    indent(levels?: number): this;
    unindent(levels?: number): this;
    emitComment(codeBlock: CodeBlock): void;
    emitJavaDoc(javaDocCodeBlock: CodeBlock): void;
    emitDecorators(decorators: DecoratorSpec[], inline: boolean): void;
    /**
     * Emits `modifiers` in the standard order. Modifiers in `implicitModifiers` will not
     * be emitted.
     */
    emitModifiers(modifiers: Modifier[], implicitModifiers?: Modifier[]): void;
    /**
     * Emit type variables with their bounds.
     *
     * This should only be used when declaring type variables; everywhere else bounds are omitted.
     */
    emitTypeVariables(typeVariables: TypeVariable[]): void;
    emitImports(path: string): this;
    emitCode(format: string, ...args: unknown[]): this;
    emitCodeBlock(codeBlock: CodeBlock): this;
    /**
     * Emits `s` with indentation as required. It's important that all code that writes to
     * [CodeWriter.out] does it through here, since we emit indentation lazily in order to avoid
     * unnecessary trailing whitespace.
     */
    emit(s: string): this;
    newLine(): this;
    /**
     * Returns the symbols that are required to be imported for this code. If there were any simple name
     * collisions, that symbol's first use is imported; which may cause compilation issues.
     */
    requiredImports(): Imported[];
    private emitIndentation;
    private emitWrappingSpace;
    private emitTypeName;
    private emitFunction;
    private emitString;
    private emitLiteral;
}
