in python/moz/l10n/formats/mf2/message_parser.py [0:0]
def complex_message(self) -> Message:
assert self.char() == "."
declarations: dict[str, Expression] = {}
declared: set[str] = set()
while keyword := self.source[self.pos : self.pos + 6]:
if keyword == ".input":
name, expr = self.input_declaration()
elif keyword == ".local":
name, expr = self.local_declaration()
if isinstance(expr.arg, VariableRef):
declared.add(expr.arg.name)
else:
break
if expr.function:
for opt_value in expr.options.values():
if isinstance(opt_value, VariableRef):
declared.add(opt_value.name)
if name in declared:
raise MF2ParseError(self, f"Duplicate declaration for ${name}")
declarations[name] = expr
declared.add(name)
self.skip_opt_space()
if keyword == ".match":
selectors = self.match_statement()
for sel in selectors:
sel_name = sel.name
sel_expr = declarations.get(sel_name, None)
while sel_expr is not None and sel_expr.function is None:
if (
isinstance(sel_expr.arg, VariableRef)
and sel_expr.arg.name != sel_name
):
sel_name = sel_expr.arg.name
sel_expr = declarations.get(sel_name, None)
else:
sel_expr = None
if sel_expr is None:
raise MF2ParseError(
self, f"Missing selector annotation for ${sel.name}"
)
variants = {}
while self.pos < len(self.source):
keys, pattern = self.variant(len(selectors))
if keys in variants:
raise MF2ParseError(self, f"Duplicate variant with key ${keys}")
variants[keys] = pattern
fallback_key = (CatchallKey(),) * len(selectors)
if fallback_key not in variants:
raise MF2ParseError(self, "Missing fallback variant")
return SelectMessage(declarations, selectors, variants)
pattern = self.quoted_pattern()
return PatternMessage(pattern, declarations)