class c {
  constructor() {
    this.toDispose = [], this.isDisposed = !1;
  }
  onDispose(e) {
    this.toDispose.push(e);
  }
  dispose() {
    this.throwIfDisposed(), this.clear(), this.isDisposed = !0, this.toDispose.forEach((e) => e.dispose());
  }
  throwIfDisposed() {
    if (this.isDisposed)
      throw new Error("This cache has already been disposed");
  }
}
class r extends c {
  constructor() {
    super(...arguments), this.cache = /* @__PURE__ */ new Map();
  }
  has(e) {
    return this.throwIfDisposed(), this.cache.has(e);
  }
  set(e, s) {
    this.throwIfDisposed(), this.cache.set(e, s);
  }
  get(e, s) {
    if (this.throwIfDisposed(), this.cache.has(e))
      return this.cache.get(e);
    if (s) {
      const t = s();
      return this.cache.set(e, t), t;
    } else
      return;
  }
  delete(e) {
    return this.throwIfDisposed(), this.cache.delete(e);
  }
  clear() {
    this.throwIfDisposed(), this.cache.clear();
  }
}
class a extends c {
  constructor(e) {
    super(), this.cache = /* @__PURE__ */ new Map(), this.converter = e ?? ((s) => s);
  }
  has(e, s) {
    return this.throwIfDisposed(), this.cacheForContext(e).has(s);
  }
  set(e, s, t) {
    this.throwIfDisposed(), this.cacheForContext(e).set(s, t);
  }
  get(e, s, t) {
    this.throwIfDisposed();
    const h = this.cacheForContext(e);
    if (h.has(s))
      return h.get(s);
    if (t) {
      const o = t();
      return h.set(s, o), o;
    } else
      return;
  }
  delete(e, s) {
    return this.throwIfDisposed(), this.cacheForContext(e).delete(s);
  }
  clear(e) {
    if (this.throwIfDisposed(), e) {
      const s = this.converter(e);
      this.cache.delete(s);
    } else
      this.cache.clear();
  }
  cacheForContext(e) {
    const s = this.converter(e);
    let t = this.cache.get(s);
    return t || (t = /* @__PURE__ */ new Map(), this.cache.set(s, t)), t;
  }
}
class n extends r {
  /**
   * Creates a new workspace cache.
   *
   * @param sharedServices Service container instance to hook into document lifecycle events.
   * @param state Optional document state on which the cache should evict.
   * If not provided, the cache will evict on `DocumentBuilder#onUpdate`.
   * *Deleted* documents are considered in both cases.
   */
  constructor(e, s) {
    super(), s ? (this.toDispose.push(e.workspace.DocumentBuilder.onBuildPhase(s, () => {
      this.clear();
    })), this.toDispose.push(e.workspace.DocumentBuilder.onUpdate((t, h) => {
      h.length > 0 && this.clear();
    }))) : this.toDispose.push(e.workspace.DocumentBuilder.onUpdate(() => {
      this.clear();
    }));
  }
}
export {
  a as ContextCache,
  c as DisposableCache,
  r as SimpleCache,
  n as WorkspaceCache
};
