class RubyLsp::Document

: [ParseResultType]
@abstract

def ==(other)

: (Document[untyped] other) -> bool
def ==(other)
  self.class == other.class && uri == other.uri && @source == other.source
end

def cache_fetch(request_name, &block)

: [T] (String request_name) { (Document[ParseResultType] document) -> T } -> T
def cache_fetch(request_name, &block)
  cached = @cache[request_name]
  return cached if cached != EMPTY_CACHE
  result = block.call(self)
  @cache[request_name] = result
  result
end

def cache_get(request_name)

: (String request_name) -> untyped
def cache_get(request_name)
  @cache[request_name]
end

def cache_set(request_name, value)

: [T] (String request_name, T value) -> T
def cache_set(request_name, value)
  @cache[request_name] = value
end

def clear_cache(request_name)

: (String request_name) -> void
def clear_cache(request_name)
  @cache[request_name] = EMPTY_CACHE
end

def create_scanner

: -> Scanner
def create_scanner
  case @encoding
  when Encoding::UTF_8
    Utf8Scanner.new(@source)
  when Encoding::UTF_16LE
    Utf16Scanner.new(@source)
  else
    Utf32Scanner.new(@source)
  end
end

def find_index_by_position(start_pos, end_pos = nil)

: (Hash[Symbol, untyped] start_pos, ?Hash[Symbol, untyped]? end_pos) -> [Integer, Integer?]
def find_index_by_position(start_pos, end_pos = nil)
  @global_state.synchronize do
    scanner = create_scanner
    start_index = scanner.find_char_position(start_pos)
    end_index = scanner.find_char_position(end_pos) if end_pos
    [start_index, end_index]
  end
end

def initialize(source:, version:, uri:, global_state:)

: (source: String, version: Integer, uri: URI::Generic, global_state: GlobalState) -> void
def initialize(source:, version:, uri:, global_state:)
  @source = source
  @version = version
  @global_state = global_state
  @cache = Hash.new(EMPTY_CACHE) #: Hash[String, untyped]
  @semantic_tokens = EMPTY_CACHE #: (Interface::SemanticTokens | Object)
  @encoding = global_state.encoding #: Encoding
  @uri = uri #: URI::Generic
  @needs_parsing = true #: bool
  @last_edit = nil #: Edit?
  # Workaround to be able to type parse_result properly. It is immediately set when invoking parse!
  @parse_result = ( # rubocop:disable Style/RedundantParentheses
    nil #: as untyped
  ) #: ParseResultType
  parse!
end

def language_id; end

Other tags:
    Abstract: -
def language_id; end

def parse!; end

Other tags:
    Abstract: -
def parse!; end

def past_expensive_limit?

: -> bool
def past_expensive_limit?
  @source.length > MAXIMUM_CHARACTERS_FOR_EXPENSIVE_FEATURES
end

def push_edits(edits, version:)

: (Array[Hash[Symbol, untyped]] edits, version: Integer) -> void
def push_edits(edits, version:)
  edits.each do |edit|
    range = edit[:range]
    scanner = create_scanner
    start_position = scanner.find_char_position(range[:start])
    end_position = scanner.find_char_position(range[:end])
    @source[start_position...end_position] = edit[:text]
  end
  @version = version
  @needs_parsing = true
  @cache.clear
  last_edit = edits.last
  return unless last_edit
  last_edit_range = last_edit[:range]
  @last_edit = if last_edit_range[:start] == last_edit_range[:end]
    Insert.new(last_edit_range)
  elsif last_edit[:text].empty?
    Delete.new(last_edit_range)
  else
    Replace.new(last_edit_range)
  end
end

def syntax_error?; end

Other tags:
    Abstract: -
def syntax_error?; end