def mf2_validate_message()

in python/moz/l10n/formats/mf2/validate.py [0:0]


def mf2_validate_message(msg: PatternMessage | SelectMessage) -> None:
    """
    Validate that the message satisfies MessageFormat 2 validity constraints.

    May reorder declarations.

    May raise `MF2ValidationError`.
    """
    if isinstance(msg, PatternMessage):
        _validate_declarations(msg.declarations)
        _validate_pattern(msg.pattern)
    elif isinstance(msg, SelectMessage):
        _validate_declarations(msg.declarations)
        if not msg.selectors or not isinstance(msg.selectors, tuple):
            raise MF2ValidationError(f"Invalid selectors: {msg.selectors}")
        for sel in msg.selectors:
            if isinstance(sel, VariableRef):
                _validate_variable(sel)
            else:
                raise MF2ValidationError(f"Invalid selector: {sel}")
            sel_name = sel.name
            sel_expr = msg.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 = msg.declarations.get(sel_name, None)
                else:
                    sel_expr = None
            if sel_expr is None:
                raise MF2ValidationError(
                    msg, f"Missing selector annotation for ${sel.name}"
                )
        sel_count = len(msg.selectors)
        if not isinstance(msg.variants, Mapping):
            raise MF2ValidationError(f"Invalid variants: {msg.variants}")
        for keys, pattern in msg.variants.items():
            if not isinstance(keys, tuple):
                raise MF2ValidationError(f"Invalid keys: {keys}")
            for key in keys:
                if not isinstance(key, str) and not isinstance(key, CatchallKey):
                    raise MF2ValidationError(f"Invalid key: {key}")
            if len(keys) != sel_count:
                raise MF2ValidationError(
                    f"Variant key mismatch, expected {sel_count} but found {len(keys)}",
                )
            _validate_pattern(pattern)
        if (CatchallKey(),) * sel_count not in msg.variants:
            raise MF2ValidationError("Missing fallback variant")
    else:
        raise MF2ValidationError(f"Invalid message: {msg}")