module Prism

interface _CodeUnitsCache
  def []: (Integer byte_offset) -> Integer
end

class Source
  attr_reader source: String
  attr_reader start_line: Integer
  attr_reader offsets: Array[Integer]

  def initialize: (String source, ?Integer start_line, ?Array[Integer] offsets) -> void
  def replace_start_line: (Integer start_line) -> void
  def replace_offsets: (Array[Integer] offsets) -> void
  def encoding: () -> Encoding
  def lines: () -> Array[String]
  def slice: (Integer byte_offset, Integer length) -> String
  def byte_offset: (Integer line, Integer column) -> Integer
  def line: (Integer byte_offset) -> Integer
  def line_start: (Integer byte_offset) -> Integer
  def line_end: (Integer byte_offset) -> Integer
  def line_offset: (Integer byte_offset) -> Integer
  def column: (Integer byte_offset) -> Integer
  def character_offset: (Integer byte_offset) -> Integer
  def character_column: (Integer byte_offset) -> Integer
  def code_units_offset: (Integer byte_offset, Encoding encoding) -> Integer
  def code_units_cache: (Encoding encoding) -> _CodeUnitsCache
  def code_units_column: (Integer byte_offset, Encoding encoding) -> Integer
  def deep_freeze: () -> void

  def self.for: (String source) -> Source
end

class CodeUnitsCache
  def initialize: (String source, Encoding encoding) -> void
  def []: (Integer byte_offset) -> Integer
end

class ASCIISource < Source
  def character_offset: (Integer byte_offset) -> Integer
  def character_column: (Integer byte_offset) -> Integer
  def code_units_offset: (Integer byte_offset, Encoding encoding) -> Integer
  def code_units_cache: (Encoding encoding) -> _CodeUnitsCache
  def code_units_column: (Integer byte_offset, Encoding encoding) -> Integer
end

class Location
  attr_reader source: Source
  attr_reader start_offset: Integer
  attr_reader length: Integer

  def initialize: (Source source, Integer start_offset, Integer length) -> void
  def leading_comments: () -> Array[comment]
  def leading_comment: (comment) -> void
  def trailing_comments: () -> Array[comment]
  def trailing_comment: (comment) -> void
  def comments: () -> Array[comment]
  def copy: (?source: Source, ?start_offset: Integer, ?length: Integer) -> Location
  def chop: () -> Location
  def source_lines: () -> Array[String]
  def slice: () -> String
  def slice_lines: () -> String
  def start_character_offset: () -> Integer
  def start_code_units_offset: (Encoding encoding) -> Integer
  def cached_start_code_units_offset: (_CodeUnitsCache cache) -> Integer
  def end_offset: () -> Integer
  def end_character_offset: () -> Integer
  def end_code_units_offset: (Encoding encoding) -> Integer
  def cached_end_code_units_offset: (_CodeUnitsCache cache) -> Integer
  def start_line: () -> Integer
  def start_line_slice: () -> String
  def end_line: () -> Integer
  def start_column: () -> Integer
  def start_character_column: () -> Integer
  def start_code_units_column: (Encoding encoding) -> Integer
  def cached_start_code_units_column: (_CodeUnitsCache cache) -> Integer
  def end_column: () -> Integer
  def end_character_column: () -> Integer
  def end_code_units_column: (Encoding encoding) -> Integer
  def cached_end_code_units_column: (_CodeUnitsCache cache) -> Integer
  def deconstruct_keys: (Array[Symbol]? keys) -> Hash[Symbol, untyped]
  def pretty_print: (untyped q) -> untyped
  def join: (Location other) -> Location
  def adjoin: (String string) -> Location
end

class Comment
  attr_reader location: Location

  def initialize: (Location location) -> void
  def deconstruct_keys: (Array[Symbol]? keys) -> Hash[Symbol, untyped]
  def slice: () -> String
end

interface _Comment
  def trailing?: () -> bool
end

type comment = Comment & _Comment

class InlineComment < Comment
  include _Comment
end

class EmbDocComment < Comment
  include _Comment
end

class MagicComment
  attr_reader key_loc: Location
  attr_reader value_loc: Location

  def initialize: (Location key_loc, Location value_loc) -> void

  def key: () -> String
  def value: () -> String

  def deconstruct_keys: (Array[Symbol]? keys) -> Hash[Symbol, untyped]
end

class ParseError
  attr_reader type: Symbol
  attr_reader message: String
  attr_reader location: Location
  attr_reader level: Symbol

  def initialize: (Symbol type, String message, Location location, Symbol level) -> void
  def deconstruct_keys: (Array[Symbol]? keys) -> Hash[Symbol, untyped]
end

class ParseWarning
  attr_reader type: Symbol
  attr_reader message: String
  attr_reader location: Location
  attr_reader level: Symbol

  def initialize: (Symbol type, String message, Location location, Symbol level) -> void
  def deconstruct_keys: (Array[Symbol]? keys) -> Hash[Symbol, untyped]
end

class Result
  attr_reader comments: Array[comment]
  attr_reader magic_comments: Array[MagicComment]
  attr_reader data_loc: Location?
  attr_reader errors: Array[ParseError]
  attr_reader warnings: Array[ParseWarning]
  attr_reader source: Source

  def initialize: (Array[comment] comments, Array[MagicComment] magic_comments, Location? data_loc, Array[ParseError] errors, Array[ParseWarning] warnings, Source source) -> void
  def deconstruct_keys: (Array[Symbol]? keys) -> Hash[Symbol, untyped]
  def encoding: () -> Encoding
  def success?: () -> bool
  def failure?: () -> bool
  def code_units_cache: (Encoding encoding) -> _CodeUnitsCache
end

class ParseResult < Result
  attr_reader value: ProgramNode

  def initialize: (ProgramNode value, Array[comment] comments, Array[MagicComment] magic_comments, Location? data_loc, Array[ParseError] errors, Array[ParseWarning] warnings, Source source) -> void
  def deconstruct_keys: (Array[Symbol]? keys) -> Hash[Symbol, untyped]
  def errors_format: () -> String
end

class LexResult < Result
  attr_reader value: Array[[Token, Integer]]

  def initialize: (Array[[Token, Integer]] value, Array[comment] comments, Array[MagicComment] magic_comments, Location? data_loc, Array[ParseError] errors, Array[ParseWarning] warnings, Source source) -> void
  def deconstruct_keys: (Array[Symbol]? keys) -> Hash[Symbol, untyped]
end

class ParseLexResult < Result
  attr_reader value: [ProgramNode, Array[[Token, Integer]]]

  def initialize: ([ProgramNode, Array[[Token, Integer]]] value, Array[comment] comments, Array[MagicComment] magic_comments, Location? data_loc, Array[ParseError] errors, Array[ParseWarning] warnings, Source source) -> void
  def deconstruct_keys: (Array[Symbol]? keys) -> Hash[Symbol, untyped]
end

class Token
  attr_reader source: Source
  attr_reader type: Symbol
  attr_reader value: String
  attr_reader location: Location

  def initialize: (Source source, Symbol type, String value, Location location) -> void
  def deconstruct_keys: (Array[Symbol]? keys) -> Hash[Symbol, untyped]
  def pretty_print: (untyped q) -> untyped
  def ==: (untyped other) -> bool
  def deep_freeze: () -> void
end

class Scope
  attr_reader locals: Array[Symbol]
  attr_reader forwarding: Array[Symbol]

  def initialize: (Array[Symbol] locals, Array[Symbol] forwarding) -> void
end

end