flattenToOther static method
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();
}