in python/moz/l10n/formats/fluent/parse.py [0:0]
def message(ftl_pattern: ftl.Pattern) -> Message:
sel_data = find_selectors(ftl_pattern, [])
sel_expressions = [sd[0] for sd in sel_data]
filter: list[Key | None] = [None] * len(sel_expressions)
msg_variants: dict[tuple[Key, ...], Pattern]
var_names: set[str] = set()
if sel_expressions:
key_lists = [list(dict.fromkeys(sd[2])) for sd in sel_data]
for keys in key_lists:
keys.sort(key=lambda k: (k[2], not k[1]))
msg_variants = {key: [] for key in product(*key_lists)}
else:
msg_variants = {(): []}
def add_pattern(ftl_pattern: ftl.Pattern) -> None:
el: (
ftl.TextElement
| ftl.Placeable
| ftl.InlineExpression
| ftl.SelectExpression
)
for el in ftl_pattern.elements:
while isinstance(el, ftl.Placeable):
el = el.expression
if isinstance(el, ftl.SelectExpression):
msg_sel = next(sd[0] for sd in sel_data if el.selector in sd[1])
idx = sel_expressions.index(msg_sel)
prev_filt = filter[idx]
for v in el.variants:
filter[idx] = variant_key(v)
add_pattern(v.value)
filter[idx] = prev_filt
else:
for keys, msg_pattern in msg_variants.items():
if all(
(filt is None or key == filt) for key, filt in zip(keys, filter)
):
if isinstance(el, ftl.TextElement):
if msg_pattern and isinstance(msg_pattern[-1], str):
msg_pattern[-1] += el.value
else:
msg_pattern.append(el.value)
else:
expr = inline_expression(el)
if isinstance(expr.arg, VariableRef):
var_names.add(expr.arg.name)
msg_pattern.append(expr)
add_pattern(ftl_pattern)
if sel_expressions:
declarations = {}
selectors = []
for expr in sel_expressions:
stem = expr.arg.name if isinstance(expr.arg, VariableRef) else ""
i = 0
name = stem
while name in var_names or name == "":
i += 1
name = f"{stem}_{i}"
declarations[name] = expr
selectors.append(VariableRef(name))
var_names.add(name)
variants = {
tuple(map(message_key, keys)): msg_pattern
for keys, msg_pattern in msg_variants.items()
if msg_pattern
}
return SelectMessage(declarations, tuple(selectors), variants)
else:
return PatternMessage(next(iter(msg_variants.values())))