in python/moz/l10n/formats/fluent/serialize.py [0:0]
def fluent_astify_message(message: str | Message) -> ftl.Pattern:
"""
Transform a message into a corresponding Fluent AST pattern.
Function names are upper-cased, and expressions using the `message` function
are mapped to message and term references.
"""
if isinstance(message, str):
return ftl.Pattern([ftl.TextElement(message)])
if not isinstance(message, (PatternMessage, SelectMessage)):
raise ValueError(f"Unsupported message: {message}")
if isinstance(message, PatternMessage):
return flat_pattern(message.declarations, message.pattern)
# It gets a bit complicated for SelectMessage. We'll be modifying this list,
# building select expressions for each selector starting from the last one
# until this list has only one entry `[[], pattern]`.
#
# We rely on the variants being in order, so that a variant with N keys
# will be next to all other variants for which the first N-1 keys are equal.
variants = [
(list(keys), flat_pattern(message.declarations, value))
for keys, value in message.variants.items()
]
other = fallback_name(message)
keys0 = variants[0][0]
while keys0:
selector = value(message.declarations, message.selectors[len(keys0) - 1])
if (
isinstance(selector, ftl.FunctionReference)
and selector.id.name == "NUMBER"
and selector.arguments.positional
and isinstance(selector.arguments.positional[0], ftl.VariableReference)
and not selector.arguments.named
):
selector = selector.arguments.positional[0]
base_keys = []
sel_exp = None
i = 0
while i < len(variants):
keys, pattern = variants[i]
key = keys.pop() # Ultimately modifies keys0
ftl_variant = ftl.Variant(
variant_key(key, other), pattern, isinstance(key, CatchallKey)
)
if sel_exp and keys == base_keys:
sel_exp.variants.append(ftl_variant)
variants.pop(i)
else:
base_keys = keys
sel_exp = ftl.SelectExpression(selector.clone(), [ftl_variant])
variants[i] = (keys, ftl.Pattern([ftl.Placeable(sel_exp)]))
i += 1
if len(variants) != 1:
raise ValueError(f"Error resolving select message variants (n={len(variants)})")
return variants[0][1]