class DisposableCache {
  constructor() {
    this.toDispose = [];
    this.isDisposed = false;
  }
  onDispose(disposable) {
    this.toDispose.push(disposable);
  }
  dispose() {
    this.throwIfDisposed();
    this.clear();
    this.isDisposed = true;
    this.toDispose.forEach((disposable) => disposable.dispose());
  }
  throwIfDisposed() {
    if (this.isDisposed) {
      throw new Error("This cache has already been disposed");
    }
  }
}
class SimpleCache extends DisposableCache {
  constructor() {
    super(...arguments);
    this.cache = /* @__PURE__ */ new Map();
  }
  has(key) {
    this.throwIfDisposed();
    return this.cache.has(key);
  }
  set(key, value) {
    this.throwIfDisposed();
    this.cache.set(key, value);
  }
  get(key, provider) {
    this.throwIfDisposed();
    if (this.cache.has(key)) {
      return this.cache.get(key);
    } else if (provider) {
      const value = provider();
      this.cache.set(key, value);
      return value;
    } else {
      return void 0;
    }
  }
  delete(key) {
    this.throwIfDisposed();
    return this.cache.delete(key);
  }
  clear() {
    this.throwIfDisposed();
    this.cache.clear();
  }
}
class ContextCache extends DisposableCache {
  constructor(converter) {
    super();
    this.cache = /* @__PURE__ */ new Map();
    this.converter = converter !== null && converter !== void 0 ? converter : ((value) => value);
  }
  has(contextKey, key) {
    this.throwIfDisposed();
    return this.cacheForContext(contextKey).has(key);
  }
  set(contextKey, key, value) {
    this.throwIfDisposed();
    this.cacheForContext(contextKey).set(key, value);
  }
  get(contextKey, key, provider) {
    this.throwIfDisposed();
    const contextCache = this.cacheForContext(contextKey);
    if (contextCache.has(key)) {
      return contextCache.get(key);
    } else if (provider) {
      const value = provider();
      contextCache.set(key, value);
      return value;
    } else {
      return void 0;
    }
  }
  delete(contextKey, key) {
    this.throwIfDisposed();
    return this.cacheForContext(contextKey).delete(key);
  }
  clear(contextKey) {
    this.throwIfDisposed();
    if (contextKey) {
      const mapKey = this.converter(contextKey);
      this.cache.delete(mapKey);
    } else {
      this.cache.clear();
    }
  }
  cacheForContext(contextKey) {
    const mapKey = this.converter(contextKey);
    let documentCache = this.cache.get(mapKey);
    if (!documentCache) {
      documentCache = /* @__PURE__ */ new Map();
      this.cache.set(mapKey, documentCache);
    }
    return documentCache;
  }
}
class WorkspaceCache extends SimpleCache {
  /**
   * 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(sharedServices, state) {
    super();
    if (state) {
      this.toDispose.push(sharedServices.workspace.DocumentBuilder.onBuildPhase(state, () => {
        this.clear();
      }));
      this.toDispose.push(sharedServices.workspace.DocumentBuilder.onUpdate((_changed, deleted) => {
        if (deleted.length > 0) {
          this.clear();
        }
      }));
    } else {
      this.toDispose.push(sharedServices.workspace.DocumentBuilder.onUpdate(() => {
        this.clear();
      }));
    }
  }
}
export {
  ContextCache,
  DisposableCache,
  SimpleCache,
  WorkspaceCache
};
//# sourceMappingURL=lib-utils-caching.js.map
