def _with_meta(gen_node):
    """Wraps the node generated by gen_node in a :with-meta AST node if the
    original form has meta.

    :with-meta AST nodes are used for non-quoted collection literals and for
    function expressions."""

    @wraps(gen_node)
    def with_meta(
        ctx: ParserContext,
        form: Union[llist.List, lmap.Map, ISeq, lset.Set, vec.Vector],
    ) -> Node:
        assert not ctx.is_quoted, "with-meta nodes are not used in quoted expressions"

        descriptor = gen_node(ctx, form)

        if isinstance(form, IMeta):
            assert isinstance(form.meta, (lmap.Map, type(None)))
            form_meta = _clean_meta(form.meta)
            if form_meta is not None:
                meta_ast = _parse_ast(ctx, form_meta)
                assert isinstance(meta_ast, MapNode) or (
                    isinstance(meta_ast, Const) and meta_ast.type == ConstType.MAP
                )
                return WithMeta(
                    form=form, meta=meta_ast, expr=descriptor, env=ctx.get_node_env()
                )

        return descriptor

    return with_meta
Wraps the node generated by gen_node in a :with-meta AST node if the
    original form has meta.

    :with-meta AST nodes are used for non-quoted collection literals and for
    function expressions.