/******************************************************************************
 * Copyright 2021 TypeFox GmbH
 * This program and the accompanying materials are made available under the
 * terms of the MIT License, which is available in the project root.
 ******************************************************************************/
import type { LangiumCoreServices } from '../services.js';
import type { AstNode, AstNodeDescription, AstReflection, CstNode, LinkingError, MultiReference, MultiReferenceItem, Reference, ReferenceInfo } from '../syntax-tree.js';
import type { AstNodeLocator } from '../workspace/ast-node-locator.js';
import type { LangiumDocument, LangiumDocuments } from '../workspace/documents.js';
import type { ScopeProvider } from './scope-provider.js';
import { CancellationToken } from '../utils/cancellation.js';
import type { LangiumProfiler } from '../workspace/profiler.js';
/**
 * Language-specific service for resolving cross-references in the AST.
 */
export interface Linker {
    /**
     * Links all cross-references within the specified document. The default implementation loads only target
     * elements from documents that are present in the `LangiumDocuments` service. The linked references are
     * stored in the document's `references` property.
     *
     * @param document A LangiumDocument that shall be linked.
     * @param cancelToken A token for cancelling the operation.
     *
     * @throws `OperationCancelled` if a cancellation event is detected
     */
    link(document: LangiumDocument, cancelToken?: CancellationToken): Promise<void>;
    /**
     * Unlinks all references within the specified document and removes them from the list of `references`.
     *
     * @param document A LangiumDocument that shall be unlinked.
     */
    unlink(document: LangiumDocument): void;
    /**
     * Determines a candidate AST node description for linking the given reference.
     *
     * @param refInfo Information about the reference.
     */
    getCandidate(refInfo: ReferenceInfo): AstNodeDescription | LinkingError;
    /**
     * Determines a candidate AST node description for linking the given reference.
     *
     * @param node The AST node containing the reference.
     * @param refId The reference identifier used to build a scope.
     * @param reference The actual reference to resolve.
     */
    getCandidates(refInfo: ReferenceInfo): AstNodeDescription[] | LinkingError;
    /**
     * Creates a cross reference node being aware of its containing AstNode, the corresponding CstNode,
     * the cross reference text denoting the target AstNode being already extracted of the document text,
     * as well as the unique cross reference identifier.
     *
     * Default behavior:
     *  - The returned Reference's 'ref' property pointing to the target AstNode is populated lazily on its
     *    first visit.
     *  - If the target AstNode cannot be resolved on the first visit, an error indicator will be installed
     *    and further resolution attempts will *not* be performed.
     *
     * @param node The containing AST node
     * @param property The AST node property being referenced
     * @param refNode The corresponding CST node
     * @param refText The cross reference text denoting the target AstNode
     * @returns the desired Reference node, whose behavior wrt. resolving the cross reference is implementation specific.
     */
    buildReference(node: AstNode, property: string, refNode: CstNode | undefined, refText: string): Reference;
    buildMultiReference(node: AstNode, property: string, refNode: CstNode | undefined, refText: string): MultiReference;
}
export declare const RefResolving: unique symbol;
export interface DefaultReference extends Reference {
    _ref?: AstNode | LinkingError | typeof RefResolving;
    _nodeDescription?: AstNodeDescription;
}
export interface DefaultMultiReference extends MultiReference {
    _items: MultiReferenceItem[] | typeof RefResolving | undefined;
    _linkingError?: LinkingError;
}
interface ReferenceResolver {
    resolveReference(reference: DefaultReference, node: AstNode, property: string): AstNode | undefined;
    resolveMultiReference(reference: DefaultMultiReference, node: AstNode, property: string): MultiReferenceItem[];
}
export declare class DefaultLinker implements Linker {
    protected readonly reflection: AstReflection;
    protected readonly scopeProvider: ScopeProvider;
    protected readonly astNodeLocator: AstNodeLocator;
    protected readonly langiumDocuments: () => LangiumDocuments;
    protected readonly profiler: LangiumProfiler | undefined;
    protected readonly languageId: string;
    protected readonly referenceResolver: ReferenceResolver;
    constructor(services: LangiumCoreServices);
    link(document: LangiumDocument, cancelToken?: CancellationToken): Promise<void>;
    protected doLink(refInfo: ReferenceInfo, document: LangiumDocument): void;
    unlink(document: LangiumDocument): void;
    getCandidate(refInfo: ReferenceInfo): AstNodeDescription | LinkingError;
    getCandidates(refInfo: ReferenceInfo): AstNodeDescription[] | LinkingError;
    buildReference(node: AstNode, property: string, refNode: CstNode | undefined, refText: string): Reference;
    buildMultiReference(node: AstNode, property: string, refNode: CstNode | undefined, refText: string): MultiReference;
    protected resolveReference(reference: DefaultReference, node: AstNode, property: string): AstNode | undefined;
    protected resolveMultiReference(reference: DefaultMultiReference, node: AstNode, property: string): MultiReferenceItem[];
    protected throwCyclicReferenceError(node: AstNode, property: string, refText: string): never;
    protected getLinkedNode(refInfo: ReferenceInfo): {
        node?: AstNode;
        descr?: AstNodeDescription;
        error?: LinkingError;
    };
    protected loadAstNode(nodeDescription: AstNodeDescription): AstNode | undefined;
    protected createLinkingError(refInfo: ReferenceInfo, targetDescription?: AstNodeDescription): LinkingError;
}
export {};
//# sourceMappingURL=linker.d.ts.map