class RubyLsp::Store

def cache_fetch(uri, request_name, &block)

: [T] (URI::Generic uri, String request_name) { (Document[untyped] document) -> T } -> T
def cache_fetch(uri, request_name, &block)
  get(uri).cache_fetch(request_name, &block)
end

def clear

: -> void
def clear
  @state.clear
end

def delete(uri)

: (URI::Generic uri) -> void
def delete(uri)
  @state.delete(uri.to_s)
end

def each(&block)

: { (String uri, Document[untyped] document) -> void } -> void
def each(&block)
  @state.each do |uri, document|
    block.call(uri, document)
  end
end

def empty?

: -> bool
def empty?
  @state.empty?
end

def get(uri)

: (URI::Generic uri) -> Document[untyped]
def get(uri)
  document = @state[uri.to_s]
  return document unless document.nil?
  # For unsaved files (`untitled:Untitled-1` uris), there's no path to read from. If we don't have the untitled file
  # already present in the store, then we have to raise non existing document error
  path = uri.to_standardized_path
  raise NonExistingDocumentError, uri.to_s unless path
  ext = File.extname(path)
  language_id = case ext
  when ".erb", ".rhtml"
    :erb
  when ".rbs"
    :rbs
  else
    :ruby
  end
  set(uri: uri, source: File.binread(path), version: 0, language_id: language_id)
  @state[uri.to_s] #: as !nil
rescue Errno::ENOENT
  raise NonExistingDocumentError, uri.to_s
end

def initialize(global_state)

: (GlobalState global_state) -> void
def initialize(global_state)
  @global_state = global_state
  @state = {} #: Hash[String, Document[untyped]]
  @features_configuration = {
    inlayHint: RequestConfig.new({
      enableAll: false,
      implicitRescue: false,
      implicitHashValue: false,
    }),
  } #: Hash[Symbol, RequestConfig]
  @client_name = "Unknown" #: String
end

def key?(uri)

: (URI::Generic uri) -> bool
def key?(uri)
  @state.key?(uri.to_s)
end

def push_edits(uri:, edits:, version:)

: (uri: URI::Generic, edits: Array[Hash[Symbol, untyped]], version: Integer) -> void
def push_edits(uri:, edits:, version:)
  @state[uri.to_s] #: as !nil
    .push_edits(edits, version: version)
end

def set(uri:, source:, version:, language_id:)

: (uri: URI::Generic, source: String, version: Integer, language_id: Symbol) -> Document[untyped]
def set(uri:, source:, version:, language_id:)
  @state[uri.to_s] = case language_id
  when :erb
    ERBDocument.new(source: source, version: version, uri: uri, global_state: @global_state)
  when :rbs
    RBSDocument.new(source: source, version: version, uri: uri, global_state: @global_state)
  else
    RubyDocument.new(source: source, version: version, uri: uri, global_state: @global_state)
  end
end