flattenToOther static method

String flattenToOther(
  1. String message, {
  2. String? keyHint,
})

Collapse every ICU plural / select / selectordinal expression in message to its other branch, recursively, and strip type/format suffixes from typed placeholders ({amount, number, currency}{amount}). Literal text, simple {placeholder} tokens, and quoted runs are preserved verbatim. This is the flat-json lowering rule — see dialect/spec/flat-json.md.

Throws FormatException if a plural/select/selectordinal expression is missing its required other branch (ICU mandates one; flat-json can't pick a branch without it). keyHint is woven into the error message so callers can point at the offending key.

Examples: '{count, plural, =1{1 item} other{{count} items}}''{count} items'. '{g, select, female{She} other{They}}''They'. 'Total: {amount, number, currency}''Total: {amount}'. 'Hello {name}''Hello {name}' (unchanged).

Implementation

static String flattenToOther(String message, {String? keyHint}) {
  final buf = StringBuffer();
  var i = 0;
  while (i < message.length) {
    final ch = message.codeUnitAt(i);
    if (ch == _apos) {
      final end = _skipQuotedRun(message, i);
      buf.write(message.substring(i, end));
      i = end;
      continue;
    }
    if (ch == _open) {
      final end = _matchClose(message, i);
      if (end == -1) {
        // Unmatched `{` — malformed. Copy the remainder verbatim rather
        // than silently truncating; the structural checks flag the real
        // problem upstream.
        buf.write(message.substring(i));
        break;
      }
      buf.write(_flattenExpr(message.substring(i + 1, end), keyHint));
      i = end + 1;
      continue;
    }
    buf.writeCharCode(ch);
    i++;
  }
  return buf.toString();
}