///|
fn Parser::parse_module_decl(self : Parser) -> ParsedModuleDecl? {
  // PKL-128d: capture annotations preceding the `module` / `amends`
  // / `extends` keyword.
  let annotations = self.take_pending_annotations()
  self.builder.start_node(module_decl())
  let buf = StringBuilder::new()
  if self.at(module_kw()) {
    ignore(self.bump())
    match self.expect(identifier(), "module name") {
      Some(tok) => buf.write_string(tok.text())
      None => ()
    }
    while ({
            self.skip_whitespace()
            self.at(dot())
          }) {
      ignore(self.bump())
      match self.expect(identifier(), "module name segment") {
        Some(tok) => {
          buf.write_string(".")
          buf.write_string(tok.text())
        }
        None => ()
      }
    }
  }
  let mut module_relation : ModuleRelation? = None
  self.skip_whitespace()
  if self.at_text("extends") || self.at_text("amends") {
    let kind = if self.at_text("amends") { ModuleAmends } else { ModuleExtends }
    ignore(self.bump())
    self.skip_whitespace()
    let uri = if self.at(string_token()) {
      unquote(self.bump().text())
    } else if self.at(lparen()) {
      self.skip_balanced_group(lparen(), rparen())
      ""
    } else {
      self.skip_unknown_member()
      ""
    }
    if uri != "" {
      module_relation = Some({ kind, uri })
    }
  }
  self.builder.finish_node()
  let text = buf.to_string()
  let parsed_name = if text == "" { None } else { Some(text) }
  if parsed_name is None && module_relation is None {
    None
  } else {
    Some({ module_name: parsed_name, module_relation, annotations })
  }
}

///|
fn Parser::parse_let_decl(self : Parser) -> Binding? {
  self.builder.start_node(let_decl())
  ignore(self.expect(let_kw(), "let"))
  let name = match self.expect(identifier(), "identifier") {
    Some(tok) => tok.text()
    None => ""
  }
  let type_name = self.parse_type_annotation()
  let value = if ({
      self.skip_whitespace()
      self.at(eq())
    }) {
    ignore(self.bump())
    self.parse_expr()
  } else {
    self.parse_empty_unsupported_expr()
  }
  self.builder.finish_node()
  if name == "" {
    None
  } else {
    let annotations = self.take_pending_annotations()
    Some({
      name,
      type_name,
      value,
      exported: false,
      is_const: false,
      annotations,
      abstract_slot: false,
      sibling_slot: false,
    })
  }
}

///|
fn Parser::parse_local_decl(self : Parser) -> Binding? {
  let annotations = self.take_pending_annotations()
  let mut is_const = self.take_pending_const()
  self.builder.start_node(let_decl())
  ignore(self.expect(local_kw(), "local"))
  // Apple Pkl accepts modifier keywords after `local` (`local const x`,
  // `local hidden x`); swallow any combination so the identifier that
  // follows is read as the binding name rather than as the second
  // modifier.
  self.skip_whitespace()
  while self.at(identifier()) && is_modifier_text(self.peek().text()) {
    if self.peek().text() == "const" {
      is_const = true
    }
    ignore(self.bump())
    self.skip_whitespace()
  }
  let name = match self.expect(identifier(), "identifier") {
    Some(tok) => tok.text()
    None => ""
  }
  let type_name = self.parse_type_annotation()
  let value = if ({
      self.skip_whitespace()
      self.at(eq())
    }) {
    ignore(self.bump())
    self.parse_expr_with_expected_type(type_name)
  } else if ({
      self.skip_whitespace()
      self.at(lbrace())
    }) {
    // PKL-148e: `local a { body }` (no `=`, brace body) is the local
    // form of Apple Pkl's amend-shorthand. Dispatch through the same
    // body-inference path that `parse_property_decl` uses.
    self.parse_inferred_new_body()
  } else {
    self.parse_empty_unsupported_expr()
  }
  self.builder.finish_node()
  if name == "" {
    None
  } else {
    Some({
      name,
      type_name,
      value,
      exported: false,
      is_const,
      annotations,
      abstract_slot: false,
      sibling_slot: false,
    })
  }
}

///|
/// PKL-140: property-level type annotation that accepts function types
/// (`(A, B) -> R`). The standard `parse_type_annotation` stops at `->`
/// so call sites that follow with a lambda body (`fn parameter type`)
/// don't accidentally swallow the arrow. Property declarations end
/// with `=` / `{`, so function types are unambiguous here.
fn Parser::parse_property_type_annotation(self : Parser) -> String? {
  self.skip_whitespace()
  if !self.at(colon()) {
    return None
  }
  ignore(self.bump())
  self.skip_whitespace()
  let type_name = self.parse_type_text(
    stop_at_arrow=false,
    stop_at_expression_operator=false,
  )
  if type_name == "" {
    None
  } else {
    Some(type_name)
  }
}

///|
fn Parser::parse_type_annotation(self : Parser) -> String? {
  self.skip_whitespace()
  if !self.at(colon()) {
    return None
  }
  ignore(self.bump())
  self.skip_whitespace()
  // PKL-148bb: `stop_at_arrow=false` so a function-typed parameter
  // (`function lambda(lambda: (String) -> Int) = lambda`) captures the
  // full function type as the parameter annotation. Lambda parameter
  // lists (`(a: Int) -> body`) still parse correctly because the outer
  // `)` ends the type text before the body's `->` is seen.
  let type_name = self.parse_type_text(
    stop_at_arrow=false,
    stop_at_expression_operator=false,
  )
  if type_name == "" {
    None
  } else {
    Some(type_name)
  }
}

///|
fn Parser::at_type_expression_boundary(self : Parser) -> Bool {
  self.at(else_kw()) ||
  self.at(or_or()) ||
  self.at(and_and()) ||
  self.at(coalesce()) ||
  self.at(pipe_forward()) ||
  self.at(equal_equal()) ||
  self.at(not_equal()) ||
  self.at(lte()) ||
  self.at(gte()) ||
  self.at(plus()) ||
  self.at(minus()) ||
  self.at(star()) ||
  self.at(slash()) ||
  self.at(percent()) ||
  self.at(int_div()) ||
  self.at(pow())
}

///|
fn Parser::parse_type_text(
  self : Parser,
  stop_at_arrow~ : Bool,
  stop_at_expression_operator~ : Bool,
) -> String {
  let buf = StringBuilder::new()
  let mut parens = 0
  let mut brackets = 0
  let mut angles = 0
  while !self.at(eof()) {
    if parens == 0 && brackets == 0 && angles == 0 {
      if self.at(eq()) ||
        self.at(lbrace()) ||
        self.at(rbrace()) ||
        self.at(comma()) ||
        (stop_at_arrow && self.at(arrow())) ||
        (stop_at_expression_operator && self.at_type_expression_boundary()) {
        break
      }
      if is_separator(self.peek_kind()) {
        // PKL-148ap: a separator at top level normally ends the type
        // text, but Apple Pkl lets a union typealias body wrap onto
        // a continuation line whose first significant token is `|`:
        //   typealias A =
        //     "a"
        //     | "b"
        //     | "c"
        // Peek past the trivia run; if the next significant token is
        // `|`, swallow the separators and continue collecting the
        // type text. Otherwise the separator is a real boundary
        // (`typealias A = Int\n typealias B = Float` etc.) and we
        // stop here.
        let next_kind = self.peek_non_trivia_kind(self.pos + 1)
        // Qualified type names may also wrap between the module alias and
        // member (`new very_long_module\n  .Type {}`). A leading dot cannot
        // start another type declaration, so the continuation is unambiguous.
        if next_kind == pipe() || next_kind == dot() {
          self.skip_trivia()
          continue
        }
        break
      }
    }
    if self.at(lparen()) {
      parens += 1
    } else if self.at(rparen()) {
      if parens == 0 {
        break
      }
      parens -= 1
    } else if self.at(lbracket()) {
      brackets += 1
    } else if self.at(rbracket()) {
      if brackets == 0 {
        break
      }
      brackets -= 1
    } else if parens == 0 && brackets == 0 && self.at(lt()) {
      angles += 1
    } else if parens == 0 && brackets == 0 && self.at(gt()) {
      if angles == 0 {
        break
      }
      angles -= 1
    }
    let tok = self.bump()
    if !is_trivia(tok.kind()) {
      // PKL-148bb: preserve a single space when the previous non-trivia
      // ended with an identifier character and this token begins with
      // one — otherwise tokens like `it is Int` collapse into `itisInt`,
      // making it impossible to re-parse the captured text as the
      // original `is` operator expression.
      let s = buf.to_string()
      let text = tok.text()
      if s.length() > 0 && text.length() > 0 {
        let last = s[s.length() - 1].to_int().unsafe_to_char()
        let first = text[0].to_int().unsafe_to_char()
        if tok.kind() == is_kw() ||
          tok.kind() == as_kw() ||
          (is_ident_char(last) && is_ident_char(first)) {
          buf.write_char(' ')
        }
      }
      buf.write_string(text)
    }
  }
  buf.to_string()
}

///|
fn is_ident_char(c : Char) -> Bool {
  (c >= 'a' && c <= 'z') ||
  (c >= 'A' && c <= 'Z') ||
  (c >= '0' && c <= '9') ||
  c == '_'
}

///|
fn inferred_glob_import_name(name : String) -> String {
  if name == "" {
    return name
  }
  let first = name[0].to_int().unsafe_to_char()
  if first >= '0' && first <= '9' {
    return "`\{name}`"
  }
  for c in name.iter() {
    if !is_ident_char(c) {
      return "`\{name}`"
    }
  }
  name
}

///|
fn Parser::parse_import_decl(self : Parser) -> ImportDecl? {
  self.builder.start_node(import_decl())
  ignore(self.expect(import_kw(), "import"))
  self.skip_whitespace()
  let mut is_glob = false
  if self.at(star()) {
    is_glob = true
    ignore(self.bump())
  }
  self.skip_whitespace()
  let uri = if self.at(string_token()) {
    unquote(self.bump().text())
  } else {
    self.skip_unknown_member()
    ""
  }
  let import_name = if ({
      self.skip_whitespace()
      self.at(as_kw())
    }) {
    ignore(self.bump())
    match self.expect(identifier(), "import alias") {
      Some(tok) => tok.text()
      None => ""
    }
  } else {
    let inferred = import_alias_from_uri(uri)
    if is_glob {
      inferred_glob_import_name(inferred)
    } else {
      inferred
    }
  }
  self.builder.finish_node()
  if uri == "" || import_name == "" {
    None
  } else {
    Some({ uri, import_name, is_glob })
  }
}

///|
fn Parser::parse_class_decl(self : Parser) -> ClassDecl? {
  // PKL-128d: drain any pending annotations the surrounding
  // `skip_member_header` collected; they precede the `class` keyword.
  let annotations = self.take_pending_annotations()
  // PKL-117: drain the `abstract` modifier if present so the
  // typechecker can refuse instantiation and enforce that
  // descendant concrete classes override every abstract method.
  let is_abstract = self.take_pending_abstract()
  self.builder.start_node(class_decl())
  self.expect_text("class", "class")
  let name = match self.expect(identifier(), "class name") {
    Some(tok) => tok.text()
    None => ""
  }
  // PKL-089: optional type parameter list immediately after the class
  // name (`class Box`). The parser collects the parameter names so
  // the AST records them, but downstream stages treat the names as
  // `UnknownType` for now — binding-at-instantiation lands with PKL-090.
  // PKL-116: each parameter may carry a `: ` suffix
  // (`class Box`); the bound expression is recorded as a raw
  // type text and the typechecker enforces it at call sites.
  let type_parameters : Array[String] = []
  let type_parameter_bounds : Array[String?] = []
  self.skip_whitespace()
  if self.at_text("<") {
    ignore(self.bump())
    let mut more = true
    while more {
      self.skip_whitespace()
      // PKL-140: Apple Pkl supports variance modifiers `` / ``
      // on type parameters. `in` is a keyword token (`in_kw`) and would
      // trip `expect(identifier())`; skip it here so the parameter name
      // parses. pkl-mbt is fully invariant under the hood — the modifier
      // is recorded as parsed but doesn't influence the typechecker.
      if self.at(in_kw()) || self.at_text("out") {
        ignore(self.bump())
        self.skip_whitespace()
      }
      match self.expect(identifier(), "type parameter") {
        Some(tok) => type_parameters.push(tok.text())
        None => type_parameters.push("")
      }
      self.skip_whitespace()
      if self.at(colon()) {
        ignore(self.bump())
        self.skip_whitespace()
        let bound = self.parse_type_text(
          stop_at_arrow=true,
          stop_at_expression_operator=true,
        )
        if bound == "" {
          type_parameter_bounds.push(None)
        } else {
          type_parameter_bounds.push(Some(bound))
        }
      } else {
        type_parameter_bounds.push(None)
      }
      self.skip_whitespace()
      if self.at_text(",") {
        ignore(self.bump())
      } else {
        more = false
      }
    }
    self.skip_whitespace()
    if self.at_text(">") {
      ignore(self.bump())
    }
  }
  let mut parent_name : String? = None
  while !self.at(eof()) && !self.at(lbrace()) {
    if is_separator(self.peek_kind()) || self.at(rbrace()) {
      break
    }
    if self.at_text("extends") {
      ignore(self.bump())
      self.skip_whitespace()
      let parsed_parent = self.parse_type_text(
        stop_at_arrow=false,
        stop_at_expression_operator=false,
      )
      if parsed_parent != "" {
        parent_name = Some(parsed_parent)
      }
    } else {
      ignore(self.bump())
    }
  }
  let properties : Array[ClassProperty] = []
  let methods : Array[FunctionDecl] = []
  if self.at(lbrace()) {
    ignore(self.bump())
    self.consume_separators()
    while !self.at(eof()) && !self.at(rbrace()) {
      self.skip_member_header()
      // PKL-148e: `local` modifier on a class property. Apple Pkl's
      // local class properties are usable from class methods but
      // hidden from PCF output / external access. Consume the keyword
      // and route through the regular property parser; the hidden
      // prefix gates rendering and `push_receiver_method_bindings`
      // strips it when seeding the method cache. PKL-148j: switch to
      // the dedicated `local_member_prefix` so external `.X` resolves
      // through `lookup_visible_member` and rejects with "Cannot find
      // property `X`".
      let local_modifier = if self.at(local_kw()) {
        ignore(self.bump())
        self.skip_whitespace()
        while self.at(identifier()) && is_modifier_text(self.peek().text()) {
          self.pending_modifiers.push(self.peek().text())
          ignore(self.bump())
          self.skip_whitespace()
        }
        true
      } else {
        false
      }
      if self.at_text("function") {
        match self.parse_function_decl() {
          Some(class_method) => methods.push(class_method)
          None => ()
        }
      } else if self.at_property_decl() {
        match self.parse_class_property_decl() {
          Some(property) =>
            if local_modifier {
              properties.push({
                name: local_member_name(property.name),
                type_name: property.type_name,
                value: property.value,
                annotations: property.annotations,
              })
            } else {
              properties.push(property)
            }
          None => ()
        }
      } else {
        self.skip_unknown_member()
      }
      self.consume_separators()
    }
    ignore(self.expect(rbrace(), "}"))
  }
  // PKL-148e: bodyless `class Foo` is well-formed; the previous
  // `skip_unknown_member` fallback ate the following separator + next
  // declaration into the current `class_decl` node, hiding subsequent
  // `class Foo2` from the top-level dispatcher.
  self.builder.finish_node()
  if name == "" {
    None
  } else {
    Some({
      name,
      type_parameters,
      type_parameter_bounds,
      parent_name,
      properties,
      methods,
      annotations,
      is_abstract,
    })
  }
}

///|
fn Parser::parse_class_property_decl(self : Parser) -> ClassProperty? {
  let annotations = self.take_pending_annotations()
  // PKL-145: drain the `hidden` modifier from the pending list that
  // `skip_member_header` populated, then prefix the stored name with
  // `hidden_member_prefix` so renderers skip the property (same
  // contract as the object-body `hidden` member path).
  let hidden = self.take_pending_hidden()
  self.builder.start_node(property_decl())
  if !self.at(identifier()) {
    self.skip_unknown_member()
    self.builder.finish_node()
    return None
  }
  let raw_name = match self.expect(identifier(), "class property name") {
    Some(tok) => tok.text()
    None => ""
  }
  let type_name = self.parse_property_type_annotation()
  let value = if ({
      self.skip_whitespace()
      self.at(lbrace())
    }) {
    Some(self.parse_object_body())
  } else if ({
      self.skip_whitespace()
      self.at(eq())
    }) {
    ignore(self.bump())
    Some(self.parse_expr())
  } else {
    None
  }
  self.builder.finish_node()
  if raw_name == "" {
    None
  } else {
    let name = if hidden { hidden_member_name(raw_name) } else { raw_name }
    Some({ name, type_name, value, annotations })
  }
}

///|
fn Parser::parse_typealias_decl(self : Parser) -> TypeAliasDecl? {
  // PKL-128d: capture annotations preceding the `typealias` keyword.
  let annotations = self.take_pending_annotations()
  self.builder.start_node(typealias_decl())
  self.expect_text("typealias", "typealias")
  let name = match self.expect(identifier(), "typealias name") {
    Some(tok) => tok.text()
    None => ""
  }
  // PKL-115: optional type parameter list `` immediately
  // after the alias name. Same shape as the class / function parameter
  // scope from PKL-089 / PKL-090. Names are recorded on the AST and the
  // typechecker substitutes them into `target` when an instantiation
  // site (`Box`) is resolved.
  let type_parameters : Array[String] = []
  self.skip_whitespace()
  if self.at_text("<") {
    ignore(self.bump())
    let mut more = true
    while more {
      self.skip_whitespace()
      // PKL-140: variance modifiers `` / `` on typealias type
      // parameters. Apple Pkl's `typealias NonNull = Any(...)` etc.
      if self.at(in_kw()) || self.at_text("out") {
        ignore(self.bump())
        self.skip_whitespace()
      }
      match self.expect(identifier(), "type parameter") {
        Some(tok) => type_parameters.push(tok.text())
        None => ()
      }
      self.skip_whitespace()
      if self.at_text(",") {
        ignore(self.bump())
      } else {
        more = false
      }
    }
    self.skip_whitespace()
    self.expect_text(">", "closing >")
  }
  let target = if ({
      // Apple Pkl allows a typealias declaration to break before the
      // equals sign as well as after it:
      //
      //   typealias A
      //     = "a"
      //     | "b"
      //
      // `skip_whitespace` only skips spaces/tabs, so use full trivia
      // here while still requiring an explicit `=`.
      self.skip_trivia()
      self.at(eq())
    }) {
    ignore(self.bump())
    // Apple Pkl allows the typealias RHS to start on the next line
    // (`typealias Foo =\n  String(...)`). Skip trivia (including
    // newlines) so the type-text parser starts at the first significant
    // token regardless of formatting.
    self.skip_trivia()
    self.parse_type_text(stop_at_arrow=false, stop_at_expression_operator=false)
  } else {
    ""
  }
  self.builder.finish_node()
  if name == "" || target == "" {
    None
  } else {
    Some({ name, type_parameters, target, annotations })
  }
}

///|
fn Parser::parse_function_parameter(self : Parser) -> FunctionParameter? {
  if !self.at(identifier()) {
    return None
  }
  let name = self.bump().text()
  let type_name = self.parse_type_annotation()
  Some({ name, type_name })
}

///|
fn Parser::parse_function_decl(self : Parser) -> FunctionDecl? {
  // PKL-128d: capture annotations preceding the `function` keyword.
  let annotations = self.take_pending_annotations()
  // PKL-148d: const provenance matters when class defaults reference
  // module-level functions.
  let is_const = self.take_pending_const()
  // PKL-117: drain the `abstract` modifier collected by
  // `skip_member_header`. Abstract functions intentionally have no
  // body — the modifier is the explicit marker the typechecker uses
  // when checking that concrete subclasses override every inherited
  // abstract method.
  let is_abstract = self.take_pending_abstract()
  self.builder.start_node(function_decl())
  self.expect_text("function", "function")
  let name = match self.expect(identifier(), "function name") {
    Some(tok) => tok.text()
    None => ""
  }
  // PKL-090: optional type parameter list `` immediately
  // after the function name. Same shape and intent as the class
  // parameter scope: names are recorded on the AST and the typechecker
  // binds them to UnknownType inside the body.
  // PKL-116: each parameter may carry a `: ` suffix
  // (`function pick(x: T) = ...`) recorded in
  // `type_parameter_bounds`; the typechecker enforces the bound at
  // call sites.
  let type_parameters : Array[String] = []
  let type_parameter_bounds : Array[String?] = []
  self.skip_whitespace()
  if self.at_text("<") {
    ignore(self.bump())
    let mut more = true
    while more {
      self.skip_whitespace()
      // PKL-140: variance modifiers `` / `` — skip before the
      // identifier parse (matches the class-decl path).
      if self.at(in_kw()) || self.at_text("out") {
        ignore(self.bump())
        self.skip_whitespace()
      }
      match self.expect(identifier(), "type parameter") {
        Some(tok) => type_parameters.push(tok.text())
        None => type_parameters.push("")
      }
      self.skip_whitespace()
      if self.at(colon()) {
        ignore(self.bump())
        self.skip_whitespace()
        let bound = self.parse_type_text(
          stop_at_arrow=true,
          stop_at_expression_operator=true,
        )
        if bound == "" {
          type_parameter_bounds.push(None)
        } else {
          type_parameter_bounds.push(Some(bound))
        }
      } else {
        type_parameter_bounds.push(None)
      }
      self.skip_whitespace()
      if self.at_text(",") {
        ignore(self.bump())
      } else {
        more = false
      }
    }
    self.skip_whitespace()
    if self.at_text(">") {
      ignore(self.bump())
    }
  }
  let parameters : Array[FunctionParameter] = []
  self.skip_whitespace()
  if self.at(lparen()) {
    ignore(self.bump())
    self.skip_whitespace()
    while !self.at(eof()) && !self.at(rparen()) {
      match self.parse_function_parameter() {
        Some(parameter) => parameters.push(parameter)
        None =>
          if self.at(comma()) {
            ignore(self.bump())
          } else {
            ignore(self.bump())
          }
      }
      self.skip_whitespace()
      if self.at(comma()) {
        ignore(self.bump())
        self.skip_whitespace()
      }
    }
    ignore(self.expect(rparen(), ")"))
  }
  // PKL-148as: function return-type annotation must accept the
  // function-type form `(X) -> Y` (the only place where `->` is part
  // of the type rather than a lambda body marker). `parse_type_annotation`
  // stops at arrow (correct for lambda-parameter annotations where
  // `(a: Int) -> body` has `Int` as the param type and `->` as the
  // body marker), so the return-type slot is the one site that must
  // bypass that stop. Inline the colon-aware walk here with
  // `stop_at_arrow=false` so `function matches(...): (String) -> Boolean
  // = ...` parses the whole function type before looking for `=`.
  self.skip_whitespace()
  let return_type_name = if self.at(colon()) {
    ignore(self.bump())
    self.skip_whitespace()
    let t = self.parse_type_text(
      stop_at_arrow=false,
      stop_at_expression_operator=false,
    )
    if t == "" {
      None
    } else {
      Some(t)
    }
  } else {
    None
  }
  let body = if ({
      self.skip_whitespace()
      self.at(eq())
    }) {
    ignore(self.bump())
    Some(self.parse_expr())
  } else {
    None
  }
  self.builder.finish_node()
  if name == "" {
    None
  } else {
    Some({
      name,
      type_parameters,
      type_parameter_bounds,
      parameters,
      return_type_name,
      body,
      annotations,
      is_const,
      is_abstract,
    })
  }
}

///|
fn Parser::parse_property_decl(self : Parser) -> Binding? {
  let annotations = self.take_pending_annotations()
  let is_const = self.take_pending_const()
  self.builder.start_node(property_decl())
  if !self.at(identifier()) {
    self.skip_unknown_member()
    self.builder.finish_node()
    return None
  }
  let name = match self.expect(identifier(), "property name") {
    Some(tok) => tok.text()
    None => ""
  }
  let type_name = self.parse_property_type_annotation()
  // PKL-140: a property declared without a `{` body and without `=`
  // is an abstract / external slot (`foo: Int?` / `external minInt: Int`).
  // Apple Pkl uses this in stdlib modules for host-bound or
  // subclass-filled properties. Mark the binding as abstract and skip
  // it at the evaluator (no value to render); only the type record
  // survives for typecheck purposes.
  let mut abstract_slot = false
  let value = if ({
      self.skip_whitespace()
      self.at(lbrace())
    }) {
    // PKL-137: `name { body }` (no `=`, brace body) is Apple Pkl's
    // *amend* form — the body's shape depends on the existing value
    // of `name` (Listing → bare elements, Mapping → `[k] = v` entries,
    // object → property decls). The parser doesn't know the existing
    // type at this point, so dispatch by peeking the first significant
    // token inside the brace, the same way PKL-138 does for
    // `new { ... }`.
    let mut body = self.parse_inferred_new_body()
    // PKL-148ap: `name { body1 } { body2 }` chains additional amend
    // bodies onto the same property. Apple Pkl's `foo { bar { "Hello"
    // } } { bar { "World" } }` produces the merged value where the
    // second body amends the first. Each trailing `{` wraps the
    // running expression in an `AmendExpr`.
    while ({
            self.skip_trivia()
            self.at(lbrace())
          }) {
      let members = self.parse_object_body_members()
      body = AmendExpr(body, members)
    }
    body
  } else if ({
      self.skip_whitespace()
      self.at(eq())
    }) {
    ignore(self.bump())
    self.parse_expr_with_expected_type(type_name)
  } else {
    abstract_slot = true
    NullLiteral
  }
  self.builder.finish_node()
  if name == "" {
    None
  } else {
    Some({
      name,
      type_name,
      value,
      exported: true,
      is_const,
      annotations,
      abstract_slot,
      sibling_slot: false,
    })
  }
}