import { isLinkingError as u } from "../syntax-tree.js";
import { streamAst as p, streamReferences as l, getDocument as d } from "../utils/ast-utils.js";
import { toDocumentSegment as a } from "../utils/cst-utils.js";
import { interruptAndCheck as N } from "../utils/promise-utils.js";
import { UriUtils as h } from "../utils/uri-utils.js";
import { c as f } from "../../../../../../../_virtual/cancellation.js";
class L {
  constructor(e) {
    this.astNodeLocator = e.workspace.AstNodeLocator, this.nameProvider = e.references.NameProvider;
  }
  createDescription(e, t, r) {
    const s = r ?? d(e);
    t ?? (t = this.nameProvider.getName(e));
    const i = this.astNodeLocator.getAstNodePath(e);
    if (!t)
      throw new Error(`Node at path ${i} has no name.`);
    let o;
    const c = () => {
      var n;
      return o ?? (o = a((n = this.nameProvider.getNameNode(e)) !== null && n !== void 0 ? n : e.$cstNode));
    };
    return {
      node: e,
      name: t,
      get nameSegment() {
        return c();
      },
      selectionSegment: a(e.$cstNode),
      type: e.$type,
      documentUri: s.uri,
      path: i
    };
  }
}
class $ {
  constructor(e) {
    this.nodeLocator = e.workspace.AstNodeLocator;
  }
  async createDescriptions(e, t = f.CancellationToken.None) {
    const r = [], s = e.parseResult.value;
    for (const i of p(s))
      await N(t), l(i).filter((o) => !u(o)).forEach((o) => {
        const c = this.createDescription(o);
        c && r.push(c);
      });
    return r;
  }
  createDescription(e) {
    const t = e.reference.$nodeDescription, r = e.reference.$refNode;
    if (!t || !r)
      return;
    const s = d(e.container).uri;
    return {
      sourceUri: s,
      sourcePath: this.nodeLocator.getAstNodePath(e.container),
      targetUri: t.documentUri,
      targetPath: t.path,
      segment: a(r),
      local: h.equals(t.documentUri, s)
    };
  }
}
export {
  L as DefaultAstNodeDescriptionProvider,
  $ as DefaultReferenceDescriptionProvider
};
