import { Logger } from "../logger.js";
import { FormatGenerator } from "./generator.js";
import { IntrospectedNamespace } from "../gir/namespace.js";
import { IntrospectedRecord, IntrospectedInterface, IntrospectedClass } from "../gir/class.js";
import { IntrospectedConstant } from "../gir/const.js";
import { IntrospectedEnum, IntrospectedError, GirEnumMember } from "../gir/enum.js";
import { IntrospectedProperty, IntrospectedField } from "../gir/property.js";
import { IntrospectedSignal, IntrospectedSignalType } from "../gir/signal.js";
import { IntrospectedFunction, IntrospectedConstructor, IntrospectedFunctionParameter, IntrospectedCallback, IntrospectedDirectAllocationConstructor, IntrospectedClassCallback } from "../gir/function.js";
import { IntrospectedClassFunction, IntrospectedStaticClassFunction, IntrospectedVirtualClassFunction } from "../gir/function.js";
import { TypeExpression } from "../gir.js";
import { IntrospectedAlias } from "../gir/alias.js";
import { AnyIntrospectedType } from "../gir/base.js";
import type { OptionsGeneration } from "../types/index.js";
export declare const enum NodeKind {
    class = "class",
    interface = "interface",
    function = "function",
    classFunction = "class_function",
    staticClassFunction = "static_class_function",
    virtualClassFunction = "virtual_class_function",
    prop = "prop",
    field = "field",
    alias = "alias",
    namespace = "namespace",
    callback = "callback",
    constant = "constant",
    record = "record",
    constructor = "constructor",
    propertiesConstructor = "properties_constructor",
    parameter = "parameter",
    enum = "enum",
    enumMember = "enum_member",
    error = "error"
}
export type Primitive = string[] | number[] | boolean[] | null | string | number | boolean;
export type Json = {
    [key: string]: Primitive | Json | Json[];
};
export type NodeJson = {
    kind: NodeKind;
    doc: string | null;
    metadata: MetadataJson | null;
    private: boolean;
} & Json;
export declare const enum TypeKind {
    or = "or",
    tuple = "tuple",
    identifier = "identifier",
    native = "native",
    array = "array",
    nulled = "null",
    closure = "closure"
}
export interface ParameterJson extends NodeJson {
    kind: NodeKind.parameter;
    optional: boolean;
    varargs: boolean;
    name: string;
    type: TypeJson;
}
export type TypeJson = Json & ({
    kind: TypeKind.native;
    type: string;
} | {
    kind: TypeKind.array;
    depth: number;
    type: TypeJson;
} | {
    kind: TypeKind.or | TypeKind.tuple;
    types: TypeJson[];
} | {
    kind: TypeKind.nulled;
    type: TypeJson;
} | {
    kind: TypeKind.closure;
    user_data: number | null;
    type: TypeJson;
} | {
    kind: TypeKind.identifier;
    namespace: string;
    name: string;
});
export interface EnumMemberJson extends NodeJson {
    kind: NodeKind.enumMember;
    name: string;
    value: string | null;
}
export interface EnumJson extends NodeJson {
    kind: NodeKind.enum;
    name: string;
    members: EnumMemberJson[];
}
export interface CallbackJson extends NodeJson {
    kind: NodeKind.callback;
    name: string;
    type: [Json, Json];
    parameters: ParameterJson[];
    returnType: TypeJson;
}
export interface PropertyJson extends NodeJson {
    kind: NodeKind.prop;
    name: string;
    type: TypeJson;
}
export interface FieldJson extends NodeJson {
    kind: NodeKind.field;
    name: string;
    type: TypeJson;
}
export interface MethodJson extends NodeJson {
    kind: NodeKind.classFunction;
    name: string;
    parameters: ParameterJson[];
    returnType: TypeJson[] | TypeJson;
}
export interface StaticMethodJson extends NodeJson {
    kind: NodeKind.staticClassFunction;
    name: string;
    parameters: ParameterJson[];
    returnType: TypeJson[] | TypeJson;
}
export interface VirtualMethodJson extends NodeJson {
    kind: NodeKind.virtualClassFunction;
    name: string;
    parameters: ParameterJson[];
    returnType: TypeJson[] | TypeJson;
}
export type MetadataJson = Json;
export interface ConstJson extends NodeJson {
    kind: NodeKind.constant;
    name: string;
    type: TypeJson;
}
export interface InterfaceJson extends NodeJson {
    kind: NodeKind.interface;
    name: string;
    extends: TypeJson | null;
    type: TypeJson;
    props: PropertyJson[];
    methods: MethodJson[];
    staticMethods: StaticMethodJson[];
    virtualMethods: VirtualMethodJson[];
}
export interface BaseClassJson extends NodeJson {
    name: string;
    type: TypeJson;
    constructors: MethodJson[];
    mainConstructor: PropertiesConstructorJson | ConstructorJson | null;
    extends: TypeJson | null;
    implements: TypeJson[];
    props: PropertyJson[];
    fields: FieldJson[];
    methods: MethodJson[];
    staticMethods: StaticMethodJson[];
    virtualMethods: VirtualMethodJson[];
}
export interface ClassJson extends BaseClassJson {
    kind: NodeKind.class;
    abstract: boolean;
}
export interface RecordJson extends BaseClassJson {
    kind: NodeKind.record;
    mainConstructor: ConstructorJson | null;
}
export interface ErrorJson extends BaseClassJson {
    kind: NodeKind.error;
    mainConstructor: ConstructorJson | null;
}
export interface FunctionJson extends NodeJson {
    name: string;
    kind: NodeKind.function;
    parameters: ParameterJson[];
    returnType: TypeJson[] | TypeJson;
}
export interface AliasJson extends NodeJson {
    name: string;
    kind: NodeKind.alias;
    type: TypeJson;
}
export interface PropertiesConstructorJson extends NodeJson {
    name: string;
    kind: NodeKind.propertiesConstructor;
    properties: ParameterJson[];
}
export interface ConstructorJson extends NodeJson {
    name: string;
    kind: NodeKind.constructor;
    parameters: ParameterJson[];
}
export type ImportsJson = {
    [lib: string]: string;
};
export interface NamespaceJson extends Json {
    kind: NodeKind.namespace;
    imports: ImportsJson;
    version: string;
    name: string;
    alias: AliasJson[];
    enums: EnumJson[];
    errors: ErrorJson[];
    functions: FunctionJson[];
    callbacks: CallbackJson[];
    constants: ConstJson[];
    records: RecordJson[];
    interfaces: InterfaceJson[];
    classes: ClassJson[];
}
export declare class JsonGenerator extends FormatGenerator<Json> {
    readonly log: Logger;
    constructor(namespace: IntrospectedNamespace, options: OptionsGeneration);
    /**
     * Intelligently reformats # and () references
     * to handle c-prefixes and namespacing.
     *
     * @param doc
     */
    private generateDoc;
    private generateMetadata;
    private generateParameters;
    generateCallbackType(node: IntrospectedCallback | IntrospectedClassCallback): [Json, Json];
    generateCallback(node: IntrospectedCallback): CallbackJson;
    generateClassCallback(node: IntrospectedClassCallback): CallbackJson;
    generateReturn(return_type: TypeExpression, output_parameters: IntrospectedFunctionParameter[]): TypeJson | TypeJson[];
    generateEnum(node: IntrospectedEnum): EnumJson;
    generateError(node: IntrospectedError): ErrorJson;
    _generateDocAndMetadata(node: AnyIntrospectedType): {
        private: boolean;
        doc: string;
        metadata: Json;
    } | {
        private: boolean;
        doc: null;
        metadata: null;
    };
    generateConst(node: IntrospectedConstant): ConstJson;
    private implements;
    private extends;
    generateInterface(node: IntrospectedInterface): InterfaceJson;
    generateRecord(node: IntrospectedRecord): RecordJson;
    generateClass(node: IntrospectedClass): ClassJson;
    generateField(node: IntrospectedField): FieldJson;
    generateProperty(node: IntrospectedProperty, construct?: boolean): PropertyJson;
    generateSignal(node: IntrospectedSignal, type?: IntrospectedSignalType): MethodJson;
    generateEnumMember(node: GirEnumMember): EnumMemberJson;
    generateParameter(node: IntrospectedFunctionParameter): ParameterJson;
    generateFunction(node: IntrospectedFunction): FunctionJson;
    generateConstructorFunction(node: IntrospectedConstructor): MethodJson;
    generateConstructor(node: IntrospectedConstructor): ConstructorJson;
    generateDirectAllocationConstructor(node: IntrospectedDirectAllocationConstructor): ConstructorJson;
    generateClassFunction(node: IntrospectedClassFunction): MethodJson;
    generateStaticClassFunction(node: IntrospectedStaticClassFunction): StaticMethodJson;
    generateAlias(node: IntrospectedAlias): AliasJson;
    generateVirtualClassFunction(node: IntrospectedVirtualClassFunction): VirtualMethodJson;
    generateNamespace(node: IntrospectedNamespace): Promise<NamespaceJson>;
    stringifyNamespace(node: IntrospectedNamespace): Promise<string | null>;
}
