export interface StartOfSourceMap {
    file?: string;
    sourceRoot?: string;
}

export interface RawSourceMap extends StartOfSourceMap {
    version: string;
    sources: string[];
    names: string[];
    sourcesContent?: string[];
    mappings: string;
}

export interface Position {
    line: number;
    column: number;
}

export interface LineRange extends Position {
    lastColumn: number;
}

export interface FindPosition extends Position {
    // SourceMapConsumer.GREATEST_LOWER_BOUND or SourceMapConsumer.LEAST_UPPER_BOUND
    bias?: number;
}

export interface SourceFindPosition extends FindPosition {
    source: string;
}

export interface MappedPosition extends Position {
    source: string;
    name?: string;
}

export interface MappingItem {
    source: string;
    generatedLine: number;
    generatedColumn: number;
    originalLine: number;
    originalColumn: number;
    name: string;
}

export class SourceMapConsumer {
    public static GENERATED_ORDER: number;
    public static ORIGINAL_ORDER: number;

    public static GREATEST_LOWER_BOUND: number;
    public static LEAST_UPPER_BOUND: number;

    constructor(rawSourceMap: RawSourceMap);
    public computeColumnSpans(): void;
    public originalPositionFor(generatedPosition: FindPosition): MappedPosition;
    public generatedPositionFor(originalPosition: SourceFindPosition): LineRange;
    public allGeneratedPositionsFor(originalPosition: MappedPosition): Position[];
    public hasContentsOfAllSources(): boolean;
    public sourceContentFor(source: string, returnNullOnMissing?: boolean): string;
    public eachMapping(callback: (mapping: MappingItem) => void, context?: any, order?: number): void;
}

export interface Mapping {
    generated: Position;
    original: Position;
    source: string;
    name?: string;
}

export class SourceMapGenerator {
    constructor(startOfSourceMap?: StartOfSourceMap);
    public static fromSourceMap(sourceMapConsumer: SourceMapConsumer): SourceMapGenerator;
    public addMapping(mapping: Mapping): void;
    public setSourceContent(sourceFile: string, sourceContent: string): void;
    public applySourceMap(sourceMapConsumer: SourceMapConsumer, sourceFile?: string, sourceMapPath?: string): void;
    public toString(): string;
}

export interface CodeWithSourceMap {
    code: string;
    map: SourceMapGenerator;
}

export class SourceNode {
    constructor();
    constructor(line: number, column: number, source: string);
    constructor(line: number, column: number, source: string, chunk?: string, name?: string);
    public static fromStringWithSourceMap(code: string, sourceMapConsumer: SourceMapConsumer, relativePath?: string): SourceNode;
    public add(chunk: string): void;
    public prepend(chunk: string): void;
    public setSourceContent(sourceFile: string, sourceContent: string): void;
    public walk(fn: (chunk: string, mapping: MappedPosition) => void): void;
    public walkSourceContents(fn: (file: string, content: string) => void): void;
    public join(sep: string): SourceNode;
    public replaceRight(pattern: string, replacement: string): SourceNode;
    public toString(): string;
    public toStringWithSourceMap(startOfSourceMap?: StartOfSourceMap): CodeWithSourceMap;
}
