///|
/// A half-open range of UTF-16 offsets in the original expression.
pub(all) struct Span {
  start : Int32
  end : Int32
} derive(Eq, Debug)

///|
pub(all) enum ErrorCode {
  Syntax
  InvalidType
  InvalidValue
  InvalidArity
  UnknownFunction
} derive(Eq, Debug)

///|
pub fn ErrorCode::to_string(self : ErrorCode) -> String {
  match self {
    Syntax => "syntax"
    InvalidType => "invalid-type"
    InvalidValue => "invalid-value"
    InvalidArity => "invalid-arity"
    UnknownFunction => "unknown-function"
  }
}

///|
pub(all) struct Diagnostic {
  code : ErrorCode
  message : String
  span : Span
} derive(Eq, Debug)

///|
/// One-based line and UTF-16 column in the supplied expression source.
pub fn Diagnostic::line_column(
  self : Diagnostic,
  source : String,
) -> (Int32, Int32) {
  let mut line = 1
  let mut column = 1
  for i in 0.. Node {
  { kind, span: { start, end, }, }
}

///|
fn problem(
  code : ErrorCode,
  span : Span,
  message : String,
) -> Unit raise JmespathError {
  raise JmespathError({ code, span, message, })
}