import { isLinkingError } from "./lib-syntax-tree.js";
import { streamAst, streamReferences, getDocument } from "./lib-utils-ast-utils.js";
import { toDocumentSegment } from "./lib-utils-cst-utils.js";
import { interruptAndCheck } from "./lib-utils-promise-utils.js";
import { UriUtils } from "./lib-utils-uri-utils.js";
import { c as cancellationExports } from "../../_virtual/cancellation.js";
class DefaultAstNodeDescriptionProvider {
  constructor(services) {
    this.astNodeLocator = services.workspace.AstNodeLocator;
    this.nameProvider = services.references.NameProvider;
  }
  createDescription(node, name, document) {
    const doc = document !== null && document !== void 0 ? document : getDocument(node);
    name !== null && name !== void 0 ? name : name = this.nameProvider.getName(node);
    const path = this.astNodeLocator.getAstNodePath(node);
    if (!name) {
      throw new Error(`Node at path ${path} has no name.`);
    }
    let nameNodeSegment;
    const nameSegmentGetter = () => {
      var _a;
      return nameNodeSegment !== null && nameNodeSegment !== void 0 ? nameNodeSegment : nameNodeSegment = toDocumentSegment((_a = this.nameProvider.getNameNode(node)) !== null && _a !== void 0 ? _a : node.$cstNode);
    };
    return {
      node,
      name,
      get nameSegment() {
        return nameSegmentGetter();
      },
      selectionSegment: toDocumentSegment(node.$cstNode),
      type: node.$type,
      documentUri: doc.uri,
      path
    };
  }
}
class DefaultReferenceDescriptionProvider {
  constructor(services) {
    this.nodeLocator = services.workspace.AstNodeLocator;
  }
  async createDescriptions(document, cancelToken = cancellationExports.CancellationToken.None) {
    const descr = [];
    const rootNode = document.parseResult.value;
    for (const astNode of streamAst(rootNode)) {
      await interruptAndCheck(cancelToken);
      streamReferences(astNode).filter((refInfo) => !isLinkingError(refInfo)).forEach((refInfo) => {
        const description = this.createDescription(refInfo);
        if (description) {
          descr.push(description);
        }
      });
    }
    return descr;
  }
  createDescription(refInfo) {
    const targetNodeDescr = refInfo.reference.$nodeDescription;
    const refCstNode = refInfo.reference.$refNode;
    if (!targetNodeDescr || !refCstNode) {
      return void 0;
    }
    const docUri = getDocument(refInfo.container).uri;
    return {
      sourceUri: docUri,
      sourcePath: this.nodeLocator.getAstNodePath(refInfo.container),
      targetUri: targetNodeDescr.documentUri,
      targetPath: targetNodeDescr.path,
      segment: toDocumentSegment(refCstNode),
      local: UriUtils.equals(targetNodeDescr.documentUri, docUri)
    };
  }
}
export {
  DefaultAstNodeDescriptionProvider,
  DefaultReferenceDescriptionProvider
};
//# sourceMappingURL=lib-workspace-ast-descriptions.js.map
